【智能车心得3】19届智能车竞赛独轮组·原理篇

1 开发平台

        主控芯片:英飞凌TC264或TC377(我是用逐飞主板的)

        编程平台:Aurix Development Studio(简称ADS),或者Hightec(需要在乾勤科技那里获取可set active的例程)

        烧录工具:ADS的集成烧录工具或者Infineon Memtool (它也可擦除所有残留)

        上位机:Vofa+上位机、匿名上位机、串口助手sscom、逐飞助手等。

        新朋友如果想快速上手这些基础工具,只需要好好阅读逐飞或者龙邱提供的说明文档pdf,然后拿着芯片、主板、下载器,跑几个例程就知道怎样使用了。毕竟嵌入式开发的基础也是学会调用库函数。值得注意的是,ADS有一些常见的报错项,有些在百度上也可以搜到,比如target pattern contains no ‘%‘,stop。详情可以查阅逐飞科技或者龙邱科技整理的《ADS软件常见报错汇总》。当时就是因为ADS软件一直编译不了,导致我中间有一个月的时间没法正常开发...最后还让技术人员帮我远程诊断了一下。

        一般该芯片的使用范式都是:CPU0负责初始化,CPU1负责视觉或定位信息,中断负责读取传感器和输出PWM。具体如何分配资源因人而异,但是注意CPU0是弱核,性能略差,CPU1和CPU2才是强核。

        至于上位机,CSDN或者百度上有大量教程。上位机的基本作用也需要知道,一个是显示参数及其波形,还有一个是进行无线调参(尤其是PID参数)。

        附上一个无线调参的学习链接(需要自备无线接收模块):

        【<PID调参>VOFA+实现实时PID调参 (附源码)】

<PID调参>VOFA+实现实时PID调参 (附源码)-CSDN博客

2 整车速览

  • 无RTK的全貌

  • 有RTK的全貌

        最重要的传感器(保护好,别接反线):

        ①陀螺仪②编码器③摄像头④GPS/RTK

        几个安装的细节点:

        (1)取消了飞轮保护罩,防止飞轮卡壳;加装了胶布,防止割手。

        (2)车头前方增加挡板(3D打印),用于碰撞目标板。

        (3)自制了RTK支架,和电池仓配适,压低重心。

        (4)MPU6050陀螺仪放在了摄像头支架上,显得中心对称些(放其他地方调出来的直立效果有点一般)。

        (5)灯驱或者其他模块的VCC和GND线一定不能接反,不然会烧!

        不同车友的机械结构或者硬件方案不同,要多摸索,找到最适合自己的。当然照抄逐飞或龙邱的也可以。

3 平衡原理

        首先摆出一些参考资料供大家查阅:

        逐飞的:

        18届独轮解析:独轮组之逐飞演示车模浅析

        19届独轮解析:独轮组之逐飞演示车模浅析

        19届独轮组准备流程及思路介绍:第十九届独轮组准备流程及思路介绍-逐飞科技

        龙邱的:

        18届独轮【基础原理】:十八届智能车竞赛独轮组——基础原理篇

        18届独轮【资源分享】:十八届智能车竞赛独轮组---资源分享

        18届独轮【总结开源】:十八届智能车竞赛独轮组——总结开源篇

        19届独轮方案:十九届智能车竞赛-独轮组室外方案分享

        推文中也有许多注意事项需要认真考虑,比如安装位置或者松紧。

        此外,我们需要了解一些机器人学和计算机控制的先导知识:

        【姿态角讲解】

机器人行业中我们常说的roll、yaw、pitch是什么? - anobscureretreat - 博客园 (cnblogs.com)

        【位置式PID与增量式PID区别浅析】

位置式PID与增量式PID区别浅析_增量式和位置式pid的优缺点-CSDN博客

        【智能车培训—并级串级pid】

智能车培训—并级串级pid_哔哩哔哩_bilibili

        下文的概念中,动量轮等价于飞轮,受无刷电机控制;行进轮等价于底轮,受直流电机控制。

        独轮车的平衡原理可以化用倒立摆模型对其平衡控制系统进行建模,相较于单车,独轮车的平衡控制可以看作是两个倒立摆模型(图片源自逐飞)。

                

(Pitch俯仰角方向)       

