Cómo convertir un archivo de modelo de robot xacro a un archivo urdf escribiendo un archivo de inicio para iniciar la simulación de gazebo y mostrar el modelo en rviz2

El archivo urdf es muy sencillo: el </link> </joint> de cada parte debe escribirse una vez y los datos de cada parte deben calcularse por sí mismo. Es muy problemático, pero es muy simple de usar. Los archivos de modelo escritos por xacro pueden definir muchas constantes de antemano. Para robots de diferentes tamaños, simplemente cambie las constantes y el modelo del robot se puede regenerar. El código se puede reutilizar. Es mucho más sencillo de escribir, pero escribir el archivo de inicio es más problemático.

Archivo de modelo de coche escrito en urdf:

<!-- base.urdf -->
<?xml version="1.0" ?>
<robot name="jtbot">
  <!-- 机器人底盘 -->
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.46 0.46 0.11"/>
      </geometry>
      <material name="Cyan">
        <color rgba="0 1.0 1.0 1.0"/>
      </material>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <geometry>
        <box size="0.46 0.46 0.11"/>
      </geometry>
    </collision>
    <inertial>
      <origin rpy="1.5707963267948966 0 1.5707963267948966" xyz="0 0 0"/>
      <mass value="15"/>
      <inertia ixx="0.279625" ixy="0.0" ixz="0.0" iyy="0.529" iyz="0.0" izz="0.279625"/>
    </inertial>
  </link>
  <!-- 机器人 Footprint -->
  <link name="base_footprint"/>
  <!-- 底盘关节 -->
  <joint name="base_joint" type="fixed">
    <parent link="base_link"/>
    <child link="base_footprint"/>
    <origin rpy="0 0 0" xyz="0.0 0.0 -0.1325"/>
  </joint>
  <link name="left_wheel_link">
    <visual>
      <origin rpy="1.5707963267948966 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.06" radius="0.0775"/>
      </geometry>
      <material name="Gray">
        <color rgba="0.5 0.5 0.5 1.0"/>
      </material>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <origin rpy="1.5707963267948966 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.06" radius="0.0775"/>
      </geometry>
    </collision>
    <inertial>
      <origin rpy="1.5707963267948966 0 0" xyz="0 0 0"/>
      <mass value="0.8"/>
      <inertia ixx="0.0014412499999999998" ixy="0" ixz="0" iyy="0.0014412499999999998" iyz="0" izz="0.0024025"/>
    </inertial>
  </link>
  <!-- 轮子关节 -->
  <joint name="left_wheel_joint" type="continuous">
    <parent link="base_link"/>
    <child link="left_wheel_link"/>
    <origin rpy="0 0 0" xyz="0.15 0.27 -0.055"/>
    <axis xyz="0 1 0"/>
  </joint>
  <link name="right_wheel_link">
    <visual>
      <origin rpy="1.5707963267948966 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.06" radius="0.0775"/>
      </geometry>
      <material name="Gray">
        <color rgba="0.5 0.5 0.5 1.0"/>
      </material>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <origin rpy="1.5707963267948966 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.06" radius="0.0775"/>
      </geometry>
    </collision>
    <inertial>
      <origin rpy="1.5707963267948966 0 0" xyz="0 0 0"/>
      <mass value="0.8"/>
      <inertia ixx="0.0014412499999999998" ixy="0" ixz="0" iyy="0.0014412499999999998" iyz="0" izz="0.0024025"/>
    </inertial>
  </link>
  <!-- 轮子关节 -->
  <joint name="right_wheel_joint" type="continuous">
    <parent link="base_link"/>
    <child link="right_wheel_link"/>
    <origin rpy="0 0 0" xyz="0.15 -0.27 -0.055"/>
    <axis xyz="0 1 0"/>
  </joint>
  <!-- 支撑轮 -->
  <link name="caster_link">
    <visual>
      <geometry>
        <sphere radius="0.03875"/>
      </geometry>
      <material name="Cyan">
        <color rgba="0 1.0 1.0 1.0"/>
      </material>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <sphere radius="0.03875"/>
      </geometry>
    </collision>
    <inertial>
      <mass value="0.5"/>
      <inertia ixx="0.0003003125" ixy="0.0" ixz="0.0" iyy="0.0003003125" iyz="0.0" izz="0.0003003125"/>
    </inertial>
  </link>
  <!-- 支撑轮gazebo颜色 -->
  <gazebo reference="caster_link">
    <material>Gazebo/Black</material>
  </gazebo>
  <!-- 支撑轮gazebo摩擦力 -->
  <gazebo reference="caster_link">
    <mu1 value="0.0"/>
    <mu2 value="0.0"/>
    <kp value="1000000.0"/>
    <kd value="10.0"/>
  </gazebo>
  <!-- 支撑轮关节 -->
  <joint name="caster_joint" type="fixed">
    <parent link="base_link"/>
    <child link="caster_link"/>
    <origin rpy="0 0 0" xyz="-0.205 0.0 -0.09375"/>
  </joint>
  <!-- imu -->
  <link name="imu_link">
    <visual>
      <geometry>
        <box size="0.06 0.03 0.03"/>
      </geometry>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <geometry>
        <box size="0.06 0.03 0.03"/>
      </geometry>
    </collision>
    <inertial>
      <origin rpy="1.5707963267948966 0 1.5707963267948966" xyz="0 0 0"/>
      <mass value="0.1"/>
      <inertia ixx="0.0001666666666666667" ixy="0.0" ixz="0.0" iyy="0.0001666666666666667" iyz="0.0" izz="0.0001666666666666667"/>
    </inertial>
  </link>
  <!-- imu关节 -->
  <joint name="imu_joint" type="fixed">
    <parent link="base_link"/>
    <child link="imu_link"/>
    <origin xyz="-0.05 0 -0.055"/>
  </joint>
  <!-- imu仿真插件 -->
  <gazebo reference="imu_link">
    <sensor name="imu_sensor" type="imu">
      <plugin filename="libgazebo_ros_imu_sensor.so" name="imu_plugin">
        <ros>
          <!-- 命名空间 -->
          <!-- <namespace>/demo</namespace> -->
          <remapping>~/out:=imu</remapping>
        </ros>
        <!-- 初始方位_参考 -->
        <initial_orientation_as_reference>false</initial_orientation_as_reference>
      </plugin>
      <always_on>true</always_on>
      <!-- 更新频率 -->
      <update_rate>100</update_rate>
      <visualize>true</visualize>
      <imu>
        <!-- 角速度 -->
        <angular_velocity>
          <x>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>2e-4</stddev>
              <bias_mean>0.0000075</bias_mean>
              <bias_stddev>0.0000008</bias_stddev>
            </noise>
          </x>
          <y>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>2e-4</stddev>
              <bias_mean>0.0000075</bias_mean>
              <bias_stddev>0.0000008</bias_stddev>
            </noise>
          </y>
          <z>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>2e-4</stddev>
              <bias_mean>0.0000075</bias_mean>
              <bias_stddev>0.0000008</bias_stddev>
            </noise>
          </z>
        </angular_velocity>
        <!-- 线性加速度 -->
        <linear_acceleration>
          <x>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>1.7e-2</stddev>
              <bias_mean>0.1</bias_mean>
              <bias_stddev>0.001</bias_stddev>
            </noise>
          </x>
          <y>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>1.7e-2</stddev>
              <bias_mean>0.1</bias_mean>
              <bias_stddev>0.001</bias_stddev>
            </noise>
          </y>
          <z>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>1.7e-2</stddev>
              <bias_mean>0.1</bias_mean>
              <bias_stddev>0.001</bias_stddev>
            </noise>
          </z>
        </linear_acceleration>
      </imu>
    </sensor>
  </gazebo>
  <!-- 差速驱动仿真插件 -->
  <gazebo>
    <plugin filename="libgazebo_ros_diff_drive.so" name="diff_drive">
      <ros>
        <!-- 命名空间 -->
        <!-- <namespace>/demo</namespace> -->
      </ros>
      <!-- 左右轮子 -->
      <left_joint>left_wheel_joint</left_joint>
      <right_joint>right_wheel_joint</right_joint>
      <!-- 轮距 轮子直径 -->
      <wheel_separation>0.52</wheel_separation>
      <!-- <wheel_separation>0.52</wheel_separation> -->
      <wheel_diameter>0.155</wheel_diameter>
      <!-- <wheel_diameter>0.155</wheel_diameter> -->
      <!-- 最大扭矩 最大加速度 -->
      <max_wheel_torque>20</max_wheel_torque>
      <max_wheel_acceleration>1.0</max_wheel_acceleration>
      <!-- 输出 -->
      <!-- 是否发布里程计 -->
      <publish_odom>true</publish_odom>
      <!-- 是否发布里程计的tf开关 -->
      <publish_odom_tf>true</publish_odom_tf>
      <!-- 是否发布轮子的tf数据开关 -->
      <publish_wheel_tf>true</publish_wheel_tf>
      <!-- 里程计的framed ID,最终体现在话题和TF上 -->
      <odometry_frame>odom</odometry_frame>
      <!-- 机器人的基础frame的ID -->
      <robot_base_frame>base_link</robot_base_frame>
    </plugin>
  </gazebo>
  <!-- 雷达 -->
  <link name="laser">
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.04"/>
      </geometry>
    </visual>
    <!-- 惯性属性 -->
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="0.125"/>
      <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001"/>
    </inertial>
    <!-- 碰撞区域 -->
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.04"/>
      </geometry>
    </collision>
  </link>
  <!-- 雷达关节 -->
  <joint name="laser_joint" type="fixed">
    <parent link="base_link"/>
    <child link="laser"/>
    <origin rpy="0 0 0" xyz="0.16 0 0.078"/>
  </joint>
  <gazebo reference="laser">
    <sensor name="laser" type="ray">
      <always_on>true</always_on>
      <visualize>false</visualize>
      <update_rate>5</update_rate>
      <ray>
        <scan>
          <horizontal>
            <samples>360</samples>
            <resolution>1.000000</resolution>
            <min_angle>0.000000</min_angle>
            <max_angle>6.280000</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.120000</min>
          <max>3.5</max>
          <resolution>0.015000</resolution>
        </range>
        <noise>
          <type>gaussian</type>
          <mean>0.0</mean>
          <stddev>0.01</stddev>
        </noise>
      </ray>
      <plugin filename="libgazebo_ros_ray_sensor.so" name="scan">
        <ros>
          <remapping>~/out:=scan</remapping>
        </ros>
        <output_type>sensor_msgs/LaserScan</output_type>
        <frame_name>laser</frame_name>
      </plugin>
    </sensor>
  </gazebo>
  <!-- 相机 -->
  <link name="camera_link">
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <box size="0.015 0.130 0.022"/>
      </geometry>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <box size="0.015 0.130 0.022"/>
      </geometry>
    </collision>
    <!-- 惯性属性 -->
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="0.035"/>
      <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001"/>
    </inertial>
  </link>
  <!-- 相机关节 -->
  <joint name="camera_joint" type="fixed">
    <parent link="base_link"/>
    <child link="camera_link"/>
    <origin rpy="0 0 0" xyz="0.16 0 0.11"/>
  </joint>
  <!-- 深度相机 -->
  <link name="camera_depth_frame"/>
  <joint name="camera_depth_joint" type="fixed">
    <origin rpy="0 0 0" xyz="0 0 0"/>
    <parent link="camera_link"/>
    <child link="camera_depth_frame"/>
  </joint>
  <!-- 相机仿真 -->
  <gazebo reference="camera_depth_link">
    <sensor name="depth_camera" type="depth">
      <visualize>true</visualize>
      <update_rate>30.0</update_rate>
      <camera name="camera">
        <horizontal_fov>1.047198</horizontal_fov>
        <image>
          <width>640</width>
          <height>480</height>
          <format>R8G8B8</format>
        </image>
        <clip>
          <near>0.05</near>
          <far>3</far>
        </clip>
      </camera>
      <plugin filename="libgazebo_ros_camera.so" name="depth_camera_controller">
        <baseline>0.2</baseline>
        <alwaysOn>true</alwaysOn>
        <updateRate>0.0</updateRate>
        <frame_name>camera_depth_frame</frame_name>
        <pointCloudCutoff>0.5</pointCloudCutoff>
        <pointCloudCutoffMax>3.0</pointCloudCutoffMax>
        <distortionK1>0</distortionK1>
        <distortionK2>0</distortionK2>
        <distortionK3>0</distortionK3>
        <distortionT1>0</distortionT1>
        <distortionT2>0</distortionT2>
        <CxPrime>0</CxPrime>
        <Cx>0</Cx>
        <Cy>0</Cy>
        <focalLength>0</focalLength>
        <hackBaseline>0</hackBaseline>
      </plugin>
    </sensor>
  </gazebo>
