CAN通信稳定要求
目前已知机器人会在以下几种情况中由于CAN异常出现控制电机不稳定的现象
- 电机已经离线,PID进程仍然在继续,当电机恢复在线时出现失控
- CAN完全离线,但是仍然在中断里执行有阻塞的发送进程,导致中断系统卡死
- CAN总线上没有一个可应答的电机时,持续向CAN总线上发送数据会使STM32中的CAN模块由于发送应答错误过多而进入离线(Bus-off),目前已知该状态即使在自动离线管理模式(ABOM)打开的情况下也不能可靠地自动恢复
- CAN总线控制数据发送ID过大,在仲裁优先级里面排最低,在没有自动重传的情况下会出现连续掉帧的情况
- STM32 一个CAN缓冲区只有三个位置,当高速接收时可能会出现Overrun
针对上述问题,在STM32通过CAN控制电机过程中应该:
- 在CAN的配置中打开自动重传(NART清0,注意NART意思是禁用自动重传,清0代表关闭禁用自动重传,在CubeMX图形界面配置时应该要区分开)以及自动离线管理(ABOM)
- 在分配CAN的ID时尽量不使用GM6020中0x2FF的反馈ID
- 在没有收到电机反馈数据不要往CAN总线上发任何数据,即使是没有用PID控制的电机
- 确保使用的HAL库的CAN发送函数不带阻塞(已知目前最新版HAL不存在这个问题)
- 在main函数的主循环内用HAL_CAN_GetState不断检测CAN是否处于离线模式(BOF),如果是,则重新启动CAN
- 打开CAN的过滤器,将不同ID的包分开到两个缓冲区
电机布局(CAN总线)应该考虑的问题
总线带宽。
在 如何判断CAN总线空闲以及帧间隙,计算传输速率 提到过可将CAN标准数据帧(8Byte)的长度视为111bit,而目前C620和GM6020 CAN总线均采用1Mbps的速率,即每毫秒传输1k bits,折算到帧的话大约是9帧/每毫秒,即9kHz的帧带宽。每个电机的反馈数据速率为1kHz,考虑到需要预留发送控制帧的带宽,因此最大能容纳的电机数为8个(恰好与控制电机帧格式最大8个对应),但是此时最高控制频率为500Hz(假设一帧控制四个电机且频率相同)。提升控制频率时也要留意带宽是否足够,否则会出现传输数据必定丢失的问题总线仲裁。
之前哨兵云台的抖动就是这个没有考虑这个问题。带宽不够的情况下必定出现仲裁完全丢失的情况,总线仲裁会将ID较大的帧丢掉,通常控制电机的帧ID较小,因此仲裁丢失的数据是电机反馈的数据,如果连续丢失可能出现电机疯掉的情况。但是即使的带宽足够的情况下,电机反馈帧和STM32发送控制的控制帧也可能会同时发送,使总线冲突。这种情况可以通过打开自动重传解决(似乎电机那边反馈的数据帧是有自动重传的,否则一定概率下电机也可能失控),在仲裁失败后马上找到总线空闲的时间再发送。选定控制电机的数据帧发送频率。
- 第一,参考1. ,通过计算确保在电机数目和该控制频率下总线带宽足够。
- 第二,频率越高,与电机反馈数据冲突的概率越大,连续冲突的概率也越大。
- 第三,为从根本上避免连续冲突,选用的频率不应被1kHz整除。由于STM32时钟在一定范围内是十分精确的,因此当第一次冲突发生后必会导致后面也有很多次。1~2次的仲裁丢失不会有太大影响,但连续冲突就是很大的问题。同时应该要计算选用的频率在第一冲突后第二次可能冲突的时间长度(即距离1kHz最近的发送时间),并且1kHz附近应该要考虑范围即111bit帧的传输时间。比如277Hz就是一个不错的频率。