gz sim机器人SDF模型 [持续更新]


不算教学,个人的记录

sdf的格式跟urdf有所不同,必须是完整的一个包括,比如< pose></ pose>这样前一个后一个,urdf中是有< orign xyz=‘0 0 0’ rpy=‘0 0 0’>的写法的,也就是没< orign>< /orign>这样写。sdf中需要注意。

下面是一个两轮小车的模型sdf文件,算是一个标准基础例子。

<?xml version='1.0'?>
<sdf version='1.9'>
  <model name='diff_drive_robot'>
    <!-- 主车身(立方体) -->
    <link name='base_link'>
    <!-- 这个pose写的是右轮在整个model的零点的相对位置 -->
      <pose>1 0 0 0 0 0</pose>
      <!-- 物理属性必须要写,urdf中是可以不写的 -->
      <inertial>
        <mass>5.0</mass>
        <inertia>
          <ixx>0.104167</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.104167</iyy>
          <iyz>0</iyz>
          <izz>0.083333</izz>
        </inertia>
      </inertial>
      <collision name='base_collision'>
        <geometry>
          <box>
            <size>0.3 0.2 0.1</size> <!-- 长宽高:30cm x 20cm x 10cm -->
          </box>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>0.5</mu>
              <mu2>0.5</mu2>
            </ode>
          </friction>
        </surface>
      </collision>
      <visual name='base_visual'>
        <geometry>
          <box>
            <size>0.3 0.2 0.1</size>
          </box>
        </geometry>
        <material>
          <ambient>0.8 0.2 0.2 1</ambient>
          <diffuse>0.8 0.2 0.2 1</diffuse>
        </material>
      </visual>
    </link>

    <!-- 左轮 -->
    <link name='left_wheel'>
      <inertial>
        <mass>1.0</mass>
        <inertia>
          <ixx>0.05</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.05</iyy>
          <iyz>0</iyz>
          <izz>0.1</izz>
        </inertia>
      </inertial>
      <collision name='left_wheel_collision'>
        <geometry>
          <cylinder>
            <radius>0.1</radius>  <!-- 轮径20cm -->
            <length>0.05</length> <!-- 厚度5cm -->
          </cylinder>
        </geometry>
      </collision>
      <visual name='left_wheel_visual'>
        <geometry>
          <cylinder>
            <radius>0.1</radius>
            <length>0.05</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.3 0.3 0.3 1</diffuse>
        </material>
      </visual>
    </link>
    
    <joint name='left_wheel_joint' type='revolute'>
      <parent>base_link</parent>
      <child>left_wheel</child>
      <axis>
        <xyz>0 1 0</xyz> <!-- Y轴为旋转轴 -->
        <limit>
          <lower>-1e9</lower> <!-- 无限旋转 -->
          <upper>1e9</upper>
        </limit>
      </axis>
      <pose>-0.15 0 -0.05 0 0 0</pose> <!-- 左偏移15cm -->
    </joint>

    <!-- 右轮(结构与左轮对称) -->
    <link name='right_wheel'>
       <!-- 这个pose写的是右轮在整个model的零点的相对位置,如果加了relative_to=‘base_link’,那就是相对base_link的位置 -->
      <pose>1 0 0 0 0 0</pose>
      <inertial>
        <mass>1.0</mass>
        <inertia>
          <ixx>0.05</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.05</iyy>
          <iyz>0</iyz>
          <izz>0.1</izz>
        </inertia>
      </inertial>
      <collision name='right_wheel_collision'>
        <geometry>
          <cylinder>
            <radius>0.1</radius>  <!-- 轮径20cm -->
            <length>0.05</length> <!-- 厚度5cm -->
          </cylinder>
        </geometry>
      </collision>
      <visual name='right_wheel_visual'>
        <geometry>
          <cylinder>
            <radius>0.1</radius>
            <length>0.05</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.3 0.3 0.3 1</diffuse>
        </material>
      </visual>
    </link>
    
    <joint name='right_wheel_joint' type='revolute'>
      <parent>base_link</parent>
      <child>right_wheel</child>
      <axis>
        <xyz>0 1 0</xyz> <!-- Y轴为旋转轴 -->
        <limit>
          <lower>-1e9</lower> <!-- 无限旋转 -->
          <upper>1e9</upper>
        </limit>
      </axis>
      <pose>0.15 0 -0.05 0 0 0</pose> <!-- 左偏移15cm -->
    </joint>
    
  </model>
