重头开始看NAV2文档(一)——URDF

本文参考设置URDF和英文原版setting Up The URDF(属于是自己的屁话+cv文档原话)

本文具体代码可在sam_bot_description下的sam_bot_description功能包中找到。

URDF除了负责机器人的建模,也负责传感器到机器人底盘base_link的TF

1、编写代码

进入工作空间/src路径,创建功能包sam_bot_description

ros2 pkg create sam_bot_description

sam_bot_description/src下新建文件夹description,并在其中创建文件sam_bot_description.urdf,写并在其中入下面的代码:(不想看可以直接跳到后面看完整代码)

<?xml version="1.0"?>
<robot name="sam_bot" xmlns:xacro="http://ros.org/wiki/xacro">


</robot>

定义一些常量,将其放在<robot>  </robot>中间:

  <!-- Define robot constants -->
  <xacro:property name="base_width" value="0.31"/>  <!-- 底盘宽 -->
  <xacro:property name="base_length" value="0.42"/> <!-- 底盘长 -->
  <xacro:property name="base_height" value="0.18"/> <!-- 底盘高 -->

  <xacro:property name="wheel_radius" value="0.10"/><!-- 轮子半径 -->
  <xacro:property name="wheel_width" value="0.04"/> <!-- 轮子宽度 -->
  <xacro:property name="wheel_ygap" value="0.025"/> <!-- 轮子和底盘y轴的间距 -->
  <xacro:property name="wheel_zoff" value="0.05"/>  <!-- 定位后轮到z轴 -->
  <xacro:property name="wheel_xoff" value="0.12"/>  <!-- 定位后轮到x轴 -->

  <xacro:property name="caster_xoff" value="0.14"/> <!-- 定位前轮到x轴 -->

定义惯性属性

<!-- Define intertial property macros  -->
  <xacro:macro name="box_inertia" params="m w h d">    <!-- 定义矩形盒子的惯性 -->
    <inertial>                                         <!-- m惯性 w宽度 h高度 d深度 -->
      <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>

 定义底盘base_link。放在<robot>  </robot>中间:

  <!-- Robot Base -->
  <link name="base_link">
    <visual>    <!-- 在visual中的参数只有视觉效果,没有物理属性 -->
      <geometry>
        <box size="${base_length} ${base_width} ${base_height}"/>
      </geometry>
      <material name="Cyan">
        <color rgba="0 1.0 1.0 1.0"/>    <!-- 颜色,a表示透明度 -->
      </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>

 连接

  <!-- Robot Footprint -->
  <link name="base_footprint"/>

  <joint name="base_joint" type="fixed"> <!-- fixed将base_joint固定在base_link上 -->
    <parent link="base_link"/>        <!-- 父 -->
    <child link="base_footprint"/>    <!-- 子。子固定在父上面-->
    <origin xyz="0.0 0.0 ${-(wheel_radius+wheel_zoff)}" rpy="0 0 0"/>  <!-- 父与子之间的xyz位移和旋转,旋转用的是弧度制 -->
  </joint>

添加两个驱动轮:

  <!-- Wheels -->
  <xacro:macro name="wheel" params="prefix x_reflect y_reflect">  <!-- prefix为关节名称添加前缀     x、y_prefix在x、y轴翻转轮子位置 -->
    <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.5" r="${wheel_radius}" h="${wheel_width}"/>    <!-- 定义惯性 -->

    </link>

    <joint name="${prefix}_joint" type="continuous">  <!-- continuous允许不限角度的旋转 -->
      <parent link="base_link"/>
      <child link="${prefix}_link"/>
      <origin xyz="${x_reflect*wheel_xoff} ${y_reflect*(base_width/2+wheel_ygap)} ${-wheel_zoff}" rpy="0 0 0"/>   <!-- x、y_reflect控制轮子沿x、y轴进行翻转 -->
      <axis xyz="0 1 0"/>    <!-- 关节围绕y轴旋转 -->
    </joint>
  </xacro:macro>

  <xacro:wheel prefix="drivewhl_l" x_reflect="-1" y_reflect="1" />   <!-- 实例化 -->
  <xacro:wheel prefix="drivewhl_r" x_reflect="-1" y_reflect="-1" />

