精华内容
下载资源
问答
  • 飞思卡尔智能车舵机算法

    万次阅读 多人点赞 2018-06-18 00:14:19
    恍恍惚惚,将近一年的智能车生涯终于结束了,虽然到目前为止我们的车子还是比不上学长的神车,但是也还算是对的起我们组一年的辛勤与努力了,为了给自己惨败的智能车比赛和还算完整的智能车学习生涯留下点东西。...

     

    恍恍惚惚,将近一年的智能车生涯终于结束了,虽然到目前为止我们的车子还是比不上学长的神车,但是也还算是对的起我们组一年的辛勤与努力了,为了给自己惨败的智能车比赛和还算完整的智能车学习生涯留下点东西。我打算慢慢的把我们做车子的一些感悟等记录下来,供新手参考,希望新手入门智能车的时候能够少烧几块k60(毕竟那种价格/哭死)。再表达一下我这一年下来对智能车的感悟吧:铁打的飞思卡尔,流水的参赛队员/手动滑稽。

    这篇文章,我将会从舵机的控制策略来向介绍我的调试经历,供新手进行参考,尽量详细的记录我们调试一步一步变化的过程,坦白的说我们的车子最终跑的不是很好,原因是各个方面的。但是我认为我们遇到的问题对新手应该还是有些用处的,时间原因,我将会不定期更新,望谅解。(已完结)

     

    前言:

    想要控制舵机,就需要先了解舵机的工作原理,这一点前辈们的资料相当的丰富,大家可以先行学习一下。

    然后因为我们组做的是光电组,所以就引入一些摄像头的一些名词,其他的组别也可以根据这个思路进行舵机调节,不影响学习(仅限赛道组,无赛道组例外)

    阶段一:

    刚刚入手舵机首要目标当然是理解它是如何工作的,控制原理很简单,这个了解了以后我们就开始想办法让他工作了。那刚开始该怎么办呢?先想一下我现在有什么呢?摄像头传来的中线信息和有效行信息。那第一步就是利用这些数据,怎么用呢?

    自然而然的我们就该想到,如果图像上面的中线是偏左的,说明我的车子是在中线的右边,那我就该让舵机往左边打角;如果中线是偏右的,说明我的车子是在中线的左边,那我们就该让舵机往右边打角。

    那么问题来了,我怎么让单片机根据现在的中线数组知道我的车子是往左还是往右的呢?我们人看到图像的时候一眼就能够看到这个中线到底是往左还是往右、、、哎,等等,你怎么能够一眼看出来?你是不是经过了某种魔术的计算啊?啊啊啊,我没有啊,你看这图不是很明显中线在图像的左边吗?Emmm有道理,我们让这个中线数组和图片最中间的那个数组做差不就得到了吗?那该选那些行进行计算呢?管他那么多呢,先选上中间行再说吧。于是我们得到:

    Deltax=Center_line[Image_H/2]-Image_L/2;
    

     

    如果deltax>0说明中线在图像的右侧,否则就在左侧,那么打多少呢?当然是直接打到Limit了,肯定不会不够用。好了知道车子相对于赛道的位置,我们就可以控制舵机向对应的方向打角就好了。那我们不如给这个方法起个名字吧,那不如就叫棒棒算法吧(嗯,这个名字好像有那么点难听,但前辈们就是这样起的啊,我也很绝望啊)。

     

    阶段二:

    拿着棒棒算法弄出来的程序到赛道上面跑一跑,怎么回事,车子走个直线都走不稳,怎么一会这边一会那边,虽然整体在中间跑的,但是这也太难看了吧。只有一点点偏差舵机就会打角非常的大,怎么解决呢?当然是让车子距离中线近的时候让舵机打角小一点;当车子距离中线远的时候让舵机的打角大一点。那么这个距离中线的远近是?对,就是上一个阶段计算出来的deltax。

    if(abs(Deltax)<Image_L/6)
        Control=Limit/3;
    else if(abs(Deltax)>=Image_L/6&&abs(Deltax)<=Image_L/3)
            Control=Limit*2/3;
         else
            Control=Limit;

    当然啦大家想分多少段多可以了,我在这里只是拿三段举个例子。

    我们就有了第二个阶段的东西,分段式棒棒算法,快整理一下代码烧进去试试效果。

    阶段三:

    棒棒算法对这个打角分了阶段,但是好像又发现了新的问题,当计算得到的deltax处在临界点附近的时候,舵机的 打角会在一个较大范围内进行摆动,这样看到车子的效果就是猛地一下在这边,然后就又变到了另一边,好像和第一阶段的棒棒算法差别不是很大,那该如何将它变得顺滑一点点呢?对,让对应范围内的打角变成线性的打角,随着这个线性系数的增加而逐渐变化的舵机打角值,这个东西其实就是一个纯p的pid算法,用代码表示就是:

     Control=S3010_kp*deltax+Contorl_median;

    接下来的问题就是该如何调参数了,终于算是进入到舵机调试的核心部分了,那这个参数该如何进行调试呢?首先是进行计算,我需要算出来这个S3010_kp到底处于一个什么样的数量级范围内怎么算呢?左右极值的差除以我所要计算的delatx的范围好像就行;

    S3010_kp=(Control_left_limit-Control_right_limit)/deltax_scale;

    通过这个公式,我们就可以得到一个最为基础的打角kp值然后代入进去,发现效果好像还行,多跑几圈,感觉还不是很理想,那该怎么办呢?我的kp调节是不是还有点问题这样粗暴的算出一个kp好像不是太合适,那该怎么调节呢?这个时候就真的没有什么办法了,只能一点一点尝试,一个参数一个的实验,最开始的时候每次增加十,直到看到的效果不好,然后一点一点往下面减,直到车子跑起来还算顺畅的时候。在这个过程之前,一定要记得加上舵机打角的限幅代码,要不然我得到的舵机打角过大或者过小而机械结构达不到然后就大概率可以考虑换舵机了/无奈。限幅的方法呢,也很简单,这样就可以了

    if(Control>Control_left_limit)Control=Control_left_limit;
    if(Control<Control_right_limit)Control=Control_right_limit;//Control_left_limit>Control_right_limit

    到这,纯p调节的舵机打角就算完成了,下一步就是继续深化了,要求不高的话这样子得到的kp值也是可以使用的,整体而言看不到太大的问题,如果想要继续优化,那就要再往下进行调节了。

    阶段四:

    纯p调节得到的舵机打角虽然能够工作,但是如果想要提速,就会参数的问题就会大范围的暴露出来,速度一高,跑出来的效果还是很差,总能感觉到我们的舵机打角不够或者太多的问题,我们还是应该对p进行精细化调节,那到底该怎么精细呢?查表法,怎么查表呢?我们的每一个deltax都会对应着一个Control值,我们把这个关系列出来,当得到这个deltax的时候查询一下此时的kp然后算出对应的Control,我们不就得到了相对应的关系。那么问题来了,我们该如何得到这个表呢?

    这个时候,就该进行一些数据测量了,我们需要从赛道上得到几组数据,怎么测量呢,让舵机固定打角,然后推着他走弯道,直到它能够完美的过来这个弯道,然后记录此时的舵机打角值和得到的deltax值,再测试不同的弯道得到至少三组数据,正走反走都需要那样就是至少六组数据得到数据以后该怎么办呢?这么点数据肯定不够查表,那我们就需要对数据进行一下处理了,最有用的办法就是对所需要的数据进行一下拟合,一般上拟合成二次函数曲线就可以了,太高次数会更加接近我们所需要的结果,但是因为数据有限,我们也只能得到这个值。那么数据拟合该怎么做呢?当然是强大的MATLAB了,参考代码如下:

    name='6.2.2';
    jpg=strcat(name,'.jpg');
    txt=strcat(name,'.txt');
    x=[59 43 19 51];y=[530 390 255 400];%参考数据,这是一边的数据
    p=polyfit(x,y,3);
    x1=1:80;
    y1=polyval(p,x1);
    h=plot(x,y,'r',x1,y1,'b');
    k1=zeros(80,1);
    fid=fopen(txt,'w');%将生成的数据写到txt文件里面方便复制
    for i=1:length(y1)
        k1(i)=y1(i);
        fprintf(fid,'%3.2f,',k1(i));
    end
    fclose(fid);

    这样我们就得到了一个表,有了这个表,我们再进行查表,舵机的打角就变得更加圆滑了,这个阶段的任务也就完成了。

    阶段五:

    做过上面的这些步骤以后,车子已经能够满足大多数情况的转弯打角等,似乎是没有什么再改变的空间了,但是在不断地加速以后,我们还是发现了问题,车子转弯的时候有点缓慢,容易冲出去,那该怎样进行调整呢?当车子快到转弯的地方的时候,我们希望他就提前打角,舵机自身的响应延迟加上此时的高车速,提前打角显得非常有必要,那该如何提前呢?加大我算出来的值,让deltax开始变大的时候我们就加上一个微分d进行校正,让得到的舵机打角更加偏向我所期待的值;当要出弯的时候,我期待车子响应不要那么快,解决方式也是对这个偏差的差值乘以某个系数加到我们的舵机打角上面。这些,其实就是我们pid调节中的微分调节过程。

    Control=Control_median+S3010_kp*deltax+S3010_kd*(deltax_last-deltax_now);

    那么下一个问题就是,这个kd的参数该如何确定呢?首先我们要确定都有哪些因素影响了kd,首先是偏差的差值,这个是我们主要要进行校正的部分,其次是速度,我们的速度不一样得到的kd值也应该是有那么一点点差别的,所以主要根据这两个之间的关系,确定出一个比较好的值。其实如果kp的值能够调好,kd调节作用不会太明显,除非你能到达一种超高速。不过车速那么快,必定老司机。老司机就不用在乎这些了。

    至此,我们组在调试舵机的时候所用到的调试方法大致讲述完了,希望你看完这篇文章以后能加快调车进程,然后开始为其他的问题头疼吧(哈哈哈哈哈哈哈)。

     

     

     

     

     

     

     

    展开全文
  • 智能车舵机控制PID

    热门讨论 2012-11-20 01:33:10
    增量式pid学控制的可以看看运用在智能车舵机 分享给大家,欢迎交流啊
  • 智能车PID
  • 为提高智能车舵机的响应速度,分析了智能车控制系统的特点以及应用常规模糊控制器进行控制的局限性,提出了模糊PI D控制算法.推导出模糊PI D控制器消除稳态误差的原理,并介绍了模糊PI D控制器的设计方法.实验结果表明,...
  • 介绍了基于MC9S12XS128单片机控制的智能车系统,...对智能车寻线舵机控制系统的软件设计思路和控制算法思想等进行了详细的论述。测试结果表明智能车能准确稳定地跟踪引导黑线行驶,该算法能够很好地对智能车进行控制。
  • 舵机控制优化,利用PID控制舵机使舵机更加容易控制以及有效切内道跑。
  • 恩智浦(飞思卡尔)智能车舵机和电机PID控制

    万次阅读 多人点赞 2018-09-01 16:44:54
    写电机PID的时候,首先要理解电机控制与舵机控制的区别。比如都是单纯的P(比例)控制,假设target(设定值)不变,measure(实际值)小于target的情况下,舵机的P输出会使得err逐渐减小,并随之时间的推移趋近于0,...

    这篇文章主要是基于B车模这种单电机四轮车模来写的,内容是讲两者PID之间的差异,以及两者各自的主要控制参数,并不讲它们的完整的PID程序要如何写。
    写PID的时候,首先要理解电机控制与舵机控制的区别。很多人有一个误区就是把电机和舵机当成同一个系统来控制,在调车的时候也是用同样的方法来进行调车。我们首先来看两个公式:
    1、err = target - measure(偏差 = 设定值 - 实际值);
    2、out(控制量) = P * err + I*err的累积 +D * (err - pre_err);
    在舵机中,err就是摄像头计算的中线与中线的偏差值,控制量则是舵机引脚的电压值,也就是舵机打角角度大小。
    在电机中,err是电机的设定速度与实际速度的差值,而我们的控制量则是电机输入电压的大小
    比如都是单纯的P(比例)控制,假设target(设定值)不变,measure(实际值)小于target的情况下,舵机的P输出会使得err逐渐减小,并随之时间的推移趋近于0,其实理论上单纯的P控制是不会达到target的,但是现实中的系统是个连续的,而我们在程序上控制是一个差分系统,舵机就会在保持上一个时间的状态直到下一个状态的输出,假设小车一开始是直线行驶,但中线在小车右侧,那么P输出会让舵机向右打角,越接近中线,舵机打角越小直到达到中心线,但我们会认为小车还是直线行驶吗?是不是越接近中线小车转弯角度越小呢?实际恰恰相反,单纯的P控制会让小车在达到中线时转弯角度最大,因为小车的转弯角度是由之前舵机打角一直积累下来的, 在这段时间内,舵机就会保持转弯的状态导致超过target,所以舵机的P控制会导致超调现象
    而在电机中,情况则不同。在理想状态下,不考虑电机死区的问题,电机的转速是与电机的输入功率接近线性关系,在单纯的P控制的情况下,假设target(设定值)不变,measure(实际值)小于target的情况下,电机的P输出会导致怎样的变化呢?结果应该是一开始的err值是最大的,所以out值最大,电机转速加快,导致err值变小,out值相应变小,电机转速减慢,err值又变大,out值相应变大,电机转速加快,电机一直这两个过程中来回变化,如果在变化不大的情况下,在我们眼中看来,电机是基本没有变化的,但measure值与target值相差甚远,所以如果不是特别极端的情况下,电机的P控制是不会导致超调现象的
    那在调车的过程中,我们要怎样去调节参数呢?其实在上面的内容中,我们能知道舵机的P控制能够去达到我们的设定值了,也就是说单纯的P控制理论上是可以控制小车的运动了,即P是舵机最主要的参数,我们可以单纯通过调节P来控制小车的转弯了,但单纯的P控制是不完美的,因为它会使得measure会在target上下浮动,要经过很长的时间才能达到target,这时候就引入了I值和D值了,D值比较容易理解,就是抑制误差剧烈变化,能够使得measure会比较平缓地接近target。而I值则是通过误差的累积来控制输出角度的大小。但赛道不仅仅是直道,有直角弯,也有小弯,还有S弯之类的,这些都是要通过情况分类和慢慢调参数才能得到一个最合适的值。所以一般调舵机的参数的时候一般都是先把I值和D值设为0,再通过调P值慢慢地使得小车能够比较好地转弯后,再引入I值和D值。
    在调节电机的过程中,我当时对它的理解是电机的转速主要是与误差的累积是相关的,当电机没有达到target时,控制量会持续增大,直到转速等于target为止,即I是电机最主要的参数。即我们可以单纯控制I值来让电机达到我们的target,在电机控制中,P值由于与err值相关联,当measure一定时,当err逐渐变小时,P值的输出量也会变小,也就是说,P值除了一开始促进电机的转速外,其他时候都是抑制电机的转速变化。所以一般我们在调电机的参数时,是先把P值和D值设为0,然后慢慢调I值直到找到一个合适的值,再引入P值和D值。

    展开全文
  • 飞思卡尔智能车——舵机PID控制

    万次阅读 多人点赞 2016-12-04 11:49:42
    有一次机器人站不起来了(优必选ALPHA1S),问了客服,说是舵机滑丝,才知道有舵机这个东东。 -------------------------------------------------------- 舵机:小车转向的控制机构。也就是控制小车的转向。它的...

    本篇博客已迁移至:飞思卡尔智能车——舵机及PID控制

    请帮个忙,去新地址访问:)。


    舵机:小车转向的控制机构。也就是控制小车的转向。它的特点是结构紧凑、易安装调试、控制简单、大扭力、成本较低等。舵机的主要性能取决于最大力矩和工作速度(一般是以秒/60°为单位)。它是一种位置伺服的驱动器,适用于那些需要角度不断变化并能够保持的控制系统。在机器人的控制系统中,舵机控制效果是性能的重要影响因素。舵机能够在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出值得单片机系统很容易与之接口。

    -->组成:舵盘、减速齿轮组、位置反馈电位计、直流电机、控制电路等

    -->工作原理:控制信号→控制电路板→电机转动→齿轮组减速→舵盘转动→位置反馈电位计→控制电路板反馈。

    -->输入线:中间红色——电源线Vcc;黑色——地线GND;白色/橘黄色——控制信号线

    -->信号:pwm信号,其中脉冲宽度从0.5-2.5ms(周期为20ms),相对应的舵盘位置为0-180度,呈线性变化。

    pwm波脉冲宽度与舵机转角角度的关系:

    也就是不同脉冲宽度的pwm波,舵机将输出不同的轴转角。所以要控制小车的转角,我们就要控制输出不同脉冲宽度的pwm波。

    什么是PWM波

    PWM:脉冲宽度调制

    -->原理:对电路元件的通断进行控制,使输出端得到一系列幅值相等的脉冲。猪八戒的耙子就可以看似脉冲宽度相等的pwm波形。那不相等的呢,可以 把一排身高相等但胖瘦不同的人排排站看做脉冲宽度不相等的pwm波形。

    比如这里有一个简单的电路:

    我们以5s为一个周期,在每一个5s内,前3s开关打开,后2s开关闭合,则ab端电压将会这样变化:

    (对电路元件的通断进行控制,使输出端得到一系列幅值相等的脉冲。)

    (在这个例子中,输入信号脉冲宽度为3s,周期为5s。)

    重复一下:所以要控制小车的转角,我们就要控制输出不同脉冲宽度的pwm波。

     

    还有一个新的概念——占空比

    占空比:在周期型的现象中,某种现象发生后持续的时间与总时间的比

    -->例如,在成语中有句话:「三天打渔,两天晒网」,如果以三天为一个周期,“打渔”的占空比则为三分之一。(这一行和上一行摘自百度百科,版权归百度百科。)

    因为感觉这个成语说得很对,就拿来它做例子,根据这个成语,大家也应该懂占空比的意思了(所以上图简单的电路,它的占空比应该是3/5)。
     

    --------------------------------------------------------

    PID控制:一种调节器控制规律为比例、积分、微分的控制。其中:P:比例(proportion)、I:积分(integral)、D:导数(derivative)

    式子中Kp为比例系数,Ti为积分时间参数,Td为微分时间常数。
    各个参数的意义作用:

    Kp:比例系数。一般增大比例系数,将加快系统的响应。

    Ti:积分时间常数。一般地,积分控制通常与比例控制或比例微分控制联合使用,构成 PI或 PID控制.增大积分时间常数  (积分变弱)有利于小超调,减小振荡,使系统更稳定,但同时要延长系统消除静差的时间.积分时间常数太小会降低系统的稳定性,增大系统的振荡次数.

    Td:微分时间常数。一般微分控制和比例控制和比例积分控制联合使用,组成PD或PID控制,微分控制可改善系统的动态特性。

    PID的控制方法常用的有两种:

    1.增量式PID

    所谓的增量,就是本次控制量和上次控制量的差值。增量式PID是一种对控制量的增量进行PID控制的一种控制算法。

    公式:


    (说明:Kp->P,Ki->I,Kd->D,e数组->error数组,
    e[n]->本次差值,e[n-1]->上次差值,e[n-2]->上上次差值)

    举个例子,增量式PID可以应用在电机上
    假设当前电机PID的pwm值为5000(精度为10000,即此时的占空比为50%)。对应的速度为100r/s。
    程序发出一个命令,要求pwm输出为0,即要求停车。(可能有人有疑问为什么不直接程序给pwm为0,这也是一种方法,可是由于惯性的存在,小车会在一段时间后才停下。)
    这时,我们可以采用PID控制的方法来实现。
    我们在程序中定义几个变量:


    int speed_now=100;     //此刻的速度
    int speed_want=0;      //期望输出的速度
    int pwm_duty=0;        //本次pwm输出值
    float P=100,I=20,D=2;  //P I D 数值
    float error_pre_pre=0;  //上上次差值
    float error_pre=0.0;    //上次差值
    float error=0.0;         //本次差值


    根据公式,我们编写程序:
    void PID()
    {
        /*
          增量式PID
          P=Kp*(error-error_pre);
          D=Kd*(error-2*error_pre+error_pre_pre);
          I=Ki*error;
          Pwm+=P+I+D;
      */
       error=speed_want-speed_now; //speed_now可以通过编码器采值等等方式得到
       pwm_duty+=(int)(P*(error-error_pre)+I*error+D*(error-2*error_pre+error_pre_pre));
       //注意上面的加号加号是增量式PID的体现。我们对增量(即右边的式子)进行PID控制。
       error_pre_pre=error_pre;
       error_pre=error;
    }


    当函数运行第一次的时候,输出的pwm为:

    电机给了一个反转的力,小车前进受到了阻力,于是可以很快的停下来了。

    增量式PID的优缺点:
    优:
    ①算式中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关,容易通过加权处理获得比较好的控制效果;
    ②计算机每次只输出控制增量,即对应执行机构位置的变化量,故机器发生故障时影响范围小、不会严重影响生产过程;
    ③手动—自动切换时冲击小。当控制从手动向自动切换时,可以作到无扰动切换。
    缺:需要对控制量进行记忆。

    2.位置式PID
    与增量式不同,位置式PID不需要对控制量进行记忆,直接对偏差值进行计算得出期望的pwm。
    公式:

    (说明:Kp->P,Ki->I,Kd->D,ek->本次误差、ek-1->上次误差)

    举个例子,位置式PID可以应用在舵机上。因为舵机本次的pwm输出值与上次pwm输出值关系不太,舵机需要的是快速转到某个角度。
    假设舵机pwm输出1000时舵盘转轴为90°,pwm输出0时舵盘转轴为0°,pwm输出2000时舵盘转轴为180°。
    现在舵机pwm输出为1500,我们要让舵盘转到最中间。
    在这里我们采用PD控制,即I值为0(I值为偏差的积分,即对偏差求和。我们当时试验小车的舵机控制时发现I值可以省略,PD控制足矣。当然,具体需不需要I项要在实际中进行分析验证)。
    代码:
    pwm_duty=(int)(P*error+D*(error-error_pre);   //红色部分表示这是位置式PID控制
    -----------------------------------------------------------------------------------------------------------------

    其他:

    反馈系统:
     
    (图片摘自百度图片,链接地址:点击打开链接
     
     
    *,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥

    广告时间:

    本宝宝开通了一个公众号,记录日常的深度学习和强化学习笔记。希望大家可以共同进步,嘻嘻嘻!求关注,爱你呦!

    KeepYourAims
     

    展开全文
  • 基于黑白CCD摄像头和...分别介绍了该智能小车的硬件系统设计、机械结构设计和程序控制总体流程,并对实现车模转向的PID控制算法进行改进和优化。经过实际测试,本系统基本实现了小车在最优路径下的高速平稳行驶。
  • 本文提出了一种基于积分环节改进的数字PID 智能车舵机控制算法以及间接PID 驱动电机控制算法,阐述了以上两种算法的主要思想和原理,并且对上述两种算法的软件实现方法作具体介绍。智能车车模以HCS12 的16 位单片机...
  • 一、智能车舵机控制

    千次阅读 多人点赞 2019-11-12 00:19:00
    我们本次智能车使用的舵机是通过PWM进行控制。而PWM几个重要的参数就是最大值,最小值和占空比。其中占空比决定了舵机的旋转角度,如下图所示: 不同的占空比控制不同的角度。而我们的目的就是通过...

    前言:
    本文章主要是近期有关舵机知识的总结,将分别从舵机的控制原理,控制流程和代码实现流程几个方面作简要介绍,由于时间紧急,难免有疏漏错误之处,欢迎留言指正
    一、舵机的控制原理:
    我们本次智能车使用的舵机是通过PWM进行控制。而PWM几个重要的参数就是最大值,最小值和占空比。其中占空比决定了舵机的旋转角度,如下图所示:在这里插入图片描述
    不同的占空比控制不同的角度。而我们的目的就是通过摄像头和电感采集上来的数据(MiddleLine)通过算法来控制占空比(脉冲宽度),进而控制舵机的旋转角度。简单介绍了原理之后下面就开始介绍舵机的使用和控制。
    二、舵机左右极值和中值参数设置:
    使用舵机的第一步就是先对舵机进行调中,目的是使舵机左右自由度相同,从而是控制更加准确和方便,如果不调中,很容易出现舵机打死现象,轻则是车子无法正常转弯,重则烧坏舵机。调中方法:
    1、调左极值:
    使以下单个参数相同,观察舵机旋转角度,当左轮即将接触车子为最佳。
    2、调中值:
    方法同上。
    3、调右极值:
    方法同上。

    位置:macro.h

    //-------舵机pwm-------------------
    #define STEER_MIN 9580  //左值9455
    #define STEER_MID 9580 //中值9500
    #define STEER_MAX 9580 //又值9580
    

    注意:在调中的过程中,应尽量做到左右对称,如果左右不对称,可以采取以下几种方法:
    (1)、调节舵机中值角度位置,尽量做到左右自由度对称
    (2)、调节连接杆位置(推荐)
    (3)、有的时候由于工艺的限制,会有部分偏差,只能通过其他硬件结构和软件设计进行弥补
    二、哪里用到这些值:
    1、角度控制
    位置:control.c

    void AngleControl(PID *pid_steer)
    {
    	float middle_line = getMiddleLine();
    	if(middle_line > IMAGE_WIDTH)//中线偏差限幅
    		middle_line = IMAGE_WIDTH;
    	else if(middle_line < 0)
    		middle_line = 0;
    #if DIR == 0//左小右大
    	steer_u = STEER_MID - PositionalPD(pid_steer, middle_line);
    #elif DIR == 1
    	steer_u = STEER_MID + PositionalPD(pid_steer, middle_line);
    #endif
    	
    	//舵机脉宽平滑变化
    	if(steer_u > STEER_MAX)
    		steer_u = STEER_MAX;
    	else if(steer_u < STEER_MIN)
    		steer_u = STEER_MIN;
    	setPWMWidth(steer_u);
    }
    
    uint8 cnt = 0;
    uint8 flag = 0;
    

    从这段代码可以看出,程序先通过函数getMiddleLine()获得中线,然后对中线进行了限幅,防止数值过大或过小损坏硬件。然后传递到 PositionalPD()函数,该函数通过中线和PID结构体中的数值进行计算,最终得出一个误差数值(PD运算得出)output,然后与舵机中值做差,数值传给steer_u ,然后再函数setPWMWidth()函数中对steer_u做一次限幅,然后传递给函数cmt_pwm_duty()就可以进行PWM的设置了,下面将对相关函数作简要介绍:
    (1)、脉冲宽度设置:

    void setPWMWidth(uint16 steer_u)
    {
    	if(steer_u > STEER_MAX) {
    		steer_u = STEER_MAX;
    	} else if(steer_u < STEER_MIN) {
    		steer_u = STEER_MIN;
    	}
            cmt_pwm_duty(steer_u/10); 
    }
    

    该函数看似是进行脉冲宽度设置,实质时进行限幅作用,真正进行脉宽设置的是cmt_pwm_duty()函数。
    (2)、cmt_pwm_duty()函数:

    void cmt_pwm_duty(uint16 duty)
    {
        
        uint32 temp_high_num, temp_low_num;
    
        //计算高低电平的计数次数
        temp_low_num = (cmt_period*(CMT_PRECISON-duty)/CMT_PRECISON);
        temp_high_num = (cmt_period*(duty)/CMT_PRECISON);
        
        //设置低电平时间
        temp_low_num--;
        CMT->CMD1 = temp_low_num >> 8;
        CMT->CMD2 = (uint8)temp_low_num;
        
        //设置高电平时间
        CMT->CMD3 = temp_high_num >> 8;
        CMT->CMD4 = (uint8)temp_high_num;
    
    }```
    这里面有几个参数需要大家了解一下:
    1、cmt_period :一个周期计数的次数
    		表达式:cmt_period = temp_clk/(temp_div+1)/freq;
    		注意:这里用到了预分频的方法,就不多做介绍
    		
    2、CMT_PRECISON:占空比精度
    3、duty:占空比
    

    该函数的作用是进行占空比设置,用到了CMT模块,这里不做详细介绍。

    (3)、PositionalPD()函数:

    
    //积分饱和,输出限幅
    int16 PositionalPD(PID *pid, float sensor_val)//位置式pd
    {
    	float output = 0.0f;
    	float error = 0.0f;
    	
    	float p_error = 0.0f;//当前误差项
    	float d_error = 0.0f;//微分误差项
    	
    	error = pid->set_point - sensor_val;
    	
    	p_error	= error;
    	d_error = error - pid->last_error;
    	
    	if(fabs(error) < 0.1f)
    		output = 0.0f;
    	else
    		output = pid->K_p * p_error + pid->K_d * d_error;
    
    	pid->last_error = error;
    	return (int)output;
    }
    

    该函数的功能主要是根据摄像头和电感传回来的数据进行误差计算,用到了PID控制,算法不是很难,不做详细介绍。
    4、 getMiddleLine()函数:

    float getMiddleLine(void)
    {
    	float inductor = getInductorMiddleLine();
    	float camera = getCameraMiddleLine();
    #if CAMERA==1
    	float result = inductor * car_info.K_g + camera * (1 - car_info.K_g);
    #else
            float result = inductor;
    #endif
    	car_info.mid_line_ = result;
    	return result;
    }
    
    

    该函数的作用是获得中线,当有摄像头时取摄像头和电感的加权值,否则使用电感的数值,这也是为什么不用摄像头也能进行循迹的原因。
    三、总结:
    由次可以看出,舵机控制大致分以下几个步骤:
    1、调中,就是调那三个数值
    2、获得中线:getMiddleLine(),分两种情况,有摄像头和无摄像头
    3、将获得的中线值和调中设置的值通过函数PositionalPD()PID运算得出差值,并将结果传给steer_u
    4、根据steer_u的数值,通过函数setPWMWidth()进行限幅
    5、限幅后将数值steer_u/10传给函数cmt_pwm_duty()进行脉宽设置
    以上就是舵机的大致控制流程,由于能力有限,难免有疏漏错误之处,欢迎留言指正,进行交流。由于本次主要是介绍舵机的有关控制,里面有很多细节没有做详细介绍,大家可以自己上网查阅相关资料进行了解。比赛是一个学习的过程,只有多动手,勤思考,才能有所收获,失败的经验比成功地经验更重要。

    展开全文
  • 基于freescale公司的16位HCS12单片机设计一种智能车系统。...实验证明:系统能很好地满足智能车对路径识别性能和抗干扰能力的要求,舵机调节响应时间快,稳态误差小,具有较好的动态性能和良好的鲁 棒性。
  • 3、PID算法原理、调试经验和代码.pdf; 4、边缘跟踪算法.vsd; 5、舵机滤波算法.txt; 6、经典滤波算法.pdf; 7、控制方法的c语言实现-王帅(摩尔吧).pdf; 8、模糊神经网络及应用程序设计.pdf; 9、...
  • 飞思卡尔 舵机和电机的PID控制算法 在此推荐使用 飞思卡尔 舵机和电机的PID控制算法 在此推荐使用 飞思卡尔 舵机和电机的PID控制算法 在此推荐使用 飞思卡尔 舵机和电机的PID控制算法 在此推荐使用
  • 位置式 PID 算法、恩智浦杯智能车电机PID

    千次阅读 多人点赞 2018-08-23 00:51:40
    由于计算机控制是一种采样控制, 它只能根据采样时刻的偏差计算控制量,而不能像模拟控制那样连续输出控制量量... 表示的控制算法式直接给出的 PID 控制规律定义进行计算的,所以它给出了全部控制量的大小,因此被称...
  • 在整个的智能车系统中包含着自动控制、模式识别、传感器技术、信号处理、控制制算法等等的学科知识,而其中直流电机和舵机的控制算法智能车自主行驶的高速性、稳定性和流畅性起着重要作用。 在目前,参加智能车...
  • 飞思卡尔智能车----模糊PID算法通俗讲

    万次阅读 多人点赞 2018-02-02 11:14:15
    在讲解模糊PID前,我们先要了解PID控制器的原理(本文主要介绍模糊PID的运用,对PID控制器的原理不做详细介绍)。PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元P、积分...
  • 所以要想手眼协调,智能车控制得当,好的视觉处理算法和好的PID调试都密不可分。不然也不会有专门的PID调试的岗位了。废话不多说,下面是我整理的一些资料。 摘录自智能车界的老学长刘键的一篇文章。如果...
  • 算法舵机位置式pid

    千次阅读 2019-12-02 16:31:18
    s3010舵机基础上的舵机位置式pid算法实现 k60 DN 144 平台 给与舵机50hz的工作频率为获取较大的工作频率! 在智能车竞赛上测试通过。 const uint16 steering_mid=715; int16 steer=715; const uint16 steering...
  • 智能车控制算法 —— PID (学习笔记)

    千次阅读 多人点赞 2020-04-24 18:53:55
    PID概念PID的控制方法-1.增量式PID-2.位置式PID 概念 PID控制:一种调节器控制规律为比例、积分、微分的控制。其中:P:比例(proportion)、I:积分(integral)、D:导数(derivative) 式子中Kp为比例系数,Ti为...
  • (2)进行PID算法的设计和改进,在增量式 PID控制的基础上, 引入了不完全微分,微分先行和“最优曲率”算法,构成了改进 PID 算法。根据实际控制的经验,设计出模糊控制表,得出自适应 PID模 糊控制算法。基于BP...
  • 智能车PID

    千次阅读 多人点赞 2020-01-22 10:43:38
    首先感谢学长带我走上飞思卡尔智能车比赛的路,万分感谢。 我们要了解pid是什么,就得知道pid是干什么的。因为没有通过专业的学过pid的用法,一切都是新鲜的,我只能用我的理解简略的介绍一下pid的用处。我们在做...
  • 本文介绍了一种基于 STC12C5A60S2单片机设计的简便智能气味循迹小车。采用两个气味传感器,根据浓度差判断气味流向,并通过PID算法控制舵机打出偏角,使小车循着气味行走。
  • 针对制约智能车快速寻迹的转向及速度问题,提出了采用优化的PID控制算法智能车舵机和电机进行控制。实验结果表明,与传统方法相比,采用连续的信号、基于反馈控制的PID控制算法智能车的快速性、灵敏性、稳定性...
  • 介绍了智能车模型系统。以MC9S12XS128微控制器为核心控制单元,通过OV7620数字摄像头检测赛道信息,并对所采集到的图像进行二...通过光电编码器检测模型车的速度,使用经典PID控制算法控制舵机的转向和驱动电机的转速。
  • 基于Arduino用PID算法实现循迹小车

    千次阅读 多人点赞 2019-09-25 22:07:42
    基于Arduino与PID算法 循迹小车的感受 // 本代码使用pid动态算法,“//后的部分是不用pid”, const int IN_A1=3; const int IN_A2=5; const int IN_B1=6; const int IN_B2=9; const int sensor1=A1; const int ...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 318
精华内容 127
关键字:

智能车舵机pid算法