ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

GM6020云台双环控制实战:从振荡到稳定的串级PID整定指南

GM6020云台双环控制实战:从振荡到稳定的串级PID整定指南 每年赛季刚开始那两个月电控组群里出现频率最高的问题永远是同一个GM6020云台为什么又抖了。不是那种轻微的高频颤动而是整条pitch轴像抽风一样来回甩底盘都被带得嗡嗡响。最开始我也对着PID公式折腾了好几天把角度环的P调大调小、加D加I怎么都不对。后来才明白GM6020这种带内部驱动器的智能电机和普通直流减速电机完全是两套玩法它的闭环能力边界在哪、你的双环到底应该搭在哪一层、陀螺仪的角速度反馈怎么跟外环的角度环配合这些事没想清楚之前参数怎么调都是白搭。这篇文章就把我从PID参数调到云台真正稳下来的完整过程拆开讲GM6020内部已经替你闭环了什么RoboMaster云台控制里常说的双环到底指哪两个环一套可落地的串级PID代码怎么写以及从内环到外环的整定顺序和实际踩过的坑。内容主要面向RoboMaster电控队员也适合所有做云台稳定、串级PID控制的嵌入式开发者参考。1. GM6020的三环能力边界哪些闭环由电机自己做哪些必须由你写1.1 先搞明白GM6020到底是什么GM6020是大疆为RoboMaster比赛设计的智能电机所谓智能是因为它把无刷电机本体、减速箱、驱动器、角度传感器全部集成到了一起外部只需要通过CAN总线发指令、收反馈。开发板C型上一般用的是CAN1接口电机内部已经跑了一个FOC电流环也就是说你给它一个电流值它内部会自己去控制三相绕组的通断你不需要关心换相、PWM占空比这些底层事情。这个东西的本质可以理解成一个“转速/力矩伺服模块”。它对外暴露三种控制模式电流模式、速度模式、多圈位置模式。我见过不少新队员拿到板子第一件事就是调用位置模式接口让云台转到某个绝对角度然后发现云台静态定位还行一受外力就“硬碰硬”地顶回来整个云台跟一块铁一样完全没有RoboMaster赛场上那种柔中带刚的动态稳定感。1.2 三种控制模式的分工和局限GM6020通过CAN报文下发控制字本质上分两类写控制值、读反馈值。下表是我常用的控制模式对比模式CAN控制字含义云台场景适用性说明电流模式期望电流转矩电流高响应最快但需要自己处理转速和位置的闭环速度模式期望转速中电机内部闭环转速但动态响应和抗扰不如自己用电流环陀螺仪角速度环多圈位置模式期望绝对角度低静态定位方便动态扰动下会表现出“刚性”对抗缺少阻尼这里有个很重要的认知GM6020的电流环在电机内部频率大约几十kHz响应极快快到你在外面根本感觉不到它的存在你发的电流指令几乎瞬间就能产生力矩。所以外面的控制环完全不需要去操心“电流环怎么调”你只需要保证发给它的电流指令是合理的、限幅是安全的。1.3 那RoboMaster语境下的“双环”到底指哪两个环这个问题我当年纠结了很久。网上搜“GM6020双环控制”有人说是电流环速度环有人说是速度环位置环。实际比赛代码里绝大多数队伍说的是角度环位置外环 角速度环速度内环这两个环跑在你的主控MCU里而GM6020内部的电流环作为最底层执行不参与你的代码逻辑。为什么不是直接调GM6020自带的速度模式因为GM6020自带的速度模式用的是电机编码器测到的转子速度它只能控制“电机转得多快”但云台要控制的是“云台在空间中指向哪个方向”。电机编码器测不到机身姿态的变化地面机器人底盘转一下、pitch轴受到线材拉扯、云台重心偏了这些扰动对编码器来说根本不存在它只知道转子转了多少。所以要想让云台真正稳定在空间中角速度反馈必须来自IMU陀螺仪而不是电机编码器。所以你的双环实际上是外环角度环输入是期望角度和当前角度来自陀螺仪积分或云台姿态解算输出是期望角速度内环角速度环输入是外环给的期望角速度和IMU实测角速度输出是期望电流指令最底层GM6020电流环把这期望电流变成实际力矩1.4 一个绕不开的疑问为什么不能用位置模式直接达到目的很多新队员会问既然GM6020有现成的多圈位置模式我把期望角度发给它它自己闭环不就行了实测下来你会发现两个问题。第一位置模式的反馈源是电机内部的编码器。电机装在云台上编码器只能测转子相对电机定子的角度测不到机身姿态。底盘在斜坡上、底盘被撞了一下、底盘在自转这些统统反应不到编码器上。你让云台固定到某个角度实际上固定的是“相对机身的某个角度”而不是“空间中的某个方向”。比赛里小陀螺一转云台就跟着偏了就是这个原因。第二位置模式为了实现“到位”内部会动用一个带刚性系数的位置控制器它默认环境是固定的。云台是悬挂结构有转动惯量、有重心偏移、有机械摩擦位置模式在这种负载下非常容易振荡或者表现为对抗外力时僵硬无比。所以结论很明确云台稳定需要的是惯性空间的姿态控制必须靠IMU反馈搭自己的双环GM6020只充当力矩执行器。2. 串级双环的物理直觉外环管“去哪”内环管“怎么去”2.1 为什么纯角度单环会振假设你偷懒只写一个角度环直接把角度误差乘以Kp发给电机。云台指向目标角度时误差为0控制量为0看起来挺合理但实际一通电就会振。原因在于纯角度单环本质上是一个大滞后系统角度反馈来自陀螺仪积分而陀螺仪数据本身有延迟和滤波电机响应又极快误差稍大就给大力大力让云台冲过头回过头误差反向又给反方向大力于是来回震荡。用一个生活化的类比你用手拿筷子去夹一个悬浮的球眼睛盯着球和目标的偏差手直接用力去推。偏差越大推得越猛结果球被推得老远你又得反方向猛推整个过程就是在那里来回扑腾。但如果你先稳住手的速度让手以一个受控的速度靠近目标再根据目标偏差调节这个速度操作就稳得多。这就是串级双环的物理直觉外环决定“要转多快”内环负责“把这个速度执行好”。2.2 内环角速度环到底起了什么作用角速度环在系统里扮演的角色是阻尼器和快速扰动抑制器。它看到的不是“角度偏了多少”而是“现在转得有多快”。只要云台在转动哪怕角度误差还是0它也能立刻感知到角速度并产生一个阻止转动的力矩。这带来一个非常好的性质当外力推一下云台时云台开始转动角速度瞬间产生内环立刻输出反向力矩去抵抗根本不需要等角度偏差积累起来。外环的响应可以设计得比较慢用来修正长时间的方向偏差内环的响应设计得很快用来扛瞬间的扰动。两个环各司其职系统的带宽和抗扰能力都能兼顾。另外内环还给外环的被控对象“降阶”了。如果没有内环你控制的对象是一个从力矩到角速度再到角度的二阶积分环节相位滞后很大。有了内环外环看到的是一个“我给它角速度指令它就能快速达到角速度”的近似一阶惯性环节相位裕度好得多外环的P可以给得更大而不振荡。2.3 双环的信号流和计算公式我习惯用这个结构angle_ref - [角度环 PID] - speed_ref - [角速度环 PID] - current_ref - [限幅] - GM6020 ↑ IMU 角速度反馈角度环的PID计算angle_err angle_ref - angle_nowspeed_ref Kp_ang * angle_err Kd_ang * (-gyro_rate)其中gyro_rate就是IMU测到的角速度直接用作微分项角度环一般不加积分或者加非常弱的积分用于消除静差这里有个关键点角度环的微分项不要对角度误差求差分而是直接引用陀螺仪角速度并取反。因为角度是陀螺仪积分出来的对角度误差求差分等于对积分的差分噪声会被无限放大。直接用陀螺仪原始角速度做微分既等效于角度微分又天然带滤波这是RoboMaster云台代码里最常见的做法。角速度环的PID计算speed_err speed_ref - gyro_ratecurrent_ref Kp_spd * speed_err Ki_spd * integral(speed_err)角速度环通常不用D因为陀螺仪角速度本身噪声就不小再微分容易把噪声放大成力矩抖动最后把current_ref限幅比如限制到GM6020最大允许电流的70%左右再通过CAN发给电机。2.4 反馈源选择的深水区编码器还是陀螺仪GM6020回传的数据里有转子角度和转速。内环到底要不要用这个速度反馈我的建议是如果做的是普通云台内环必须用IMU陀螺仪角速度编码器速度只用来做机械限位提示如果做的是需要极高响应速度的超级电容、发射机构这类直驱任务编码器速度反馈才更重要。原因是云台稳定在空间中转速控制也必须相对惯性空间。底盘原地旋转时编码器测到云台没有相对转动但陀螺仪测得云台在跟着底盘一起转。如果内环用编码器反馈它认为“转速为0不用出力”实际云台已经甩起来了。用陀螺仪反馈它立刻检测到角速度异常输出力矩把云台反向拉回来消炎小陀螺就是这么实现的。相当于你在高速行驶的火车上想让自己始终面朝窗外某个方向编码器只知道你的头相对身体转了多少度陀螺仪才知道你的脸实际朝哪个方向。云台稳定这件事必须以陀螺仪为基准。3. 可落地的云台控制代码骨架从CAN收发到双环计算3.1 整体任务结构设计我的云台代码跑在FreeRTOS上核心是一个1kHz的控制任务。GM6020的反馈报文通过CAN接收中断解析存储IMU通过SPI或I2C以1kHz的频率读取控制任务每1ms跑一次双环计算再组包发给两个轴的GM6020。任务优先级上IMU读取和控制计算要高于CAN发送任务。我的习惯是CAN接收用中断IMU读取放在最高优先级的定时器任务里控制任务紧随其后CAN发送延迟到控制任务里同步完成不单独建发送任务避免CAN发送缓冲区占用导致控制指令延迟。3.2 GM6020的CAN报文收发与数据解析GM6020的CAN通信需要先通过发送特定报文进入对应模式然后周期性发控制值。发控制值的时候ID和数据内容有关联发送时数据字段依次是0xFF、控制字节、期望值高8位、期望值低8位、0xFF、0xFF、0xFF、0xFF。下面是我常用的一组代码包含发送控制和中断解析// gm6020.c #define GM6020_CAN hcan1 #define GM6020_CTRL_ID 0x1FF // 发送控制帧的标准ID #define GM6020_RSP_ID_BASE 0x204 // 反馈帧起始ID按电机通道加偏移 typedef struct { int16_t angle_raw; // 转子角度16bit0~8191对应0~360度 int16_t speed_raw; // 转子转速rpm int16_t current_raw; // 电流实际值需乘以系数 uint8_t temp; // 温度 float angle_deg; // 换算后的角度 float speed_rpm; // 实际转速 } GM6020_Feedback_t; void GM6020_SendCommand(int16_t current_cmd1, int16_t current_cmd2) { uint8_t data[8]; data[0] 0xFF; data[1] 0x01; // 控制字节1为电流模式 data[2] (current_cmd1 8) 0xFF; data[3] current_cmd1 0xFF; data[4] 0xFF; data[5] 0x02; // 第二个电机通道 data[6] (current_cmd2 8) 0xFF; data[7] current_cmd2 0xFF; CAN_TxHeaderTypeDef txHeader { .StdId GM6020_CTRL_ID, .IDE CAN_ID_STD, .RTR CAN_RTR_DATA, .DLC 8 }; uint32_t mailbox; HAL_CAN_AddTxMessage(GM6020_CAN, txHeader, data, mailbox); } void GM6020_ParseFeedback(CAN_RxHeaderTypeDef *rxHeader, uint8_t *data) { if (rxHeader-StdId GM6020_RSP_ID_BASE rxHeader-StdId GM6020_RSP_ID_BASE 8) { GM6020_Feedback_t *fb feedback[rxHeader-StdId - GM6020_RSP_ID_BASE]; fb-angle_raw (data[0] 8) | data[1]; fb-speed_raw (data[2] 8) | data[3]; fb-current_raw (data[4] 8) | data[5]; fb-temp data[6]; fb-angle_deg (float)fb-angle_raw / 8191.0f * 360.0f; fb-speed_rpm (float)fb-speed_raw; // current_raw 乘以一个系数得到实际电流值不同版本系数不同 // 参考官方文档一般约为 0.002A/LSB但比赛里直接用归一化电流更直观 } }注意上面的角度是转子单圈角度如果你要读多圈位置需要自己处理圈数拼接。云台控制里我一般不用编码器角度做外环反馈所以不对它做多圈拼接只用它做初始位置检测和限位判断。3.3 PID控制器结构体与双环计算实现PID实现我建议写成一个通用结构体参数、限幅、积分项都在里面方便调试时用上位机在线修改参数。下面是我的PID模块简化版// pid.c typedef struct { float kp; float ki; float kd; float integral; float integral_limit; // 积分限幅 float output_limit; // 输出限幅 float prev_error; } PID_t; float PID_Calculate(PID_t *pid, float ref, float feedback) { float error ref - feedback; // 积分分离误差过大时不积分防止积分饱和 if (fabsf(error) 20.0f) { pid-integral error; pid-integral CLAMP(pid-integral, -pid-integral_limit, pid-integral_limit); } float output pid-kp * error pid-ki * pid-integral pid-kd * (error - pid-prev_error); pid-prev_error error; output CLAMP(output, -pid-output_limit, pid-output_limit); return output; }然后是云台控制任务1kHz周期执行。角度环用到的角度来自姿态解算我这里直接用IMU的roll/pitch/yaw角欧拉角或四元数转换出的角度角速度直接用IMU的三轴角速度// gimbal_task.c #define CTRL_FREQ 1000.0f #define DT 1.0f / CTRL_FREQ PID_t pid_ang_yaw, pid_spd_yaw; PID_t pid_ang_pitch, pid_spd_pitch; void Gimbal_Task(void const *arg) { // 初始化PID参数 PID_Init(pid_ang_yaw, 2.5f, 0.0f, 0.0f, 0.0f, 300.0f, 300.0f); PID_Init(pid_spd_yaw, 60.0f, 0.8f, 0.0f, 50.0f, 3000.0f, 3000.0f); PID_Init(pid_ang_pitch, 3.0f, 0.0f, 0.0f, 0.0f, 300.0f, 300.0f); PID_Init(pid_spd_pitch, 70.0f, 1.0f, 0.0f, 50.0f, 3000.0f, 3000.0f); for (;;) { // 1kHz控制周期 uint32_t now HAL_GetTick(); // 这里应有同步等待代码保证任务以1ms周期运行 // 读取IMU角度和角速度 float yaw_angle imu.yaw; // 度 float yaw_rate imu.gyro_z; // 度/秒注意方向与电机正方向对应 float pitch_angle imu.pitch; float pitch_rate imu.gyro_y; // 期望角度来自遥控器、视觉或自主决策 float yaw_ref target.yaw; float pitch_ref target.pitch; // 外环角度环 → 期望角速度 float yaw_speed_ref PID_Calculate(pid_ang_yaw, yaw_ref, yaw_angle); float pitch_speed_ref PID_Calculate(pid_ang_pitch, pitch_ref, pitch_angle); // 内环角速度环 → 期望电流 float yaw_current_ref PID_Calculate(pid_spd_yaw, yaw_speed_ref, yaw_rate); float pitch_current_ref PID_Calculate(pid_spd_pitch, pitch_speed_ref, pitch_rate); // 限幅和符号校准后在CAN指令中发送 GM6020_SendCommand((int16_t)pitch_current_ref, (int16_t)yaw_current_ref); } }这段代码核心思路是把两个环拆开外环输出是“期望转速”内环输出是“期望电流”。内环的反馈是IMU角速度GM6020只当力矩放大器。方向问题格外重要IMU角速度方向和电机正方向如果不一致内环会变成正反馈一通电就飞车。3.4 控制频率稳定性和CAN时序的细节双环PID对控制频率的一致性要求很高。我见过有人用HAL_Delay(1)来控制周期结果实际周期不稳定参数整定时曲线忽好忽坏。后来换成基于系统tick的绝对时间等待加上一个简单的统计变量检测最大任务循环时间才解决这个问题。CAN发送频率我习惯跟控制频率一致都是1kHz。GM6020官方资料支持1kHz控制指令频率如果控制频率高于1kHzCAN总线可能出现拥塞低于1kHz双环响应会变迟钝云台会感觉“肉肉的”跟手性变差。注意发送电流值时要确认符号方向和实际电机转动方向一致否则内环正反馈会让云台瞬间打到底。4. 双环参数整定实战从内环P一路调到不发散4.1 整定前置检查机械配平和反馈方向调参之前必须先做两件事。第一云台机械配平。yaw轴要保证云台重心大致在旋转轴线上pitch轴要保证枪管和云台重心配平或接近配平否则pitch轴会有一个恒定重力矩内环需要持续输出电流去顶住积分项会一直很大极限转向时容易饱和。第二反馈方向验证。给云台一个正向角速度指令看IMU报告的角速度是否为正如果不是在代码里取反否则整个双环是正反馈一通电就飞车。这里分享一个我常用的验证方法不开任何PID直接给一个很小的恒定电流指令比如100让云台缓慢转动观察陀螺仪角速度方向。然后把指令反过来看陀螺仪角速度是否也跟着反过来。如果符号对不上优先查IMU安装方向和电机方向映射关系而不是在代码里乱加负号。4.2 第一步内环速调P把“阻尼”立起来整定顺序一定是先内环后外环。先把外环全部置零也就是角度环输出恒为0这样内环的期望角速度为0。此时给云台一个外力扰动观察它如何响应。内环P从0开始以1.5到2倍逐步增加看两个现象一是用手拨动云台是否有一种“阻尼感”拨一下它很快就停住不抖二是云台是否发出高频啸叫或振荡电流是否过大。内环P太小的时候云台像没刹车的转盘拨一下要晃好几下才停。P到位后云台会感觉很“紧”你快速拨它一下它几乎不超调就稳稳停下。注意这里的“紧”和位置环闭环的那种“硬”不一样你同样能转动它但它会抵抗快速转动。内环要不要先加D我建议不加。角速度环的对象本身就是电机负载的一阶惯性系统P就能提供很好的阻尼加D只会在陀螺仪噪声上做文章。先把P调到“拨一下迅速停下、不啸叫”记为当前轴的Kp_spd基准值。4.3 第二步内环加I消除转向静差和重力偏置云台pitch轴有重心偏置时内环只靠P会在目标角速度附近留下一个静差。因为云台需要持续输出一个恒定力矩去抵抗重力而纯P控制在误差为零时输出也为零没法提供这个恒定力矩。加上I之后积分项会积累出一个稳定的输出分量去顶住重力。整定I的方法给定一个小角度阶跃比如5度观察云台是否最终停在期望角度附近。如果最后差一点角度不动说明I太小如果云台围绕目标来回低频摆动说明I太大或者积分限幅太大。实际参数我一般控制在I的输出分量不超过总输出的20%整定状态下用手轻托云台pitch轴应该能感觉到它有一个柔和的回中力。4.4 第三步外环P让云台“跟手”内环稳定后重新启用角度环。角度环先只给P不给I。期望角度设为当前角度加上一个固定偏置比如让云台突然转30度观察它跟过去的过程。P太小云台转得慢吞吞、到位迟缓P太大云台快速冲过目标然后来回震荡。最理想的外环阶跃响应是快速逼近目标有一次微弱的轻微超调或干脆没有超调随后迅速稳定。外环P整定到“刚刚开始出现轻微超调”的位置然后回退10%到20%这是一个很好的起点。切记不要一上来就追求“极度跟手”角度环的带宽受限于内环能力外环调得太猛内环根本跟不住系统还是振荡。4.5 第四步微分与阻尼的配合角度环的微分项我直接复用IMU角速度等效于位置微分也就是给系统增加阻尼。当你发现外环P稍微调大云台就开始来回点头时可以适当增加角速度在角度环输出中的权重而不是一味降低P。实测下来Kd_ang典型值可以取Kp_ang的10%到30%左右效果是在不牺牲响应速度的情况下增加稳定性。这里有个容易犯的错误把IMU角速度同时既做内环反馈又做角度环微分项会让两个环耦合。正确的理解是外环的角度微分项只是提前感知到角度的变化趋势给内环的期望速度做一个“刹车”修正它与内环本身的阻尼并不重复。4.6 典型参数范围参考经过多个赛季多套云台的调试我整理了一张典型的起始参数表注意不同机械结构、不同IMU安装位置差异很大参数只能做量级参考参数yaw轴典型范围pitch轴典型范围说明角度环Kp1.0 ~ 5.01.0 ~ 6.0期望角度误差为1度时输出期望角速度角度环Kd0.1 ~ 1.50.2 ~ 2.0直接乘陀螺仪角速度单位换算注意角速度环Kp30 ~ 12040 ~ 150期望角速度误差为1度/秒时输出电流角速度环Ki0.3 ~ 2.00.5 ~ 3.0消除静差和重力偏置积分限幅50 ~ 20050 ~ 300防止积分饱和输出限幅2000 ~ 40002000 ~ 4000电机电流上限的安全保护调试时注意yaw轴和pitch轴参数差异很大。pitch轴受重力影响明显积分项通常比yaw大yaw轴如果装了延长线线材的弹性阻力也会影响参数。同车型同配置参数可以复用但更换任何机械结构后都要重新验证而不是无脑copy。4.7 调参工具用波形说话调参全靠手感容易自我欺骗一定要把关键变量发到上位机看波形。我用过VOFA和匿名上位机简单可靠。需要打点的数据包括期望角度、实际角度、期望角速度、实际角速度、输出电流、CAN接收状态。观察波形时最重要的判断点是阶跃响应中超调量、振荡频率和静差。发送调试数据时我一般用DMA串口把数据打包成float数组1kHz发送会占不少带宽实际调试时降到100Hz到200Hz就够了波形足够看清趋势又不至于拖慢控制任务。另外波形一定要记录“输出电流”这一路如果你发现振荡时电流已经顶到限幅值说明内环已经饱和此时外环再调也是无用功应该降低角度环的期望速度或增加限幅余量。5. 实测中常见的振荡、超调、漂移问题与排查链路5.1 现象一通电就高频振荡甚至啸叫这个现象九成是内环正反馈或内环P过大。先检查IMU角速度和电机输出方向的符号最简单的办法是把角速度环P设成0只给一个恒定电流让云台缓慢转起来看IMU角速度的方向是否和期望方向一致。如果方向反了负反馈变正反馈P一给大必然飞车。排除方向问题后把内环P降低到当前值的30%左右看振荡是否消失。如果P降到很低仍振荡检查CAN指令发送频率是否稳定控制任务是否有被其他任务抢占导致周期不稳。我遇到过调度器配置问题控制任务优先级不够高CAN接收中断又抢占执行导致控制周期抖动表现为特定的高频噪声。5.2 现象二外力推一下云台来回“点头”好几下才停这个现象说明阻尼不足。典型原因是角度环P过大、内环P不足或者角度环微分项没有接上。先检查内环效果单独给内环一个角速度阶跃看它是不是能在很短的时间内把角速度拉到目标值。如果内环本身就软绵绵的外环给再多的阻尼都补不回来。如果内环没问题那就是外环P太大。外环P大意味着角度误差轻微变化就会产生很大角速度期望内环拼命去追这个期望结果超调振荡。此时降低外环P同时增加角度环微分项的权重让云台在接近目标时有一个“提前刹车”的力矩。还要检查一个容易忽略的点IMU角速度的滤波。如果陀螺仪低通滤波截止频率太低角速度反馈会有显著相位延迟相当于内环看到的角速度比实际晚了一拍这会让系统在带宽附近产生额外的相位滞后表现为振荡。我一般用陀螺仪原始数据配合一个截止频率100Hz左右的低通过高的滤波反而坏事。5.3 现象三云台缓慢漂移回中不准漂移问题要分两种情况。一种是角度环没有积分云台受到恒定外力或重心偏置时会有一个稳定的角度静差看起来像“回不到中”。这种可以在角度环增加少量积分项但要注意外环积分容易引起振荡积分限幅要非常小。更好的做法是检查机械配平和线材拉力从物理上消除恒定干扰。另一种是陀螺仪零漂和姿态解算漂移。角速度环的反馈来源是IMU如果陀螺仪零漂没有被校准静止时角速度读数不为零内环就会误以为云台在转动输出一个缓慢的修正力矩带动云台慢慢漂移。处理办法是在系统初始化时采集一段静止时的陀螺仪均值作为零偏每次上电都重新校准。还可以在姿态解算中加入互补滤波或卡尔曼滤波但这属于姿态解算范畴这里不展开。5.4 现象四大力矩动作后电机发热甚至过流保护云台在快速甩动、急停时会需求很大的力矩此时内环输出可能瞬间达到限幅值。如果限幅设置过高GM6020持续输出大电流电机发热严重触发驱动器保护。两个排查方向一是确认输出限幅是否合理正常云台的峰值电流可以设到驱动器允许值的70%左右不要指望靠冗余电流掩盖机械卡顿二是检查角度环和角速度环的参数是否匹配如果角度环只给了很大的P而内环响应跟不上输出电流会出现剧烈的冲击尖峰发热也随之增大。遇到这种情况我习惯在代码里加一个输出电流变化率限制或者叫输出平滑。也就是说控制量的变化不能一步到位而是一个周期最多变化某个上限值。这样牺牲一点点响应速度换来的是电流波形平滑和电机寿命对比赛这种长时间高强度运行的场景很值得。5.5 现象五CAN断线后云台失去控制直接甩飞GM6020如果收不到CAN指令会保持最后的指令状态这是非常危险的因为最后的指令可能是一个很大的电流值。必须在主控里做CAN超时检测比如100ms没收到CAN发送成功回调或200ms没收到反馈报文就认为通信异常立刻将控制输出置零同时把期望角度锁定为当前角度禁止云台再朝目标角度运动。实践中我还会加一个“急停”服务当裁判系统收到断电指令或操作手按下急停按钮时走一条独立于控制任务的路径直接发送零电流指令保证在任何时候都能让电机撤力。这个小细节在比赛现场能救回一整台机器人。6. 进阶方向前馈、滤波与整定工具效率6.1 前馈补偿让云台跟手度更进一步双环PID反馈控制处理的是“出了偏差再去纠正”天然会有滞后。如果想让云台面对快速移动的目标或者遥控器大角度拨杆时更跟手可以加前馈。角度环的前馈是这样做的期望角度变化时直接把期望角速度的一部分用微分计算出的目标角速度叠加到角度环输出上让内环提前就知道“该转多快”了而不是等误差拉大再去纠正。前馈强度系数一般从0开始逐步加加到闭环响应明显加快、但没有产生额外振荡为止。需要注意前馈会绕过误差反馈如果期望角速度计算本身噪声大前馈反而会引入抖动。所以目标角度信号要足够平滑遥控器摇杆我会做一个限幅的低通滤波视觉的期望角度则依赖视觉算法本身的平滑性。6.2 pitch轴重力前馈先出力再修正pitch轴和yaw轴最大的不同是永远有一个重力力矩。如果云台重心配平不完全角度环和角速度环需要额外输出一个恒定力矩去抵抗重力。只靠积分也能做到但动态响应不够快。更好的做法是一个重力前馈项根据pitch轴当前角度计算重物力矩方向上的期望电流补偿量直接加到内环输出上。公式很简单feedforward GRAVITY_COMP_COEFF * cos(pitch_angle)。这个系数在配平不完美时测量方法是在不同的pitch角度下手动加大积分或者直接给开环电流寻找让云台静止不动的电流值描点拟合出一条余弦曲线。有了重力前馈pitch轴内环的积分负担大大减轻快速俯仰时也更跟手。6.3 数据打点与整定效率别再用肉眼调参了早期我调参是改一个参数、编译下载、上电看效果一晚上只能调出两三个参数。后来把PID参数改成全局变量通过串口或裁判系统的用户数据链路在线修改参数改完立刻生效波形实时刷新整定效率起码翻三倍。具体做法在PC上位机里设置一个简单的文本协议比如yaw_p_ang 3.5这样一条指令解析后直接修改对应的PID结构体字段。控制任务每周期把当前参数和波形数据一起往外发调参时看着波形改参数哪个参数生效了效果如何一目了然。比赛前我用这个方法半小时就能把一台新云台调到一个可用的状态。6.4 什么时候要考虑加速度环网上能搜到很多“电压环电流环双环控制”“串级PID”的讨论其中经常涉及加速度环。我的观点是在做RoboMaster云台稳定时GM6020内部的电流环已经足够快你再在外面加一个加速度环把IMU加速度计测得的角加速度作为反馈只会引入大量噪声收益有限。除非你做的是四轴飞行器那种对力矩响应极度敏感的平台或者云台在剧烈颠簸、飞坡过程中需要极限抗扰才值得去碰加速度环。真要往深了做更值得投入的是自适应增益和模糊PID。云台在不同姿态、不同负载下的最佳参数是不一样的比如pitch轴在大俯仰角时的重力影响小一些角速度环整体增益可以放宽。这类高级算法虽然复杂但理解双环PID的基本逻辑之后你才知道应该把自适应加在哪个环节上而不是盲目套公式。最后再说句实在话我从最初对着GM6020一脸懵到后来能在一小时内把一套新云台调稳最大的转变是理解了“电机帮你闭环了什么”这一层。GM6020内部的电流环是一个又快又准的力矩执行器你要做的不是在它的位置模式里省事而是在MCU里搭一个属于惯性空间的双环角度环管方向角速度环管阻尼。两者的反馈必须来自IMU而不是电机编码器。调参的顺序、积分的处理、CAN超时的保护这些细节都是靠一次一次炸机、飞车、烧板子换来的经验。希望这篇文章能让你少走几步弯路但该动手的还是要动手。云台稳定这种控制问题看十篇文章不如自己调一次参数当你亲手把一个振荡发散的云台调到拨一下稳稳停住时你对PID的理解会上升一个档次。
返回列表