在前部添加万向轮:

  <!-- Caster Wheel -->
  <link name="front_caster">
    <visual>
      <geometry>
        <sphere radius="${(wheel_radius+wheel_zoff-(base_height/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+wheel_zoff-(base_height/2))}"/>
      </geometry>
    </collision>

    <xacro:sphere_inertia m="0.5" r="${(wheel_radius+wheel_zoff-(base_height/2))}"/>

  </link>

  <joint name="caster_joint" type="fixed">
    <parent link="base_link"/>
    <child link="front_caster"/>
    <origin xyz="${caster_xoff} 0.0 ${-(base_height/2)}" rpy="0 0 0"/>
  </joint>

完整URDF代码:

<?xml version="1.0"?>
<robot name="sam_bot" xmlns:xacro="http://ros.org/wiki/xacro">

  <!-- Define robot constants -->
  <xacro:property name="base_width" value="0.31"/>  <!-- 底盘宽 -->
  <xacro:property name="base_length" value="0.42"/> <!-- 底盘长 -->
  <xacro:property name="base_height" value="0.18"/> <!-- 底盘高 -->

  <xacro:property name="wheel_radius" value="0.10"/><!-- 轮子半径 -->
  <xacro:property name="wheel_width" value="0.04"/> <!-- 轮子宽度 -->
  <xacro:property name="wheel_ygap" value="0.025"/> <!-- 轮子和底盘y轴的间距 -->
  <xacro:property name="wheel_zoff" value="0.05"/>  <!-- 定位后轮到z轴 -->
  <xacro:property name="wheel_xoff" value="0.12"/>  <!-- 定位后轮到x轴 -->

  <xacro:property name="caster_xoff" value="0.14"/> <!-- 定位前轮到x轴 -->

  <!-- Define intertial property macros  -->
  <xacro:macro name="box_inertia" params="m w h d">    <!-- 定义矩形盒子的惯性 -->
    <inertial>                                         <!-- m惯性 w宽度 h高度 d深度 -->
      <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>

  <!-- Robot Base -->
  <link name="base_link">
    <visual>    <!-- 在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>

  <xacro:box_inertia m="15" w="${base_width}" d="${base_length}" h="${base_height}"/>

  <!-- Robot Footprint -->
  <link name="base_footprint"/>
  <joint name="base_joint" type="fixed"> <!-- fixed将base_joint固定在base_link上 -->
    <parent link="base_link"/>        <!-- 父 -->
    <child link="base_footprint"/>    <!-- 子。子固定在父上面-->
    <origin xyz="0.0 0.0 ${-(wheel_radius+wheel_zoff)}" rpy="0 0 0"/>  <!-- 父与子之间的xyz位移和旋转 -->
  </joint>

  <!-- Wheels -->
  <xacro:macro name="wheel" params="prefix x_reflect y_reflect">  <!-- prefix为关节名称添加前缀     x、y_prefix在x、y轴翻转轮子位置 -->
    <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.5" r="${wheel_radius}" h="${wheel_width}"/>
    </link>

    <xacro:cylinder_inertia m="0.5" r="${wheel_radius}" h="${wheel_width}"/>

    <joint name="${prefix}_joint" type="continuous">  <!-- continuous允许不限角度的旋转 -->
      <parent link="base_link"/>
      <child link="${prefix}_link"/>
      <origin xyz="${x_reflect*wheel_xoff} ${y_reflect*(base_width/2+wheel_ygap)} ${-wheel_zoff}" rpy="0 0 0"/>   <!-- x、y_reflect控制轮子沿x、y轴进行翻转 -->
      <axis xyz="0 1 0"/>    <!-- 关节围绕y轴旋转 -->
    </joint>
  </xacro:macro>

  <xacro:wheel prefix="drivewhl_l" x_reflect="-1" y_reflect="1" />   <!-- 实例化 -->
  <xacro:wheel prefix="drivewhl_r" x_reflect="-1" y_reflect="-1" />

  <!-- Caster Wheel -->
  <link name="front_caster">
    <visual>
      <geometry>
        <sphere radius="${(wheel_radius+wheel_zoff-(base_height/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+wheel_zoff-(base_height/2))}"/>
      </geometry>
    </collision>

    <xacro:sphere_inertia m="0.5" r="${(wheel_radius+wheel_zoff-(base_height/2))}"/>
  </link>

  <joint name="caster_joint" type="fixed">
    <parent link="base_link"/>
    <child link="front_caster"/>
    <origin xyz="${caster_xoff} 0.0 ${-(base_height/2)}" rpy="0 0 0"/>
  </joint>

