写在开始之前:为什么会有这篇文章

最近的工作中,我实际使用了一段时间 JAKA(节卡)六轴机械臂

在现场的常规用法是:

  • 安装节卡官方软件

  • 使用平板作为示教器

  • 通过触摸、拖动完成示教和调试

在交互层面,主要只有两类操作方式:

  1. 关节运动(单轴 / 多轴角度控制)

  2. 空间坐标运动(末端在笛卡尔空间的移动)

同时,节卡提供的是一种模块化、拖拽式的编程方式。在实际使用中,这种方式对调试人员是友好的:

  • 平板便于携带

  • 操作直观,上手快

  • 不需要编程背景

  • 中文界面,可读性很好

但在使用一段时间后,我也逐渐感受到一些明显的限制:

  • 拖拽式逻辑在流程复杂时不够清晰

  • 程序整体的可读性和可维护性较差

  • 很难像代码一样进行版本管理和复用

  • 对于做二次开发或系统级理解并不友好

简单来说:

它非常适合“用机器人”,但不太适合“理解机器人”。

于是我开始思考一个问题:

如果抛开示教器,用“写代码”的方式去理解六轴机械臂,会不会更清楚?

在查阅节卡官方资料时,我发现他们其实提供了底层 SDK 和接口示例,但基本都是 C++ 实现

考虑到学习和验证效率,我把其中一部分结构用 Python 重新抽象了一遍,并不追求功能完整,而是希望:

  • 用代码把机械臂的系统结构拆清楚

  • 理解真实工业机械臂的软件组织方式

  • 为后续的运动学、控制和仿真打下基础

这篇文章,就是从这个背景开始的。

接下来,我们不从公式出发,而是从一份最小可理解的机械臂控制代码骨架开始,一步步展开。

本文以ZU12六轴机器人驱动代码为例,系统解析工业级机器人驱动的核心架构设计。代码聚焦于状态管理、模块解耦与安全边界构建,适用于六轴/SCARA等多关节机器人控制系统开发。

一、整体架构概览

class ZU12Driver:
    def __init__(self):
        self.robot_state = RobotState.DISABLED  # 状态机
        self.kinematics = Kinematics()          # 运动学
        self.dynamics = Dynamics()              # 动力学
        self.safety = Safety()                  # 安全监控
        self.connected = False                  # 通信状态

该架构采用四层解耦设计

  • 状态管理层:统一管理机器人操作状态流转
  • 运动学层:负责正/逆运动学解算、轨迹规划
  • 动力学层:处理力矩计算、重力补偿、振动抑制
  • 安全层:独立的安全监控与响应机制

各模块通过组合(Composition)方式集成,避免继承导致的紧耦合,符合SOLID原则中的单一职责原则(SRP)。

二、状态机设计:操作安全的基石

class RobotState:
    DISABLED = 0  # 伺服未使能/断电
    ENABLED = 1   # 伺服使能,可接收指令
    ERROR = 2     # 安全事件触发,需人工复位
    RUNNING = 3   # 运动执行中

状态流转约束

当前状态

允许操作

目标状态

校验条件

DISABLED

power_on()

DISABLED

仅上电,未使能伺服

DISABLED

enable_robot()

ENABLED

需先connect() + power_on()

ENABLED

发送运动指令

RUNNING

安全模块检测通过

ANY

安全事件触发

ERROR

立即锁定所有操作

ERROR

reset_error()

DISABLED

需人工确认后复位

实现要点
  • 所有操作方法(enable_robot(), power_off()等)前置校验self.connected
  • 状态变更集中管理,避免分散赋值导致状态不一致
  • ERROR状态设计为终端状态,必须显式复位才能恢复,符合ISO 10218安全规范

三、模块解耦设计分析

1. 运动学与动力学分离
self.kinematics = Kinematics()  # 位置/速度级计算
self.dynamics = Dynamics()      # 力/力矩级计算