</sdf>

查看sdf文件是否有效,gazebo能检测到并且输出
在这里插入图片描述

link

link的一级pose

给了base_link和左轮右轮的pose,这是相对整个model的零点的位置,也就是左轮的0 0 0 0 0 0处,因为三个link都是写在了< model> < /model>中,所以 也是相对模型零点的位置。

    <link name='base_link'>
      <pose>0 0 1 0 0 0</pose>
    <link name='left_wheel'>
      <pose>0 0 0 0 0 0</pose>
    <link name='right_wheel'>
      <pose>1 0 0 0 0 0</pose>

在这里插入图片描述
整体都有位移,三个都改为0 0 1 0 0 0了
在这里插入图片描述
一般机器人都是写的有关节和链接,如果只用pose表示相对位置,只改了一个部件,那这个部件就会相对整个机器人发生位移,但是这个部件的子链接又没有位移就会扰乱了机器人模型,所以对一个完整的机器人,我会在pose里写一个relative_to=‘’

    <link name='left_wheel'>
      <pose relative_to='base_link'>0 -0.125 0 1.57 0 0</pose>
    <link name='right_wheel'>
      <pose relative_to='base_link'>0 0.125 0 1.57 0 0</pose>

在这里插入图片描述

材质

材质文件的保存形式,原来的sdf文件没定义纹理,可以自己创建material文件夹以及下面的scripts文件夹写纹理脚本文件,texture文件夹是纹理图片。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
两种写法

        <script>
                <uri>model://B2Z1/materials/scripts/gazebo.material</uri>
                <name>Gazebo/Grey</name>
        </script>
        <!-- 只要求显示的话可以自己写,也不用脚本 -->
        <material>
          <shader type='pixel'/>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>1 1 1 1</diffuse>
          <specular>1 1 1 1</specular>
          <emissive>0 0 0 1</emissive>
          <shininess>90</shininess>
        </material>

在这里插入图片描述

plugin

常见插件类型

  1. 传感器插件(如摄像头、激光雷达)
  2. 控制器插件(关节控制、机器人运动控制)
  3. 物理引擎插件(自定义物理行为)
  4. 系统插件(全局逻辑,如环境光照控制)

话题信息通信

为了与ros2进行通信的功能,写plugin引出gz topic话题,然后转换成ros2 topic话题
在这里插入图片描述
到官方文档中查看可以使用的接口
gz::sim::systems Namespace Reference
在这里插入图片描述
看到joint的控制器这里,可以看到给出了sdf中可写的内容
在这里插入图片描述

  <!-- JointController 插件 -->
  <plugin name="joint_controller" filename="gz-sim-joint-controller-system">
    <!-- 必须参数 -->
    <joint_name>your_joint</joint_name>  <!-- 要控制的关节名称 -->

    <!-- 可选参数 -->
    <use_force_commands>false</use_force_commands>  <!-- 是否使用力控制模式,默认 velocity 模式 -->
    <use_actuator_msg>false</use_actuator_msg>     <!-- 是否使用 actuator 消息,默认 false -->
    <actuator_number>0</actuator_number>           <!-- 执行器索引,默认 0 -->
    <topic>/your_topic</topic>                     <!-- 命令话题,默认自动生成 -->
    <sub_topic>your_subtopic</sub_topic>           <!-- 子话题,默认自动生成 -->
    <initial_velocity>0</initial_velocity>         <!-- 初始速度 -->

    <!-- 力控制模式下的 PID 参数(可选) -->
    <p_gain>1.0</p_gain>
    <i_gain>0.0</i_gain>
    <d_gain>0.0</d_gain>
    <i_max>1.0</i_max>
    <i_min>-1.0</i_min>
    <cmd_max>1000.0</cmd_max>
    <cmd_min>-1000.0</cmd_min>
    <cmd_offset>0.0</cmd_offset>
  </plugin>

找到插件文件的存放路径发现这里有插件,在plugin中的filename填的就是插件文件名的部分,去掉lib和.so的格式

filename=“gz-sim-joint-controller-system” → 实际加载的库文件为 libgz-sim-joint-controller-system.so

在这里插入图片描述
能实现外部与仿真模型进行消息控制,< topic>和< sub_topic>非常重要, 主要就是自定义一个话题名成为gz topic,这样就有了接口,然后使用ros_gz_bridge进行转换让ros2代码进行操控消息数据

