news 2026/4/4 18:33:13

关节控制和笛卡尔空间控制表示位姿的区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
关节控制和笛卡尔空间控制表示位姿的区别

🤖 两种表示方式的区别

1.robot_qpos (关节空间/Joint Space)

robot_qpos=[j0,j1,j2,j3,j4,j5,j6,j7,j8]
  • 含义: 机器人的9个关节角度(弧度)
  • 空间: 9维关节空间
  • 特点: 机器人的内部状态

2.end_effector (笛卡尔空间/Cartesian Space)

end_effector={"position":[x,y,z],# 3D位置"quaternion":[w,x,y,z]# 4D姿态}
  • 含义: 末端执行器在世界坐标系中的位置和姿态
  • 空间: 6维任务空间(3个位置 + 3个旋转自由度)
  • 特点: 末端的外部表现

🔄 转换关系

正运动学 (Forward Kinematics, FK)- 确定性

# 关节角度 → 末端位姿robot_qpos → end_effector_pose

唯一确定: 给定关节角度,末端位姿是唯一的

逆运动学 (Inverse Kinematics, IK)- 多解性

# 末端位姿 → 关节角度end_effector_pose → robot_qpos(可能有多个解)

⚠️多解或无解:

  • 可能有多个关节配置达到同一末端位姿
  • 可能无解(位姿超出工作空间)
  • 需要额外约束选择"最优"解

🎯 为什么要同时保存两者?

1.不同的控制方式

关节空间控制
# 直接控制每个关节action=[Δj0,Δj1,Δj2,Δj3,Δj4,Δj5,Δj6,Δj7,Δj8]
  • ✅ 精确控制每个关节
  • ✅ 避免奇异点问题
  • ❌ 不直观(难以理解末端位置)
笛卡尔空间控制
# 控制末端位姿action=[Δx,Δy,Δz,Δrx,Δry,Δrz]# 需要IK转换
  • ✅ 直观(直接控制末端位置)
  • ✅ 适合任务规划
  • ❌ 可能遇到奇异点或无解

2.数据用途不同

用途需要的数据原因
机器人控制robot_qpos直接发送到关节电机
任务规划end_effector在3D空间规划轨迹
碰撞检测robot_qpos需要知道每个关节位置
可视化end_effector显示工具位置
学习模型两者都需要不同模型需要不同表示

3.示例:同一末端位姿的不同关节配置

# 手臂弯曲方式1(肘部向上)qpos_1=[0.0,0.5,0.0,-1.5,0.0,2.0,0.0,0.04,0.04]# → end_effector: position=[0.5, 0.0, 0.6], quat=[...]# 手臂弯曲方式2(肘部向下)qpos_2=[0.0,-0.5,0.0,-1.5,0.0,2.0,0.0,0.04,0.04]# → end_effector: position=[0.5, 0.0, 0.6], quat=[...] (相同!)

末端位姿相同,但关节配置不同!这在训练模型时很重要。

📊 在数据采集中的作用

采集时的信息流

# 1. 获取关节状态(底层传感器)robot_qpos=env.agent.robot.get_qpos()# 从编码器读取# 2. 计算末端位姿(正运动学)ee_pose=env.agent.tcp.pose# ManiSkill内部通过FK计算# 3. 两者都保存frame_data={"robot_qpos":robot_qpos,# 原始关节数据"end_effector":{# 计算得到的末端位姿"position":ee_position,"quaternion":ee_quaternion}}

训练模型时的选择

不同模型可能使用不同的表示:

# 模型1: 在关节空间学习observation=robot_qpos# (9,)action=delta_qpos# (9,)# 模型2: 在笛卡尔空间学习observation=end_effector_pose# (7,) = pos(3) + quat(4)action=delta_pose# (6,) = delta_pos(3) + delta_rot(3)# 模型3: 混合表示observation=concat([robot_qpos,end_effector_pose])# (16,)action=...

🎓 实际应用示例

场景1: UMI模型训练

# UMI主要使用笛卡尔空间obs={'robot0_eef_pos':end_effector.position,# 使用末端位置'robot0_eef_rot_axis_angle':axis_angle# 使用末端旋转}# 但在replay时可能需要robot_qpos来初始化环境

场景2: 数据回放

# 如果只保存end_effector:# 需要IK求解 → 可能得到不同的关节配置 → 回放不准确# 同时保存robot_qpos:# 直接设置关节状态 → 精确回放 ✅env.agent.robot.set_qpos(robot_qpos)

场景3: 故障排查

# 如果机器人行为异常:# 查看robot_qpos → 发现某个关节超限# 查看end_effector → 发现末端位置正常# 结论:IK求解可能有问题,应该检查关节限制

💡 结论

虽然理论上可以互相转换,但实际上:

  1. 两者互补: 关节空间提供内部状态,笛卡尔空间提供外部表现
  2. 避免计算误差: 保存原始数据比每次重新计算更准确
  3. 灵活性: 不同算法可以选择最适合的表示
  4. 完整性: 关节空间信息更丰富(9维 vs 6维)
  5. 安全性: 关节状态可以检测异常配置(如关节超限)

存储成本低,但价值高- 在机器人学习和控制中,同时保存两种表示是最佳实践!📊🤖

robot_qpos=[j0,j1,j2,j3,j4,j5,j6,j7,j8]
end_effector={"position":[x,y,z],# 3D位置"quaternion":[w,x,y,z]# 4D姿态}
# 关节角度 → 末端位姿robot_qpos → end_effector_pose
# 末端位姿 → 关节角度end_effector_pose → robot_qpos(可能有多个解)
# 直接控制每个关节action=[Δj0,Δj1,Δj2,Δj3,Δj4,Δj5,Δj6,Δj7,Δj8]
# 控制末端位姿action=[Δx,Δy,Δz,Δrx,Δry,Δrz]# 需要IK转换
# 手臂弯曲方式1(肘部向上)qpos_1=[0.0,0.5,0.0,-1.5,0.0,2.0,0.0,0.04,0.04]# → end_effector: position=[0.5, 0.0, 0.6], quat=[...]# 手臂弯曲方式2(肘部向下)qpos_2=[0.0,-0.5,0.0,-1.5,0.0,2.0,0.0,0.04,0.04]# → end_effector: position=[0.5, 0.0, 0.6], quat=[...] (相同!)
# 1. 获取关节状态(底层传感器)robot_qpos=env.agent.robot.get_qpos()# 从编码器读取# 2. 计算末端位姿(正运动学)ee_pose=env.agent.tcp.pose# ManiSkill内部通过FK计算# 3. 两者都保存frame_data={"robot_qpos":robot_qpos,# 原始关节数据"end_effector":{# 计算得到的末端位姿"position":ee_position,"quaternion":ee_quaternion}}
# 模型1: 在关节空间学习observation=robot_qpos# (9,)action=delta_qpos# (9,)# 模型2: 在笛卡尔空间学习observation=end_effector_pose# (7,) = pos(3) + quat(4)action=delta_pose# (6,) = delta_pos(3) + delta_rot(3)# 模型3: 混合表示observation=concat([robot_qpos,end_effector_pose])# (16,)action=...
# UMI主要使用笛卡尔空间obs={'robot0_eef_pos':end_effector.position,# 使用末端位置'robot0_eef_rot_axis_angle':axis_angle# 使用末端旋转}# 但在replay时可能需要robot_qpos来初始化环境
# 如果只保存end_effector:# 需要IK求解 → 可能得到不同的关节配置 → 回放不准确# 同时保存robot_qpos:# 直接设置关节状态 → 精确回放 ✅env.agent.robot.set_qpos(robot_qpos)
# 如果机器人行为异常:# 查看robot_qpos → 发现某个关节超限# 查看end_effector → 发现末端位置正常# 结论:IK求解可能有问题,应该检查关节限制
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/2 7:07:31

深度学习毕设项目:基于卷积神经网络训练识别牙齿是否健康基于python-CNN卷积神经网络训练识别牙齿是否健康

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/21 3:08:43

深度学习毕设选题推荐:基于python-CNN卷积神经网络对鸟类识别基于机器学习python-CNN卷积神经网络对鸟类识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/28 19:37:37

安装Anaconda+Python(2025超详细)

下载Anaconda安装包访问Anaconda官网(https://www.anaconda.com/download),选择对应操作系统的版本(Windows/macOS/Linux)。推荐下载Python 3.x版本的安装包,确保与最新工具链兼容。运行安装程序双击下载的…

作者头像 李华
网站建设 2026/4/3 5:27:01

Java锁机制八股文

一、简短结论 CAS是基础:所有Java锁机制的底层都依赖CAS实现原子操作AQS是框架:ReentrantLock等JUC锁基于AQS,AQS使用CASCLH队列synchronized是混合锁:经历了偏向锁→轻量级锁→重量级锁的升级过程,内部大量使用CAS锁选…

作者头像 李华
网站建设 2026/4/2 10:18:20

微信视频号下载器,蝴蝶号视频下载

自媒体必备神器-微信视频号下载器 - 教你如何下载视频号视频 体积小、使用简单、支持 macOS 和 Windows 系统。 一、下载器简介 对于自媒体人来说,获取和保存微信视频号上的优质视频内容,是日常创作和学习的重要一环。为了帮助大家轻松下载微信视频号…

作者头像 李华