(Roll横滚角方向)

        暂时先不考虑用于指导转向的Yaw(偏航角)方向。

        如左上图所示,如果车模在Pitch(俯仰角)方向右侧倾倒,电机需要带动底轮顺时针转动,从而产生回复力(上方大箭头所示)使得车身保持直立。同理可分析车身在Pitch方向左侧倾倒。

        如右上图所示,如果车模在Roll(横滚角)方向右侧倾倒,电机需要带动飞轮顺时针加速旋转,从而产生逆时针的回复力(上方大箭头所示)使得车模保持直立。同理可分析车身在Roll方向左侧倾倒。

        在我刚入门独轮车时,想要建立一个函数关系,即车身倾斜多少度,就给电机多大的PWM来保持平衡。但是后来发现,自己的理论功底确实有点匮乏,我不太会运用理论力学的知识来对独轮进行受力分析。也没有具体的实验参数来对独轮车进行动力学建模。因此也就放弃了建立精密控制函数的想法。最终只运用了普通的PID控制。

        当然后来和车友交流时发现,除了串并级PID,其实也是可以采用多种控制思路的,比如模糊控制(Fuzzy Control)、线性二次型调节器(LQR)控制、LADRC线性自抗扰控制等。大家可以多多摸索!

        那么具体该如何控制电机输出的转矩大小呢?这里采用串级(位置式)PID的方法来实现控制。

        首先要解释几种叫法,免得新朋友入门时容易产生误会:

        内环中间环外环:指的是串级的三个环。

        直立环和速度环:串级的内环和中间环指的是直立环,外环指的是速度环(因为用了编码器)。

        平衡环和转向环:平衡环一般指的是Pitch和Roll方向上的平衡控制,转向环一般指的是Yaw方向上的转向控制。

        (1)原地平衡

        对于Pitch方向

        即底轮(行进轮)的前进方向。采用三级的串级:速度环(外环)、角度环(中间环)、角速度环(内环),各环的名称来源于对应的反馈量,即分别为编码器采集到的速度、陀螺仪解算出的倾斜角度、陀螺仪感受到的倾斜角速度。反馈极性分别为外环用正反馈、中间环用负反馈、内环用负反馈。原因是,我们希望中间环的角度变化和内环的角速度变化几乎被扼制为0,所以是负反馈,而底轮一旦移动,我们希望它的速度越来越快以及时跟上倾倒趋势,所以是正反馈,跟上之后才慢下来。调试PID参数时,极性的正负可由手感来判定。有时候编码器或电机接线接反,参数极性可能就会改变。

        主控芯片需要获取编码器和陀螺仪的传感数值,进行相应的解算换算,之后根据指示信息来控制直流电机的PWM,进而控制输出转矩。

        控制框架如图所示,原地平衡时给定速度为0,即最外环输入为0。当车模有倾倒的趋势时,陀螺仪最先感受到倾斜角速度,于是内环进行PID运算;当开始产生倾斜角时,中间环也开始进行PID运算,此时电机已开始工作带动底轮行进一小段以维持车身平衡,根据车轮的转速,又传到最外环进行PID运算,直到满足速度为0的约束。由此可见,三个环的工作时序不同,可以每隔一段时间采取一次控制,即可以用2ms、10ms、20ms的时序来从内到外工作(设置个定时器)。

        对于Roll方向

        即动量轮(飞轮)的旋转方向。也采用三级的串级:速度环(外环)、角度环(中间环)、角速度环(内环)。反馈极性分别为外环用正反馈、中间环用负反馈、角速度环用负反馈。原因是,我们希望中间环的角度变化和内环的角速度变化几乎被扼制为0,所以是负反馈,而飞轮一旦转动,我们希望它的速度越来越快以让车身及时跟上倾倒趋势,所以是正反馈,跟上之后才慢下来。调试PID参数时,极性的正负可由手感来判定。有时候电机接线接反或者陀螺仪换了个方向,参数极性可能就会改变。

        主控芯片需要采集无刷电机集成编码器的值和陀螺仪信息,进行相应的解算换算,之后根据指示信息来控制无刷电机的PWM,进而控制输出转矩,决定动量轮的旋转速度。

        控制框架如图所示,飞轮的目标转速总是为0的,我们希望原地平衡且不转向时,飞轮能尽可能保持静止。当车模有倾倒的趋势时,陀螺仪最先感受到倾斜角速度,于是内环进行PID运算,输出PWM使得无刷电机工作,当开始产生倾斜角时,中间环也开始进行PID运算,此时飞轮已经旋转,由于最外环正反馈的作用,使得飞轮越转越快,从而尽快让车体恢复平衡,并在平衡之后使得飞轮转速降低接近为0。三个环的工作时序同样可以用2ms、10ms、20ms来从内到外工作。

        当Pitch方向和Roll方向都能保持平衡后,独轮车就实现了直立。它可以在原地前后10cm的范围内来回移动,不会跑远。具体实现可参考如下代码(放在CPU中断里执行):

 void Balance(void)
{
   VelocityTime_ms += SystemData.interrupt_time;  //计时器启用
   AngleTime_ms += SystemData.interrupt_time;
​
   //外环
   if(VelocityTime_ms==SystemData.velocity_time)  
   {
       VelocityTime_ms=0;
        //获取编码器值
       Get_Encoder();
  
       Pitch_v = PID_Calculate(&Balance_Pitch.v, SystemData.velocity_set-(float)SystemData.Encoder_C, 1); //此处先忽略速度设定
       Roll_v = PID_Calculate(&Balance_Roll.v, (float)(SystemData.Encoder_A-SystemData.Encoder_B), 1);
 
   }
​
   //中间环
   if(AngleTime_ms==SystemData.angle_time)    
   {
       AngleTime_ms=0;
​
       Pitch_a = PID_Calculate(&Balance_Pitch.a, Pitch_v-(posture.data.pitch-SystemData.Pitch_Zero), 0);
       Roll_a = PID_Calculate(&Balance_Roll.a, Roll_v-(posture.data.roll-SystemData.Roll_Zero-Bend_Alpha), 0);//这里涉及压弯角和机械零点的概念
       
   }
​
   //内环
   Pitch_w = PID_Calculate(&Balance_Pitch.w, Pitch_a-((float)posture.data.gyro_origin.y),0);
   Roll_w = PID_Calculate(&Balance_Roll.w, Roll_a-((float)posture.data.gyro_origin.x), 0);
​
   //输出PWM
   SystemData.Motor_A = (int)(Roll_w+Yaw_w);//转向部分先忽略
   SystemData.Motor_B =-(int)(Roll_w-Yaw_w);
   SystemData.Motor_C = (int)(Pitch_w); 
   Motor_Out(SystemData.Motor_A, SystemData.Motor_B, SystemData.Motor_C);
​
   //可增加倾倒保护,当倾斜程度太大时,如倒地,清空PWM并将相关数据重置
}