</robot>

Archivo de modelo de coche escrito por xacro:

<!-- base.urdf.xacro -->
<?xml version="1.0"?>
<robot name="jtbot"
  xmlns:xacro="http://ros.org/wiki/xacro">

  <!-- 定义机器人常量 -->
  <!-- 底盘 长 宽 高 -->
  <xacro:property name="base_width" value="0.46"/>
  <xacro:property name="base_length" value="0.46"/>
  <xacro:property name="base_height" value="0.11"/>
  <!-- 轮子半径 -->
  <xacro:property name="wheel_radius" value="0.0775"/>
  <!-- 轮子宽度 -->
  <xacro:property name="wheel_width" value="0.06"/>
  <!-- 轮子和底盘的间距 -->
  <xacro:property name="wheel_ygap" value="0.01"/>
  <!-- 轮子z轴偏移量 -->
  <xacro:property name="wheel_zoff" value="0.055"/>
  <!-- 轮子x轴偏移量 -->
  <xacro:property name="wheel_xoff" value="0.15"/>
  <!-- 支撑轮x轴偏移量 -->
  <xacro:property name="caster_xoff" value="0.205"/>

  <!-- 定义长方形惯性属性宏  -->
  <xacro:macro name="box_inertia" params="m w h d">
    <inertial>
      <origin xyz="0 0 0" rpy="${pi/2} 0 ${pi/2}"/>
      <mass value="${m}"/>
      <inertia ixx="${(m/12) * (h*h + d*d)}" ixy="0.0" ixz="0.0" iyy="${(m/12) * (w*w + d*d)}" iyz="0.0" izz="${(m/12) * (w*w + h*h)}"/>
    </inertial>
  </xacro:macro>
  <!-- 定义圆柱惯性属性宏  -->
  <xacro:macro name="cylinder_inertia" params="m r h">
    <inertial>
      <origin xyz="0 0 0" rpy="${pi/2} 0 0" />
      <mass value="${m}"/>
      <inertia ixx="${(m/12) * (3*r*r + h*h)}" ixy = "0" ixz = "0" iyy="${(m/12) * (3*r*r + h*h)}" iyz = "0" izz="${(m/2) * (r*r)}"/>
    </inertial>
  </xacro:macro>
  <!-- 定义球体惯性属性宏  -->
  <xacro:macro name="sphere_inertia" params="m r">
    <inertial>
      <mass value="${m}"/>
      <inertia ixx="${(2/5) * m * (r*r)}" ixy="0.0" ixz="0.0" iyy="${(2/5) * m * (r*r)}" iyz="0.0" izz="${(2/5) * m * (r*r)}"/>
    </inertial>
  </xacro:macro>

  <!-- 机器人底盘 -->
  <link name="base_link">
    <visual>
      <geometry>
        <box size="${base_length} ${base_width} ${base_height}"/>
      </geometry>
      <material name="Cyan">
        <color rgba="0 1.0 1.0 1.0"/>
      </material>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <geometry>
        <box size="${base_length} ${base_width} ${base_height}"/>
      </geometry>
    </collision>
    <!-- 惯性特性 -->
    <xacro:box_inertia m="15" w="${base_width}" d="${base_length}" h="${base_height}"/>
  </link>

  <!-- 机器人 Footprint -->
  <link name="base_footprint"/>
  <!-- 底盘关节 -->
  <joint name="base_joint" type="fixed">
    <parent link="base_link"/>
    <child link="base_footprint"/>
    <origin xyz="0.0 0.0 ${-(wheel_radius+wheel_zoff)}" rpy="0 0 0"/>
  </joint>

  <!-- 创建轮子宏函数 -->
  <xacro:macro name="wheel" params="prefix x_reflect y_reflect">
    <link name="${prefix}_link">
      <visual>
        <origin xyz="0 0 0" rpy="${pi/2} 0 0"/>
        <geometry>
          <cylinder radius="${wheel_radius}" length="${wheel_width}"/>
        </geometry>
        <material name="Gray">
          <color rgba="0.5 0.5 0.5 1.0"/>
        </material>
      </visual>
      <!-- 碰撞区域 -->
      <collision>
        <origin xyz="0 0 0" rpy="${pi/2} 0 0"/>
        <geometry>
          <cylinder radius="${wheel_radius}" length="${wheel_width}"/>
        </geometry>
      </collision>
      <!-- 惯性属性 -->
      <xacro:cylinder_inertia m="0.8" r="${wheel_radius}" h="${wheel_width}"/>
    </link>
    <!-- 轮子关节 -->
    <joint name="${prefix}_joint" type="continuous">
      <parent link="base_link"/>
      <child link="${prefix}_link"/>
      <origin xyz="${x_reflect*wheel_xoff} ${y_reflect*(base_width/2+wheel_width/2+wheel_ygap)} ${-wheel_zoff}" rpy="0 0 0"/>
      <axis xyz="0 1 0"/>
    </joint>
  </xacro:macro>
  <!-- 根据上面的宏函数实例化左右轮 -->
  <xacro:wheel prefix="left_wheel" x_reflect="1" y_reflect="1" />
  <xacro:wheel prefix="right_wheel" x_reflect="1" y_reflect="-1" />

  <!-- 支撑轮 -->
  <link name="caster_link">
    <visual>
      <geometry>
        <sphere radius="${(wheel_radius/2)}"/>
      </geometry>
      <material name="Cyan">
        <color rgba="0 1.0 1.0 1.0"/>
      </material>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <sphere radius="${(wheel_radius/2)}"/>
      </geometry>
    </collision>
    <!-- 惯性属性 -->
    <xacro:sphere_inertia m="0.5" r="${(wheel_radius/2)}"/>
  </link>
  <!-- 支撑轮gazebo颜色 -->
  <gazebo reference="caster_link">
    <material>Gazebo/Black</material>
  </gazebo>
  <!-- 支撑轮gazebo摩擦力 -->
  <gazebo reference="caster_link">
    <mu1 value="0.0"/>
    <mu2 value="0.0"/>
    <kp value="1000000.0" />
    <kd value="10.0" />
  </gazebo>
  <!-- 支撑轮关节 -->
  <joint name="caster_joint" type="fixed">
    <parent link="base_link"/>
    <child link="caster_link"/>
    <origin xyz="${-caster_xoff} 0.0 ${-(base_height+wheel_radius)/2}" rpy="0 0 0"/>
  </joint>
  <!-- imu -->
  <link name="imu_link">
    <visual>
      <geometry>
        <box size="0.06 0.03 0.03"/>
      </geometry>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <geometry>
        <box size="0.06 0.03 0.03"/>
      </geometry>
    </collision>
    <!-- 惯性属性 -->
    <xacro:box_inertia m="0.1" w="0.1" d="0.1" h="0.1"/>
  </link>
  <!-- imu关节 -->
  <joint name="imu_joint" type="fixed">
    <parent link="base_link"/>
    <child link="imu_link"/>
    <origin xyz="-0.05 0 -0.055"/>
  </joint>
  <!-- imu仿真插件 -->
  <gazebo reference="imu_link">
    <sensor name="imu_sensor" type="imu">
      <plugin filename="libgazebo_ros_imu_sensor.so" name="imu_plugin">
        <ros>
          <!-- 命名空间 -->
          <!-- <namespace>/demo</namespace> -->
          <remapping>~/out:=imu</remapping>
        </ros>
        <!-- 初始方位_参考 -->
        <initial_orientation_as_reference>true</initial_orientation_as_reference>
      </plugin>
      <always_on>true</always_on>
      <!-- 更新频率 -->
      <update_rate>100</update_rate>
      <visualize>true</visualize>
      <imu>
        <!-- 角速度 -->
        <angular_velocity>
          <x>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>2e-4</stddev>
              <bias_mean>0.0000075</bias_mean>
              <bias_stddev>0.0000008</bias_stddev>
            </noise>
          </x>
          <y>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>2e-4</stddev>
              <bias_mean>0.0000075</bias_mean>
              <bias_stddev>0.0000008</bias_stddev>
            </noise>
          </y>
          <z>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>2e-4</stddev>
              <bias_mean>0.0000075</bias_mean>
              <bias_stddev>0.0000008</bias_stddev>
            </noise>
          </z>
        </angular_velocity>
        <!-- 线性加速度 -->
        <linear_acceleration>
          <x>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>1.7e-2</stddev>
              <bias_mean>0.1</bias_mean>
              <bias_stddev>0.001</bias_stddev>
            </noise>
          </x>
          <y>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>1.7e-2</stddev>
              <bias_mean>0.1</bias_mean>
              <bias_stddev>0.001</bias_stddev>
            </noise>
          </y>
          <z>
            <noise type="gaussian">
              <mean>0.0</mean>
              <stddev>1.7e-2</stddev>
              <bias_mean>0.1</bias_mean>
              <bias_stddev>0.001</bias_stddev>
            </noise>
          </z>
        </linear_acceleration>
      </imu>
    </sensor>
  </gazebo>
  <!-- 差速驱动仿真插件 -->
  <gazebo>
    <plugin name='diff_drive' filename='libgazebo_ros_diff_drive.so'>
      <ros>
        <!-- 命名空间 -->
        <!-- <namespace>/demo</namespace> -->
      </ros>

      <!-- 左右轮子 -->
      <left_joint>left_wheel_joint</left_joint>
      <right_joint>right_wheel_joint</right_joint>

      <!-- 轮距 轮子直径 -->
      <wheel_separation>${base_width+wheel_width}</wheel_separation>
      <!-- <wheel_separation>0.52</wheel_separation> -->
      <wheel_diameter>${wheel_radius*2}</wheel_diameter>
      <!-- <wheel_diameter>0.155</wheel_diameter> -->

      <!-- 最大扭矩 最大加速度 -->
      <max_wheel_torque>20</max_wheel_torque>
      <max_wheel_acceleration>1.0</max_wheel_acceleration>

      <!-- 输出 -->
      <!-- 是否发布里程计 -->
      <publish_odom>true</publish_odom>
      <!-- 是否发布里程计的tf开关 -->
      <publish_odom_tf>true</publish_odom_tf>
      <!-- 是否发布轮子的tf数据开关 -->
      <publish_wheel_tf>true</publish_wheel_tf>

      <!-- 里程计的framed ID,最终体现在话题和TF上 -->
      <odometry_frame>odom</odometry_frame>
      <!-- 机器人的基础frame的ID -->
      <robot_base_frame>base_link</robot_base_frame>
    </plugin>
  </gazebo>
  <!-- 雷达 -->
  <link name="laser">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="0.04" length="0.04"/>
      </geometry>
    </visual>
    <!-- 惯性属性 -->
    <inertial>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <mass value="0.125"/>
      <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
    </inertial>
    <!-- 碰撞区域 -->
    <collision>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="0.04" length="0.04"/>
      </geometry>
    </collision>
  </link>
  <!-- 雷达关节 -->
  <joint name="laser_joint" type="fixed">
    <parent link="base_link"/>
    <child link="laser"/>
    <origin xyz="0.16 0 0.078" rpy="0 0 0"/>
  </joint>

  <gazebo reference="laser">
    <sensor name="laser" type="ray">
      <always_on>true</always_on>
      <visualize>false</visualize>
      <update_rate>5</update_rate>
      <ray>
        <scan>
          <horizontal>
            <samples>360</samples>
            <resolution>1.000000</resolution>
            <min_angle>0.000000</min_angle>
            <max_angle>6.280000</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.120000</min>
          <max>3.5</max>
          <resolution>0.015000</resolution>
        </range>
        <noise>
          <type>gaussian</type>
          <mean>0.0</mean>
          <stddev>0.01</stddev>
        </noise>
      </ray>
      <plugin name="scan" filename="libgazebo_ros_ray_sensor.so">
        <ros>
          <remapping>~/out:=scan</remapping>
        </ros>
        <output_type>sensor_msgs/LaserScan</output_type>
        <frame_name>laser</frame_name>
      </plugin>
    </sensor>
  </gazebo>
  <!-- 相机 -->
  <link name="camera_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <box size="0.015 0.130 0.022"/>
      </geometry>
    </visual>
    <!-- 碰撞区域 -->
    <collision>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <box size="0.015 0.130 0.022"/>
      </geometry>
    </collision>
    <!-- 惯性属性 -->
    <inertial>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <mass value="0.035"/>
      <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
    </inertial>
  </link>
  <!-- 相机关节 -->
  <joint name="camera_joint" type="fixed">
    <parent link="base_link"/>
    <child link="camera_link"/>
    <origin xyz="0.16 0 0.11" rpy="0 0 0"/>
  </joint>
  <!-- 深度相机 -->
  <link name="camera_depth_frame"/>

  <joint name="camera_depth_joint" type="fixed">
    <origin xyz="0 0 0" rpy="0 0 0"/>
    <parent link="camera_link"/>
    <child link="camera_depth_frame"/>
  </joint>
  <!-- 相机仿真 -->
  <gazebo reference="camera_depth_link">
    <sensor name="depth_camera" type="depth">
      <visualize>true</visualize>
      <update_rate>30.0</update_rate>
      <camera name="camera">
        <horizontal_fov>1.047198</horizontal_fov>
        <image>
          <width>640</width>
          <height>480</height>
          <format>R8G8B8</format>
        </image>
        <clip>
          <near>0.05</near>
          <far>3</far>
        </clip>
      </camera>
      <plugin name="depth_camera_controller" filename="libgazebo_ros_camera.so">
        <baseline>0.2</baseline>
        <alwaysOn>true</alwaysOn>
        <updateRate>0.0</updateRate>
        <frame_name>camera_depth_frame</frame_name>
        <pointCloudCutoff>0.5</pointCloudCutoff>
        <pointCloudCutoffMax>3.0</pointCloudCutoffMax>
        <distortionK1>0</distortionK1>
        <distortionK2>0</distortionK2>
        <distortionK3>0</distortionK3>
        <distortionT1>0</distortionT1>
        <distortionT2>0</distortionT2>
        <CxPrime>0</CxPrime>
        <Cx>0</Cx>
        <Cy>0</Cy>
        <focalLength>0</focalLength>
        <hackBaseline>0</hackBaseline>
      </plugin>
    </sensor>
  </gazebo>