查看一个plugin的库文件

之前使用gz_ros2_control插件报错
在这里插入图片描述

  • Gazebo 在加载系统插件时失败,原因是库文件中没有找到请求的插件,插件名称或库路径不匹配。
  • Requested plugin name: [gz_ros2_control]:用户或系统尝试加载名为 gz_ros2_control 的插件
  • Requested library name: [libgz_ros2_control-system.so],Resolved library path: [/usr/lib/x86_64-linux-gnu/gz-sim-8/plugins/libgz_ros2_control-system.so] :Gazebo 尝试从 libgz_ros2_control-system.so 库加载插件,且已找到该库文件,库文件存在且路径正确。
  • Detected Plugins:库文件中实际存在的插件是 gz_ros2_control::GazeboSimROS2ControlPlugin

以后就可以这样做

gz plugin --info --plugin /usr/lib/x86_64-linux-gnu/gz-sim-8/plugins/libgz-sim-imu-system.so

# 输出
Loading plugin library file [/usr/lib/x86_64-linux-gnu/gz-sim-8/plugins/libgz-sim-imu-system.so]
* Found 1 plugin in library file:
  - gz::sim::v8::systems::Imu
* Found 3 interfaces in library file:
  - gz::sim::v8::System
  - gz::sim::v8::ISystemPreUpdate
  - gz::sim::v8::ISystemPostUpdate
<plugin filename="libgz-sim-imu-system.so" name="gz::sim::systems::Imu">
<!-- name哪里写gz::sim::v8::systems::Imu更好  -->

键盘操作plugin

监听特定输入消息,当匹配到预设条件时,自动发布指定的输出消息,在仿真中实现 “事件触发响应” 的机制,16777234是一个按键的对应码,类似c++中按键有对应的ASCII码那样。通过话题/cmd_vel输出速度数据。

        <plugin filename="gz-sim-triggered-publisher-system"
                name="gz::sim::systems::TriggeredPublisher">
            <input type="gz.msgs.Int32" topic="/keyboard/keypress">
                <match field="data">16777234</match>
            </input>
            <output type="gz.msgs.Twist" topic="/cmd_vel">
                linear: {x: 0.0}, angular: {z: 0.5}
            </output>
        </plugin>

Sensor传感器

相机、imu、激光雷达是比较常用的

imu

官方文档,说是plugin项放在world里就行,sensor项放在link中
在这里插入图片描述

<link name='imu_link'>
      <pose relative_to='base_link'>0 0 0.125 0 0 0</pose>
      <inertial>
        <mass>0.1</mass>
        <inertia>
          <ixx>0.0001</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.0001</iyy>
          <iyz>0</iyz>
          <izz>0.0001</izz>
        </inertia>
      </inertial>
      <visual name='imu_visual'>
        <geometry>
          <box>
            <size>0.05 0.05 0.02</size>
          </box>
        </geometry>
        <material>
          <shader type='pixel'/>
          <script>
            <uri>model://joint/materials/scripts/gazebo.material</uri>
            <name>Gazebo/Blue</name>
          </script>          
        </material>
      </visual>
      <sensor name="imu_sensor" type="imu">
        <always_on>true</always_on>
        <update_rate>10</update_rate>
        <topic>imu</topic>
        <visualize>true</visualize>
      </sensor>
    </link>

    <!-- IMU传感器配置 -->
    <plugin filename="libgz-sim-imu-system.so" name="gz::sim::systems::Imu">
    </plugin>
# 查看话题有没有imu
gz topic -l	
# 查看imu 的具体信息
gz topic -e -t /imu

在这里插入图片描述
在这里插入图片描述

