P5c-2:仿真世界 + 机器人描述 + 控制器配置,并解决两处官方描述与 Gazebo 的不兼容
这一步解决的是"官方 Flexiv 描述能不能喂给 Gazebo"的问题。结论是**不能直接用**,
有两处不兼容,且都只有 Gazebo 会暴露 —— RViz/MoveIt 完全正常,所以此前从未发现。
问题一:7 轴本体的质量/惯量是"孤儿标签"
rizon_arm.xacro 调 get_inertias 时没写 <inertial> 包裹,而那个宏只吐
<origin>/<mass>/<inertia> 三个碎片。RViz/MoveIt 忽略不认识的子元素所以看着
没事;sdformat 判定 "link has no <inertial> block",然后把 **link 和它的父
关节一起丢掉**。症状极具误导性:机械臂凭空消失或只剩夹爪,报错只有一句
"link[sim_link1] is not modeled in sdf"。
问题二:夹爪有零质量 link,导致 sdformat 惯性叠加出 NaN
grav_macro.xacro 给六个纯坐标系 dummy link 写了 mass=0、惯量全 0。
sdformat 对 fixed 关节会把子 link 惯性叠加到父 link,叠加要除以总质量 →
质量 0 就出 NaN。而报错指向的是**父** link:
Pose values must be finite. link[sim_left_finger_mount]/inertial/pose
完全看不出根因在子 link 的质量上。
修法:启动时归一化(不走改上游文件的路,因为上游由 fetch_flexiv.sh 获取、改了会被
覆盖;而且换别的臂时大概率有别的坑,在启动时统一过一道更可持续)
- 孤儿三件套 → 只重新分组已有元素,一个数字都不改
- 零质量 → 补 1e-4 kg(与夹爪其他配件同量级,0.1g 对动力学无影响),
惯量全 0 时补极小对角值避免张量退化
不发明物理数据,也不掩盖真问题:上游真没给质量时这里什么都不会包。
16 项单测,含"已有 <inertial> 不能被二次包裹"(早期用全局正则踩过,
sdformat 报 "Inertial element must have a mass element")与幂等性。
新增/改动
- devices/sim/gazebo/urdf/:arm.sim.urdf.xacro(主)、.ros2_control(gz 硬件)、
.gazebo(系统插件/材质/接触刚度)、.sensors(D405 + 双指触觉)
- devices/sim/gazebo/worlds/assembly.world:1ms 步长 + 150 次接触迭代(力信号
要干净才谈得上"切向力突变"判据)、工作台、world 级渲染插件、D435
- devices/sim/gazebo/config/controllers.yaml:控制器名 rizon_arm_controller
**故意与真机一致** —— 隔离的是关节/TF 层(sim_ 前缀),不是应用层依赖的接口
- src/arm_sim_gazebo/:新包,含 urdf_normalize(库 + CLI)与单测
一处设计纠正:D435 从 URDF 挪进 world。原本挂在 URDF 的 world link 上,结果
整台相机转 SDF 时凭空消失(sdformat 丢弃无质量根 link 时连带丢了整棵子树,
且退出码 0、不报错)。眼在手外的相机物理上就属于场景,放 world 才对;
渲染插件也一并归 world 级,避免"插件在模型里、相机在世界里"的错配。
验证(不是只看退出码)
- 带夹爪全量:sdformat 退出码 0、0 报错、15 link / 15 joint / 26 frame
- 传感器 d405_rgbd + tactile_left/right 均在;控制器插件与参数路径正确
- 世界文件 sdformat 通过
- 包在 ros_gz_sim 环境构建通过,CLI 实跑结果与库调用一致
- 未注册 gazebo_sim_launcher 入口点:模块还没写,注册了构建能过但一运行就
ImportError,不如老实缺着(manifest 里如实标注为未实现)
注:实测确认 gz_ros2_control 的硬件/接口声明**不在 SDF 里**,插件是从
/robot_description 话题读 URDF 的 <ros2_control> —— 所以启动器必须先起
robot_state_publisher 且发布归一化后的同一份 URDF,否则控制器注册的关节名
会和 Gazebo 里的对不上。这条已写进 P5c-3 的实现要求。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
=============================================================================
|
||||
仿真版 ros2_control 硬件描述。
|
||||
|
||||
为什么不复用官方 flexiv_description 的 rizon.ros2_control.xacro:
|
||||
那个宏只认两种硬件插件 —— 要么 mock_components/GenericSystem,
|
||||
要么 flexiv_hardware/FlexivHardwareInterface(真机 RDK)。
|
||||
Gazebo 需要第三种:gz_ros2_control/GazeboSimSystem。官方宏里没有这个分支,
|
||||
而且改官方文件等于分叉上游描述,上游一升级就冲突。所以仿真自己写一份。
|
||||
|
||||
两处必须对齐,否则 controller_manager 会报 "no hardware interface found":
|
||||
1. 关节名 —— 必须是 sim_joint1..sim_joint7(前缀 sim_,见 naming 约定)
|
||||
2. command/state interface 名字 —— 必须与 gz_ros2_control 实际提供的接口一致
|
||||
Gazebo 侧:position/velocity 可读可写,effort 只能读。
|
||||
我们只下 position 指令(应用层走 JTC 位置轨迹),所以 command 只声明 position。
|
||||
|
||||
验证插件名的方法(换 Gazebo/ros2_control 版本后建议重跑一遍确认):
|
||||
strings $CONDA_PREFIX/lib/libgz_ros2_control-system.so | grep GazeboSimSystem
|
||||
cat $CONDA_PREFIX/share/gz_ros2_control/gz_hardware_plugins.xml
|
||||
本机实测(gz_ros2_control 0.7.15):硬件名为 gz_ros2_control/GazeboSimSystem。
|
||||
=============================================================================
|
||||
-->
|
||||
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
|
||||
|
||||
<xacro:macro name="arm_sim_ros2_control" params="prefix joint_count:=7">
|
||||
|
||||
<ros2_control name="GazeboSimSystem" type="system">
|
||||
<hardware>
|
||||
<!--
|
||||
Gazebo 的 ros2_control 硬件插件。它由 Gazebo 侧的系统插件
|
||||
(arm.sim.gazebo.xacro 里声明的 GazeboSimROS2ControlPlugin)加载,
|
||||
controller_manager 在 Gazebo 进程内被拉起来。
|
||||
|
||||
注意:硬件参数(update_rate 等)不写在这里,而是在 Gazebo 的
|
||||
<plugin> 标签里配置(见 arm.sim.gazebo.xacro)。写在 <hardware> 下
|
||||
不会生效,这是 gz_ros2_control 与真机 hardware 的一个区别。
|
||||
-->
|
||||
<plugin>gz_ros2_control/GazeboSimSystem</plugin>
|
||||
</hardware>
|
||||
|
||||
<!-- 关节 1..7。全部只给 position 指令 + position/velocity 状态。 -->
|
||||
<xacro:macro name="arm_sim_joint" params="name">
|
||||
<joint name="${name}">
|
||||
<command_interface name="position"/>
|
||||
<state_interface name="position"/>
|
||||
<state_interface name="velocity"/>
|
||||
</joint>
|
||||
</xacro:macro>
|
||||
|
||||
<xacro:arm_sim_joint name="${prefix}joint1"/>
|
||||
<xacro:arm_sim_joint name="${prefix}joint2"/>
|
||||
<xacro:arm_sim_joint name="${prefix}joint3"/>
|
||||
<xacro:arm_sim_joint name="${prefix}joint4"/>
|
||||
<xacro:arm_sim_joint name="${prefix}joint5"/>
|
||||
<xacro:arm_sim_joint name="${prefix}joint6"/>
|
||||
<xacro:arm_sim_joint name="${prefix}joint7"/>
|
||||
|
||||
</ros2_control>
|
||||
|
||||
</xacro:macro>
|
||||
|
||||
</robot>
|
||||
Reference in New Issue
Block a user