含自由体场景下KinematicTrajectoryOptimization使用报错解决方案咨询
解决KinematicTrajectoryOptimization添加自由体后AddVelocityBounds维度不匹配问题
你遇到的异常是因为添加自由体砖块后,系统的位置维度包含了机器人关节位置、砖块的3个平移自由度和4个四元数旋转自由度,总维度增加了7,但你设置的速度上下界数组长度还是原机器人的维度,导致和num_positions()返回的总长度不匹配。以下是具体解决步骤:
调整速度边界数组长度
先通过plant.num_positions()获取系统总位置维度,然后构建对应长度的速度上下界数组。原机器人的速度边界保持不变,新增的砖块部分:- 平移速度可以设置合理上下限(比如±0.5 m/s)
- 四元数对应的速度约束,建议通过角速度来间接控制:先给砖块的角速度设置上下限(比如±2 rad/s),再利用Drake提供的相关工具将角速度约束转换为四元数导数的约束,或者直接添加角速度的硬约束,避免手动处理四元数导数的复杂关系。
拆分系统状态处理
利用Drake的MultibodyPlant实例,分别获取机器人和砖块的位置维度,再拼接各自的速度上下界:# 假设robot_instance和object_instance是对应的模型实例 robot_vel_lb = np.full(plant.num_positions(robot_instance), -1.0) robot_vel_ub = np.full(plant.num_positions(robot_instance), 1.0) # 砖块的速度上下界:3个平移+4个四元数导数 object_trans_lb = np.array([-0.5, -0.5, -0.5]) object_trans_ub = np.array([0.5, 0.5, 0.5]) # 四元数导数的边界可先设为合理范围,后续再结合角速度约束优化 object_rot_lb = np.array([-0.1, -0.1, -0.1, -0.1]) object_rot_ub = np.array([0.1, 0.1, 0.1, 0.1]) object_vel_lb = np.concatenate([object_trans_lb, object_rot_lb]) object_vel_ub = np.concatenate([object_trans_ub, object_rot_ub]) # 拼接完整的速度上下界传入优化器 full_vel_lb = np.concatenate([robot_vel_lb, object_vel_lb]) full_vel_ub = np.concatenate([robot_vel_ub, object_vel_ub]) traj_opt.AddVelocityBounds(full_vel_lb, full_vel_ub)处理旋转自由度的约束特殊性
四元数是单位长度约束,其导数和角速度存在固定关系($\dot{q} = \frac{1}{2} \Omega q$,$\Omega$为角速度的反对称矩阵),直接设置四元数导数边界容易违反这个关系。更稳妥的方式是添加角速度约束:from pydrake.all import BodyIndex, AngularVelocityConstraint body = plant.GetBodyByName("brick_body") max_angular_vel = 2.0 traj_opt.AddConstraint(AngularVelocityConstraint(plant, body, -max_angular_vel * np.ones(3), max_angular_vel * np.ones(3)))验证初始状态和优化器配置
确保初始化轨迹优化器时,传入的是包含砖块的完整MultibodyPlant,并且初始状态包含砖块的平移位置、四元数姿态,以及对应的平移速度、角速度(或四元数导数)。
内容的提问来源于stack exchange,提问作者saitcanbaskol
相关产品推荐
相关产品推荐