分离价值

  • 运动学计算频率高(1-2ms周期),需轻量级实现
  • 动力学计算可降频执行(5-10ms),避免实时性压力
  • 便于独立测试:运动学可用DH参数验证,动力学可用仿真数据标定

典型调用链:

# 轨迹规划
joint_pos = kinematics.inverse(xyz, rpy)  # 逆解
torque = dynamics.calculate_torque(joint_pos, velocity)  # 力矩补偿
driver.send_command(joint_pos, torque)   # 下发指令
2. 安全模块独立化
from safety import Safety, CollisionLevel
self.safety = Safety()

安全层级设计(CollisionLevel):

class CollisionLevel:
    WARNING = 1   # 降速运行(软限位)
    PROTECT = 2   # 停止运动,保持伺服使能
    EMERGENCY = 3 # 触发急停,切断伺服电源

关键实现要求

  • 安全检测必须在运动指令下发前执行(前置校验)
  • 安全事件触发后应异步通知上层,同时同步阻断运动链
  • 硬件安全回路(安全继电器)必须与软件安全形成双冗余

四、通信抽象与扩展性

当前代码中connect()/disconnect()为模拟实现,实际工程需扩展通信抽象层:

class CommunicationInterface(ABC):
    @abstractmethod
    def connect(self) -> bool: pass
    @abstractmethod
    def send(self, cmd: bytes) -> bool: pass
    @abstractmethod
    def receive(self) -> Optional[bytes]: pass
    @abstractmethod
    def is_alive(self) -> bool: pass

class EtherCATDriver(CommunicationInterface): ...
class ModbusTCPDriver(CommunicationInterface): ...

集成建议

class ZU12Driver:
    def __init__(self, comm: CommunicationInterface):
        self.comm = comm  # 依赖注入,便于测试与替换

优势:

  • 支持协议热切换(开发用Modbus,量产用EtherCAT)
  • 单元测试时可注入Mock通信层,无需真机
  • 符合依赖倒置原则(DIP)

五、工程实践建议

1. 状态持久化
def _persist_state(self):
    state_data = {
        'timestamp': time.time(),
        'state': self.robot_state,
        'joints': self.kinematics.get_current_joints()
    }
    with open('/var/lib/robot/state.json', 'w') as f:
        json.dump(state_data, f)
  • 断电恢复时可快速重建状态
  • 便于故障后根因分析
2. 安全监控增强
def enable_robot(self) -> bool:
    # 使能前安全自检
    if not self.safety.check_joint_limits():
        return False
    if self.safety.collision_level != CollisionLevel.NONE:
        return False
    # ... 使能逻辑
3. 错误码标准化

建议将print()替换为结构化日志+错误码:

class ErrorCode:
    NOT_CONNECTED = 0x1001
    SAFETY_CHECK_FAILED = 0x1002
    POWER_OFF_REQUIRED = 0x1003

def enable_robot(self) -> Tuple[bool, int]:
    if not self.connected:
        return False, ErrorCode.NOT_CONNECTED

六、架构适用性分析

机器人类型

适配要点

修改建议

六轴关节型

原生支持

无需修改

SCARA

运动学模型差异

替换Kinematics实现,保留驱动接口

Delta

工作空间约束强

Safety中增强工作空间校验

协作机器人

需力控安全

扩展Safety增加力/力矩阈值监控

七、总结

该驱动架构的核心价值在于:

  1. 状态机驱动操作流:通过有限状态机约束操作顺序,从架构层面杜绝非法操作
  2. 垂直分层解耦:运动学/动力学/安全各司其职,支持独立开发与测试
  3. 安全前置设计:安全校验嵌入操作链路,而非事后补救
  4. 接口抽象预留:通信层、安全等级等均预留扩展点,适应不同硬件平台

完整代码结构建议:

zu12_driver/
├── __init__.py
├── driver.py          # ZU12Driver主类
├── kinematics.py      # Kinematics实现
├── dynamics.py        # Dynamics实现
├── safety.py          # Safety + CollisionLevel
└── communication/     # 协议抽象层(可选)

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