7自由度机械臂漂浮系统质量矩阵偏微分求解遇阻求助
我正尝试对带自由漂浮基座的7自由度机械臂系统的质量矩阵进行位置(含基座单位四元数)偏微分。思路是先在符号化质量矩阵中代入单位四元数约束(即$q_0^2 + q_1^2 + q_2^2 + q_3^2 = 1$),再对除$q_0$外的所有位置求偏导。
使用plant.ToSymbolic()并通过plant.CalcMassMatrixViaInverseDynamics()(调用自示例代码的ManipulatorDynamics函数)提取符号化质量矩阵时,单漂浮刚体(3自由度)、漂浮基座+3自由度机械臂(6自由度)系统均正常运行,但切换为漂浮基座+7自由度机械臂(13自由度)系统时,质量矩阵可计算,但代入单位四元数约束的操作耗时过长甚至无法完成。相关代码片段如下:
q0 = Variable("q0") q1 = Variable("q1") q2 = Variable("q2") q3 = Variable("q3") unit_cons = Expression.sqrt(1 - q1**2 - q2**2 - q3**2) mixed_q = np.array([q0, q1, q2, q3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) v = np.zeros(plant.num_velocities()) (M, Cv, tauG, B, tauExt) = ManipulatorDynamics(plant.ToSymbolic(), mixed_q, v) M[0, 0].Substitute({q0: unit_cons})
我仅需一阶偏导,请问在Drake符号引擎中是否有更优实现方式?或是AutoDiff更适合该场景?
背景:我正尝试实现嵌入单位四元数约束的MultiBodyPlant自定义线性化,需在代入约束后仅保留四元数向量部分的运动方程项偏导数。
AutoDiff是更适合的方案,符号代入在高自由度系统中会因表达式膨胀导致性能急剧下降,而AutoDiff可以直接计算带约束的偏导数,无需显式代入约束表达式,具体思路如下:
避免显式代入四元数约束
四元数的单位约束可通过AutoDiff的链式法则隐式处理:将$q_0$视为$q_1,q_2,q_3$的函数(即$q_0 = \sqrt{1 - q_1^2 - q_2^2 - q_3^2}$),直接对$q_1,q_2,q_3$求导时,AutoDiff会自动计算$q_0$对这三个变量的偏导,无需先做符号代入。使用Drake的AutoDiffXd类型计算偏导
构造带有AutoDiffXd类型的状态变量,将$q_1,q_2,q_3$设为带偏导信息的AutoDiffXd变量,$q_0$通过约束计算得到同类型变量;调用CalcMassMatrixViaInverseDynamics计算质量矩阵后,直接提取元素的偏导值即可得到目标一阶偏导。具体实现示例
from pydrake.autodiffutils import AutoDiffXd # 定义q1,q2,q3为带偏导的AutoDiff变量 q1 = AutoDiffXd(0.0, [1.0, 0.0, 0.0]) # 对q1的偏导为1 q2 = AutoDiffXd(0.0, [0.0, 1.0, 0.0]) # 对q2的偏导为1 q3 = AutoDiffXd(0.0, [0.0, 0.0, 1.0]) # 对q3的偏导为1 q0 = AutoDiffXd.sqrt(1 - q1*q1 - q2*q2 - q3*q3) # 构造完整的q向量(包含基座四元数和关节位置) q = np.array([q0, q1, q2, q3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], dtype=object) v = np.zeros(plant.num_velocities(), dtype=object) # 转换plant为AutoDiffXd类型并计算质量矩阵 plant_autodiff = plant.ToAutoDiffXd() M = plant_autodiff.CalcMassMatrixViaInverseDynamics(q, v) # 提取M[0,0]对q1,q2,q3的偏导 dM00_dq1 = M[0,0].derivatives()[0] dM00_dq2 = M[0,0].derivatives()[1] dM00_dq3 = M[0,0].derivatives()[2]AutoDiff的效率优势
符号运算会生成庞大的表达式树,代入约束后化简的计算量随自由度呈指数增长;而AutoDiff是逐元素计算偏导,计算量与自由度呈线性关系,在13自由度系统中性能优势明显。同时Drake的AutoDiffXd与MultiBodyPlant深度集成,无需额外符号化简步骤,直接利用逆动力学计算过程完成偏导计算。
若仍想使用符号引擎,可尝试延迟代入约束+分步求导:先对符号化质量矩阵求关于$q_0,q_1,q_2,q_3$的偏导,再代入$q_0 = \sqrt{1 - q_1^2 - q_2^2 - q_3^2}$以及$q_0$对$q_1,q_2,q_3$的偏导,利用链式法则组合得到最终偏导,这种方式避免了对庞大质量矩阵元素直接代入约束,能一定程度提升效率,但仍不如AutoDiff高效。
内容的提问来源于stack exchange,提问作者Shubham Vyas