(2)按给定速度行驶

        只需要在Pitch的串级PID外环输入预期给定速度即可。直流电机会追随给定的速度来工作,并由编码器检测来确定速度是否跟上。

(3)转弯

        独轮车的转向是依靠两个无刷电机控制动量轮的反向旋转达到的,是通过前后动量轮的差加速运动,对偏航角方向提供转向力,从而达到独轮车的转向。如图所示,两个动量轮都往顺时针旋转,会带动车身往右转(图片源自逐飞)。

        控制时,只需要在两个飞轮的PWM输出部分±转向PWM即可。

SystemData.Motor_A = (int)(Roll_w+Yaw_w);
SystemData.Motor_B =-(int)(Roll_w-Yaw_w);

        这里引入一个概念,转向饱和:控制飞轮的无刷电机,所输出的PWM一般有个限幅。当大于这个幅度时就不再产生更高的输出,由于输出不再变化,此时也就失去了控制作用,除非退饱和。当转向程度很大,或者连续转向时,会让输出的PWM比较接近限幅值,于是发生转向饱和,使得车身既无法完成转向,又失去平衡而倒地。

        那么,一般这个转向PID的输入偏差来自于室外定位或者室内惯导的计算值,即转向角度。这是转向环的中间环,即角度环。

//纯RTK,没找到目标板的时候用RTK自己的转向参数
if(SystemData.Controller == RTK)
       {{Yaw_a = PID_Calculate(&RTK_DT.PID,  RTK_DT.expect_yaw.theta, 0);} }
​
//纯惯导,没找到目标板的时候用专属的惯导参数
if(SystemData.Controller == Navigation)//调用转向优化函数,将角度进行切片,但显示的是实际的角度偏差
        {Yaw_a = PID_Calculate(&NavigationDT.PID, NavigationDT.turn_angle, 0);} 
​
//RTK或惯导,且找到目标板的时候,可以用视觉偏差加以修正
if(SystemData.Controller == Navigation_Camera || SystemData.Controller == RTK_Camera)
       {Yaw_a = PID_Calculate(&Balance_Yaw.a, (float)SystemData.Visual_Offset, 0);}  

        但在实际操作中,由于独轮车车模自身存在一些偏差,如:行进轮左右面接触不均匀、传动轴位置不正、传动皮带松动等。最终会导致在没有加入转向控制时,独轮车会向一个方向自然而然走歪。所以这时,需要加入角速度环,即转向环的内环,提供一个阻尼力来阻止独轮车因自身机械结构而产生的偏转。