<think>嗯,用户想了解如何在Gazebo中进行多机器人仿真,需要教程、配置和示例。首先,我得回忆一下Gazebo的基本知识。Gazebo是一个机器人仿真工具,结合ROS使用的话,通常需要用到ROS Control和Gazebo插件。多机器人仿真的话,可能需要每个机器人有独立的命名空间,避免话题和参数的冲突。 记得之前看过引用[3]里提到安装ros-noetic-gazebo-ros-control,这可能和多机器人控制有关。然后引用[4]提到了一些开源项目,比如diffbot和agribot,这些可能提供多机器人的示例。需要确认这些项目是否有多个机器人的仿真案例。 配置步骤的话,首先每个机器人应该有自己的URDF模型,并且使用xacro来参数化,这样可以方便地生成多个实例。URDF里可能需要设置不同的关节和传感器,但关键是命名空间。每个机器人的控制器和话题应该放在各自的命名空间下,比如robot1和robot2。 然后,启动文件方面,可能需要使用ROS的group标签来为每个机器人分配命名空间,并加载相应的控制器。比如,使用<group ns="robot1">来加载第一个机器人的参数和节点。同时,Gazebo的world文件需要包含多个机器人模型,可能需要通过xacro宏来生成多个实例。 在示例部分,diffbot项目可能有双机器人的例子,或者用户需要自己创建。比如,在world文件中使用多个<include>标签,每个标签引用同一个模型但设置不同的命名空间和初始位置。这样可以在同一个Gazebo环境中生成多个机器人。 另外,传感器数据的话题也需要在各自的命名空间下,比如/robot1/camera/image_raw和/robot2/camera/image_raw,避免冲突。控制指令同样需要发布到对应的控制器话题,比如/robot1/mobile_base_controller/cmd_vel。 可能遇到的问题包括模型加载冲突、话题重复、控制器无法正确启动等。需要检查每个机器人的命名空间是否正确,以及启动文件中的参数是否正确分配。引用[2]提到的Gazebo Sim最新版本可能对多机器人支持更好,可能需要确认版本兼容性。 最后,测试部分可能需要同时控制多个机器人,比如分别发布速度指令,或者使用导航栈进行路径规划。引用[1]提到的ROS控制框架在这里很重要,确保每个机器人的关节控制器正确加载并与Gazebo交互。 总结步骤应该是:准备模型、配置命名空间、编写启动文件、生成世界文件、测试验证。同时,参考现有的开源项目可以加快开发,比如引用[4]中的diffbot和agribot项目可能提供有用的示例代码。</think>### Gazebo多机器人仿真配置指南 ### 一、环境准备 1. 安装ROS和Gazebo版本匹配环境(示例使用Noetic版本): ```bash sudo apt-get install ros-noetic-gazebo-ros-pkgs ros-noetic-gazebo-ros-control ``` 2. 建议安装最新版gz-sim仿真器(引用[2]项目) ### 二、核心配置步骤 1. **模型命名空间隔离** 每个机器人需要独立的命名空间,通过xacro宏定义实现: ```xml <xacro:macro name="create_robot" params="robot_namespace"> <group ns="${robot_namespace}"> <param name="tf_prefix" value="${robot_namespace}/"/> <!-- 机器人模型定义 --> </group> </xacro:macro> ``` 2. **控制器配置** 为每个机器人创建独立控制器配置: ```yaml # robot1_control.yaml robot1: joints: [robot1_wheel1, robot1_wheel2] type: diff_drive_controller/DiffDriveController # robot2_control.yaml robot2: joints: [robot2_wheel1, robot2_wheel2] type: diff_drive_controller/DiffDriveController ``` 3. **启动文件配置** 使用ROS launch文件加载多机器人: ```xml <launch> <group ns="robot1"> <include file="$(find robot_description)/launch/spawn_robot.launch"> <arg name="namespace" value="robot1"/> <arg name="x" value="0.0"/> </include> <node pkg="controller_manager" type="spawner" name="controller_spawner" args="robot1_joint_state_controller robot1_diff_drive_controller"/> </group> <group ns="robot2"> <!-- 相同结构,修改坐标和命名空间 --> </group> </launch> ``` ### 三、Gazebo世界文件 ```xml <sdf version="1.6"> <world name="multi_robot"> <!-- 地面等环境元素 --> <include> <uri>model://robot1</uri> <name>robot1</name> <pose>0 0 0 0 0 0</pose> </include> <include> <uri>model://robot2</uri> <name>robot2</name> <pose>3 0 0 0 0 0</pose> </include> </world> </sdf> ``` ### 四、开源示例参考 1. diffbot双机器人仿真(引用[4]项目2): ```bash git clone https://github.com/ros-mobile-robots/diffbot ``` 2. Gazebo官方多机器人示例: ```bash gz sim -v4 -r multi_robot.sdf ``` ### 五、调试要点 1. 使用`rostopic list`检查话题命名空间隔离 2. 验证TF树结构: ```bash rosrun tf view_frames ``` 3. 检查控制器状态: ```bash rosservice call /robot1/controller_manager/list_controllers ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值