人体动作重定向原理与实现:GMR、PyRoKi 与 OmniRetarget
把人体动作搬到机器人上,困难不在于读取一段关节角,而在于人体与机器人不是同一套运动学系统。肩宽、腿长、关节轴、自由度和物体尺寸变化后,“姿态看起来像”与“脚不滑、手仍贴着箱子”可能互相冲突。
理解 GMR、PyRoKi 和 OmniRetarget,先要问四件事:优化变量是什么,误差怎样定义,哪些条件必须满足,时间上联合优化多长。 求解器名字只回答其中一部分。
下面先从 FK 和误差定义推导局部求解,再分别看单帧速度级 IK、多帧轨迹优化和交互网格约束。QP、Gauss–Newton、LM 与 SQP 对应不同的局部模型;Rest Pose 是姿态先验,CasADi 是建模与自动微分工具,不能把这些名称当成同一层级的算法排列。
1. 人体关节角不是机器人的监督真值
设机器人浮动基座位姿为 ,关节角为 ,第 个连杆的世界位姿为:
重定向先从人体动作构造目标 ,再求机器人自己的 。直接设置 一般没有意义:两个模型的同名关节未必有相同转轴、零位和旋转分解顺序。
尺度适配也不是随便乘一个身高比。将人体手、脚位置相对根节点缩放后,要重新检查脚底与地面的关系、手与物体表面的关系。人体和物体如果分别缩放、再分别“落地”,接触点可能已经错位,优化器只是忠实拟合了错误目标。
对于交互任务,建议先在物体坐标系定义手部目标:
这样箱子整体平移时,“手在箱子哪一侧”仍保持稳定。改变箱子尺寸则需要显式重新映射接触位置,不能假定这个相对坐标自动适用。
2. IK 如何变成一个残差问题
位置残差可定义为:
旋转误差应在局部切空间定义,例如:
这里的符号、左右乘约定和 Jacobian 必须一致。四元数 与 表示同一旋转,不能直接把四元数四维差值作为全局姿态距离。
将位置、旋转、姿态先验、平滑等残差堆叠:
常见归一化方式是 、。例如 m,2 cm 位置误差对应无量纲残差 1; rad,约 误差也对应残差 1。这样讨论权重才不会混淆米与弧度。
PyRoKi 也不需要“同时求 FK 和 IK”两个未知问题。FK 是给定关节状态后的可微计算图;IK 优化器通过 FK 计算 residual,再改变状态。
3. Jacobian 在哪里计算,线性化到底近似了什么
在当前迭代点 ,有:
其中, 表示在位姿流形上的增量更新。浮动基座旋转增量通常是三维角速度或旋转向量,不能把四元数分量直接加上任意四维更新。
Jacobian 为“当前状态下,状态小变化会让 residual 改变多少”。它不是整段动作只算一次的常量。一个 2 m 长度尺度的简化机构,若一阶导数约为 2 m/rad,目标相差 2 cm,则局部角度修正约 0.01 rad;远离当前点后,同一线性比例通常不再成立。
手—物体、足底接触
残差与 Jacobian
接触、碰撞、步长
检查真实残差
图 1:三类方法都要定义目标、求局部模型、更新状态;区别在目标结构、变量范围和约束。
有限差分可以验证解析或自动微分 Jacobian:
应扫描多个 ,例如 ,看误差是否先下降再受舍入影响。碰撞距离在最近点切换处可能不可微,不能在这些位置机械要求光滑函数的误差规律。
4. GMR/Mink:在当前姿态附近求速度级 IK
Mink 的任务一般要求误差按指定速率衰减。使用 的简化记号,可写成:
关节位置和速度限制可以线性化进约束:
实现也可以以 为变量;两种形式的系数要同步变换。不能一边用速度 Jacobian,一边把位置增量直接当速度约束。
展开平方得到二次目标:
这就是 QP 出现的原因,不是因为整个机器人运动学本来就是线性的。Mink 文档 与 GMR 源码 可对应检查任务构造与积分过程。
约束怎样进入求解,而不是事后裁剪
对上面的二次目标,最优点满足 KKT 条件:
其中, 是不等式约束的乘子。未碰到限位时,相应乘子为零;限位激活后,求解器联合调整各自由度,让目标误差与有效约束同时满足这些条件。先求无约束解、再逐关节裁剪,一般不满足带约束问题的驻点条件,其他末端的误差也会随之改变。
碰撞距离也可在当前姿态线性化。设有符号间距为 d,正数表示分离,要求保留安全间距:
例如当前间距 4 mm、安全间距 10 mm,则线性模型要求这次更新至少增加 6 mm。它是局部几何条件,不包含动量、摩擦和接触力;更新幅度过大或最近碰撞点切换时,必须重新计算真实距离。这个区别也是后文 OmniRetarget 同时设置非穿透约束和步长界的原因。
GMR 支持两组匹配任务,分别调用 mink.solve_ik 并继续迭代。两阶段执行不自动等于严格的词典序层级优化:如果第二阶段没有显式锁定第一阶段的最优任务,第一阶段误差仍可能被重新改变。
硬约束也有前提
如果关节已在 1.49 rad、上限 1.50 rad, s,那么局部位置约束要求 rad/s;目标再远也不能越过这个界。
但局部不穿透约束是在当前姿态的近似,单步太大时真实非线性几何仍可能穿透。因此需要步长控制、更新后距离检查,而不是仅看到优化器返回 optimal 就认为整段轨迹物理可执行。
GMR 的匹配参数:当前任务只启用一级
重定向没有策略回报,下面列的是优化代价。本文的 SMPL-X 重定向案例将身体/下肢比例设为 0.9、上肢为 0.75,并固定头 yaw/pitch 为 0;这些是目标生成参数,不是奖励系数。以下 cost 来自该任务的实际匹配表,绝不是 GMR 对所有机器人的统一常数。
点击名称可跳到对应的公式与实现说明,并自动展开。
| 名称 | API cost | 状态 | 作用 |
|---|---|---|---|
GMR / base |
position 100;orientation 500 | 启用 | 确定躯干基准 |
GMR / torso |
position 80;orientation 200 | 启用 | 约束胸腰姿态 |
GMR / hip |
position 8;orientation 30 | 启用 | 腿部链起点 |
GMR / knee |
position 5;orientation 20 | 启用 | 腿部弯曲 |
GMR / ankle |
position 4;orientation 10 | 启用 | 足部落点与朝向 |
GMR / shoulder |
position 6;orientation 10 | 启用 | 上臂方向 |
GMR / elbow |
position 4;orientation 10 | 启用 | 肘部构型 |
GMR / hand |
position 3;orientation 10 | 启用 | 末端交互位置 |
逐项实现
GMR / base
首级匹配将人体骨盆映射到机器人浮动基座。100 与 500 分别传给 Mink FrameTask 的位置/朝向 cost,不能当成一项 RL 奖励相加。FrameTask 在构造加权误差与 Jacobian 后形成二次目标,因此必须连同所用 Mink 版本的 cost 语义解释。这里保留 API 原始参数,不把它们与下面的目标系数直接比较。
1 | task = mink.FrameTask(frame_name="base_link", frame_type="body", |
GMR / torso
对应首级匹配表中的 waist_pitch_link,双侧项使用相同 cost,但位置/旋转 offset 逐侧标定。这里的 cost 只能在相同误差单位与任务定义下比较;手的位置参数较小,不代表最终手部误差必然更大,因为 Jacobian、其他任务与可达性同时参与求解。配置 use_ik_match_table1=true、use_ik_match_table2=false,第二级为空,不能描述成该任务实际执行了两级 IK。
1 | position_cost = 80.0 |
GMR / hip
对应首级匹配表中的 hip_yaw_link,双侧项使用相同 cost,但位置/旋转 offset 逐侧标定。这里的 cost 只能在相同误差单位与任务定义下比较;手的位置参数较小,不代表最终手部误差必然更大,因为 Jacobian、其他任务与可达性同时参与求解。配置 use_ik_match_table1=true、use_ik_match_table2=false,第二级为空,不能描述成该任务实际执行了两级 IK。
1 | position_cost = 8.0 |
GMR / knee
对应首级匹配表中的 knee_link,双侧项使用相同 cost,但位置/旋转 offset 逐侧标定。这里的 cost 只能在相同误差单位与任务定义下比较;手的位置参数较小,不代表最终手部误差必然更大,因为 Jacobian、其他任务与可达性同时参与求解。配置 use_ik_match_table1=true、use_ik_match_table2=false,第二级为空,不能描述成该任务实际执行了两级 IK。
1 | position_cost = 5.0 |
GMR / ankle
对应首级匹配表中的 ankle_roll_link,双侧项使用相同 cost,但位置/旋转 offset 逐侧标定。这里的 cost 只能在相同误差单位与任务定义下比较;手的位置参数较小,不代表最终手部误差必然更大,因为 Jacobian、其他任务与可达性同时参与求解。配置 use_ik_match_table1=true、use_ik_match_table2=false,第二级为空,不能描述成该任务实际执行了两级 IK。
1 | position_cost = 4.0 |
GMR / shoulder
对应首级匹配表中的 shoulder_roll_link,双侧项使用相同 cost,但位置/旋转 offset 逐侧标定。这里的 cost 只能在相同误差单位与任务定义下比较;手的位置参数较小,不代表最终手部误差必然更大,因为 Jacobian、其他任务与可达性同时参与求解。配置 use_ik_match_table1=true、use_ik_match_table2=false,第二级为空,不能描述成该任务实际执行了两级 IK。
1 | position_cost = 6.0 |
GMR / elbow
对应首级匹配表中的 elbow_link,双侧项使用相同 cost,但位置/旋转 offset 逐侧标定。这里的 cost 只能在相同误差单位与任务定义下比较;手的位置参数较小,不代表最终手部误差必然更大,因为 Jacobian、其他任务与可达性同时参与求解。配置 use_ik_match_table1=true、use_ik_match_table2=false,第二级为空,不能描述成该任务实际执行了两级 IK。
1 | position_cost = 4.0 |
GMR / hand
对应首级匹配表中的 hand_manip,双侧项使用相同 cost,但位置/旋转 offset 逐侧标定。这里的 cost 只能在相同误差单位与任务定义下比较;手的位置参数较小,不代表最终手部误差必然更大,因为 Jacobian、其他任务与可达性同时参与求解。配置 use_ik_match_table1=true、use_ik_match_table2=false,第二级为空,不能描述成该任务实际执行了两级 IK。
1 | position_cost = 3.0 |
5. 非线性最小二乘:从梯度到 Gauss–Newton
对 求导:
Gauss–Newton 忽略第二项,求:
当 residual 很小或自身近似线性时,这个近似通常更合适。它不是“对 objective 只用一阶信息”:线性化 residual 后平方,已经得到一个二次子问题。
实现时应求解线性系统,避免显式计算 inverse(J.T @ J)。正规方程会平方条件数;根据规模和稀疏性可以选择 QR、Cholesky、迭代求解等。公式中的逆矩阵描述的是映射关系,不要求代码显式构造逆矩阵。
LM 为什么会更稳
Levenberg–Marquardt 解:
其中 可以是单位阵或与尺度有关的对角阵。 小时接近 GN,大时接近经过缩放的梯度步。阻尼随局部模型预测与真实下降的吻合程度调整,不能只理解成“永远加一个很大的稳定常数”。
标量例子:,从 出发,GN 给出 ,直接走到 5.05,远离目标;取 ,LM 步长约 0.1904,更新到 0.2904,残差有所下降。它展示的是阻尼的作用,不证明任意问题上某个固定 都最好。
6. PyRoKi:当变量跨越多个时刻
一类轨迹重定向目标为:
单帧残差只连接该帧状态,速度项连接两帧,加速度项连接三帧,因此整体 Jacobian 很大,却有可利用的稀疏结构。它不是简单把 GMR 的 QP 换成 LM,收益也不能全部归功于求解器。
PyRoKi 是机器人优化工具;整段优化来自使用它的具体建模方式。某个 PyRoKi 应用可以逐帧工作,GMR 外部也可以增加离线平滑。讨论时必须限定实现。
本文的整段轨迹优化将关节速度上限写成以下残差:
1 | velocity = (q_now - q_prev) / dt |
这是软惩罚,不能说它“保证不超速”。并且 residual 乘 weight 后再平方,目标中的实际权重是 weight**2。如果想让目标系数为 ,应该乘 。
一个 0.1 rad 的相邻帧差,在 50 Hz 下是 5 rad/s,在 100 Hz 下是 10 rad/s。丢失 FPS 元数据后,再漂亮的速度限制参数也不对应原始运动。
重采样还会改变平滑项的尺度。相邻角度差与关节速度不是同一个量,二阶差分也不直接等于加速度:
对同一段连续动作加密采样,相邻角度差通常减小,而物理速度并没有因此减小。若希望比较相同物理时长内的速度/加速度代价,可按时间积分构造目标:
这是对量纲一致目标的说明,不表示下表每个实现都采用了这个归一化。实际代码可能直接惩罚帧间差;此时修改 FPS 后,必须检查分母、求和方式与权重,不能只保留原来的配置数字。
脚接触项则约束接触期间的脚部运动和几何关系。是否启用自碰撞还要看运行配置:本文的轨迹优化案例将 self-collision 设为 0,不能仅因为框架提供碰撞模块,就宣称该次输出经过自碰撞优化。
基于 PyRoKi 的整段轨迹优化:代价与权重
下面列出整段关键点重定向使用的最小二乘代价。除特别说明外,“残差 ×w”意味着目标内相应系数为 w²(忽略所有项共享的 1/2 约定);权重没有可跨任务比较的统一单位。
| 名称 | 配置与目标系数 | 状态 | 作用 |
|---|---|---|---|
local_alignment |
残差 ×1;目标系数 1 | 启用 | 匹配关键点之间的局部结构 |
global_alignment |
残差 ×3;基础目标系数 9 | 启用 | 约束世界位置 |
root_smoothness |
残差 ×1;目标系数 1 | 启用 | 平滑根节点 SE(3) 变化 |
joint_smoothness |
残差 ×4;目标系数 16 | 启用 | 减少相邻关节跳变 |
joint_vel_limit |
残差 ×50;目标系数 2500 | 启用,20 rad/s | 惩罚超速 |
joint_limit |
残差 ×100;目标系数 10000 | 启用 | 限制位置越界 |
foot_contact |
残差 ×30;基础目标系数 900 | 接触标签门控 | 抑制支撑脚滑移 |
foot_tilt |
残差 ×1;目标系数 1 | 接触标签门控 | 压低支撑时的脚倾斜 |
scale_regularization |
残差 ×1 / ×100 / ×100 | 启用 | 约束尺度接近 1、对称且非负 |
joint_rest_penalty |
字典值 1;实际贡献 0 | 未加入 costs | 候选姿态先验 |
self_collision |
字典值 0;实际贡献 0 | 未生效 | 候选自碰撞抑制 |
逐项实现
local_alignment
retargeting_cost 约束关键点之间的局部相对关系,并优化身体尺度变量。这样可减少直接照搬人体绝对尺寸引起的不可达;它仍需要全局对齐项确定位置。要把 pair mask 与参与点集一起记录,不能只报告一个标量 1。
1 | r_local = local_geometry_error * 1.0 |
global_alignment
pc_alignment_cost 对正运动学点与目标点的位置差乘 3;肘和髋等选定点在相减前除以 4,因此这些点相应的目标系数为 9/16=0.5625。还有躯干辅助点,不能只数输入人体关节。
1 | r_global = 3.0 * (robot_points_scaled - target_points_scaled).reshape(-1) |
root_smoothness
相邻根位姿通过 log(T_now.inverse() @ T_prev) 得到六维残差。平移和旋转混在一个向量中时,权重没有自动解决 m 与 rad 的量纲差异。此处没有除 dt,换采样率后代价含义会变化。
1 | r_root = (T_now.inverse() @ T_prev).log().flatten() * 1.0 |
joint_smoothness
调用 PyRoKi smoothness_cost。该项控制相邻帧差异,不等于带物理单位的加速度限制;不能把平滑后的动作直接视为动力学可行。
1 | r_smooth = 4.0 * (q_now - q_prev) |
joint_vel_limit
joint_vel_limit_cost 先用真实时间差计算速度,再惩罚超过 20 rad/s 的部分。时间差为 subsample_factor / input_fps;它是软约束,残差再大也不保证求解结果严格满足上限。
1 | dt = subsample_factor / input_fps |
joint_limit
虽然没有出现在 weights 字典里,pk.costs.limit_cost(..., 100.0) 实际加入了 costs 列表。检查任务时必须同时查看权重字典和求解器接收的列表。这里依然是最小二乘软代价。
1 | costs.append(pk.costs.limit_cost(robot_batch, joint_variables, 100.0)) |
foot_contact
foot_contact_cost 同时包含脚踝/脚尖相邻帧位移和两点高度差。变量名叫 velocity,但实现用的是位置差,没有除 dt。接触置信度 c 也乘进残差,平方后贡献为 900*c²,不能按线性 c 理解。
1 | r_foot = 30.0 * contact * np.concatenate([ |
foot_tilt
foot_tilt_cost 用旋转矩阵 R[2,2] 与 1 的差。若倾角为 θ,残差是 cosθ−1,小角度时平方代价近似 θ⁴/4,比直接角度平方在零点附近平坦很多。该实现并没有直接奖励脚 yaw。
1 | r_tilt = contact * (R_foot[2, 2] - 1.0) |
scale_regularization
该函数返回三组残差:尺度偏离 1、尺度矩阵不对称、负尺度。相应基础目标系数是 1、10000、10000。它是形体变量的先验,不是关节 rest pose。
1 | r_scale = np.concatenate([(S - 1).ravel(), |
joint_rest_penalty
pk.costs.rest_cost 整个调用被注释掉。即使 joint_rest_penalty=1 存在,求解器也收不到该 residual。不能将其写为“已用 Rest Pose 解决冗余”。
1 | rest_cost_is_appended = False |
self_collision
当前默认值为 0,实际 costs 列表也没有自碰撞项。重定向输出的自碰撞质量必须另做几何检查;动画看起来流畅不是碰撞验证。
1 | self_collision_weight = 0.0 |
7. OmniRetarget:保留的是交互关系
只匹配手的世界位置,可能把手放到箱子内部;只匹配人体姿态,可能让脚悬空。OmniRetarget 把人体/机器人与场景采样点的关系写进 interaction mesh,用局部相对结构描述交互,再配合关节和几何约束。OmniRetarget 论文

论文原图:OmniRetarget 作者,Figure 1;未修改。来源:论文/原图。图中“5 Rewards”描述论文方案,不等于本文适配后的搬箱奖励数量。
图中蓝色区域对应 InteractionMeshRetargeter 的几何求解,绿色区域表示改变物体/地形后重新求解参考,紫色区域才是物理控制器训练。数据增强不能只把物体缩放后沿用原手部轨迹,否则交互关系已经被破坏。

论文交互网格原图,来源:OmniRetarget/原图,未修改。
图中的连边说明优化器同时看到身体与环境的局部关系。在代码中,正运动学产生顶点 V,拉普拉斯矩阵 L 将其变成局部坐标,J_L = (L ⊗ I₃) J_V 把关节增量映射到这些坐标的变化。只对每只手独立做位置 IK,不具有这套共享几何残差。
设顶点矩阵 包含身体关键点与物体/场景点,拉普拉斯坐标为:
将所有点一起平移 ,有 。因此这种表征天然削弱了整体平移的影响,更突出手、脚与邻近环境的相对关系。它不是自动拥有旋转、尺度和所有接触物理不变性;使用哪个坐标系、如何缩放,仍影响目标。
局部优化可概括为:
同时加入关节限位、足部锁定、非穿透等约束。
代码里的子问题不应一概叫普通 QP
Holosoma 的交互重定向将局部子问题写为:
1 | # 教学化表达;省略尺寸和辅助变量 |
cp.SOC(step_size, dq) 表示 ,属于二阶锥约束。因此该子问题是带二次目标的凸锥优化,可以转写为 SOCP;不能严格等同于只有线性约束的标准 QP。
另一处值得注意的是:某些初始化失败分支会移除 SOC 步长限制再尝试求解。这个回退提高找到初始姿态的机会,却弱化了该次局部线性化的步长保护。应检查真实距离和约束残差,而不是把回退后成功当成与原约束等价。
基于 Omni 的普通交互与柔顺交互
普通交互与柔顺交互使用同一类交互重定向基础。柔顺交互额外改变的是执行/训练时的参考及交互处理。重定向让手在几何上贴合箱子,柔顺让真实接触出现偏差时可以退让;这两层不能互相替代。
因此比较 GMR、PyRoKi、OmniRetarget 时,讨论的是数据生成与优化建模;比较普通物体交互与柔顺交互时,讨论的是接触中的闭环行为。不能把后者的接触力下降直接归功于某种离线重定向求解器。
OmniRetarget:基础代价与物体交互约束
以下以箱体交互适配为例,列出优化目标的系数与生效条件。关节限位、非穿透、足部锁定和 SOC 步长界属于约束,不应虚构成一个有限的“奖励权重”。
| 名称 | 目标系数 | 生效条件 | 作用 |
|---|---|---|---|
interaction_mesh |
目标系数 23 | 启用 | 保持身体—物体—地形关系 |
temporal_smoothness |
目标系数 1 | 启用 | 靠近上一帧姿态 |
root_z_floor |
配置系数 400;未启用 | floor=None,关闭 | 限制过深下蹲 |
com_support |
目标系数 300 | 满足支撑点条件才启用 | 限制静态支撑范围外的 CoM |
foot_flat |
目标系数 100 | 支撑脚及角点存在时 | 让鞋底角点靠近地面 |
foot_level |
目标系数 30 | 足部姿态节点存在时 | 约束足底水平 |
base_facing |
0 | 关闭 | 候选根节点朝向约束 |
nominal_tracking / Q_diag |
逐任务/逐关节;非统一常数 | 按输入选择 | 冗余姿态先验 |
逐项实现
interaction_mesh
laplacian_weights=23,实现先取 sqrt 后乘拉普拉斯误差再平方,因此目标系数是 23,不是 529。身体点与环境点共享局部几何,优化的不是独立末端的绝对位置。
1 | r = np.sqrt(23.0) * (laplacian - target_laplacian) |
temporal_smoothness
当前迭代增量 dq 与“上一帧姿态减当前线性化点”比较,等价于拉近新姿态和上一帧姿态。它不是一味把每次迭代增量压到零。
1 | dq_smooth = q_previous_frame - q_linearization |
root_z_floor
基础实现的默认系数为 40,搬箱适配将候选系数设为 400,但没有设置根高度下界,因此该项未加入优化。若启用,应同时验证手还能接触地上的箱子。
1 | if floor is not None: |
com_support
搬箱适配将系数从默认的 200 调为 300,支撑范围内缩 0.03 m。实际实现取高度低于 0.05 m 的足部支撑点,至少两个时构造 XY 轴对齐包围盒并收缩,而不是精确足底凸包;mj_jacSubtreeCom(...,0) 线性化模型 world subtree 的 CoM。模型若含物体,其质量也参与。它只是静态几何代理,不能证明动态平衡。
1 | com_new = com_xy + J_com @ dq |
foot_flat
该项在基础实现中默认关闭,搬箱适配使用系数 100。对被判为支撑脚的足部,把各足底角点的新高度线性化并平方。不要把这个软项描述为绝对不穿地:防穿透来自另一个约束。
1 | z_new = corner_z + J_z @ dq |
foot_level
该项在基础实现中默认关闭,搬箱适配使用系数 30,作用于所有帧,包括摆动脚。对足底法向量 n 的水平分量做一阶线性化再平方。它会削弱自然滚脚,是可达性与姿态稳定之间的取舍。
1 | n_new_xy = n[:2] + J_normal_xy @ dq |
base_facing
搬箱任务将该系数设为 0,因此没有显式锁定基座朝向。物体交互可以间接约束朝向,但不等于显式朝向目标存在。
1 | base_facing_weight = 0.0 |
nominal_tracking / Q_diag
w_nominal_tracking 作用于指定索引上的名义姿态偏差,Q_diag 则惩罚新姿态本身。后者以零为中心,不自动以默认站姿为中心。它们来自运行配置/调用参数,不能借用 23 当作所有项的权重;未固定任务参数时没有唯一可报告标量。
1 | nominal_cost = w_nominal * cp.sum_squares(q_new[idx] - q_nominal[idx]) |
原方法与机器人适配的边界
GMR 的核心是 FrameTask 与速度级 IK;该机器人适配增加了身体比例、末端 offset、固定头关节及任务匹配表。PyRoKi 提供自动微分/最小二乘基础设施;整段时间变量、脚接触 residual、尺度先验和速度上限来自本文的轨迹优化建模。OmniRetarget 的 interaction mesh 是论文主线;这里的 CoM 支撑盒、根高度、足底角点与水平项是搬箱任务中的工程扩展,不应全部归为原论文方法。
这些改动共同解决的是“先让几何参考更适合机器人”。它们还没有实时外力状态;柔顺交互在执行阶段增加的导纳参考、夹持状态机和力奖励,见柔顺控制篇。对比实验应分别关闭某个离线代价或在线机制,避免一次更换整个系统后把收益归到单一算法。
8. SQP、Rest Pose 与 CasADi 应放在什么位置
对一般非线性约束问题:
SQP 在当前点构造近似:
其中, 通常近似拉格朗日函数 Hessian,而不只是 objective Hessian。SQP 的本质不是“支持 sparse 的 QP”;稀疏性是可利用的结构,序列线性化约束与二次建模才是方法核心。
Rest Pose 可以写为:
它解决冗余自由度缺乏偏好的问题,不应大到压过必要的手—物接触。若姿态先验很强,系统可能宁愿把手离开物体也要回到“漂亮”站姿。
CasADi 是表达、自动微分与构建优化问题的工具链;Mink 偏向速度级 IK;PyRoKi 面向可微机器人优化。把它们简单排列成“低级→高级求解器”会混淆软件层级。
GN 中的 同样出现在 SLAM、bundle adjustment、ICP:都是 residual 线性化后的二次近似。机器人重定向的特殊处在于状态流形、接触、关节范围和后续动态可执行性,而不在于这个矩阵公式本身。
9. 怎样做有意义的三方比较
将上述三种建模方式并列比较:
| 维度 | GMR/Mink | PyRoKi 轨迹适配 | OmniRetarget 交互适配 |
|---|---|---|---|
| 主要变量 | 当前姿态附近的速度或增量 | 多帧基座位姿与关节状态 | 当前姿态增量及交互目标 |
| 时间耦合 | 当前帧求解与上一帧初始化 | 相邻帧速度、平滑等残差直接耦合 | 逐步求解中的姿态与平滑项;需核对具体配置 |
| 局部问题 | 任务平方误差形成 QP | 非线性最小二乘的局部近似 | 二次目标与几何约束,所查实现含 SOC |
| 限制如何进入 | 关节/速度等显式不等式 | 所查速度限制为软 residual | 限位、非穿透、足部条件与步长界 |
| 交互如何表达 | 需要自行构造任务与环境约束 | 取决于添加的接触和碰撞 residual | interaction mesh 显式保留身体—环境关系 |
这张表描述具体建模取向,不表示工具只能支持表中的一种方法。做输出质量比较时,固定同一机器人、同一动作与物体尺度、相同 FPS 和评价身体集合,再报告:
- 几何精度:关键点误差、旋转误差,注明是否做根节点/朝向对齐。
- 接触质量:接触阶段足滑距离、手—物体相对位置误差、最大穿透深度。
- 时间质量:关节速度/加速度分位数、超限比例,而非只看播放是否顺滑。
- 计算代价:每帧耗时、整段耗时、硬件与轨迹长度;离线方法不能和实时系统只比总时间。
- 动态执行:将结果交给同一控制器,看整段完成率与饱和情况。几何优化不自动满足刚体动力学和摩擦锥。
例如 很平滑,但支撑脚与质心关系不合理,跟踪策略仍可能摔倒。反过来,控制器足够强也可能掩盖部分参考缺陷,所以几何指标和执行指标应同时存在。
本文比较优化建模与实现机制,尚未在同一机器人、动作和场景上完成三种方法的输出质量基准。
10. 从重定向走向控制器
离线重定向得到的是期望轨迹,不是驱动器命令。ProtoMotions 可以把这些轨迹作为训练数据学习反馈控制,FALCON 一类系统也需要把动作参考与运动控制接口衔接。视觉差异可能来自动作源、坐标规范、控制参数和策略能力,不能一律解释成某种重定向算法更优。
最实用的排查顺序是:先证明 FK 与坐标映射正确,再检查 residual 与约束,再检查时间尺度,最后看闭环执行。否则一次 90 度坐标轴错误,会被误当成一个需要调很多权重的“优化问题”。
阅读依据
- GMR、Mink:任务与差分 IK。
- PyRoKi、ProtoMotions:轨迹重定向与动作数据管线。
- OmniRetarget、官方项目页、Holosoma:交互保持与实现。
- CasADi 文档:建模、自动微分和非线性优化接口。文中的任务适配系数与原方法的默认参数应分别理解。