Yaw_w = PID_Calculate(&Balance_Yaw.w, Yaw_a-((float)posture.data.gyro_origin.z), 0); 

        将上述两环,即角度环和角速度环,进行串联,即可达到较好的转向效果。有时候可以引入转向外环(负反馈),能一定程度上减弱转向饱和。

(4)压弯(动态零点)

        车身在转弯过程中,由于独轮车是靠动量轮的差加速度进行的,长时间循迹会造成动量轮转速加至极限,达到饱和,最终不能控制平衡和转向。除了增加转向环的负反馈差速度环(外环)可以缓解之外,还有个合适的办法是压弯,也称之为动态机械零点。

        在这里,压弯并不是为了减少路程而跑的更快,而是用于减缓飞轮PID的饱和。通过压弯让离心力与重力分量相抵消,可以更自然地保持姿态平衡,从而使得飞轮可以更低负担地实现转向(以下推导引自逐飞科技)。

        首先建立离心力等于重力在横滚角方向的分力的数学表达式得:

sin(θ) × mg + m×v²/r = 0

        等式中的θ为我们需要压弯的角度,v是当前移动速度,但是需要压弯角度我们并不能非常直接的计算出来,我们只能通过传感器得到小车需要转向的角度α,因此增加一个转向pid计算,令:θ=α× K2。并且根据路径的分析可以得知,小车倾斜越多,绕圈的半径越小,因此以上公式中的半径r和压弯角θ可以视为固定的比例关系,记作r=θ×K1,

        因此我们得到了最终的压弯公式:

sin(α× K2) ×g + v²/ (α×K2 ×K1) = 0

        将其增加到横滚角的角度环影响机械零点即可,得:

Machine_zero = Machine_zero + sin(α× K2) ×g + v²/ (α×K2×K1)

        我们可以尝试简化一些,其中sin(α×K2)×g可以看作是转角α与一堆比例运算的结果,v²/(a×K2×K1)可以看作是速度v与转角α一堆比例运算的结果,那么如果将这些运算直接看作一个系数,就可以得出一个极简的计算公式:

Machine_zero = Machine_zero +α×K2 + v²×α×K1

        在直行时,K1和K2以0来处理即可;进入转弯状态时,将它设置为调出来的合适的参数,就可以比较好地实现压弯。这样的动态机械零点,就是为了解决转向饱和而产生的。

        我的代码如下,只随意用了一个压弯参数SystemData.Bend_K,将求出来的压弯角放在平衡代码的中间环部分即可:

float Bend_Alpha=0;   //压弯角度
​
void Bend_Handle(void)  //转向压弯角的计算处理
{
   float turn_angle=0;
​
   if(SystemData.Turn_Flag)//切点才压弯
   {
       if(SystemData.Controller == RTK)          turn_angle = RTK_DT.expect_yaw.theta; 
       if(SystemData.Controller == Navigation)   turn_angle = NavigationDT.turn_angle; 
       Bend_Alpha =  (SystemData.Run_Speed*SystemData.Run_Speed) * turn_angle * SystemData.Bend_K;  //可调压弯参数,注意极性的正负和数量级
   }
​
   else Bend_Alpha = 0;
}

        有时候动态机械零点的思想可以用于Pitch方向上,促进变速、撞击板子和过凸起。

        以上全部就是平衡部分所依赖的原理。

        创作不易,如果觉得对您有帮助,可以打赏作者予以支持喔~

根据引用\[1\]和引用\[2\]的信息,第十八全国大学智能汽车竞赛的成绩和奖项已经公布。在华北赛区,比赛的项目包括负压电磁、专科电磁、三轮摄像头、电能接力、独轮车、完全模型、智能视觉、极速越野、单车越野和声音信标等。而在东北赛区,比赛的项目包括单车越野、电能接力、独轮车、负压电磁、极速越野、摄像头三轮、声音信标、完全模型、智能视觉和专科电磁等。具体的成绩和奖项可以在全国大学生智能车竞赛网站上查看。 #### 引用[.reference_title] - *1* [第十八全国大学生智能车竞赛华北赛区成绩与奖项](https://blog.csdn.net/zhuoqingjoking97298/article/details/131869636)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [第十八全国大学生智能车竞赛东北赛区成绩与奖项](https://blog.csdn.net/zhuoqingjoking97298/article/details/131868907)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [第十八全国大学生智能车大赛 大疆天途智能仓储创意](https://blog.csdn.net/zhuoqingjoking97298/article/details/129440486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yair

感谢每一个鼓励!1元就好!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值