</robot>

2、构建

编写package.xml:

在package.xml中添加:(最好放到<buildtool_depend>后面)

  <exec_depend>joint_state_publisher_gui</exec_depend>
  <exec_depend>robot_state_publisher</exec_depend>
  <exec_depend>rviz</exec_depend>
  <exec_depend>xacro</exec_depend>

编写launch启动文件:

在sam_bot_description下创建文件夹launch并在其中创建文件display.launch.py,在其中写入代码:

import launch
from launch.substitutions import Command, LaunchConfiguration
import launch_ros
import os

def generate_launch_description():
    pkg_share = launch_ros.substitutions.FindPackageShare(package='sam_bot_description').find('sam_bot_description')
    default_model_path = os.path.join(pkg_share, 'src/description/sam_bot_description.urdf')
    default_rviz_config_path = os.path.join(pkg_share, 'rviz/urdf_config.rviz')

    robot_state_publisher_node = launch_ros.actions.Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        parameters=[{'robot_description': Command(['xacro ', LaunchConfiguration('model')])}]
    )
    joint_state_publisher_node = launch_ros.actions.Node(
        package='joint_state_publisher',
        executable='joint_state_publisher',
        name='joint_state_publisher',
        condition=launch.conditions.UnlessCondition(LaunchConfiguration('gui'))
    )
    joint_state_publisher_gui_node = launch_ros.actions.Node(
        package='joint_state_publisher_gui',
        executable='joint_state_publisher_gui',
        name='joint_state_publisher_gui',
        condition=launch.conditions.IfCondition(LaunchConfiguration('gui'))
    )
    rviz_node = launch_ros.actions.Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen',
        arguments=['-d', LaunchConfiguration('rvizconfig')],
    )

    return launch.LaunchDescription([
        launch.actions.DeclareLaunchArgument(name='gui', default_value='True',
                                            description='Flag to enable joint_state_publisher_gui'),
        launch.actions.DeclareLaunchArgument(name='model', default_value=default_model_path,
                                            description='Absolute path to robot urdf file'),
        launch.actions.DeclareLaunchArgument(name='rvizconfig', default_value=default_rviz_config_path,
                                            description='Absolute path to rviz config file'),
        joint_state_publisher_node,
        joint_state_publisher_gui_node,
        robot_state_publisher_node,
        rviz_node
    ])

修改CMakeList文件: 

将下面的代码放在14行(大概)if(BUILD_TESTING)之前:

install(
  DIRECTORY src launch rviz
  DESTINATION share/${PROJECT_NAME}
)

配置rviz显示页面文件:

在sam_bot_description下创建文件夹rviz并在其中创建文件urdf_config.rviz,并在其中写入代码:

