历史上的今天
返回首页

历史上的今天

今天是:2024年08月25日(星期日)

正在发生

2021年08月25日 | 飞思卡尔智能车之舵机算法

2021-08-25 来源:eefocus

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


前言:


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


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


阶段一:


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


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


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


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

 

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


阶段二:


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


if(abs(Deltax)    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(ControlControl_right_limit

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


阶段四:


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


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


name='6.2.2';

jpg=strcat(name,'.jpg?imageView2/2/w/550');

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调节作用不会太明显,除非你能到达一种超高速。不过车速那么快,必定老司机。老司机就不用在乎这些了。


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

推荐阅读

史海拾趣

ARCOLECTRICSWITCHES公司的发展小趣事

在技术进步的基础上,ARCOLECTRIC SWITCHES公司积极拓展国内外市场。公司通过与各大电子厂商建立合作关系,将产品广泛应用于家电、通讯、汽车等多个领域。同时,公司注重品牌建设,通过广告宣传和市场推广活动提升品牌知名度和美誉度。这些努力使得ARCOLECTRIC SWITCHES公司的市场份额逐年增长,品牌影响力不断扩大。

昆泰(CHRONTEL)公司的发展小趣事

多年来,昆泰始终秉持着创新的理念,不断推动其在CRO领域的技术突破和业务创新。通过与全球各地的药企、科研机构合作,昆泰在药物研发、临床试验等领域取得了多项重要成果。展望未来,昆泰将继续坚持创新驱动的发展战略,为全球医药行业的发展做出更大的贡献。

Cicoil公司的发展小趣事

在20世纪60年代,人类开始了对月球的探索。Cicoil公司的柔性扁平电缆被选为阿波罗任务的关键组件之一。这些电缆为宇航员在月球上的活动提供了安全可靠的电力和数据传输保障。当尼尔·阿姆斯特朗和巴兹·奥尔德林在月球上行走时,他们的每一步都离不开Cicoil电缆的支持。这一历史性的时刻让Cicoil公司名声大噪,也进一步巩固了其在电子行业中的地位。

ABB Group公司的发展小趣事

Cicoil公司的创立可以追溯到电子行业的快速发展时期。创始人看到了扁平电缆在电子设备中的巨大潜力,于是决定专注于这一领域的研究和开发。他们投入大量资源,研发出具有独特技术的柔性扁平电缆,为电子设备提供了更为灵活和可靠的连接方案。这一创新产品在市场上引起了轰动,为Cicoil公司赢得了良好的声誉和市场份额。

Analytic Instruments Corp公司的发展小趣事

随着技术的不断成熟和产品线的不断丰富,Analytic Instruments Corp开始积极拓展市场。公司通过与行业内的知名企业和研究机构建立合作关系,成功地将产品打入多个重要的应用领域。同时,公司还加大了品牌宣传力度,通过参加行业展会、举办技术研讨会等方式,提升了品牌知名度和影响力。

Ememory Technology Inc公司的发展小趣事

为了满足市场对高性能、低功耗芯片的需求,eMemory在2016年宣布向150nm高电压制程工艺扩展其可编程Neobit技术。这一技术的成功开发,使得eMemory能够在LCD驱动IC、逻辑IC和功率控制IC等高速增长的市场中占据一席之地。Neobit技术的可擦编程只读存储器特性,为芯片设计提供了更大的灵活性和可定制性。

问答坊 | AI 解惑

请教:在vc++下能通过,移植到evc下提示链接错误!

HTTPServer.obj : error LNK2019: unresolved external symbol \"public: __cdecl std::_Lockit::~_Lockit(void)\" (??1_Lockit@std@@QAA@XZ) referenced in function \"public: __cdecl std::_Tree::~_Tree(vo id)\" (??1?$_Tree@V?$basic_string ...…

查看全部问答>

pci的bar问题

请问高手们,怎样通过pci的配置寄存器中的bar读取的值,来获取映射到io或者memory的地址?bar是一个32位的寄存器。。。…

查看全部问答>

IDE转SATA时,端口怎么初始化?

我想利用IDE转SATA和SATA转IDE 2种卡实现并/串高速数据传输! 有2个地方都是并口,40M速度,想利用IDE转SATA卡先并--串行,然后用SATA转IDE卡再把串--并行,实现近距离数据传输。实验时距离不超过30cm, 但用示波器就是看不到数据传过来。此方案若 ...…

查看全部问答>

mxchip制作的中文手册不厚道

                                 mxchip制作的中文手册排版上太浪费空间,本来一页能写下的东西洋洋洒洒写了两页多,还不让编辑,要是把一本stm32固 ...…

查看全部问答>

请教香水城

VTarget = 3.352V Info: TotalIRLen = 9, IRPrint = 0x0011 ***JLink Error: Wrong ROM location (15:2). Expected 0xE00FF003, Found 0x14 ...…

查看全部问答>

寻找测量物体竖直高度的传感器

公司的垂直连续电镀线上面需要安装一个能测量PCB板的高度的传感器,PCB板子是垂直悬吊起来的,排成一排,在水平方向运动…

查看全部问答>

FCI连接器已解决FFC/FPC方案

      FCI已推出高速I/O接口的完整产品线。然而随着科技的不断进步,由FCI公司生产的新型SFGL系列( 0.4毫米间距和0.9毫米高度)FPC后翻式ZIF连接器含有各种微间距后翻执行机构系列,它们就是目前的间距0.5毫米、高度0.9毫米( ...…

查看全部问答>

M430 UART0 接收数据

最近在研究430 看到有人写的一段代码,为了接收GPS的数据,使用串口中断接收,部分代码如下: if(global_temp_data_num==0)   //获取\"GG\"标志         {           if ...…

查看全部问答>

keil5里添加文件

在keil5里,我如何在一个已经建好的工程里添加新的c和h文件啊? …

查看全部问答>