基于DDPG的机械臂关节锁死容错控制与仿真复现

发布时间:2026/10/3 17:22:14
基于DDPG的机械臂关节锁死容错控制与仿真复现 简介针对机械臂突发单关节故障场景提供一份基于深度强化学习的容错控制研究文献。资源为PDF文档共1个文件大小约1.03MB内容摘自2020年《传感器与微系统》期刊。论文提出以无模型强化学习算法进行离线训练结合Rviz三维建模实现在线控制并通过正常与故障双状态实验验证了方法的自适应性与鲁棒性。文中还对比了传统被动/主动容错控制的局限性涵盖机械臂关节故障、深度神经网络、强化学习等关键技术点适合深度学习、数据分析、故障诊断及自动化控制方向的科研人员与工程师学习参考也可作为相关课题立项或学术写作的引证资料。已有258人学习资源虽小但信息密度高对理解深度强化学习在非线性控制中的落地价值很有帮助。1. 机械臂关节锁死后的容错控制这篇论文告诉你怎样用DDPG跑通一次仿真机械臂关节突然锁死末端还要继续追踪轨迹这是容错控制里最典型也最尴尬的场景。这篇来自《传感器与微系统》2020年第1期的论文把问题压缩到一个很干净的框架里平面3R机械臂单关节锁死用深度强化学习算法中的DDPG做离线训练再把训练好的网络放到Rviz里做在线轨迹跟踪。它的价值在于论文从环境建模、奖惩函数、网络更新到仿真验证四个环节全部给全。对正在做机械臂强化学习课题、或者需要一篇能直接引用的期刊文献的人来说这份PDF能帮你省掉大量查资料的时间。实验数据也很明确奖励在约320个episode后稳定跟踪误差收敛到4mm以内。下面我按复现顺序把每个环节拆开讲。2. 环境建模与奖惩函数先解决“离线训练时谁给反馈”的问题2.1 为什么必须自建环境模型“无模型”不等于“没有模型”先澄清一个最容易混淆的地方。论文说“使用无模型的强化学习算法”这里的“无模型”指的是DDPG不需要环境转移概率不需要动力学微分方程直接靠采样和奖励学习策略。但训练过程里仍然需要一个环境模型来反馈状态和奖励否则算法连误差信号都没有。论文采用的是离线训练、在线控制的方式没法像在线学习那样通过外部传感器实时获取环境信息所以第一步必须先在代码里把机械臂的运动学模型搭出来。论文选择了平面3R机械臂用指数积POE公式而不是DH参数建立正运动学。三个关节的转轴方向都是[0,0,1]^T所以式(1)中单位运动旋量的方向部分很简单位置部分要根据各关节轴在基坐标系中的坐标来填。把当前关节角θ1、θ2、θ3分别代入指数映射连乘后得到末端位姿再对每个关节角求偏导就得到雅可比矩阵J。对平面3R机械臂来说J是3乘3矩阵秩的变化一眼就能看出来。这里有一个选型层面的考量POE公式在容错控制里比DH参数更友好。因为关节锁死表现为对应指数因子的角度被固定正运动学乘积里其余关节的因子保留原样代码上就是一个参数分支的事。如果用DH参数故障后相邻连杆坐标系之间的转换关系要重新推导每次换故障关节都得改一遍模型结构。常见做法是先写一个带fault_joint参数的正运动学函数锁死时把该关节的角速度置零雅可比矩阵自动退化后面算退化可操作度就方便了。提示论文里的雅可比不是做动力学控制用的它的主要用途就是计算可操作度和末端位置误差。整篇实验都建立在运动学模型上没有惯量、摩擦和电机模型这也是训练能快速收敛的原因之一。2.2 退化可操作度怎么算删掉故障列看还剩多少控制余量关节锁死后机械臂的工作空间会收缩末端在某些方向上几乎失去控制能力。论文引用了容错空间的思想把锁死关节对应的雅可比列删掉得到退化雅可比矩阵kJ_i然后定义退化可操作度w_ik等于退化雅可比矩阵行列式的绝对值。这个值越大说明在这个位形下其余关节对末端速度的控制余地越大值越接近零说明机械臂正处在退化奇异位形附近末端在某一个方向上已经不受控。再进一步把各个关节的退化可操作度加权求和得到综合可操作度HΣa_i·w_i。加权系数a_i的作用是调节容错能力在各个关节间的分配。论文没有给出a_i的具体取值我复现时按实验目的来定如果重点验证关节2故障就把a_2调成a_3的两倍让网络在故障状态下倾斜更多训练注意力。H不直接作为控制目标而是和末端距离一起进入奖惩函数网络在学习靠近目标的同时也会避开那些对当前故障状态不利的位形。这里有个容易踩的小坑可操作度是“越大越好”但末端距离是“越小越好”两者直接相加会互相抵消。论文式(6)写的是R(p)λD(p)ηH实际落地时我习惯写成奖励形式rλ*(D_max-D)ηH或者干脆写成r-λDηH。只要保证奖励函数和网络最大化目标方向一致就行否则训练出来的策略是远离目标而不是靠近目标。2.3 λ与η的配合两个系数差了三个数量级是为什么论文里λ取10η取0.01两者相差三个数量级。这个配比背后是主次关系末端到达目标是主任务权重必须大可操作度是辅助约束用来防止机械臂走进病态位形权重只要给一点信号就行。如果η调得过大网络会优先保可操作度末端离目标还有一大截就停下来如果η直接置零训练收敛后机械臂照样到达目标但轨迹经常贴着奇异位形走关节锁死状态下的容错余量没有被充分利用。调整顺序我建议分两步第一步固定η0.01只调λ让末端误差进入10mm以内第二步再逐渐增大η观察跟踪误差和可操作度两条曲线的交换行为。如果误差变大但可操作度明显提升说明机器人用更大的绕行代价换取了更健康的位形这个交换是否值得取决于你的应用场景。参数论文参考值作用调整倾向λ10末端到目标点的距离权重误差大就加大过大会震荡η0.01退化可操作度的权重末端稳定后再缓慢增加a_i未给出各关节容错能力分配按故障概率或实验目的设置3. DDPG训练循环四个网络、一组超参数、一个可以直接抄的骨架3.1 为什么是DDPG而不是DQN或Sarsa论文在引言里点过一个问题现有机械臂强化学习研究大量用DQN、Sarsa这类离散算法但机械臂是以连续动作进行运动的。关节角度是连续变量轨迹跟踪每一步都要输出细粒度的角度增量。DQN把动作空间离散化哪怕每个关节只分100档三自由度组合就是100的三次方训练量指数上升末端轨迹还是一段段锯齿。DDPG是深度确定性策略梯度Actor网络直接输出连续动作向量比如三个关节角的增量Critic网络负责评估这个动作在当前状态下的Q值。这套框架天然适合平面3R机械臂这种动作维度不高但要求连续输出的控制问题。再加上论文要做离线训练、在线控制DDPG的off-policy特性可以从经验回放池里反复采样历史数据正好契合“先用大量探索样本训练再部署到仿真器”的流程。3.2 四个网络的更新关系在线与目标网络怎么配合DDPG里有四个网络。在线策略网络μ和在线Q网络Q负责训练更新目标策略网络μ和目标Q网络Q负责计算TD目标值。每次更新分三步第一步最小化损失L更新Q网络L1/NΣ(y_i-Q(s_i,a_i|θ^Q))²第二步沿策略梯度更新μ网络让Actor往Q值增大的方向调整动作第三步软更新目标网络参数θ^Q←γθ^Q(1-γ)θ^Qθ^μ←γθ^μ(1-γ)θ^μ。这篇论文里γ取0.01意思是每步只把在线网络参数向目标网络挪1%。这是DDPG的标准写法防止目标网络变化太快导致训练发散。这里要特别提醒一句γ在强化学习里通常是折扣因子但在这篇论文里是软更新系数两个概念含义完全不同。复现时别把0.01当成折扣因子去算累积回报否则整个训练目标都歪了。下面这段伪代码是我按论文描述整理出来的超参数全部来自原文可以直接作为自己脚本的骨架# DDPG 训练循环按论文参数整理适配平面 3R 机械臂 global_step 0 C random.randint(1000, 2000) # 故障切换时刻全局步数 state_mode normal # 初始工作状态 for episode in range(1, Ep 1): # Ep 800 s env.reset() # 随机初始关节角 total_r 0.0 for t in range(1, E_S 1): # E_S 200 a actor(s) noise(var) # 策略网络输出 探索噪声 global_step 1 if global_step C: # 到达切换时刻 state_mode random.choice([ normal, joint2_lock, joint3_lock ]) global_step 0 C random.randint(1000, 2000) if state_mode ! normal: # 关节锁死故障 lock_idx 2 if state_mode joint2_lock else 3 # 故障关节角度固定为当前角度雅可比删除对应列 s_, r env.step(a, state_mode) # 按式(6)计算奖励 memory.push((s, a, r, s_, state_mode)) # 记忆区 Re8000 if len(memory) Re: batch memory.sample(N) # N 16 # 1) 最小化式(7)损失更新 Q 网络 q_loss calc_q_loss(batch) update_q(q_loss) # 学习率 LC 1e-4 # 2) 沿式(8)策略梯度更新 μ 网络 p_loss calc_policy_loss(batch) update_actor(p_loss) # 学习率 LA 1e-4 # 3) 软更新目标网络γ 0.01 soft_update(tau0.01) s s_ total_r r逐段说几个关键点。Ep800是训练总周期E_S200是每个周期内的最大步数每一步对应一次机械臂动作。C表示故障切换的全局时刻范围在1000到2000之间所以故障不是每一局都发生而是在训练过程中随机出现。注意C用的是全局步数累计不是单个episode内的步数。论文里E_S只有200步如果计数器放在episode内部重置C永远到不了1000故障就永远不会触发这是复现时的经典错误。记忆区Re8000随机采样N16。Re不能太小否则故障状态的经验还没积累够就被新数据覆盖也不能太大让旧经验和新策略不匹配。N16在DDPG里属于偏小的Batch配1e-4的学习率每一步更新都很温和训练曲线平稳。如果条件允许N可以调到32或64但学习率也要跟着调整否则收敛速度会变得很慢。论文没有给出网络隐藏层结构我复现时用的是两层全连接每层256个神经元加ReLU输出层用tanh把动作压缩到关节角增量范围。动作边界一定要归一化比如每个关节单步增量限制在±0.1rad这比直接输出绝对关节角稳得多。机械臂强化学习实战里动作范围设错是最常见的隐形杀手范围太大机械臂满世界乱飞范围太小末端走不出几个有效位置。3.3 超参数照抄但得知道每个参数在管什么超参数论文取值训练中管什么Ep800训练总周期约320个episode后收敛E_S200每个episode最大步数N16mini-batch采样数影响梯度方向稳定性Re8000经验回放容量决定故障样本保留量LA1e-4Actor网络学习率LC1e-4Critic网络学习率γ0.01目标网络软更新系数不是折扣因子λ10末端距离在奖励中的权重η0.01可操作度在奖励中的权重这套参数的收敛特征论文写得很清楚奖励R在20到100个episode之间快速上升大约320个episode后稳定在100附近轨迹跟踪误差收敛到4mm以内。同时也要留意论文提到的几次尖峰在420、480、600个episode附近奖励会突然下降原因是随机锁死角度导致目标点落在故障后的工作空间之外。这不是算法失效而是物理上不可达复现时千万不要一看到尖峰就去调学习率。4. 在Rviz里在线控制从本地权重到轨迹跟踪的接线过程4.1 先把3R机械臂的Rviz模型立起来Rviz本身不做物理仿真它负责把URDF描述的连杆、关节和TF关系可视化。写三连杆机械臂URDF不算复杂base_link固定在地面link1、link2、link3用revolute关节依次连接每个关节加上原点坐标和旋转轴。平面3R机械臂的三个关节转轴都是竖直方向URDF里任何一根轴的方向写错Rviz里就会看到机械臂扭成一团。建议在URDF里给每个link加一个朝向标记否则这种轴方向问题很难靠肉眼排查。论文没有附带URDF文件需要自己补。我一般会先单独启动robot_state_publisher节点发布TF再用Rviz加载模型配置确认关节顺序和坐标系没有反掉再接控制节点。常见做法是下面这条命令链# 常见做法在 ROS 工作空间中启动机器人状态发布节点 rosrun robot_state_publisher robot_state_publisher # 再打开 RViz加载 3R 机械臂模型配置 rosrun rviz rviz -d rviz/3r_manipulator.rviz这段命令本身很简单但要注意模型配置和URDF路径必须匹配。如果你只是临时验证也可以直接在Rviz里手动添加RobotModel加载URDF文件然后给每个关节发一个静态角度先看模型会不会自相交。这一步通过后再接入训练好的网络。4.2 在线控制节点不叠加噪声固定频率推理在线控制阶段和训练阶段最大的区别是去掉探索噪声。训练时Actor输出后会叠加var才能保证探索部署时直接用μ(s|θ^μ)前向推理输出当前状态下的最优动作增量。下面是ROS节点的核心逻辑只保留骨架import rospy from sensor_msgs.msg import JointState from std_msgs.msg import Float64MultiArray class FaultTolerantController: def __init__(self): self.q None rospy.Subscriber(/joint_states, JointState, self.state_cb) self.pub rospy.Publisher( /joint_position_cmd, Float64MultiArray, queue_size1 ) self.actor load_actor_weights() # 加载训练好的策略网络 def state_cb(self, msg): # 回调里只更新最新关节状态不做网络推理 self.q list(msg.position) def control_loop(self, rate50): rate_obj rospy.Rate(rate) # 固定控制频率 50 Hz while not rospy.is_shutdown(): if self.q is None: continue target get_target_point() # 从轨迹生成器获取目标点 action self.actor.predict(self.q, target) self.pub.publish(Float64MultiArray(dataaction)) rate_obj.sleep()这段代码有两个易错点。第一不要在joint_states回调里直接做网络推理因为ROS回调触发频率不稳定网络推理时间也会波动两者叠加会让动作输出产生抖动机械臂在Rviz里表现为高频颤振。合理写法是在回调里只更新状态主循环固定50Hz做推理。第二在线控制的状态向量必须和训练时完全一致。如果训练时s由三个关节角、故障标志、目标点坐标组成那么部署时也要拼出同样维度的输入不能只喂关节角。4.3 轨迹跟踪实验怎么记录才算真正复现论文在线实验分别验证了正常、关节2锁死、关节3锁死三种工况。复现时做一个简单的轨迹生成器让目标点沿直线或圆弧运动末端实时跟踪。记录两组数据每一时刻的末端位置误差以及每个测试周期的综合可操作度H。判断复现成功与否不要只看某一段曲线好看。至少要连续跑三次每次随机故障发生时间和锁死关节统计稳态跟踪误差的均值和峰值。如果正常工况误差能稳定在4mm附近故障工况在目标可达范围内也保持同量级说明训练是有效的。如果正常工况很好、故障工况直接偏掉问题大概率出在故障样本的覆盖上而不是网络更新公式错了。这一步的排查正好引出下一章的避坑指南。5. 复现容错控制实验的避坑指南五个值得记下来的坑5.1 奖励曲线先升后降然后彻底发散现象前100个episode奖励稳定上升之后突然掉下去再也涨不回来。原因经验回放里故障样本占比过高Q网络开始过估计。故障工况的目标值里包含可操作度H项H的数值量级远小于距离项DQ网络容易把注意力全放在距离上忽略了对容错位形的约束。解决把正常样本和故障样本分开存储每次采样按比例混合比如7比3。或者给故障状态的奖励乘一个缩放系数控制在0.1到0.2之间。论文没有处理这个问题但多随机轨迹训练时属于概率性出现的坑。5.2 关节锁死角度被错误地设成零现象机械臂在故障瞬间位置跳动一个很大的角度训练过程全程震荡。原因代码里设故障关节角度时直接写0而正确做法是把故障关节角度固定为当前角度。论文写了“固定故障关节的角度为当前角度θ”但很多复现者只看到“固定”没看到“当前角度”四个字。解决检查env.step函数里故障分支的赋值必须是当前关节角度不能是初始值或零。故障关节锁定角度不同工作空间完全不同网络需要感知这个数值才能做出正确的容错规划。5.3 把软更新系数当成折扣因子现象复现时累积回报计算错误训练目标完全混乱。原因论文把目标网络软更新系数写成γ和强化学习里常用的折扣因子符号撞车。折扣因子通常接近1比如0.9或0.99而这篇论文的γ0.01含义和数值完全不同。解决在实现里拆成两个变量折扣因子用gamma_discount0.99软更新系数用tau0.01。对应到代码就是target_network的更新参数和奖励衰减的计算参数严格分开。5.4 故障切换计数器放错了位置现象训练明显不碰故障工况网络只掌握正常控制容错效果没训练出来。原因把故障切换的随机时刻C和E_S混淆了。论文中C的范围是1000到2000而每个episode只有200步如果计数器在episode内重置C永远到不了1000故障永远不会触发。解决把C理解为全局训练步数计数器跨episode累积不要写在单局的t循环里重置。伪代码里global_step的位置就是对的。这个问题很隐蔽我见过不止一个复现项目在这里翻车。5.5 Rviz里的机械臂高频抖动轨迹像锯齿一样不连续现象机械臂每一步都在抖轨迹看起来非常破碎。原因控制频率太低或动作增量范围太大。网络在一个状态上推理出较大角度增量机械臂瞬间跳到新位置下一帧又被拉回来。解决把控制频率固定到50Hz动作增量做限幅比如每个关节单步限制在0.05rad超过就截断。这个限制要和训练时的动作边界一致训练用±0.1rad部署时就不要突然改成±0.5rad。这5条是我实际跑这类实验时踩过的坑。如果你在不同仿真平台上做机械臂容错控制遇到“mujoco加载机械臂乱动”或者“Gazebo里刚体碰撞参数没设置导致臂体翻转”这类问题大概率也能归到控制频率或关节限幅这一层先查这两项再动网络结构。6. 把可操作度当成第二个精度指标消融实验与扩展方向6.1 做一组消融实验去掉H项看差异复现这篇论文最值得做的不是复现它的成功而是复现它的对照组。把η设为0重新训练800个episode奖励函数里只保留距离项。正常工况的跟踪误差可能还在4mm附近但关节锁死工况下末端经过某些位形时会明显变慢甚至卡住原因是那些位形对应的退化可操作度接近零网络根本没有感知到危险。有这组对照结果“引入可操作度约束”这个结论才真正立得住。写课题报告时这样说比直接说“强化学习能容错”要更有说服力不是深度强化学习本身神奇而是奖励函数设计里加入了机械臂自身的运动学性能约束网络才学会了绕开退化奇异位形。6.2 同时记录误差、奖励、可操作度三条曲线只盯着4mm误差会漏掉关键信息。建议每个训练周期末尾记录三个值末端跟踪误差、累积奖励R、综合可操作度H。我用数据分析的习惯把这些都写成CSV画三条曲线放在一起看。如果误差下降但H同步下降说明网络正在利用奇异位形走捷径。纯运动学仿真里这种行为看不出问题一旦换到带物理引擎的环境就会翻车因为真实关节速度有限制。我刚接触这套方法时也吃过这个亏。训练出的网络在Rviz里能准确吸到目标点换到Gazebo后轨迹后半段剧烈震荡最后排查出来就是H值过低。从那以后我跑机械臂强化学习课题都强制把可操作度曲线放在误差曲线旁边先确认H维持在合理区间再讨论精度。这个习惯比任何调参技巧都管用。6.3 两个可执行的扩展方向一个方向是把单关节锁死扩展到多关节锁死。H的计算要从单个退化雅可比转为多个退化雅可比取最小值或加权和故障状态组合在训练时随机生成代码改动不大但训练难度会明显上升建议先用关节数较少的机械臂验证。另一个方向是把Rviz仿真换成Gazebo或CoppeliaSim加入重力、摩擦和关节速度限制后原先4mm的误差可能变成12mm以上。这不一定是网络的问题而是环境模型从纯运动学变成了带物理参数的动态模型需要重新收集训练样本。动作边界和故障切换随机性这两个参数换平台后一定要重新标定。如果你正在做机械臂容错控制或深度强化学习课题这份PDF建议下载下来把文中的超参数和公式当作起点。下载前只需要确认一点你要的是一个能照着搭的实验框架还是一篇可以直接引用的期刊参考文献。前者照着第3章的代码骨架走后者把原文的地址和DOI存好就行。希望帮到你。本文还有配套的精品资源点击获取