
机械臂安全机制开发软限位、硬限位、碰撞急停逻辑机械臂这玩意儿动起来就是个铁拳头安全机制不到位分分钟教你做人——今天聊聊怎么让它听话又不伤人。一、为什么安全是机械臂的第一优先级先泼一盆冷水一个普通的六轴机械臂末端线速度可以轻松超过 1 m/s carrying load 几公斤的金属体以这个速度撞上人或者设备后果不亚于被锤子抡一下。工业场景里机械臂安全事故年年都有轻则夹坏手指重则打断骨头。具身智能机械臂虽然多为桌面级但安全这根弦一样不能松。原因有三人机协作距离近桌面机械臂就放在你手边不像工业机械臂关在围栏里开发期代码 bug 多逆运动学算错一个符号机械臂就能给你跳一段广场舞硬件故障不可控电机驱动器失控、编码器掉线都是随时可能发生的所以安全机制必须分层、冗余、独立任何单点失效都不能导致机械臂失控。这就引出了经典的三层防线架构。二、安全机制三层防线┌─────────────────────────────────────────┐ │ 第一层软件限位 (Software Limit) │ ← 代码层面预防为主 ├─────────────────────────────────────────┤ │ 第二层硬件限位 (Hardware Limit) │ ← 硬件开关兜底保护 ├─────────────────────────────────────────┤ │ 第三层紧急停止 (E-Stop) │ ← 物理切断最后防线 └─────────────────────────────────────────┘三层防线的核心思想越往下越底层、越独立、响应越快。软件限位是尽量别撞硬件限位是撞上了立刻停,急停是出大事了一刀切电源。三、软限位Software Limit软限位是纯代码层面的保护在运动命令下发前进行检查超限就直接拒绝执行。3.1 关节角度软限位每个关节都有机械结构允许的转动范围超过这个范围就会撞机械限位或者卡死。我们在软件里给每个关节设置min_angle和max_angle# 关节软限位配置单位度JOINT_LIMITS[{name:joint_1,min:-170.0,max:170.0},# 底座旋转{name:joint_2,min:-90.0,max:90.0},# 肩部{name:joint_3,min:-120.0,max:120.0},# 肘部{name:joint_4,min:-170.0,max:170.0},# 腕部旋转{name:joint_5,min:-90.0,max:90.0},# 腕部俯仰{name:joint_6,min:-180.0,max:180.0},# 末端旋转]defcheck_joint_limits(joint_angles):检查关节角度是否在软限位范围内fori,angleinenumerate(joint_angles):limitJOINT_LIMITS[i]ifanglelimit[min]oranglelimit[max]:raiseSafetyError(f关节{limit[name]}角度{angle:.2f}° 超出限位 f[{limit[min]},{limit[max]}])returnTrue注意软限位要比机械硬限位往里收 2~5 度给硬件限位开关留出触发余量避免机械臂直接撞到机械止挡。3.2 工作空间软限位关节限位管的是胳膊能不能弯成这样工作空间限位管的是手能不能伸到那儿。某些场景下机械臂虽然关节角没超限但末端会伸到危险区域比如操作台外、设备遮挡区。WORKSPACE_LIMITS{x_min:-0.30,x_max:0.30,# 单位米y_min:-0.30,y_max:0.30,z_min:0.05,z_max:0.45,# z_min 防止扎桌面}defcheck_workspace_limits(cartesian_pos):笛卡尔空间边界检查x,y,zcartesian_posifnot(WORKSPACE_LIMITS[x_min]xWORKSPACE_LIMITS[x_max]):raiseSafetyError(f末端 X{x:.3f}超出工作空间)# y、z 同理...returnTrue3.3 速度限制每个关节都有最大角速度限制命令下发的速度超过阈值要拒绝防止电机过载或者失控狂转JOINT_MAX_VEL[60.0,60.0,60.0,90.0,90.0,120.0]# 度/秒defcheck_velocity_limits(joint_velocities):fori,velinenumerate(joint_velocities):ifabs(vel)JOINT_MAX_VEL[i]:raiseSafetyError(f关节{i1}速度{vel:.1f}°/s 超限)returnTrue3.4 运动命令预检查流水线所有运动命令下发前都要过一遍这道检查关defexecute_motion(target_joints,target_velocities):# 1. 目标位置检查check_joint_limits(target_joints)# 2. 目标速度检查check_velocity_limits(target_velocities)# 3. 正运动学求末端位置end_posforward_kinematics(target_joints)check_workspace_limits(end_pos)# 4. 全部通过才下发send_to_controller(target_joints,target_velocities)四、硬限位Hardware Limit软限位再严密也挡不住代码逻辑出错或者通信数据被篡改。硬件限位是物理层面的独立保护——只要触发立即切断运动不经过任何软件逻辑。4.1 限位开关选型类型原理优点缺点机械式限位开关触点通断便宜、可靠、抗干扰有机械寿命、有触点抖动光电式限位红外遮挡无接触、寿命长怕灰尘、怕强光干扰磁感应限位磁场检测防水防尘精度一般桌面机械臂推荐机械式便宜耐操工业级再考虑光电式。4.2 硬件接线设计限位开关的接线有个原则常闭触点NC串联接入急停回路。这样开关正常时回路闭合触发时限位开关断开回路哪怕线断了也能触发停机fail-safe。24V ────[E-Stop]────[Limit SW J1]────[Limit SW J2]──── ... ──── GPIO_INPUT │ GND限位开关信号接入 STM32 的 GPIO配置为**外部中断EXTI**模式触发沿设为下降沿信号从高变低表示回路断开。4.3 STM32 中断处理// 限位开关中断回调STM32 HALvoidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){if(GPIO_PinLIMIT_SW_J1_PIN){// 立即关闭所有 PWM 输出disable_all_pwm_outputs();// 设置错误标志g_safety_stateSTATE_LIMIT_TRIGGERED;g_error_joint1;// 上报主控send_error_packet(ERR_LIMIT_SWITCH,1);}// 其他关节同理...}注意中断里只做最紧急的动作关 PWM、设状态、发消息。不要在中断里做复杂逻辑判断越短越好。4.4 设备树配置RK3588 侧如果限位开关直接接到 RK3588 的 GPIO 上不经过 STM32需要在设备树里配置节点/ { limit_sw: limit-switch { compatible gpio-limit-sw; j1-gpios gpio0 RK_PA0 GPIO_ACTIVE_LOW; j2-gpios gpio0 RK_PA1 GPIO_ACTIVE_LOW; j3-gpios gpio0 RK_PA2 GPIO_ACTIVE_LOW; interrupt-parent gpio0; interrupts RK_PA0 IRQ_TYPE_EDGE_FALLING, RK_PA1 IRQ_TYPE_EDGE_FALLING, RK_PA2 IRQ_TYPE_EDGE_FALLING; }; };五、碰撞检测与急停5.1 电流检测碰撞机械臂碰到障碍物时电机会因为堵转而电流激增这是最经济的碰撞检测方式——不需要额外传感器只要读取驱动器的电流反馈COLLISION_CURRENT_THRESHOLD2.5# 安培根据电机额定电流调整defcheck_collision_by_current(joint_currents):通过电流异常检测碰撞fori,currinenumerate(joint_currents):# 实际阈值要考虑运动状态静止时阈值低运动时阈值高ifcurrCOLLISION_CURRENT_THRESHOLD:trigger_collision_response(i,curr)returnTruereturnFalse5.2 力传感器检测对协作要求高的场景末端加装六维力传感器直接测量接触力。这种方式灵敏度高但成本也高一颗传感器抵半条机械臂。5.3 碰撞响应流程碰撞检测 → 立即减速停止(50ms内) → 上报错误 → 等待人工恢复 ↓ 记录碰撞数据(电流曲线/位置/时间)碰撞响应必须快从检测到停机要控制在 50ms 以内否则机械臂可能已经把东西推飞了。六、急停按钮电路设计急停按钮是最后也是最关键的一道防线设计上有几条铁律常闭触点按钮按下时断开回路避免触点氧化导致失效硬件切断电机电源不依赖软件直接用急停继电器切断电机供电自锁式按钮按下后必须手动旋转复位防止误恢复串联接入所有急停按钮串联任何一个都能触发AC220V ──┬──[E-Stop 1]──[E-Stop 2]──┬── 急停继电器线圈 ──┬── N │ │ │ └──── 急停继电器常开触点 ────┴──── 控制回路供电 ──┘ 电机主回路 ──── 急停继电器常开触点 ──── 电机驱动器急停继电器触点直接串联在电机驱动器的主供电回路里一旦急停按下继电器线圈断电触点断开电机瞬间失电——这套逻辑完全不依赖任何 MCU是最硬核的保护。七、安全状态机设计把所有安全状态串起来用一个有限状态机管理逻辑清晰又不会漏判┌──────────┐ │ NORMAL │ ← 正常运行 └────┬─────┘ 限位触发 │ 碰撞检测 ┌────────┼────────┐ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ LIMIT │ │COLLISION│ │ ESTOP │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ 人工复位 │ 人工复位 │ 急停复位 ▼ ▼ ▼ ┌─────────────────────────────────┐ │ FAULT_RECOVERY │ ← 故障恢复 └────────────┬────────────────────┘ │ 系统自检通过 ▼ ┌──────────┐ │ NORMAL │ └──────────┘状态机实现要点classSafetyStateMachine:def__init__(self):self.stateNORMALself.error_infoNonedeftrigger(self,event,**kwargs):ifself.stateNORMAL:ifeventlimit_triggered:self.stateLIMITemergency_stop_motion()elifeventcollision_detected:self.stateCOLLISIONemergency_stop_motion()elifeventestop_pressed:self.stateESTOP# 硬件已经切断电源这里只更新状态# ESTOP 状态是最高优先级任何其他状态下急停都强制进入ifeventestop_pressed:self.stateESTOPdefrecover(self):人工确认后才能恢复ifself.statein(LIMIT,COLLISION):ifcheck_system_ok():# 自检self.stateFAULT_RECOVERY# 缓慢回零位move_to_home_slowly()self.stateNORMAL# ESTOP 必须物理复位软件不能恢复八、安全测试清单开发完不测等于没做。下面这份清单是项目上线前必须跑一遍的测试项测试方法预期结果关节软限位生效命令关节运动到超限角度命令被拒绝日志记录工作空间限位生效末端目标超出工作空间命令被拒绝限位开关触发手动拨动机械臂触发限位立即停机上报错误电流碰撞检测按住末端模拟堵转50ms 内停机急停按钮响应急停按下电机瞬间失电软件进入 ESTOP急停后恢复旋转复位急停按钮进入故障恢复流程不自动启动通信断开保护拔掉串口线3 秒内机械臂停止编码器掉线模拟编码器断线立即停机上报错误上电默认状态重新上电进入 IDLE不自动执行任务7x24h 老化连续运行一周无安全事故九、结语机械臂安全这事儿说起来都是常识,但出事的都是没想到。三层防线、状态机、测试清单这三板斧整明白了你的机械臂就算偶尔抽风也不至于酿成大祸。安全代码不嫌多事故面前没有后悔药。