实战:同时控制机械臂末端位姿与接触力)
Isaac Lab 操作空间控制器OSC实战同时控制机械臂末端位姿与接触力【免费下载链接】IsaacLabUnified framework for robot learning with multi-physics/renderer support项目地址: https://gitcode.com/GitHub_Trending/is/IsaacLab本篇教程基于 Isaac Lab 的run_osc.py示例讲解如何利用OperationalSpaceController操作空间控制器驱动机械臂在跟踪期望末端位姿的同时对倾斜墙面施加恒定接触力模拟擦桌子等接触作业。读完本文你将掌握 OSC 的核心原理、OperationalSpaceControllerCfg全量配置参数、与差分 IK 控制器的区别以及如何在 Isaac Lab 仿真环境中完成力/位混合控制的完整闭环。为什么需要操作空间控制器在 Isaac Lab 中差分 IK 控制器教程 通过运动学求解将末端位姿映射为关节位置指令适用于纯轨迹跟踪场景。但以下任务场景中差分 IK 并不够用需要强制指定任务空间的位姿跟踪误差动力学如保证末端以指定刚度、阻尼特性逼近目标需要用关节力矩/力effort/torque指令直接驱动机器人需要在一个方向上控制运动、同时在其他方向施加接触力例如用抹布擦桌面、墙面抛光等接触作业。此时就需要操作空间控制器Operational Space ControllerOSC。OSC 的理论基础是 Khatib 于 1987 年提出的操作空间公式Operational Space Formulation它把任务空间笛卡尔空间的期望动力学映射到关节空间力矩。控制器实现及配置定义于控制器实现控制器配置本教程将复用OperationalSpaceController让 Franka Panda 机械臂对一面红色倾斜墙持续施加垂直于墙面沿任务帧 z 轴的恒定力同时在其他五个方向跟踪期望末端位姿。运行示例搭建场景并驱动 128 台机器人示例脚本位于 scripts/tutorials/05_controllers/run_osc.py通过仓库根目录下的启动脚本运行./isaaclab.sh -p scripts/tutorials/05_controllers/run_osc.py --num_envs 128脚本将启动包含 128 台机器人的并行仿真环境。场景构成SceneCfg包括地面平面GroundPlaneCfg与半球光DomeLightCfg一面半透明红色倾斜墙CuboidCfg尺寸为 2.0 × 1.5 × 0.01 m启用碰撞与接触传感器姿态四元数(0, -0.3827, 0, 0.9239)绕 y 轴旋转约 45°位置(0.685, 0, 0.3)一个ContactSensorCfgprim_path/World/envs/env_.*/TiltedWallhistory_length2用于读取接触力Franka Panda 机械臂关键设定是把panda_shoulder、panda_forearm驱动器的刚度与阻尼清零力矩控制模式并关闭重力disable_gravityTrue使关节完全由 OSC 输出的力矩指令驱动。仿真循环中机械臂将在三组目标三个不同的末端位姿均对应墙面上不同的接触点之间循环切换。运行结果中当前与目标末端位姿通过帧标记frame marker显示你将看到机械臂到达目标位姿的同时保持垂直于墙面施加恒定力。运行效果如下停止仿真只需关闭窗口或在终端按下CtrlC。创建操作空间控制器OperationalSpaceControllerCfg 全参数解析OperationalSpaceController的任务是在任务空间内同时进行运动控制与力控制输出关节力矩。任务空间参考系task frame可以是欧氏空间中的任意坐标系默认取机器人基座坐标系。当目标坐标相对其他坐标系更容易定义时例如本教程中墙面平行坐标系应在set_command的current_task_frame_pose_b参数中提供该任务参考系相对基座的位姿。本教程中目标位姿与墙面同姿态将其作为任务帧后力控制方向恰好只落在任务帧的 z 轴全部配置参数都围绕这一任务参考系展开。控制器在 operational_space.py 中以批处理 PyTorch 运算实现天然支持并行环境num_envs。target_types任务空间目标类型指定任务空间目标的类型与参考系由类型 参考两个子串用下划线拼接取值含义命令维度pose_abs绝对位姿相对机器人基座含位置 四元数7pose_rel相对末端当前位姿的位姿增量旋转用轴角表示6wrench_abs绝对力/力矩相对机器人基座6若需同时做位姿与力控制将target_types设为列表如[pose_abs, wrench_abs]或[pose_rel, wrench_abs]。各目标的命令向量按target_types顺序拼接action_dim为各目标维度之和见下节。本教程使用target_types[pose_abs, wrench_abs]除 z 轴外的五个方向做绝对位姿控制z 轴做绝对力控制。控制轴选择motion_control_axes_task 与 contact_wrench_control_axes_task用 0/1 长度为 6 的列表分别指定运动控制与力控制作用的轴顺序为 x、y、z 平动 绕 x、y、z 转动。两列表应互补例如 x 轴若motion_control_axes_task为 0则contact_wrench_control_axes_task应为 1。本教程中motion_control_axes_task[1, 1, 0, 1, 1, 1], # 除 z 平动外的所有轴做运动控制 contact_wrench_control_axes_task[0, 0, 1, 0, 0, 0], # 仅在 z 平动方向做力控制注意源码中会将增益矩阵与选择矩阵相乘把非运动控制轴的增益清零operational_space.py第 95-97 行避免因轴间耦合导致未控制轴产生意外力矩。运动控制刚度、阻尼比与阻抗模式运动控制轴上的期望刚度stiffness与阻尼比damping ratio通过以下参数设置motion_stiffness_task位置增益N/m 或 N·m/rad可为标量所有轴相同或 6 元素列表默认100.0 × 6motion_damping_ratio_task阻尼比配合位置增益计算速度增益d_gains 2 * sqrt(p_gains) * damping_ratio默认1.0 × 6。若希望刚度/阻尼比作为命令参数动态改变例如用 RL 学习阻抗或运行中在线调整设置impedance_mode取值含义fixed增益固定命令只含任务空间目标variable_kp命令额外包含 6 个刚度值action_dim target_dim 6variable命令额外包含刚度与阻尼比action_dim target_dim 6 6使用variable_kp/variable时必须同时设置motion_stiffness_limits_task刚度上下限默认(0, 1000)motion_damping_ratio_limits_task阻尼比上下限默认(0, 100)仅variable使用。命令中的刚度/阻尼比会被裁剪到上述范围内见operational_space.py第 224-227、243-248 行。本教程设置impedance_modevariable_kp、motion_damping_ratio_task1.0阻尼比固定为 1kd 随 kp 自适应维持临界阻尼响应并在命令中动态传入三组 kp360、420、320每个目标一组。力控制开环与闭环开环力控制不设置contact_wrench_stiffness_task保持None直接输出期望力闭环力控制设置contact_wrench_stiffness_task标量或 6 元素列表在期望力上叠加刚度 × 期望力与实测力之差含前馈项形成反馈修正。由于目前接触传感器只能测量线性力、无法测量力矩闭环控制仅使用contact_wrench_stiffness_task的前三个元素线性部分力矩方向保持开环见operational_space.py第 459-472 行。本教程设置contact_wrench_stiffness_task[0.0, 0.0, 0.1, 0.0, 0.0, 0.0]仅对 z 轴力做闭环反馈增益 0.1期望力为任务帧 z 轴方向 10 N。惯性动力学解耦inverse dynamicsinertial_dynamics_decouplingTrue利用机器人的质量/惯性矩阵解耦任务空间的期望加速度逆动力学计算操作空间质量矩阵M_task (J M⁻¹ Jᵀ)⁻¹再得到F M_task · ẍ_des。这对快速运动下的控制精度至关重要解耦覆盖全部六个运动轴之间的耦合partial_inertial_dynamics_decouplingTrue忽略平动与转动之间的惯性耦合分别计算平移与旋转部分如 测试用例 test_franka_pose_abs_with_partial_inertial_decoupling 所示。若为False则退化为不包含惯性项的任务空间阻抗控制命令力直接等于期望加速度。本教程使用inertial_dynamics_decouplingTrue且partial_inertial_dynamics_decouplingFalse做完整惯性解耦。重力补偿gravity_compensationTrue时将重力补偿向量gravity叠加到关节力矩中。本教程中机器人的重力已在场景配置中关闭disable_gravityTrue因此不启用。冗余机械臂的零空间控制零空间null-space是关节空间中不影响任务空间坐标的子空间。若不加以控制冗余关节会飘浮甚至逼近关节限位。有两种选择nullspace_controlnone默认不施加零空间控制nullspace_controlposition集成零空间 PD 控制器把关节吸引到期望位置而不影响任务空间。零空间行为由nullspace_stiffness默认 10.0与nullspace_damping_ratio默认 1.0定义。理论上的零空间与任务空间完全解耦仅在inertial_dynamics_decouplingTrue且partial_inertial_dynamics_decouplingFalse时成立此时使用动力学一致的伪逆否则退化为 Moore-Penrose 伪逆见operational_space.py第 498-505 行。本教程设置nullspace_controlposition将关节目标设为关节限位中心joint_centers torch.mean(robot.data.soft_joint_pos_limits.torch[:, arm_joint_ids, :], dim-1)本教程的完整配置osc_cfg OperationalSpaceControllerCfg( target_types[pose_abs, wrench_abs], impedance_modevariable_kp, inertial_dynamics_decouplingTrue, partial_inertial_dynamics_decouplingFalse, gravity_compensationFalse, motion_damping_ratio_task1.0, contact_wrench_stiffness_task[0.0, 0.0, 0.1, 0.0, 0.0, 0.0], motion_control_axes_task[1, 1, 0, 1, 1, 1], contact_wrench_control_axes_task[0, 0, 1, 0, 0, 0], nullspace_controlposition, ) osc OperationalSpaceController(osc_cfg, num_envsscene.num_envs, devicesim.device)控制器实例化需要三个参数配置、环境数num_envs与计算设备device。所有配置字段的完整说明见 operational_space_cfg.py。更新机器人状态向控制器喂入动力学量OperationalSpaceController是纯计算类不持有机器人内部状态需要调用方在每个控制周期提供全部在机器人基座/root 坐标系下末端雅可比矩阵jacobian_broot 系形状num_envs × 6 × num_DoF关节空间质量/惯性矩阵mass_matrixnum_envs × num_DoF × num_DoF重力补偿向量gravitynum_envs × num_DoF末端位姿current_ee_pose_bnum_envs × 7位置 四元数末端速度current_ee_vel_bnum_envs × 6线速度 角速度末端接触力current_ee_force_bnum_envs × 3关节位置/速度current_joint_pos、current_joint_vel可选零空间关节目标位置nullspace_joint_pos_target与重力向量。示例脚本中的update_states()函数负责从 Isaac Lab 的Articulation与ContactSensor提取这些量关键步骤包括Jacobian 提取与坐标系转换取body_link_jacobian_w中末端连杆对应的块注意固定基座机器人的基座自由度偏移num_base_dofs再用matrix_from_quat(quat_inv(root_quat_w))将旋转部分与世界坐标下的 Jacobian 从世界系旋转到 root 系质量矩阵与重力向量从robot.data.mass_matrix、robot.data.gravity_compensation_forces中按臂关节索引切片末端位姿/速度用subtract_frame_transforms将世界系末端位姿转换到 root 系速度用quat_apply_inverse把末端相对 root 的相对速度从世界系旋转到 root 系接触力更新接触传感器后对历史窗口history_length2内的净接触力取平均再取三面最大值得到平滑的末端接触力脚本注释说明这是为了测试所做的简化处理。设置命令与计算关节力矩控制循环三要素OSC 将设置期望命令与计算关节指令分离这是使用该控制器的关键编程约定。1. 组装并转换目标命令命令向量是一个形状为(num_envs, action_dim)的张量内容按target_types顺序拼接。本教程的impedance_modevariable_kp因此命令为pose_abs(7) wrench_abs(6) kp(6) 19维。每组目标定义为ee_target_set torch.cat([ee_goal_pose_set_tilted_b, ee_goal_wrench_set_tilted_task, kp_set_task], dim-1)期望力已在任务帧中定义ee_goal_wrench_set_tilted_task仅 z 轴为 10 N而期望位姿定义在基座系。convert_to_task_frame()用subtract_frame_transforms把位姿目标从基座系转换到任务帧即目标位姿本身作为任务参考系命令全部统一到任务帧command, task_frame_pose_b convert_to_task_frame(osc, commandcommand, ee_target_pose_bee_target_pose_b)2. 设置 OSC 命令将任务帧下的命令向量、末端当前位姿基座系与任务参考系位姿基座系一起交给set_command。内部计算在基座系完成因此需要任务帧相对基座的位姿用于坐标变换包括增益矩阵、选择矩阵的旋转变换与期望力/力矩的传递见operational_space.py第 293-345 行osc.set_command(commandcommand, current_ee_pose_bee_pose_b, current_task_frame_pose_btask_frame_pose_b)3. 计算关节力矩并施加compute()在内部依次完成运动控制末端位姿误差 弹簧阻尼动力学 → 惯性解耦 → 经选择矩阵与 Jacobian 转置映射到关节力矩、力控制开环或带前馈的闭环力修正同样映射到关节力矩、重力补偿叠加、零空间控制叠加最终返回(num_envs, num_DoF)的关节力矩joint_efforts osc.compute( jacobian_bjacobian_b, current_ee_pose_bee_pose_b, current_ee_vel_bee_vel_b, current_ee_force_bee_force_b, mass_matrixmass_matrix, gravitygravity, current_joint_posjoint_pos, current_joint_veljoint_vel, nullspace_joint_pos_targetjoint_centers, ) # 施加关节力矩仅作用于臂关节并写回仿真 robot.set_joint_effort_target_index(targetjoint_efforts, joint_idsarm_joint_ids) robot.write_data_to_sim()重置与目标切换仿真每 500 步重置一次将关节状态恢复默认值、力矩清零、重置接触传感器随后重新计算目标命令并调用osc.reset()清空内部目标缓存再重新set_command。目标索引通过current_goal_idx在三个目标间循环next_goal_idx (current_goal_idx 1) % len(ee_target_set)。从控制器到动作项OSC 在 RL 环境中的封装除脚本级使用外Isaac Lab 还将 OSC 封装为 Manager-based RL 环境的动作项Action Term配置类为 OperationalSpaceControllerActionCfg实现位于task_space_actions.py的OperationalSpaceControllerAction。其关键字段joint_names动作映射到的关节列表支持正则body_name执行运动/力控制的末端连杆/坐标系名称body_offset末端坐标系相对父刚体的偏移很多机器人的末端是虚构坐标系如 Franka 的末端相对panda_hand存在偏移task_frame_rel_path指定任务参考系对应的RigidObject路径如一面墙controller_cfg内嵌的OperationalSpaceControllerCfgposition_scale/orientation_scale/wrench_scale/stiffness_scale/damping_ratio_scale对各类命令的缩放因子nullspace_joint_pos_target零空间关节目标策略取none/zero/default/center仅当nullspace_controlposition时生效。验证与测试仓库中的 OSC 覆盖矩阵仓库测试 test_operational_space.py 系统验证了 OSC 的各种组合模式可作为理解各配置项行为的最佳参照test_franka_pose_abs_without_inertial_decoupling固定阻抗 无惯性解耦的绝对位姿控制test_franka_pose_abs_with_partial_inertial_decoupling部分惯性解耦test_franka_pose_abs_fixed_impedance_with_gravity_compensation启用重力补偿机器人不关闭重力test_franka_pose_abs/test_franka_pose_rel绝对/相对位姿 完整惯性解耦test_franka_pose_abs_variable_impedancevariable阻抗模式命令含 kp 与阻尼比test_franka_wrench_abs_open_loop/test_franka_wrench_abs_closed_loop纯力控制的开环与闭环模式test_franka_hybrid_decoupled_motion、test_franka_hybrid_variable_kp_impedance位姿 力混合控制固定阻抗 / variable_kptest_franka_taskframe_pose_abs、test_franka_taskframe_pose_rel、test_franka_taskframe_hybrid以任务参考系非 root 系定义目标的位姿控制与混合控制。例如混合控制测试使用的配置与教程配置高度一致target_types[pose_abs, wrench_abs]、contact_wrench_stiffness_task[0.1, 0, 0, 0, 0, 0]、互补的控制轴进一步印证了运动轴与力轴互补 任务帧定义这一 OSC 标准用法。小结本文围绕run_osc.py完整演示了 Isaac Lab 操作空间控制器的使用闭环场景搭建 →OperationalSpaceControllerCfg配置目标类型、控制轴、阻抗模式、惯性解耦、零空间控制→ 机器人状态提取Jacobian、质量矩阵、接触力→ 任务帧命令转换 →set_command/compute力矩输出。关键要点可归纳为运动与力控制通过互补的motion_control_axes_task与contact_wrench_control_axes_task划分任务空间六轴任务参考系可自由选择默认基座系配合current_task_frame_pose_b传入即可简化目标定义惯性解耦提升快速运动精度且是零空间与任务空间理论解耦的前提接触力闭环只作用于线性力方向传感器测不到接触力矩冗余机械臂务必规划零空间控制策略避免关节失控飘移。进一步阅读可参考仓库中的 差分 IK 控制器教程 对比两类任务空间控制器的差异以及 任务空间动作项封装 了解如何将 OSC 接入端到端强化学习训练。【免费下载链接】IsaacLabUnified framework for robot learning with multi-physics/renderer support项目地址: https://gitcode.com/GitHub_Trending/is/IsaacLab创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考