Panels:
  - Class: rviz_common/Displays
    Help Height: 78
    Name: Displays
    Property Tree Widget:
      Expanded:
        - /Global Options1
        - /Status1
        - /RobotModel1/Links1
        - /TF1
      Splitter Ratio: 0.5
    Tree Height: 557
Visualization Manager:
  Class: ""
  Displays:
    - Alpha: 0.5
      Cell Size: 1
      Class: rviz_default_plugins/Grid
      Color: 160; 160; 164
      Enabled: true
      Name: Grid
    - Alpha: 0.6
      Class: rviz_default_plugins/RobotModel
      Description Topic:
        Depth: 5
        Durability Policy: Volatile
        History Policy: Keep Last
        Reliability Policy: Reliable
        Value: /robot_description
      Enabled: true
      Name: RobotModel
      Visual Enabled: true
    - Class: rviz_default_plugins/TF
      Enabled: true
      Name: TF
      Marker Scale: 0.3
      Show Arrows: true
      Show Axes: true
      Show Names: true
  Enabled: true
  Global Options:
    Background Color: 48; 48; 48
    Fixed Frame: base_link
    Frame Rate: 30
  Name: root
  Tools:
    - Class: rviz_default_plugins/Interact
      Hide Inactive Objects: true
    - Class: rviz_default_plugins/MoveCamera
    - Class: rviz_default_plugins/Select
    - Class: rviz_default_plugins/FocusCamera
    - Class: rviz_default_plugins/Measure
      Line color: 128; 128; 0
  Transformation:
    Current:
      Class: rviz_default_plugins/TF
  Value: true
  Views:
    Current:
      Class: rviz_default_plugins/Orbit
      Name: Current View
      Target Frame: <Fixed Frame>
      Value: Orbit (rviz)
    Saved: ~

ys启动!

还有一件事,安装一个小工具

 sudo apt install ros-humble-joint-state-publisher-gui

如果还报错缺什么东西安装就好

编译,source,然后启动:

ros2 launch sam_bot_description display.launch.py

左边RobotModel里面collision和Visual可以看机器人的视觉和碰撞体积 

拖这个框里的滑条可以控制轮子转:

### 如何在Spyder中防止epoch训练从头开始 为了确保模型能够继续之前保存的状态进行训练而非重新开始,在启动训练脚本时需指定加载已有的检查点(checkpoint),这通常通过命令行参数或修改配置文件来实现。当执行`train.py`时,如果希望基于先前的checkpoint恢复训练,则应设置相应的选项以指示程序查找这些checkpoint。 对于给定的情况,可以考虑如下方法: 1. **利用--fine_tune_checkpoint 参数** 如果框架支持此功能,可以在调用 `train.py` 脚本时加入 `--fine_tune_checkpoint` 参数指向最近次训练结束所保存下来的 checkpoint 文件位置。这样做的目的是告诉训练器从特定的权重初始化网络,从而延续之前的训练过程[^1]。 2. **更新配置文件中的 fine_tune_checkpoint 字段** 修改位于 `training/faster_rcnn_inception_v2_pets.config` 的配置文件,找到关于 `fine_tune_checkpoint` 的部分,并将其值设为上轮训练结束后产生的 `.ckpt` 文件路径。这样做同样可以让新的训练周期继承旧有学习成果。 3. **确认 train_dir 中存在有效的 checkpoints** 确认 `training/` 目录内确实包含了完整的 checkpoint 数据集(即带有 index 和 data 后缀的系列文件)。只有当该目录中有合法且最新的 checkpoint 存档时,才能顺利从中断处接续训练工作。 ```bash python train.py \ --logtostderr \ --train_dir=training/ \ --pipeline_config_path=training/faster_rcnn_inception_v2_pets.config \ --fine_tune_checkpoint=training/model.ckpt-<step_number> ``` 上述命令展示了如何向 `train.py` 添加额外参数以便于恢复训练状态。其中 `<step_number>` 应替换为实际存在的 checkpoint 步骤编号。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值