ARTICLE DETAIL

资讯详情

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

CiA402伺服协议详解:状态机、对象字典与多模式切换实战

CiA402伺服协议详解:状态机、对象字典与多模式切换实战 伺服调试这行干久了会发现一个挺有意思的现象很多人能把 CANopen 的报文收发写得明明白白SDO 读写、PDO 映射、心跳、NMT 状态机这些玩得挺溜可一旦要用 CiA402 去驱动一台真正带轴的伺服就开始卡壳——使能不了、模式切不过去、一切模式就飞车。问题往往不在底层通信而在 CiA402 这层行为约定上。它规定了伺服在什么状态下能接受什么指令、状态怎么迁移、工作模式怎么切换、参数怎么换算这些恰恰是手册里写得最分散、最容易漏掉的部分。这篇内容我打算把 CiA402 的伺服协议从头拆一遍重点放在状态机、对象字典、多工作模式切换的时序控制上顺带把我这些年踩过的坑、验证过的切换流程、以及一套可以直接抄作业的代码结构拿出来分享。不管你是刚接触伺服总线的嵌入式新手还是已经会调单模式、想搞明白怎么做模式热切换的老手应该都能从中捞到点有用的东西。1. 搞懂 CiA402 在整个控制链路里的位置1.1 它不是协议栈而是行为约定刚上手的人特别容易把 CiA402 和 CANopen 混为一谈觉得它俩是一回事。其实分层很清楚CANopen 解决的是怎么把数据从 A 点搬到 B 点——报文格式长什么样、怎么寻址、怎么分优先级、怎么保证大块数据可靠传输而 CiA402 解决的是驱动器收到这些数据后该干什么。前者是通信规则后者是设备行为规则。你可以这么理解CANopen 像是邮编加门牌号加邮递员保证包裹能送到CiA402 则是包裹里那份操作说明书规定收件人拆包后第一步做什么、第二步做什么、做错了怎么退回。少了 CiA402驱动器只能告诉你我收到了 3 个字节但完全不知道这 3 个字节是让它上电、让它转、还是让它停。这也是为什么有的工程师用裸 CAN 也能把伺服转起来——因为他自己在上位机里手搓了一整套操作说明书只是这套说明书没标准化而已换一台不同品牌的驱动器就得重写。CiA402 的官方定位是驱动与运动控制设备子协议对应的国际标准编号是 IEC 61800-7-201。它管的事包括一套固定的状态机、一套固定的对象字典索引、一套固定的控制字/状态字位定义、以及一组标准工作模式。只要你按它来理论上不同厂家的驱动器可以互换——当然理论上三个字是被现实反复教育的后面会讲。1.2 对象字典把伺服参数做一次性封装对象字典是 CiA402 最核心的载体。它本质是一张十六进制索引表每个索引Index加子索引Subindex指向一个具体参数。你读写任何东西都是在跟这张表打交道。对伺服来说常用的索引其实就那么几十个但必须记熟因为它们决定了你的控制逻辑索引名称作用常用度0x6040Controlword控制字上位机下发命令极高0x6041Statusword状态字驱动器反馈状态极高0x6060Modes of operation下发工作模式极高0x6061Modes of operation display回读当前实际模式极高0x6064Position actual value实际位置用户单位极高0x606CVelocity actual value实际速度高0x6077Torque actual value实际转矩高0x607ATarget position目标位置高0x60FFTarget velocity目标速度高0x6071Target torque目标转矩高0x6081Profile velocity位置模式下的运行速度高0x6083Profile acceleration加速度高0x6084Profile deceleration减速度高0x6098Homing method回零方式中0x6502Supported drive modes支持的模式位图中0x60B0Position offset位置偏移CSP 切换常用中0x60B1Velocity offset速度偏移中0x60B2Torque offset转矩偏移中这张表的价值在于它把参数配置和实时控制分开了。配置类的参数加减速、软限位、原点偏移、单位换算走 SDO上电初始化时写一次就行实时类的数据控制字、目标值走 PDO靠同步周期循环刷新。这个分工你要是一开始就想明白后面架构设计会顺很多。注意0x6060 是我要用什么模式0x6061 是驱动器现在实际在什么模式。不要想当然地认为写完 0x6060 就切过去了一定要回读 0x6061 确认。很多切换失败的问题根源就是没做这一步校验。1.3 会用 CANopen 却不会用 CiA402 的典型症状我见过太多这样的案例总结下来症状挺集中一是能发 SDO 读参数但不知道该按什么顺序把驱动器使能起来二是知道有 0x6040 这个对象但控制字每个 bit 什么意思说不清三是模式切完之后电机不动或者报个模糊的故障码不知道从哪查起四是位置模式跑得挺好一换到 CSP 就抖。根子都在这三点状态机没吃透、位定义没记牢、切换时序没约束。后面我就按这三条主线往下走。2. 状态机是命门从冷启动到使能的完整迁移路径2.1 八个状态与它们的触发条件CiA402 定义了一套强制状态机驱动器任何时候都处在下面八个状态之一。你可以把它想成一个逐级上锁的保险箱——每开一道锁都需要特定条件跳步是不允许的。状态状态字低 7 位特征值含义Not ready to switch on0x00上电自检中不接受控制Switch on disabled0x40已就绪待机主电源断开Ready to switch on0x21可以合闸上动力电Switched on0x23动力电已上但输出级未使能Operation enabled0x27输出级使能电机带电Quick stop active0x07快速停机中Fault reaction active0x0F故障响应处理中Fault0x08故障锁定需复位这套状态机的设计逻辑很务实把能不能上电和要不要输出分成两个独立环节。上动力电Switched on和使能输出级Operation enabled分开好处是可以在电机不转的前提下先把母线电压建起来避免一上电就冲击。很多设备每次上电都要走一遍 0x06→0x07→0x0F就是这个道理。2.2 控制字与状态字逐位拆解这两个 16 位对象是整个协议的心脏必须刻进脑子里。控制字 0x6040 的关键位位名称说明bit 0Switch on配合 bit1、bit2 完成合闸bit 1Enable voltage允许上动力电bit 2Quick stop0 触发快速停机bit 3Enable operation使能输出级bit 4-6模式相关位各模式含义不同bit 7Fault reset上升沿复位故障bit 8Halt暂停当前运动bit 9模式相关位部分模式使用状态字 0x6041 的关键位位名称说明bit 0Ready to switch on已就绪可合闸bit 1Switched on已合闸bit 2Operation enabled输出级已使能bit 3Fault故障标志bit 4Voltage enabled母线电压到位bit 5Quick stop0 快速停机激活bit 6Switch on disabled待机状态标志bit 7Warning警告不影响运行bit 9Remote远程控制生效bit 10Target reached目标到达bit 11Internal limit active内部限幅激活bit 12-13模式相关位各模式含义不同bit 14-15厂商自定义看具体厂家上电标准序列的控制字取值我这里列一下直接背下来省事#define CW_SHUTDOWN 0x0006 // 进入 Ready to switch on #define CW_SWITCH_ON 0x0007 // 进入 Switched on #define CW_ENABLE_OPERATION 0x000F // 进入 Operation enabled #define CW_DISABLE_VOLTAGE 0x0000 // 断开动力电 #define CW_QUICK_STOP 0x0002 // 快速停机 #define CW_DISABLE_OPERATION 0x0007 // 退出使能保留动力电 #define CW_FAULT_RESET 0x0080 // 故障复位上升沿有效状态字低 7 位的解码用 switch 最清爽typedef enum { ST_NOT_READY 0x00, ST_SWITCH_ON_DISABLED 0x40, ST_READY_TO_SWITCH_ON 0x21, ST_SWITCHED_ON 0x23, ST_OPERATION_ENABLED 0x27, ST_QUICK_STOP_ACTIVE 0x07, ST_FAULT_REACTION 0x0F, ST_FAULT 0x08, ST_UNKNOWN 0xFF } cia402_state_t; cia402_state_t decode_state(uint16_t statusword) { switch (statusword 0x006F) { case 0x0000: return ST_NOT_READY; case 0x0040: return ST_SWITCH_ON_DISABLED; case 0x0021: return ST_READY_TO_SWITCH_ON; case 0x0023: return ST_SWITCHED_ON; case 0x0027: return ST_OPERATION_ENABLED; case 0x0007: return ST_QUICK_STOP_ACTIVE; case 0x000F: return ST_FAULT_REACTION; case 0x0008: return ST_FAULT; default: return ST_UNKNOWN; } }这里有个实操细节掩码用的是 0x006F也就是 bit0-3、bit5、bit6。为什么不用 0x007F 把 bit4 也算进去因为 bit4 是电压已建立标志它在状态迁移过程中会变但和当前处于哪个状态没关系。你要是把它算进去Switched on 和 Operation enabled 的判定就会出错。这个坑我早年踩过状态死活判不对查了半天才发现是掩码写多了。提示有些厂家的驱动器在 Fault 状态下状态字会同时显示 bit3 和其他位别只看 bit3 就完事最好用上面那张特征值表做精确匹配。2.3 三条典型指令序列冷启动使能序列走的是标准四步下发0x0006Shutdown等待状态字低 7 位变为0x21下发0x0007Switch on等待变为0x23下发0x000FEnable operation等待变为0x27此时电机已带电可以下目标值每一步之间都要有超时判断不能死等。我给的建议超时是 200 毫秒超过就报错退出别无限循环把主循环卡死。快速停机序列把 bit2 清掉即可下发0x0002驱动器会按 0x6085Quick stop deceleration减速减完进入 Quick stop active 状态。想恢复的话重新下发0x000F但前提是停机已经完成。故障复位序列关键在上升沿三个字// 先确保 bit7 为 0 drv_write_controlword(node, current_cw ~0x0080); delay_ms(5); // 再置 1 产生上升沿 drv_write_controlword(node, current_cw | 0x0080);有些驱动器对复位脉宽有要求太短识别不到我一般给 5 到 10 毫秒。还有一点复位的时候如果电机还在转或者还有运动指令挂着可能复位完立马又报同一个故障。所以复位前一定先停机、清目标值再复位。这个顺序别颠倒。2.4 卡状态的排查顺序遇到使能不了我固定的排查顺序是这样的先读 0x6041 看当前在哪一步倒推是哪一步没走通再读 0x2310 之类厂商自定义的报错对象不同厂家索引不一样常见的有 0x603F 错误码然后检查硬件——动力电到位没有、抱闸有没有松开、急停回路是不是断开的最后才是看控制字发的对不对。为什么要先读状态再查控制字因为状态字是结果控制字是你的意图先看结果能立刻缩小范围。如果状态卡在 Switch on disabled说明驱动器压根没让你上电那多半是硬件问题或者被禁用了如果卡在 Switched on 上不去 Operation enabled说明合闸了但输出级不肯开一般是模式没设对或者有软件互锁。3. 多工作模式解析六种模式到底该怎么选3.1 周期同步三兄弟CSP、CSV、CSTCSPCyclic Synchronous Position模式码 8、CSV模式码 9、CST模式码 10这三个是上位机做插补控制时的主力。它们的共同特点是上位机每个同步周期SYNC 触发下发一个目标值驱动器在这个周期内完成位置/速度/转矩的闭环。CSP 是最常用的。上位机每个周期把算好的目标位置写进 0x607A驱动器负责在这个周期内把电机转到那个位置。它不要求上位机给出速度速度由位置差除以周期时间反推。这就意味着上位机的插补周期必须和驱动器的同步周期严格对齐否则会抖。CSV 则是上位机给速度指令 0x60FF。适合做连续送料、传送带这类不需要精确位置、只要求速度稳定的场景。有的设备用它做速度前馈配合 CSP 一起用能让轨迹跟踪更顺。CST 上位机给的是转矩 0x6071用在力控场景——比如打磨、压装需要控制接触力而不是位置。用 CST 的时候最忌讳上位机不管实际情况闭眼给转矩电机堵转了你还在加力很容易烧线圈。注意这三个模式在 CiA402 标准里控制字 bit4-6 是没有定义的同步完全靠 SYNC 报文驱动。有些厂商自己扩展了 bit4 用来使能周期同步这种私有扩展你不查手册根本猜不到所以换品牌一定要重新看控制字定义。3.2 轨迹规划三件套PP、PV、PTPPProfile Position模式码 1、PVProfile Velocity模式码 3、PTProfile Torque模式码 4这三个的特点正好相反上位机只管下目标加减速规划由驱动器内部完成。它的好处是不占用总线带宽同步周期要求也不高坏处是轨迹不连续点位之间会有停顿。以 PP 为例上位机设好 0x607A目标位置、0x6081运行速度、0x6083/0x6084加减速然后通过控制字 bit4New set-point的上升沿触发一次运动。bit5 决定是立即切换目标还是等上一个目标到位再接下一条bit6 决定是绝对位置还是相对位置。这几个位的组合决定了你的点位运动是连起来还是断开。我个人的经验是单轴点位搬运、上下料这种场合PP 模式最省心但如果你要两个轴插补出一个圆弧那就必须上 CSPPP 做不到。3.3 回零模式与它的隐藏坑回零模式码是 6靠 0x6098 选择具体方式。标准里定义了三十多种回零方式常用的也就那么几种0x6098 值回零方式适用场合1 / 2负/正限位开关 索引有硬限位的直线轴3-6原点开关上升/下降沿一般带原点的场合17 / 18无索引脉冲仅靠限位/原点无编码器索引19-30原点开关 索引脉冲精度要求高35 / 36以当前位置为原点手动对好点后清零回零的坑在于两点。第一控制字 bit4 是回零启动位你要给一个上升沿不是一直保持。第二回零速度分高速寻找和低速精定位两段分别由 0x6099 的子索引 1 和 2 设置很多人只设了一个结果要么找得慢要么定位不准。回零完成怎么判断状态字 bit10 和 bit12 同时为 1表示回零到达且无错误如果 bit13 为 1那就是回零出错了一般是没找到原点开关或者走了超长距离检查一下 0x6098 方式和实际接线对不对得上。3.4 模式选择速查表需求推荐模式理由点位搬运PP规划在驱动器总线负担小连续调速PV速度闭环简单直接恒力打磨、压装PT / CST需要控制力矩多轴插补CSP周期同步位置精确送料匀速CSV速度指令连续开机找原点Homing建立机械坐标基准4. 模式切换实战时序、条件与参数对齐4.1 切换前必须满足的四个条件模式切换不是随便写的我总结了四条硬性前提缺一条都可能失败第一输出级必须先退出使能。也就是控制字要从 0x000F 退回 0x0007Disable operation让状态回到 Switched on。当然有的驱动器允许在线切换但那是在它内部做了无扰补偿的前提下普通应用还是老实退出使能更稳。第二当前模式下的目标值要清零。比如你从 PV 切到 CSP得先把 0x60FF 写成 0否则切过去瞬间电机可能突然加速。第三状态必须是 Switched on 或 Operation enabled不能在 Fault、Quick stop active 状态下切。故障状态下写 0x6060有的驱动器直接忽略有的干脆报错。第四切换后的新模式必须在设备支持列表里。读一下 0x6502Supported drive modes它是位图bit0 对应 PP、bit1 对应 PV……先确认支持再切免得白折腾。4.2 切换时序与代码实现下面是我验证过多次的切换函数逻辑是先退使能、再写模式、回读确认、最后重新使能bool drv_switch_mode(uint8_t node, int8_t target_mode) { // 1. 退出使能回到 Switched on if (!drv_write_cw(node, CW_DISABLE_OPERATION)) return false; if (!wait_state(node, ST_SWITCHED_ON, 200)) return false; // 2. 清零所有目标值避免切换瞬间的冲击 drv_sdo_write_i32(node, 0x60FF, 0x00, 0); // Target velocity drv_sdo_write_i16(node, 0x6071, 0x00, 0); // Target torque // 3. 写模式 if (!drv_sdo_write_i8(node, 0x6060, 0x00, target_mode)) return false; // 4. 回读确认 int8_t actual 0; if (!drv_sdo_read_i8(node, 0x6061, 0x00, actual)) return false; if (actual ! target_mode) return false; // 5. 按目标模式准备参数 switch (target_mode) { case 8: { // CSP把目标位置对齐到当前位置实现零冲击 int32_t cur 0; drv_sdo_read_i32(node, 0x6064, 0x00, cur); drv_sdo_write_i32(node, 0x607A, 0x00, cur); break; } case 9: // CSV先给 0 速度 drv_sdo_write_i32(node, 0x60FF, 0x00, 0); break; case 10: // CST先给 0 转矩 drv_sdo_write_i16(node, 0x6071, 0x00, 0); break; default: break; } // 6. 重新使能 if (!drv_write_cw(node, CW_ENABLE_OPERATION)) return false; if (!wait_state(node, ST_OPERATION_ENABLED, 200)) return false; return true; }这段代码里有两个地方值得展开说。一是第 2 步的清零看着多余其实很关键——你想想从速度模式切到位置模式时如果速度目标值还挂着非零数驱动器重新使能的瞬间可能先按速度跑一下再切闭环表现出来就是电机抖一下。二是 CSP 切换前把 0x607A 对齐到 0x6064这一步是让新模式的起点等于当前位置相当于接力棒交接时两边位置严丝合缝这样再叠加 0x60B0 位置偏移就不会有跳变。4.3 零冲击对齐的核心原理为什么对齐这么重要我拿个生活化的比喻解释。假设你开车从定速巡航切手动控制如果切换瞬间你脚下的油门和巡航设定的油门差很多车就会猛冲或猛收。伺服也一样CSP 模式下驱动器每周期比较目标位置和实际位置差值大就输出大速度。你要是切换时目标位置离实际位置很远第一个周期就会下个巨大的速度指令电机自然飞车。标准做法是切换瞬间令0x607A 0x6064之后每个同步周期再逐步给增量。如果要做连续轨迹还可以用 0x60B0Position offset叠加一个偏移量让上位机在切换前后保持自己的轨迹坐标连续。// CSP 每个同步周期的写入逻辑 void csp_cycle(uint8_t node, int32_t next_target) { drv_pdo_write_i32(node, 0x607A, next_target); }4.4 PDO 重新映射还是全量映射这是个挺实际的问题。不同模式需要的实时对象不一样PP 需要 0x607APV 需要 0x60FFCST 需要 0x6071。你是每次切换模式都重新映射 PDO还是干脆把所有需要的数据都映射进去我试过两种结论是固定全量映射更省事但要把 PDO 长度控制住。CANopen 标准帧最多 8 字节数据经典 PDO 一般映射两到三个对象RPDO1 (0x1600): 0x6040 (2B) 0x607A (4B) 0x6060 (1B) 7B TPDO1 (0x1A00): 0x6041 (2B) 0x6064 (4B) 0x6061 (1B) 7B这样无论切到哪个模式控制字、目标位置、模式都能一帧发出去也不需要重新映射。缺点是位置、速度、转矩没法同时塞进一帧——如果三个都要得再开一组 PDO。我的做法是位置类应用用 RPDO1 传 0x607A速度类再单独开 RPDO2 传 0x60FF两帧并行比反复改映射稳得多。提示PDO 映射改完必须重新配置一次通信参数并复位通信否则不生效。具体触发方式有的靠 NMT 复位节点有的靠写 0x1400/0x1600 的通讯参数对象。别改完映射以为立刻生效这个坑不少人栽过。5. 实操环境搭建与关键配置5.1 硬件与工具清单先把环境列清楚方便复现主控STM32F407 或以上带两路 CAN或直接用带 EtherCAT 的板子跑 CANopen协议栈CANopenNode 或商用协议栈都能直接支持 CiA402伺服支持 CiA402 的任意品牌常见的有汇川、台达、松下、安川工具CAN 分析仪一只用来抓报文伺服厂家的调试软件一台配 USB 转 CAN从站节点 ID一般默认 1波特率 1 Mbps波特率必须两边一致这个低级错误天天有人犯。1 Mbps 下面总线总长别超过 40 米节点多了还要考虑终端电阻一般首尾各 120 欧姆。5.2 SDO 配置脚本示例上电初始化的参数我用 SDO 一次性配置。下面是一段配置脚本把模式、加减速、单位换算都设好bool drv_init(uint8_t node) { // 配置单位换算先设编码器分辨率每个电机圈多少增量 drv_sdo_write_u32(node, 0x608F, 0x01, 131072); // 编码器增量 drv_sdo_write_u32(node, 0x608F, 0x02, 1); // 电机圈数 // 齿轮比电机 10 圈 负载 1 圈 drv_sdo_write_u32(node, 0x6091, 0x01, 10); drv_sdo_write_u32(node, 0x6091, 0x02, 1); // 进给常数负载每圈对应 10000 用户单位 drv_sdo_write_u32(node, 0x6092, 0x01, 10000); drv_sdo_write_u32(node, 0x6092, 0x02, 1); // 位置模式参数 drv_sdo_write_u32(node, 0x6081, 0x00, 100000); // Profile velocity drv_sdo_write_u32(node, 0x6083, 0x00, 500000); // 加速度 drv_sdo_write_u32(node, 0x6084, 0x00, 500000); // 减速度 // 软限位 drv_sdo_write_i32(node, 0x607D, 0x01, -1000000); // 下限 drv_sdo_write_i32(node, 0x607D, 0x02, 1000000); // 上限 // 设默认模式为位置模式 drv_sdo_write_i8(node, 0x6060, 0x00, 1); return true; }5.3 单位换算为什么容易出错单位换算这块我单独拎出来讲因为它决定你的位置精度也最容易埋雷。按标准位置用户单位的换算链条是这样的编码器分辨率0x608F告诉你一个电机圈对应多少增量齿轮比0x6091告诉一个负载圈对应多少个电机圈进给常数0x6092告诉一个负载圈对应多少用户单位。综合起来1 用户单位 编码器增量 × 齿轮比分子 × 进给常数分母 / (齿轮比分母 × 进给常数分子)套上面的配置131072 × 10 × 1 / (1 × 10000) 131.072。这里就出问题了——131.072 不是整数。多数驱动器内部做换算的时候要求比率是整数非整数会出现位置累积漂移或者直接报换算比非法。解决办法有两个一是调整进给常数把 10000 改成一个能整除的值比如 1310720这样比率正好是 1二是把编码器分辨率那一级的分母设大让整体能约成整数。我一般的经验是先反推你需要的分辨率再倒推进给常数别拿别人的公式硬套。比如你要 1 微米的分辨率丝杠导程 10 毫米那负载一圈就是 10000 微米进给常数设 10000 刚好再配合上面的齿轮比就能得到干净的整数比率。6. 踩坑与排查实录6.1 常见问题速查表现象可能原因排查方向使能不上卡在 0x40动力电未上 / 被禁用查母线电压、抱闸、急停回路卡在 0x23 上不去 0x27模式未设 / 存在软件互锁读 0x6061、查使能条件模式切换无效未先退使能确认控制字已回 0x0007回读 0x6061 不匹配目标模式不被支持读 0x6502 位图确认CSP 使能后飞车目标位置未对齐当前值切换前写 0x607A 0x6064PP 模式点位间停顿bit5 设为 0改成立即切换目标位置累积漂移单位换算比非整数重设 0x6091/0x6092回零总失败回零方式与实际接线不符查 0x6098 与原点开关接线通信偶发丢帧波特率不匹配 / 缺终端电阻查线缆两端 120Ω6.2 使能瞬间飞车的三个原因飞车是吓人的问题但原因并不复杂我归纳成三类。第一类是目标值和当前位置差太大。前面讲过切到 CSP 或重新使能前没对齐位置就会这样。这类飞车的特点是方向固定、幅度大因为差值算出来就是个固定的大数。第二类是单位换算设反了。比如上位机按脉冲算驱动器按毫米算你给的目标位置数值其实是个微米级的小数但驱动器理解成毫米级的大数结果就是跑十万八千里。这类飞车的特点是目标值本身看着正常但实际走的距离离谱。第三类是编码器反馈方向反了。上位机给正向指令编码器给反向反馈闭环越修越远。这类问题在初次调试时特别常见解决办法是设 0x607EPolarity反转或者干脆调换电机动力线两相。注意动力线和编码器方向要一起调只调一个会更乱。6.3 模式切换被静默拒绝有一种情况特别坑你写 0x6060SDO 返回成功但回读 0x6061 还是老值。这就是静默拒绝——驱动器收到了但因为某些条件不满足它就是不切也不报错。我遇到的静默拒绝基本是这几个原因一是驱动器固件版本不支持该模式虽然 0x6502 位图上标着支持但实际有 bug二是切换时电机还有残余速度驱动器要求先停稳三是某些安全功能如 STO还处于激活状态。排查的时候先把 0x6502 读出来确认位图再确保电机停稳最后检查安全回路。三条都排除了还不行那就只能找厂家确认固件了。6.4 同步周期和插补周期不匹配这个坑比较隐蔽。CSP 模式下两个周期如果不对齐表现出来是运行平滑但位置总差一点或者周期性的轻微抖动。原理上驱动器的同步周期是它内部电流环/速度环的执行周期一般 125 微秒或 250 微秒而上位机的插补周期可能是 1 毫秒。上位机每 1 毫秒发一个位置点驱动器在这个点到来之前会一直保持上一周期的位置增量这就出现了阶梯。解决方式是上位机在每毫秒内做插值或者干脆让上位机的插补周期和驱动器的同步周期成整数倍关系。调试的时候我会在 CAN 分析仪上同时抓 SYNC 报文和 PDO 报文看它们的时间间隔是否严格规律。如果 SYNC 的抖动超过 10 微秒那多半是上位机的实时性不够得考虑用 RTOS 或者干脆上 FPGA。7. 参数整定与性能优化的几个经验点7.1 前馈比调 PID 更管用做 CSP 的时候很多人使劲调位置环 PID效果始终差一口气。其实更有效的手段是在速度前馈和转矩前馈上做文章。0x60B1Velocity offset和 0x60B2Torque offset就是给这个用的。上位机算出轨迹的速度和加速度把速度前馈量写进 0x60B1转矩前馈写进 0x60B2位置环的负担就轻了跟踪误差能明显下降。前馈系数怎么定速度前馈一般取 80% 到 100%转矩前馈看负载惯量比。负载惯量比大的场合比如直驱转矩前馈占比可以到 70% 以上。这个不是标准给的得靠实测调。7.2 跟随误差窗口要设对0x6065Following error window和 0x6066Following error time out这俩参数决定驱动器什么时候报跟随误差过大。设小了正常加减速也报警设大了真出问题也不报。我的经验值是窗口设在正常运行时最大跟随误差的 2 到 3 倍超时时间设在 100 到 500 毫秒。先按保守值跑一段用示波器或驱动器的曲线功能抓实际跟随误差再回头收紧。一上来就设很紧十有八九是自找麻烦。7.3 停止曲线不要用急停硬停最后说一个安全的细节。很多设备停机直接切 0x0000 断动力电或者猛切 0x0002结果机械冲击大得吓人。正确做法是设好 0x6085Quick stop deceleration配合 0x6084 的减速曲线让急停有个可控的减速过程。急停默认用的是快速停机减速这个值一般比正常减速快但也不能设成趋近无穷大不然跟硬停没区别。做丝杠、皮带这类有惯性的负载减速曲线一定要试出来。回想我自己第一次调 CiA402 的那台设备使能序列写了三天最后发现是状态字掩码算错了一位把电压标志当成了状态标志一直判在错误的步上。这种低级错误在早期特别常见但踩过之后对状态机的理解会深刻很多。真正让我转变思路的是后来把状态机和对象字典的关系画成一张流程图贴在墙上——每个状态能接受什么命令、会迁移到哪里全部标清楚。那之后调新设备基本上两个小时就能把整条使能链路跑通。参数整定这块我给的建议是别迷信手册上的默认值惯量比、负载特性每台机器都不一样一定要自己抓曲线、自己算把 0x60B1 和 0x60B2 这两条前馈通道用起来通常比死磕位置环增益效果好得多。
返回列表