01940f54e7
端到端验收(headless,本机无显示器):
ign 加载 Physics/UserCommands/SceneBroadcaster/Sensors + gz_ros2_control
机械臂 spawn 进 assembly 世界,7 个 sim_joint 全在 /joint_states
joint_state_broadcaster 与 rizon_arm_controller 双双 active
world → sim_tcp 可查,且末端位姿 3 秒内不变(重力下站住)
网格解析报错 0 条
新增:
scripts/run_sim_gz.sh 此前**不存在**,却被 install_sim_env.sh
与 build_sim.sh 的提示语引用
arm_sim_gazebo/robot_description.py 展开 + 归一化,launch 与 CLI 共用一份
arm_sim_gazebo/gazebo_sim_launcher.py 薄壳:准备描述后转发给 launch 文件
launch/gazebo_sim.launch.py 起 gz → 发归一化 URDF → spawn → 拉控制器
test/test_robot_description.py 含"仓库里这份 world 必须过守卫"的测试
接线过程中实测踩到并修掉的三个坑,共同特征是**每一步看起来都成功**:
1) urdf_normalize 在 Python 路径下静默失效(我自己引入的,最严重)
xacro 的输出格式在不同环境里不一样:真机环境的 CLI 缩进成多行,而仿真环境
走 xacro.process_file().toxml() 时全挤在一行。归一化的正则要求标签之间必须有
\n,于是**仿真路径下它什么都没做**(报告"包裹 0 处"),而 CLI 路径下正常 ——
之前那次"已修好"的验证走的就是 CLI,所以看起来过了。
后果是 Gazebo 会丢掉整条机械臂,正是这个归一化本来要防的事。
已改成对空白格式零假设,并加回归测试锁住。
2) world 里声明了 <plugin> 会把默认系统挤掉
只要 world 声明任何一个 <plugin>,Gazebo 就不再加载 server.config 的
Physics/UserCommands/SceneBroadcaster。缺 UserCommands →
/world/<名>/create 服务不存在 → ros_gz_sim create 调服务超时后回退发 topic、
没人收 → **模型从未进入 Gazebo**,而 create 节点仍打印
"OK creation of entity",控制器则永远卡在 "waiting for service"。
已在这三个系统在 assembly.world 里显式声明,并加纯文本守卫
check_base_plugins(),让"加了插件忘了补基础系统"在启动前就被指出。
3) gz 的插件与资源搜索路径缺 $CONDA_PREFIX/lib
gz_ros2_control 报 "Failed to load system plugin
[libgz_ros2_control-system.so] : couldn't find shared library",而 ldd 全齐、
库就在 $CONDA_PREFIX/lib 下。原因是 gz 的 SystemLoader 先在搜索路径里找文件,
找不到就直接放弃,不去 dlopen 裸文件名(所以 conda 二进制的 RPATH 兜不住);
而 ros_gz_sim 只把 LD_LIBRARY_PATH 拼进搜索路径,conda 激活并不往那里加。
同一原因导致 mesh 的 model:// 也解析不了(视觉报错很吵,但更要紧的是
**碰撞网格也加载不出来**,会让后续装配的接触判据失效)。
由于 gz_sim.launch.py 用 `from os import environ` 在生成 launch 描述时就读
进程环境,这些变量**必须在 ros2 launch 之前**设好,因此放在 sim_env.sh ——
在 launch 文件里用 SetEnvironmentVariable 补是无效的,会被它自己算的那份
字典覆盖。
Co-authored-by: Cursor <cursoragent@cursor.com>
128 lines
6.4 KiB
YAML
128 lines
6.4 KiB
YAML
# =============================================================================
|
||
# devices/sim/gazebo/manifest.yaml
|
||
#
|
||
# Gazebo 仿真平台清单。
|
||
#
|
||
# 进度(截至 P5c-3,如实记录,不要凭印象改):
|
||
# ✔ 环境 独立 conda 环境 ros_gz_sim(Gazebo Fortress + ROS 2 Humble)
|
||
# 安装见 scripts/install_sim_env.sh,激活见 scripts/sim_env.sh
|
||
# ✔ 世界文件 worlds/assembly.world(sdformat 校验通过)
|
||
# ✔ 机器人描述 urdf/(复用官方 flexiv_description,已通过 sdformat 校验)
|
||
# ✔ 控制器 config/controllers.yaml(控制器名与真机一致)
|
||
# ✔ 描述归一化 arm_sim_gazebo 包的 urdf_normalize(37 项单测)
|
||
# ✔ 启动器 gazebo_sim_launcher 已实现并端到端跑通
|
||
# 起 Gazebo → 发归一化 URDF → spawn → 拉起两个控制器(active)
|
||
# 入口脚本 scripts/run_sim_gz.sh(此前缺失,被 install_sim_env.sh
|
||
# 与 build_sim.sh 的提示语引用,照做会报文件不存在)
|
||
# ✘ 场景模型 models/ 还是空的(工件/通止规模型未做)
|
||
# ✘ 触觉插件 sensor_plugins/ 还是空的(Orisys 三向力插件未做)
|
||
# ✘ 相机出图 D405/D435 传感器已在 Gazebo 里成功注册并发布话题,
|
||
# 但还没接 ros_gz_bridge 到 ROS,也还没验证图像内容
|
||
#
|
||
# 所以:D405/D435 与触觉还要等 P5c-4 / P5c-5,装配状态机(P6)依赖它们。
|
||
#
|
||
# 三个实测踩到、且都属于"静默失效"的坑(后续改仿真时务必先看这三条):
|
||
# 1. 官方 flexiv_description 直接喂 Gazebo 会被 sdformat 拒掉:7 轴本体缺
|
||
# <inertial> 包裹;夹爪有零质量 link 导致惯性叠加出 NaN。两者都只有
|
||
# Gazebo 会暴露,RViz/MoveIt 完全正常。已在启动时归一化解决。
|
||
# 2. world 文件里只要声明了**任何一个** <plugin>,Gazebo 就不再加载默认的
|
||
# Physics/UserCommands/SceneBroadcaster。少了 UserCommands,
|
||
# /world/<名>/create 服务不存在 → 模型根本没进 Gazebo,而 create 仍打印
|
||
# "OK creation of entity"。所以这三个系统必须在 world 里显式声明。
|
||
# 3. gz 的插件搜索路径不含 $CONDA_PREFIX/lib(ros_gz_sim 只拼 LD_LIBRARY_PATH,
|
||
# 而 conda 激活不往那里加),于是 gz_ros2_control 报 "couldn't find shared
|
||
# library" 而库其实就在那儿。必须在 ros2 launch 之前设
|
||
# GZ_SIM_SYSTEM_PLUGIN_PATH;资源路径同理(否则 mesh 全加载不出来)。
|
||
# 两者都由 scripts/sim_env.sh 负责。详见该文件里的长注释。
|
||
# =============================================================================
|
||
|
||
id: gazebo
|
||
label: Gazebo 仿真
|
||
kind: sim
|
||
vendor: openrobotics
|
||
# 实测版本。注意:Humble 配的是 Fortress(ignition-gazebo6),不是现代 gz-sim ——
|
||
# 后者要 libprotobuf>=6.31,与 RoboStack 给 Humble 钉的 5.29.3 解不开依赖。
|
||
version: "Fortress 6.16 (ignition-gazebo6, ros_gz + gz_ros2_control 0.7.15)"
|
||
|
||
description: >
|
||
物理仿真平台。环境、世界、机器人描述、控制器与启动器均已就绪并端到端验证
|
||
(起 Gazebo → spawn → 两个控制器 active → 机械臂在重力下站住)。
|
||
场景模型(工件/通止规)与 Orisys 触觉插件尚未实现;
|
||
相机传感器已在 Gazebo 内注册并出话题,但还没接到 ROS 侧(P5c-4)。
|
||
注意:Orisys 视触觉没有现成 Gazebo 插件,自定义插件做出来之前,
|
||
仿真里无法验证通止规装配的 S07 接触与 S08 拧紧力判据。
|
||
|
||
# --- 物料放置要求 ----------------------------------------------------------
|
||
assets:
|
||
- path: worlds
|
||
required: false
|
||
what: Gazebo 世界文件(.world / .sdf)
|
||
format: Gazebo 原生格式
|
||
naming: 场景名.world,如 assembly.world
|
||
where_used: 由 site.yaml 的 sim.world 指向
|
||
|
||
- path: models
|
||
required: false
|
||
what: 工件 / 夹具 / 通止规模型
|
||
format: 每个模型一个子目录,内含 <模型名>.sdf 与 meshes/
|
||
naming: >
|
||
模型名必须与推理用的类别名一致(如 workpiece),否则仿真里算出的坐标
|
||
与推理结果对不上。网格单位必须是米,用毫米建模的必须先缩放。
|
||
where_used: Gazebo 场景加载
|
||
|
||
- path: urdf
|
||
required: false
|
||
what: 仿真版机器人描述
|
||
format: .urdf / .xacro,需含 gazebo 与 ros2_control 标签
|
||
naming: 关节前缀必须以 sim_ 开头,与真实臂(Rizon4-xxxxxx_)区分
|
||
where_used: 仿真机器人加载
|
||
|
||
- path: sensor_plugins
|
||
required: false
|
||
what: 传感器插件(含 Orisys 触觉自定义插件)
|
||
format: 插件源码 + CMakeLists.txt
|
||
naming: 插件类名以 Orisys 开头
|
||
where_used: 仿真传感器数据发布
|
||
|
||
# --- 适配器 ----------------------------------------------------------------
|
||
driver:
|
||
package: arm_sim_gazebo
|
||
executable: gazebo_sim_launcher
|
||
build: colcon
|
||
notes: >
|
||
已实现并在 setup.py 注册。它只做"准备描述(展开 + 归一化)+ 转发给
|
||
launch/gazebo_sim.launch.py",启动逻辑不在可执行文件里 —— ros2 launch 的
|
||
日志/退出码/中断处理都更成熟,自己重造一份只会更难调试。
|
||
入口建议走 scripts/run_sim_gz.sh(它会先 source scripts/sim_env.sh,
|
||
而 Gazebo 的插件/资源搜索路径必须在 ros2 launch 之前设好,见 sim_env.sh)。
|
||
单独排查描述用:gazebo_sim_launcher --check / --print-urdf。
|
||
|
||
# --- 配置项声明 ------------------------------------------------------------
|
||
# 设计约束:仿真与真机共用同一套 site.yaml 参数(servo.* / hole_detect.stage2.*),
|
||
# 避免「仿真调好的值搬到真机不生效」。只有物理引擎自身的参数放在 sim.* 下。
|
||
config_schema:
|
||
- key: world
|
||
site_path: sim.world
|
||
type: str
|
||
required: false
|
||
default: ""
|
||
doc: >
|
||
仿真世界文件路径。留空表示使用 Gazebo 默认空场景。
|
||
Gazebo 接线完成后填真实路径,如 devices/sim/gazebo/worlds/assembly.world。
|
||
|
||
- key: physics_enable
|
||
site_path: sim.physics_enable
|
||
type: bool
|
||
required: false
|
||
default: true
|
||
doc: 是否启用物理引擎。关闭可用于纯运动学验证。
|
||
|
||
- key: joint_prefix
|
||
site_path: sim.joint_prefix
|
||
type: str
|
||
required: false
|
||
default: sim_
|
||
doc: >
|
||
仿真关节名前缀。必须与真实臂的前缀(Rizon4-xxxxxx_)不同,
|
||
否则仿真与真机的 TF 会互相污染。
|