</robot>

El archivo de modelo xacro debe convertirse en un archivo de modelo urdf antes de poder usarse.

Método 1 Convertir por adelantado:

Abra la terminal en la carpeta actual e ingrese: base.urdf.xacro > base.urdf para generar un archivo urdf puro.

Método 2: transferir automáticamente al ejecutar el archivo de inicio, debe agregar el paso de análisis xacro

En el archivo package.xml, agregue: <exec_depend>xacro</exec_depend> antes de <test_depend>

Iniciar escritura de archivos:

# 此launch文件是机器人仿真程序,包含 gazebo启动,机器人仿真生成,机器人模型状态发布
import os
from launch import LaunchDescription
from launch.actions import ExecuteProcess
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
from launch.substitutions import LaunchConfiguration
import xacro

def generate_launch_description():
    robot_name_in_model = 'jtbot'         #机器人模型名字
    package_name = 'jtbot_description'    #模型包名

    ld = LaunchDescription()
    use_sim_time = LaunchConfiguration('use_sim_time', default='true')
    pkg_share = FindPackageShare(package=package_name).find(package_name) 
    gazebo_world_path = os.path.join(pkg_share, 'world/jt.world')        #世界仿真文件路径
    default_rviz_config_path = os.path.join(pkg_share, 'rviz/mrviz2.rviz')  #rviz配置文件路径
    urdf_xacro_file = os.path.join(pkg_share, 'urdf/jtbot_base.urdf.xacro') #xacro模型文件路径
    #解析xacro模型文件
    doc = xacro.parse(open(urdf_xacro_file))
    xacro.process_doc(doc)
    params = {'robot_description': doc.toxml()}

    # 开启ros Gazebo server
    start_gazebo_cmd = ExecuteProcess(
        cmd=['gazebo',
        '--verbose', 
        gazebo_world_path,
        '-s', 'libgazebo_ros_init.so',   
        '-s', 'libgazebo_ros_factory.so', 
         
         ],
        output='screen')

     # Start Robot State publisher
    start_robot_state_publisher_cmd = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        output='screen',
        
        parameters=[params,{'use_sim_time': use_sim_time}]
    )    

    # gazebo内生成机器人
    spawn_entity_cmd = Node(
        package='gazebo_ros', 
        executable='spawn_entity.py',
        arguments=['-entity', robot_name_in_model,  '-topic', 'robot_description'], 
        output='screen'
      
        )
	
   

    # Launch RViz
    start_rviz_cmd = Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen',
        arguments=['-d', default_rviz_config_path]
        )

    ld.add_action(start_gazebo_cmd)
    ld.add_action(spawn_entity_cmd)
    ld.add_action(start_robot_state_publisher_cmd)
    ld.add_action(start_rviz_cmd)


    return ld

Supongo que te gusta

Origin blog.csdn.net/m0_73694897/article/details/132265373
Recomendado
Clasificación