资讯动态

GM6020云台双环PID控制:原理、代码实现与调参实战

发布时间:2026/10/6 10:35:38 来源:尧图企业网站定制
要说做RoboMaster电控最绕不开的也就是电机控制了。尤其是GM6020这种云台电机你要是只会给它发个电压让它转那基本没法用真正的难点在于怎么让它又快又稳地转到你想让它去的角度同时还要抗得住底盘运动带来的扰动。说白了这就是双环PID控制要解决的事情。这篇东西我打算从一个实际调车的视角把GM6020的双环控制从原理到代码再到调参完完整整捋一遍适合正在备赛的队员也适合刚接触PID控制、想搞明白串级控制到底怎么落地的嵌入式开发者。先说清楚一件事GM6020本身是个FOC矢量控制的无刷电机电机内部自带电流环和速度环。你可能要问那我们还做双环干什么因为GM6020的电流环和速度环都封装在电机内部了你没法直接改它的电流环参数你通过CAN总线发给它的还是目标转速。所以对电控队员来说我们真正要做的是在外部再加一层位置环和电机内部的速度环构成“位置-速度”双环也就是串级PID。很多教程里说的“电压环电流环双环控制”在GM6020的语境下并不成立我们外部能操纵的其实就是速度环的输入。这个误区必须一开始就纠正不然你会拿着代码到处找电流采样白费功夫。我自己当年第一次给6020调云台的时候犯过特别蠢的错先把外环的P给得很大结果云台跟抽风一样来回甩还以为是电机坏了。后来才明白串级PID必须先让内环硬起来再去碰外环。这篇文章的整个顺序也是按这个逻辑来的先讲清楚GM6020和云台控制的底层逻辑再把双环PID的原理掰开揉碎接着给出可以直接抄的代码实现最后用大量篇幅讲调参过程和那些你在文档里绝对查不到的坑。你不用从零开始研究照着做至少能保证你的云台能稳得住。1. GM6020电机与云台控制的底层逻辑1.1 GM6020到底是什么样的电机GM6020是RoboMaster官方推出的一款大扭矩云台电机和3508、2006这种动力电机不一样它天生就是给云台、机械臂关节这类需要精确位置控制的场景设计的。它有个特点电机本体集成了驱动器你只需要通过CAN总线给它发指令它自己就能把电流闭环和速度闭环跑好。这极大的降低了电控队员的上手门槛但同时也带来一个思维上的转变你不再是控制“电枢电压”或者“PWM占空比”的底层开发者而是变成了一个“运动规划师”。我们看一下GM6020的官方参数额定电压24V虽然不同版本扭矩不同但云台用的主要是GM6020扭矩足够带着整个云台结构和相机做快速响应。它的通信协议走CAN数据回来之后你能拿到转子角度多圈累计、实际转速、甚至扭矩电流这些都是做控制环路的反馈量。这里要特别提醒GM6020反馈的转子角度是机械角度而且是多圈累积的不是你常规理解的0到360度。这意味着你完全可以用它来对付云台的偏航轴因为偏航轴理论上可以无限旋转传统编码器那种单圈回零的方案在这里根本行不通。另外一个很多人不清楚的点是GM6020的电机内部速度环非常灵敏响应快到你外部再叠一个位置环整个系统的带宽基本由外环决定。所以你要是觉得云台反应慢别急着怪电机大概率是你外环的参数太软、或者是目标值给得太肉。这就像你开一辆动力很强的车起步慢不是因为发动机不行而是因为你油门不敢踩到底。1.2 云台控制为什么非要用双环云台控制的本质任务是让相机坐标系稳定在某个期望的姿态上不管底盘怎么晃、怎么被撞。竞技比赛里云台稍微抖一下子弹散布就会变大视觉识别到的目标在图像里的位置也会跳导致打击精度直线下降。所以云台系统对控制的“快速性”和“稳定性”要求都极高。如果只用单个位置环也就是直接用“目标角度-当前角度”的误差去给电机发扭矩或者速度指令会出现什么问题第一云台会有明显的振荡因为位置误差大时你会想给很大的输出但电机和云台结构有转动惯量冲过头了再反向修正就是来回振荡第二外界的扰动比如底盘急转会直接被“算进”角度误差里等你看到角度偏了再去纠正已经晚了半拍。这就像你倒车入库只看后视镜里车歪没歪再打方向盘一定会画龙你得看着车尾的走向趋势、提前给方向盘一个反向动作。双环控制的思路就完全不一样了。外环是位置环它负责把“角度误差”换算成“期望转速”内环是速度环它负责让电机的实际转速快速、精准地跟上这个期望转速。底盘被撞一下导致云台角度偏移外环马上给出一个较大转速指令内环立刻提速往回拉由于内环响应比外环快得多整体效果就是既快速又稳定不会猛冲猛打。这就是为什么几乎所有比赛强队云台控制一律是串级PID而不是单环PID。1.3 澄清一个常见误区电压环电流环与6020的关系很多刚接触的人看了一些资料会把“双环控制”理解成“电压外环电流内环”甚至拿这个思路去套GM6020结果发现完全无从下手。这里我明确说GM6020的驱动器内部已经实现了电流环扭矩环和速度环你从外部CAN报文里写入的目标值直接就是“RPM”转速不是PWM也不是电压值。所以你在外部搭建的闭环是“角度位置环速度环”。如果你非要说“双环”那也是外部位置环内部速度环电机内部的电流环是硬件驱动器自己处理的不归你管。这带来两个实际影响。其一是调参对象变了你代码里的PID参数是给“角度误差-转速指令”这条通路用的不是给“转速误差-电压输出”用的。其二是CAN通信延迟你发一帧转速指令然后等电机反馈一帧状态这个过程本身有延迟如果外环PID参数太激进这个延迟就会变成系统的“相位裕度杀手”导致震荡。理解了这一点你就明白为什么很多调参经验帖都会说“外环P别太大”这不是因为电机不行而是因为整个串级系统受传输延迟约束外环带宽天然不能太高。2. 双环PID控制的核心原理与参数设计2.1 从PID基础到串级结构的必然性PID控制说起来很简单输出 Kp * 误差 Ki * 误差积分 Kd * 误差微分。先别急着背公式我在实际调车里的理解是P决定了你“回中”的力气有多大I负责消掉那些一直存在的“偏置力”比如云台重心不完全在转轴上导致的一侧下沉D负责“踩刹车”防止冲过头。单环PID在大部分普通电机调速里够用但只要对象是云台这种惯量大、要求响应快的系统你就必须得用串级。串级PID的结构是外环输出作为内环的设定值。以GM6020为例外环输入是“期望角度与实际角度的误差”输出是“期望转速”内环输入是“期望转速与实际转速的误差”输出是“发送给电机的目标转速值”。但这里有个细节因为GM6020的驱动器本身就是个速度闭环我们发出去的目标转速会被电机内部的速度环跟踪所以我们的内环实际上是“借用”了电机内部的速度环而不是自己再写一个速度环去算电压。这样设计的好处非常直观内环能把“转速”这个中间量控制得很硬外环就能够“放心大胆”地工作在线性区不会因为外界的瞬时冲击而让整个系统呈现强烈的非线性。你可以把内环想象成一个“执行力超强的下属”你告诉他目标转速他不管多大风浪都给你拉上去外环是“领导”只需要根据偏差给任务不用亲自下场掰扯。领导管方向下属管执行这就是串级最朴素的哲学。2.2 位置式PID与增量式PID选型PID具体实现上常见就是位置式PID和增量式PID两种。位置式PID的输出直接就是控制量本身表达式是输出 比例项 积分项 微分项。它的优点是直观、能处理积分饱和如果你加抗饱和逻辑缺点是它输出的是绝对值一旦误差突变输出会瞬间冲到很大而且它需要累加历史误差代码里得专门维护积分变量容易出问题。增量式PID的输出是“控制量的增量”也就是这次比上次多输出多少。表达式是输出变化量 Kp*(e(k)-e(k-1)) Kie(k) Kd(e(k)-2e(k-1)e(k-2))。它的优点是没有积分累加项不会出现积分饱和而且输出增量天然有“限幅”的思维——不管误差多大每次变化量都是有限的对执行机构有保护作用。缺点是它本身不带积分功能需要靠外部累计来消除稳态误差。在实际GM6020云台控制里我强烈建议用位置式PID或者带抗积分饱和的位置式PID因为云台控制需要快速消除位置误差积分项能有效对付云台重心偏移带来的持续偏差。如果你用增量式你会发现云台回中之后总是差那么一点然后慢慢悠悠飘过去这就是缺少绝对积分项的典型症状。当然凡事不绝对有些人做速度环用增量式也稳得很但位置环确实位置式更合适。2.3 双环参数设计的数学直觉调参数之前你得先有个数学层面的直觉。串级系统中内环的响应速度必须远快于外环工程上一般要求内环带宽是外环的3到5倍。这意味着你调的时候内环PID的P要比外环大一个量级相对各自反馈量程这样内环才能“指哪打哪”。另一个重要原则外环的D不能随便加因为在串级结构里外环的微分项放大了噪声而噪声经过内环又会被放大一次最后云台就是高频抖动。那么Kp、Ki、Kd要怎么搭配呢我的习惯是“先P后I再D”。第一步先给一个很小的P内环先加P到电机响应干脆无抖动第二步外环加P到云台回中有力但不振荡第三步加外环I消除稳态误差注意I给大了会超调给小了回中慢第四步如果云台有来回摆动的趋势稍微给一点点Kd不要多意思到了就行。整个过程就像调音响的低中高音低音管“沉”中音管“清晰”高音管“亮”但高音给多了就刺耳对应到PID就是D给多了就发颤。我个人的习惯是先把限幅做好。外环输出限幅到内环能承受的转速范围比如-1000RPM到1000RPM内环输出限幅到CAN指令范围比如-16384到16384具体取决于你的速度指令映射。限幅看起来是个小事但它决定了你的参数能不能给得大给了大参数不出事故这才是极限调参的前提。3. 双环控制的代码实现从数据结构到完整逻辑3.1 工程结构与数据结构设计代码质量决定调试效率。我自己习惯把云台控制写成独立模块命名清晰方便一个文件搞定一个轴的逻辑。工程结构大概是这样pid.c/h通用PID控制器不区分内环外环传参数就能用。gm6020.c/hGM6020的CAN收发与数据解析把电机ID、角度、转速这些整理成结构体。gimbal.c/h云台控制逻辑负责把遥控器/视觉的目标角度转化成PID目标值再调用PID计算最终写成CAN发送缓存。remote.c/h遥控器数据解析如果有。数据结构方面我的经验是别把不同电机的数据揉在一起。GM6020返回的数据是8字节包含角度低16位、角度高16位、转速低16位、转速高16位你需要自己拼出int32_t和int16_t。对应的结构体可以这样写typedef struct { uint8_t id; int32_t angle; // 多圈累计机械角度 int16_t speed_rpm; // 实际转速 int16_t torque; // 扭矩 } GM6020_State_t;PID结构体建议这样设计typedef struct { float kp; float ki; float kd; float integral; float last_error; float out_max; // 输出限幅 float integral_limit; // 积分限幅 } PID_t;注意我特意加了两个限幅输出限幅和积分限幅。输出限幅决定了这个环能给出的最大指令积分限幅防止积分项“巨无霸化”。我在实战中见过太多人只做输出限幅不做积分限幅结果误差一直存在时积分项涨到几千误差一消失输出还下不来云台直接偏到一边去。这种问题排查起来非常隐蔽代码层面预防是最省事的。3.2 角度归一化与增量处理的坑GM6020返回的机械角度是多圈累计的但你实际控制位置环时期望值和你当前值不可能一直单调增加。比如目标角度是0度当前角度是350度以你定义的零点为基准如果直接算误差误差就是-350度电机就会逆时针转一大圈这显然是错的。实际上你希望它从350度往0度走走的是10度那个方向。所以在做位置环之前必须对误差做归一化处理把误差限制到-180度到180度之间。我常用的角度误差计算函数长这样float angle_error(float target, float actual) { float error target - actual; while (error 180.0f) error - 360.0f; while (error -180.0f) error 360.0f; return error; }这个函数在所有云台/机械臂项目中几乎通用。你可能会问为什么用while不用一个取模因为while写法在边界条件下鲁棒性更好而且编译优化后开销也不大。另一个细节是目标角度在代码里最好也用归一化后的值否则累积误差和处理逻辑都会变得混乱。还有一个容易忽略的点GM6020的转速反馈单位是RPM而你外环输出的期望转速也自然要“适配单位”。假设你的外环P是10那意味着1度角度误差会产生10 RPM的速度指令。这里面没有什么绝对标准但你在设定外环输出限幅时要清楚自己单位是什么别把度每秒和RPM搞混了——RPM是每分钟转数1度每秒等于1/6 RPM这个换算关系我建议你写在注释里不然过三个月你自己回来看都懵。3.3 双环控制核心代码接下来直接上一个可用的双环控制代码框架。这段代码用的是标准STM32 HAL库配合FreeRTOS或裸机定时器调用均可。核心思路是先读反馈再算外环再算内环最后把CAN指令写到发送邮箱一个控制周期完成。#define GM6020_SPEED_TO_CAN (1.0f) // 如果CAN指令直接对应RPM就为1 #define OUTER_PID_MAX 800.0f // 外环最大输出RPM #define INNER_PID_MAX 16384.0f // 内环最大输出CAN指令留作预留 PID_t pid_speed; // 内环实际上GM6020内部有速度环我们这里做的是给目标转速的平滑映射 PID_t pid_angle; // 外环位置环 uint16_t gimbal_set_speed(float target_angle, float actual_angle, float actual_speed) { // 1. 计算外环误差角度误差单位度 float angle_err angle_error(target_angle, actual_angle); // 2. 外环PID计算得到期望转速 float target_speed pid_calculate(pid_angle, angle_err); // 3. 内环这里直接把target_speed作为CAN发送目标值 // 你可以选择自己再做一个速度PID但GM6020内部已有速度环这里就不再自己做内环 // 如果你真的想自己做内环速度反馈就是actual_speed内环输出就是CAN指令 float can_value target_speed; // 4. 输出限幅 if (can_value INNER_PID_MAX) can_value INNER_PID_MAX; if (can_value -INNER_PID_MAX) can_value -INNER_PID_MAX; return (uint16_t)((int16_t)can_value); }等一下上面这段代码里我注释写得有点模糊。实际比赛代码中很多队伍确实不再写内环PID而是直接让外环的输出等于目标RPM然后发给GM6020。但这样做对GM6020内部速度环的跟踪性能要求很高而且你没办法修正电机内部速度环的误差比如带负载时的转速跌落。所以更稳的做法是外环输出期望转速然后自己再写一个速度环内环输入是期望转速和实际转速的误差输出是CAN速度指令修正量。这样做的效果是即使GM6020内部速度环有误差我们外部的内环也能帮忙补一点。完整版的双环代码建议这样写int16_t gimbal_control_dual_loop(float target_angle, float actual_angle, float actual_speed) { // 外环角度 - 期望转速 float angle_err angle_error(target_angle, actual_angle); float target_speed pid_calculate(pid_angle, angle_err); // 限制期望转速范围 LIMIT(target_speed, -OUTER_PID_MAX, OUTER_PID_MAX); // 内环期望转速 - 指令值 float speed_err target_speed - actual_speed; float out pid_calculate(pid_speed, speed_err); LIMIT(out, -INNER_PID_MAX, INNER_PID_MAX); return (int16_t)out; }你可能会疑惑内环PID的输出到底是什么单位因为GM6020的CAN指令本身是“目标转速”不同固件、不同电机不太一样但多数情况你发的值就是RPM。所以严格来说内环的输出应该叠加在期望转速上而不是直接替换。我见过更稳的写法是最终指令 target_speed inner_speed_pid_out即内环只在期望转速附近做“微调”。这种方法的好处是保留了前馈通道系统响应更快同时内环又能修正转速误差。强烈建议你用这种结构实测效果比单纯串级输出好很多。3.4 PID核心计算函数实现float pid_calculate(PID_t *pid, float error) { float output; // 积分项带积分限幅 pid-integral error; LIMIT(pid-integral, -pid-integral_limit, pid-integral_limit); // 微分项 float derivative error - pid-last_error; pid-last_error error; output pid-kp * error pid-ki * pid-integral pid-kd * derivative; LIMIT(output, -pid-out_max, pid-out_max); return output; }这个函数有个小问题它的微分项是“误差变化率”不是真正的转速变化率。在位置环里如果误差信号噪声大这个微分项会非常暴躁。所以实际项目里位置环一般不加D或者只在速度环加一点D。但有些特殊场景比如云台高速运动中突然刹车角度环加一点D确实能让云台更“干脆”地停下来。这就要靠你现场听电机的声音来判断了如果电机有“滋滋”的高频声音多半是微分项在放大噪声记得把它砍掉。积分限幅我习惯设成输出限幅的30%左右。这个比例不是绝对的但如果你把积分限幅设得和输出限幅一样大积分项会经常占据整个输出让比例项和微分项失去作用系统动态响应会变得很肉。我见过最夸张的一次有人积分限幅直接没做云台开机转了一圈才停下来就是因为积分项累计到爆炸输出一直是最大值这种失控在调试现场特别吓人。4. 调参与调试从内环到外环的完整流程4.1 准备调试环境与工具调参之前先把工具备齐。你至少要有一个能实时显示角度、转速、期望值和控制输出波形的上位机。RoboMaster圈子里最常用的是Vofa它支持JustFloat协议直接在串口上打印数据就能实时绘图非常方便。如果你不习惯Vofa用匿名上位机也完全没问题重点是你得能看到“目标角度、实际角度、实际转速、PID输出”四条曲线缺一不可。发送数据的代码很简单比如通过串口DMA发送一组float数组。我这里用的是JustFloat协议数据末尾加帧尾float debug_data[4] {target_angle, actual_angle, actual_speed, pid_output}; uint8_t *p (uint8_t *)debug_data; for (uint8_t i 0; i 16; i) // 4个float共16字节 usart_send_byte(p[i]); usart_send_byte(0x00); usart_send_byte(0x00); usart_send_byte(0x80); usart_send_byte(0x7f);调试时一定要把云台悬空或者固定好别对着人也别让云台在断电状态下乱转。一个安全的调试台能省一半的事故。我的习惯是先用一个很低的电压给系统供电确认CAN通信正常、电机能响应遥控器数据然后再开始贴参数。4.2 第一步内环速度环调参很多人一上来就调位置环这是错误的。串级系统里内环是基础内环不稳外环调得再好也是白搭。对内环进行调试时你可以先屏蔽外环直接把一个期望转速发给内环然后打印实际转速和期望转速曲线观察内环的跟随性能。具体操作步骤如下把外环PID参数全设为0代码里临时给速度环一个固定目标值比如500RPM。内环P从0.1开始往上加观察实际转速是否快速逼近目标转速。P加到电机声音干脆、转速曲线没有明显振荡停。如果曲线来回跳说明P太大往回降。加一点I让转速的稳态误差尽量小。注意I会带来超调宁缺毋滥。如果转速曲线有高频毛刺加一点点D或者检查一下CAN反馈是否滤波我这里一般直接用一阶低通滤波处理转速信号截止频率在100Hz左右。GM6020内部已经有速度环所以你外部再加一个速度环时等效于“速度外环”套“内部速度环”。这时候你的速度环P值不能给太大因为两个速度环叠加容易引发共振。我实测下来外部速度环P一般取0.5到3之间就够用了再大就会听到电机连续高频啸叫那就是共振的声音得赶紧降。4.3 第二步外环位置环调参内环稳定后把目标值切换成角度。先给一个小角度阶跃比如让云台转15度观察角度曲线和转速曲线。外环P从0.5开始加每次加0.2到0.5观察云台响应。你会看到三种典型状态角度慢慢悠悠回中而且回不到零说明P太小需要加大。角度快速回中但冲过头来回震荡一两次说明P偏大或者D不够。角度“啪”一下到位且基本不超调说明P在甜点区。记住P不要一次加太多我通常每调整一次就等云台完全静止再观察曲线这个习惯能帮你分清是参数问题还是机械振动问题。位置环的I要用得很克制一般只在云台有明显“垂头”趋势时加因为云台重心不完全在转轴上回中后角度会偏差一点这时候I就是用来补这个力的。I从0开始加每次加0.01观察角度静态误差是否消失一旦出现缓慢振荡立刻减半。外环的D我个人的经验是尽量不加至少是最后再加。原因前面说过外环误差信号有噪声D会放大噪声。如果你非要加那就从0.05这种极小值开始试直到云台刹车时干脆利落、没有发飘的感觉就停手。4.4 第三步联合调试与动态特性优化单轴调通之后必须做联合调试——云台两个轴一起动甚至让底盘也动起来模拟实际比赛工况。这里会发现很多单轴调试发现不了的问题比如两个轴互相影响产生机械共振或者底盘的振动通过结构传到云台造成角度曲线高频抖动。动态特性优化的几个常用手段降低外环带宽如果外环P给的太高云台对底盘振动的响应太敏感会一直抖。此时需要降低P或者在目标角度输入侧加一个低通/斜坡滤波器让云台的运动意图更加平滑。增加转速前馈比如你瞄准的目标在图像里快速移动位置环目标角度变化也很快。如果只靠位置环的误差去追云台会一直慢半拍。这时候可以在目标角度变化率上做文章把目标角度的微分也就是期望转速直接加到外环输出上作为前馈位置环只负责修正误差。这样云台追目标特别快而且不容易超调。动态切换参数云台在瞄准静止目标和扫描移动目标时最优PID参数是不同的。很多队伍会做多组参数根据视觉状态或遥控器模式切换。这个我建议等基础调通之后再玩否则你都不知道到底是哪组参数起作用容易绕晕。关于PID前馈网上争议挺大热搜里还专门有“pid前馈怎么使用”这个词条。我的理解是前馈不是让你替代PID而是让你“提前给一个底料”PID只需要在这个底料上做细微修正。拿云台来说目标角度以50度每秒匀速移动你就直接把这一项加到输出里位置环的负担就大大减轻。最终效果是云台能“死死咬住”运动目标而不是跟在后头画龙。4.4.1 前馈带通滤波的细节前馈虽好但直接用目标角度的微分会有个问题目标角度噪声经过微分后会被放大导致前馈量忽大忽小云台反而抖。所以实用做法是给前馈通道加一个低通滤波器或者用跟踪微分器来获得平滑的目标角速度。如果你手里有陀螺仪甚至可以把云台的实际角速度作为前馈来源这样响应更快、噪声更低。前馈的量级也要控制好一个简单的标定方法是让云台匀速旋转记下目标角速度对应的电机转速输出这个比值就是前馈系数。比如目标角速度1度每秒最终输出的RPM需要50那前馈系数就是50。把这个系数写在配置里先给80%的量剩下的20%交给PID去修正效果通常比空手调P好得多。5. 常见问题与排查技巧实录5.1 云台启动瞬间猛地窜一下这种问题多半出在PID初始值没处理好。上电瞬间实际角度是当前值目标角度可能默认设成0度两者误差很大外环一个巨大输出甩到内环内环再甩给电机就是猛地窜动。解决办法有两个一是上电后把目标角度直接同步为当前角度让闭环从零误差开始二是给外环输出加一个限速斜坡也就是“目标角度”不是直接跳变而是按最大角速度慢慢逼近当前目标。我强烈建议两步都做尤其是调试时目标角度经常被人为改来改去没有斜坡保护电机很容易“打人”。限速斜坡代码可以直接放目标值生成处比如static float smooth_target 0.0f; void set_gimbal_target(float raw_target) { float delta raw_target - smooth_target; float max_delta MAX_SPEED_DEG_PER_SEC * DT; if (delta max_delta) delta max_delta; if (delta -max_delta) delta -max_delta; smooth_target delta; }这个“目标平滑”是云台控制里最值得做的小事之一它比任何滤波都能减少超调而且不会引入相位滞后到反馈回路里。5.2 云台稳定后还是嗡嗡发颤这是典型的高频振荡声音不大但相机画面能看出来。排查思路先别急着降PID先检查机械固定件有没有松动。云台结构上任意一个螺丝没拧紧就会形成一个高频谐振点PID参数再完美也压不住。确认机械没问题后再检查反馈信号质量——用上位机看角度曲线上有没有毛刺。如果毛刺明显就在角度反馈上加滑动平均或者一阶低通。别小看这个滤波反馈干净了你才能把P给大而不会抖。如果反馈也干净那就是PID参数确实太激进。通常优先减小内环P和外环D。内环P太大会让电机产生高频啸叫这个声音你隔着两米都听得见外环D太大会放大角度噪声表现为云台一直在微小幅度地“哆嗦”。5.3 目标角度变了但云台迟迟不动这种情况一般是外环P太小或者目标平滑太慢。如果你用了斜坡限制先确认斜坡最大速度是不是设得太小了。另一个隐藏原因CAN通信丢帧。GM6020的数据反馈和指令发送如果频率太低或者丢包内环的速度误差会计算得断断续续云台就“卡顿”。我习惯把控制频率固定到1kHz也就是在1ms定时器中断里跑一次云台控制逻辑CAN发送也挂在这个中断里。这样系统延迟可控后续加视觉、加陀螺仪数据都好衔接。5.4 云台回中后有偏移静置一段时间慢慢漂走偶尔偏一点且回不去多半是I不够或者没有I。正常情况下I能把稳态误差吃掉。但如果你发现云台是“缓慢漂移”而不是“停在一个偏置位置”那更像反馈角度在漂。GM6020的角度是多圈累计值你每次上电后的零点不一定一致如果你在代码里把“零点”错误地设成了某个范围值角度就会产生偏移。建议单独做一个“云台初始化”函数开机后把当前角度记为零点或通过陀螺仪进行融合校准。5.5 PID参数调试速查表为了节省你现场翻笔记的时间我把常见问题对应的调整方向整理成一张表现象检查方向参数调整建议回中慢、拖泥带水P太小增大外环P来回振荡、发散P太大或I太大降低外环P/I考虑加轻微D高频微颤、啸叫反馈噪声或内环P过激降低内环P反馈加低通有静态偏差、垂头I不够增大外环I注意配合积分限幅刹车过冲严重D不够或目标斜坡太慢加一点外环D检查限速斜坡撞一下回正特别慢外环带宽低提高外环P或者加转速前馈数值一会儿正常一会儿乱跳CAN解析错误检查ID与数据字节序打印原始CAN数据5.6 调试中的心态与习惯最后说一点项目经验之外的东西。调试PID最忌讳“一次改好几个参数”你改了P又改了I出了问题根本不知道是谁的锅。我的原则是每次只改一个参数改了就跑一个阶跃测试然后看曲线记录。调试记录本上把参数、现象、结论都写清楚这样后面回归测试时能快速找到上一次的甜点。另一个建议是保存多组参数到配置文件里一键切换而不是每次调好了就覆盖源文件否则改崩了只能从头调。用上位机曲线调试时我一般把采样率设到500Hz到1kHz之间太低了看不到振荡细节太高了浪费串口带宽。其实很多时候你听电机的声音就能判断正常的PID控制电机转动声是干净的“呜呜”声如果听到“嗡嗡”或者“咔咔”基本就是参数或者机械出了问题优先停下来检查再继续。6. 扩展思考从云台到更多电机控制场景双环控制这套思路解决了GM6020云台之后你能把它平移到很多地方。比如RoboMaster里的步兵云台、哨兵云台本质上都是位置-速度双环。你甚至可以把它用在机械臂关节上只是机械臂对力矩规划要求更高还需要配合重力补偿和轨迹规划。PID不是万能的但对大多数“输入-输出可测”的运动控制系统来说串级PID是最实用、最容易调试的起点。至于代码实现我建议你从一开始就把数据结构、限幅、滤波这些基础设施做好因为到了后期你会发现瓶颈根本不在PID算法本身而在你的代码能不能让你快速做实验、快速回滚。GM6020的CAN通信、角度归一化、反馈滤波这些才是真正的护城河。最后祝各位调试顺利云台稳稳当当。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