3、力控系统架构:从传感器到控制器的信号流、力控软件框架、实时性要求
聊力控调试,很多人一上来就调PID参数。我个人的习惯是,先搞清楚整个系统是怎么连起来的。你想想看,信号从传感器出来,到控制器做出反应,中间经过了多少环节?哪个环节慢了半拍,力控就抖给你看。
这一节,咱们就把力控系统的骨架搭起来。说白了,就是三件事:信号怎么走、软件怎么搭、实时性怎么保。
3.1 信号流:从传感器到控制器
力控的第一步,是拿到准确的力信号。这个信号流,我习惯把它分成三段:
- 感知层:六维力传感器采集力/力矩数据
- 传输层:通过某种总线(EtherCAT、CAN、模拟量)送到控制器
- 处理层:控制器内部做滤波、标定、坐标变换
我在项目中遇到过最头疼的问题,就是传感器信号跳变。后来发现,不是传感器坏了,而是屏蔽线没接好。嗯,这里要注意,力传感器的电缆一定要用双屏蔽线,而且屏蔽层要单端接地。
典型信号流路径:
六维力传感器 → 信号调理模块 → EtherCAT从站 → 主站控制器 → 力控算法 → 关节指令
为什么会强调EtherCAT?因为它的实时性够硬。我曾经用模拟量方案做过一个项目,采样率只有1kHz,稍微加点力控增益就震荡。换成EtherCAT后,采样率跑到4kHz,系统稳得像块石头。
3.2 力控软件框架
软件框架这块,我见过很多种写法。有的把力控逻辑直接写在机器人主循环里,有的单独开一个实时任务。我个人建议,力控软件至少包含以下四个模块:
| 模块 | 功能 | 实时性要求 |
|---|---|---|
| 数据采集模块 | 读取传感器原始数据,做单位转换 | 高(1-4kHz) |
| 预处理模块 | 滤波、零点漂移补偿、重力补偿 | 高 |
| 力控算法模块 | 阻抗控制/力位混合控制计算 | 高 |
| 安全监控模块 | 超限保护、急停逻辑 | 极高(独立线程) |
这里我画了一张力控软件框架的结构图,你看一眼就明白了:
我的经验:预处理模块里,重力补偿是最容易出错的。我曾经因为工具重心标定差了2mm,导致力控在某个姿态下突然失控。后来我养成了一个习惯——每次换工具,先做一次重力补偿标定,再跑力控。
3.3 实时性要求
实时性,是力控系统的命门。你想想看,如果传感器数据到了控制器,控制器却因为别的事情耽误了,力控指令晚发了10ms,机器人可能已经撞上工件了。
我一般把实时性分成三个等级:
- 硬实时(Hard Real-Time):力控循环、安全监控。必须保证在1ms内完成,错过就是事故。
- 软实时(Soft Real-Time):状态监测、数据记录。允许偶尔延迟,但不能太频繁。
- 非实时(Non Real-Time):人机界面、日志存储。延迟几秒也没关系。
在实际项目中,我推荐用这样的方案:
// 伪代码:力控实时任务结构
void ForceControlTask()
{
while(1)
{
// 1. 读取传感器(EtherCAT 同步)
sensor_data = ReadForceSensor();
// 2. 预处理(滤波 + 补偿)
filtered_data = LowPassFilter(sensor_data);
compensated_data = GravityCompensation(filtered_data);
// 3. 力控算法(阻抗控制)
force_command = ImpedanceControl(compensated_data);
// 4. 发送关节指令
SendJointCommand(force_command);
// 5. 等待下一个周期(1ms)
WaitForNextCycle();
}
}
注意:千万不要在力控循环里做文件写入、打印日志这类操作。我曾经见过一个同事,在力控循环里加了printf调试,结果循环时间从1ms飙到了5ms,机器人直接抖成了筛子。
关于实时操作系统,我个人比较推荐RT-Linux或者基于Xenomai的方案。Windows虽然方便,但它的调度不确定性太大。你想想看,Windows后台可能突然跑个更新,力控就断片了。工业现场,还是得用硬实时系统。
最后说一句,实时性不是靠硬件堆出来的。代码写得再快,如果架构设计不合理,该抖还是抖。先把信号流理清楚,再把软件框架搭稳,最后才去调参数。这个顺序,我踩过坑才明白。
公众号:蓝海资料掘金营,微信deep3321