ROS2 第6章 使用URDF创建机器人

6.1 使用URDF创建机器人

在主目录下新建chapt6,在该目录下创建chapt6_ws,接着递归创建src目录,在src下创建fishbot_description。

ros2 pkg create fishbot_description --build-type ament_cmake --license Apache-2.0

接着在fishbot_description下创建urdf目录,并在urdf目录下创建first_robot.urdf文件,代码如下

(可以先下载一个urdf扩展,帮助编写代码)

<?xml version="1.0"?> <!-- 机器人名称:first_robot --> <robot name="first_robot"> <!-- 1. 机器人身体部分(底座) --> <link name="base_link"> <!-- visual:描述部件的“外观”(形状、颜色,只影响显示,不影响物理) --> <visual> <!-- origin:部件自身的几何中心相对于“父关节”的偏移和旋转(这里是自身中心,所以全0) --> <origin xyz="0 0 0" rpy="0 0 0" /> <!-- geometry:部件的几何形状(这里是圆柱体) --> <geometry> <!-- cylinder:圆柱体,length=高度(0.12米),radius=半径(0.10米) --> <cylinder length="0.12" radius="0.10" /> </geometry> <!-- material:部件的材质(颜色) --> <material name="white"> <!-- color:颜色(rgba格式:红、绿、蓝、透明度,0-1之间) --> <color rgba="1.0 1.0 1.0 0.5" /> </material> </visual> </link> <!-- 2. 机器人IMU部件(惯性测量单元,用来测姿态) --> <link name="imu_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <!-- box:立方体,size=长×宽×高(0.02米×0.02米×0.02米,很小的方块) --> <box size="0.02 0.02 0.02" /> </geometry> <material name="black"> <color rgba="0 0 0 0.5" /> </material> </visual> </link> <!-- 3. 关节:连接base_link(底座)和imu_link(IMU) --> <joint name="imu_joint" type="fixed"> <parent link="base_link" /> <!-- 父部件:底座(IMU装在底座上) --> <child link="imu_link" /> <!-- origin:子部件(IMU)相对于父部件(底座)的位置和旋转 --> <!-- xyz="0 0 0.03":IMU在底座的正上方0.03米处(z轴向上),x/y方向对齐(0,0) --> <origin xyz="0 0 0.03" rpy="0 0 0" /> </joint> </robot>

编写完成后,在终端中进入urdf目录下,输入以下代码将URDF结构可视化,结果如下

~/chapt6/chapt6_ws/src/fishbot_description/urdf$ urdf_to_graphviz first_robot.urdf first_robot Created file first_robot.gv Created file first_robot.pdf

打开生成的first_robot.pdf内容如下:

6.2 在Rviz中显示机器人

安装依赖

sudo apt install ros-$ROS_DISTRO-robot-state-publisher sudo apt install ros-$ROS_DISTRO-joint-state-publisher

为了方便运行,使用launch文件组织节点,在fishbot_description目录下新建launch目录,接着创建display_robot.launch.py,写入以下代码

import launch import launch_ros from ament_index_python.packages import get_package_share_directory def generate_launch_description(): urdf_turtorial_path = get_package_share_directory('fishbot_description') default_model_path = urdf_turtorial_path + '/urdf/first_robot.urdf' action_delcare_arg_mode_path = launch.actions.DeclareLaunchArgument( name='model', default_value=str(default_model_path), description='URDF 的绝对路径') robot_description = launch_ros.parameter_descriptions.ParameterValue( launch.substitutions.Command( ['cat ', launch.substitutions.LaunchConfiguration('model')]), value_type=str) robot_state_publisher_node = launch_ros.actions.Node( package='robot_state_publisher', executable='robot_state_publisher', parameters=[{'robot_description':robot_description}] ) joint_state_publisher_node = launch_ros.actions.Node( package='joint_state_publisher', executable='joint_state_publisher', ) rviz_node = launch_ros.actions.Node( package='rviz2', executable='rviz2', ) return launch.LaunchDescription([ action_delcare_arg_mode_path, joint_state_publisher_node, robot_state_publisher_node, rviz_node ])

代码完成后,在CMakeLists.txt中将urdf和launch文件复制到install目录下,代码如下

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

随后在工作空间下构建功能包,source 并启动launch文件,启动命令与结果如下

~/chapt6/chapt6_ws$ ros2 launch fishbot_description display_robot.launch.py [INFO] [launch]: All log files can be found below /home/cwq/.ros/log/2025-11-06-20-50-29-922420-cwq-virtual-machine-12869 [INFO] [launch]: Default logging verbosity is set to INFO [INFO] [joint_state_publisher-1]: process started with pid [12871] [INFO] [robot_state_publisher-2]: process started with pid [12873] [INFO] [rviz2-3]: process started with pid [12875] [rviz2-3] qt.qpa.plugin: Could not find the Qt platform plugin "wayland" in "" [robot_state_publisher-2] [INFO] [1762433430.026086874] [robot_state_publisher]: got segment base_link [robot_state_publisher-2] [INFO] [1762433430.026263877] [robot_state_publisher]: got segment imu_link [joint_state_publisher-1] [INFO] [1762433430.485811579] [joint_state_publisher]: Waiting for robot_description to be published on the robot_description topic... [rviz2-3] [INFO] [1762433430.610920615] [rviz2]: Stereo is NOT SUPPORTED [rviz2-3] [INFO] [1762433430.611039547] [rviz2]: OpenGl version: 4.3 (GLSL 4.3) [rviz2-3] [INFO] [1762433430.643061933] [rviz2]: Stereo is NOT SUPPORTED

需要将Rviz的Display模块中的Fixed Frame修改为base_link,添加RobotModel并修改Description Source为Topic,在Description Topic处选择/robot_description。

在launch中添加启动rviz2命令

def generate_launch_description(): urdf_turtorial_path = get_package_share_directory('fishbot_description') default_model_path = urdf_turtorial_path + '/urdf/first_robot.urdf' default_rviz_config_path = urdf_turtorial_path + '/config/display_model.rviz'
 arguments=['-d', default_rviz_config_path]

修改完后,修改CMakeLIsts.txt,将config目录复制到install对应目录下,重新构建功能包并运行launch文件,即可显示机器人模型

6.3 使用Xacro简化URDF

在urdf目录下创建first_robot.urdf.xacro,编写以下代码

<?xml version="1.0"?> <!-- 机器人名称:first_robot --> <robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="first_robot"> <xacro:macro name="base_link" params="length radius"> <!-- 1. 机器人身体部分(底座) --> <link name="base_link"> <!-- visual:描述部件的“外观”(形状、颜色,只影响显示,不影响物理) --> <visual> <!-- origin:部件自身的几何中心相对于“父关节”的偏移和旋转(这里是自身中心,所以全0) --> <origin xyz="0 0 0" rpy="0 0 0" /> <!-- geometry:部件的几何形状(这里是圆柱体) --> <geometry> <cylinder length="${length}" radius="${radius}" /> </geometry> <!-- material:部件的材质(颜色) --> <material name="white"> <!-- color:颜色(rgba格式:红、绿、蓝、透明度,0-1之间) --> <color rgba="1.0 1.0 1.0 0.5" /> </material> </visual> </link> </xacro:macro> <xacro:macro name="imu_link" params="imu_name xyz"> <!-- 2. 机器人IMU部件(惯性测量单元,用来测姿态) --> <link name="${imu_name}_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <!-- box:立方体,size=长×宽×高(0.02米×0.02米×0.02米,很小的方块) --> <box size="0.02 0.02 0.02" /> </geometry> <material name="black"> <color rgba="0 0 0 0.5" /> </material> </visual> </link> <!-- 3. 关节:连接base_link(底座)和imu_link(IMU) --> <joint name="${imu_name}_joint" type="fixed"> <parent link="base_link" /> <!-- 父部件:底座(IMU装在底座上) --> <child link="${imu_name}_link" /> <!-- origin:子部件(IMU)相对于父部件(底座)的位置和旋转 --> <!-- xyz="0 0 0.03":IMU在底座的正上方0.03米处(z轴向上),x/y方向对齐(0,0) --> <origin xyz="${xyz}" /> </joint> </xacro:macro> <xacro:base_link length="0.12" radius="0.1" /> <xacro:imu_link imu_name="imu_up" xyz="0 0 0.02" /> <xacro:imu_link imu_name="imu_down" xyz="0 0 -0.02" /> </robot>

在终端中安装xacro工具,将xacro解析成URDF格式

sudo apt install ros-$ROS_DISTRO-xacro

在终端进入fishbot_description/urdf目录,使用以下代码将Xacro解析为URDF

~/chapt6/chapt6_ws/src/fishbot_description/urdf$ xacro first_robot.urdf.xacro <?xml version="1.0" ?> <!-- =================================================================================== --> <!-- | This document was autogenerated by xacro from first_robot.urdf.xacro | --> <!-- | EDITING THIS FILE BY HAND IS NOT RECOMMENDED | --> <!-- =================================================================================== --> <!-- 机器人名称:first_robot --> <robot name="first_robot"> <!-- 1. 机器人身体部分(底座) --> <link name="base_link"> <!-- visual:描述部件的“外观”(形状、颜色,只影响显示,不影响物理) --> <visual> <!-- origin:部件自身的几何中心相对于“父关节”的偏移和旋转(这里是自身中心,所以全0) --> <origin rpy="0 0 0" xyz="0 0 0"/> <!-- geometry:部件的几何形状(这里是圆柱体) --> <geometry> <cylinder length="0.12" radius="0.1"/> </geometry> <!-- material:部件的材质(颜色) --> <material name="white"> <!-- color:颜色(rgba格式:红、绿、蓝、透明度,0-1之间) --> <color rgba="1.0 1.0 1.0 0.5"/> </material> </visual> </link> <!-- 2. 机器人IMU部件(惯性测量单元,用来测姿态) --> <link name="imu_up_link"> <visual> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <!-- box:立方体,size=长×宽×高(0.02米×0.02米×0.02米,很小的方块) --> <box size="0.02 0.02 0.02"/> </geometry> <material name="black"> <color rgba="0 0 0 0.5"/> </material> </visual> </link> <!-- 3. 关节:连接base_link(底座)和imu_link(IMU) --> <joint name="imu_up_joint" type="fixed"> <parent link="base_link"/> <!-- 父部件:底座(IMU装在底座上) --> <child link="imu_up_link"/> <!-- origin:子部件(IMU)相对于父部件(底座)的位置和旋转 --> <!-- xyz="0 0 0.03":IMU在底座的正上方0.03米处(z轴向上),x/y方向对齐(0,0) --> <origin xyz="0 0 0.02"/> </joint> <!-- 2. 机器人IMU部件(惯性测量单元,用来测姿态) --> <link name="imu_down_link"> <visual> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <!-- box:立方体,size=长×宽×高(0.02米×0.02米×0.02米,很小的方块) --> <box size="0.02 0.02 0.02"/> </geometry> <material name="black"> <color rgba="0 0 0 0.5"/> </material> </visual> </link> <!-- 3. 关节:连接base_link(底座)和imu_link(IMU) --> <joint name="imu_down_joint" type="fixed"> <parent link="base_link"/> <!-- 父部件:底座(IMU装在底座上) --> <child link="imu_down_link"/> <!-- origin:子部件(IMU)相对于父部件(底座)的位置和旋转 --> <!-- xyz="0 0 0.03":IMU在底座的正上方0.03米处(z轴向上),x/y方向对齐(0,0) --> <origin xyz="0 0 -0.02"/> </joint> </robot>

将display_robot.launch.py中的'cat'命令替换为'xacro'。

在工作空间下重新构建和启动launch文件,并修改model参数为对应的文件地址,即可更新生成机器人模型。

~/chapt6/chapt6_ws$ ros2 launch fishbot_description display_robot.launch.py model:=/home/cwq/chapt6/chapt6_ws/src/fishbot_description/urdf/first_robot.urdf.xacro [INFO] [launch]: All log files can be found below /home/cwq/.ros/log/2025-11-07-17-31-27-774942-cwq-virtual-machine-21242 [INFO] [launch]: Default logging verbosity is set to INFO [INFO] [joint_state_publisher-1]: process started with pid [21244] [INFO] [robot_state_publisher-2]: process started with pid [21246] [INFO] [rviz2-3]: process started with pid [21248] [rviz2-3] qt.qpa.plugin: Could not find the Qt platform plugin "wayland" in "" [robot_state_publisher-2] [INFO] [1762507887.971557955] [robot_state_publisher]: got segment base_link [robot_state_publisher-2] [INFO] [1762507887.971697529] [robot_state_publisher]: got segment imu_down_link [robot_state_publisher-2] [INFO] [1762507887.971708736] [robot_state_publisher]: got segment imu_up_link [rviz2-3] [INFO] [1762507888.289264420] [rviz2]: Stereo is NOT SUPPORTED [rviz2-3] [INFO] [1762507888.289391344] [rviz2]: OpenGl version: 4.3 (GLSL 4.3) [rviz2-3] [INFO] [1762507888.321751638] [rviz2]: Stereo is NOT SUPPORTED [joint_state_publisher-1] [INFO] [1762507888.333985018] [joint_state_publisher]: Waiting for robot_description to be published on the robot_description topic...

6.4 创建机器人及传感器部件

在fishbot_description/urdf/目录下新建fisbot目录,在该目录下新建base.urdf.xacro,写入以下代码

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:macro name="base_xacro" params="length radius"> <link name="base_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <cylinder length="${length}" radius="${radius}" /> </geometry> <material name="white"> <color rgba="1.0 1.0 1.0 0.5" /> </material> </visual> </link> </xacro:macro> </robot>

在fishbot目录下新建sensor子目录,在sensor下新建imu.urdf.xacro,写入以下代码

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:macro name="imu_xacro" params="xyz"> <link name="imu_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <box size="0.02 0.02 0.02" /> </geometry> <material name="black"> <color rgba="0 0 0 0.8" /> </material> </visual> </link> <joint name="imu_joint" type="fixed"> <parent link="base_link" /> <child link="imu_link" /> <origin xyz="${xyz}" /> </joint> </xacro:macro> </robot>

在sensor下新建camera.urdf.xacro,写入以下代码

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:macro name="camera_xacro" params="xyz"> <link name="camera_link"> <visual> <origin xyz="0 0 0.0" rpy="0 0 0" /> <geometry> <box size="0.02 0.10 0.02" /> </geometry> <material name="green"> <color rgba="0.0 1.0 0.0 0.8" /> </material> </visual> </link> <joint name="camera_joint" type="fixed"> <parent link="base_link" /> <child link="camera_link" /> <origin xyz="${xyz}" /> </joint> </xacro:macro> </robot>

在sensor下新建laser.urdf.xacro,写入以下代码

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:macro name="laser_xacro" params="xyz"> <link name="laser_cylinder_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <cylinder length="0.10" radius="0.01" /> </geometry> <material name="green"> <color rgba="0.0 1.0 0.0 0.8" /> </material> </visual> </link> <joint name="laser_cylinder_joint" type="fixed"> <parent link="base_link" /> <child link="laser_cylinder_link" /> <origin xyz="${xyz}" /> </joint> <link name="laser_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <cylinder length="0.02" radius="0.02" /> </geometry> <material name="green"> <color rgba="0.0 1.0 0.0 0.8" /> </material> </visual> </link> <joint name="laser_joint" type="fixed"> <parent link="laser_cylinder_link" /> <child link="laser_link" /> <origin xyz="0 0 0.05" /> </joint> </xacro:macro> </robot>

传感器代码完成,现在需要将传感器组装起来,在urdf/fishbot/下新建fishbot.urdf.xacro,写入以下代码

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="first_robot"> <xacro:include filename="$(find fishbot_description)/urdf/fishbot/base.urdf.xacro" /> <xacro:include filename="$(find fishbot_description)/urdf/fishbot/sensor/imu.urdf.xacro" /> <xacro:include filename="$(find fishbot_description)/urdf/fishbot/sensor/laser.urdf.xacro" /> <xacro:include filename="$(find fishbot_description)/urdf/fishbot/sensor/camera.urdf.xacro" /> <xacro:base_xacro length="0.12" radius="0.1" /> <xacro:imu_xacro xyz="0 0 0.02" /> <xacro:laser_xacro xyz="0 0 0.10" /> <xacro:camera_xacro xyz="0.10 0 0.075" /> </robot>

重新编译并运行display_robot.launch.py(需将路径改为fishbot.urdf.xacro,代码及显示结果如下

ros2 launch fishbot_description display_robot.launch.py model:=/home/cwq/chapt6/chapt6_ws/src/fishbot_description/urdf/fishbot/fishbot.urdf.xacro [INFO] [launch]: All log files can be found below /home/cwq/.ros/log/2025-11-07-18-08-07-719699-cwq-virtual-machine-21855 [INFO] [launch]: Default logging verbosity is set to INFO [INFO] [joint_state_publisher-1]: process started with pid [21857] [INFO] [robot_state_publisher-2]: process started with pid [21859] [INFO] [rviz2-3]: process started with pid [21861] [rviz2-3] qt.qpa.plugin: Could not find the Qt platform plugin "wayland" in "" [robot_state_publisher-2] [INFO] [1762510087.926664599] [robot_state_publisher]: got segment base_link [robot_state_publisher-2] [INFO] [1762510087.926850670] [robot_state_publisher]: got segment camera_link [robot_state_publisher-2] [INFO] [1762510087.926862145] [robot_state_publisher]: got segment imu_link [robot_state_publisher-2] [INFO] [1762510087.926868633] [robot_state_publisher]: got segment laser_cylinder_link [robot_state_publisher-2] [INFO] [1762510087.926874791] [robot_state_publisher]: got segment laser_link [joint_state_publisher-1] [INFO] [1762510088.451227984] [joint_state_publisher]: Waiting for robot_description to be published on the robot_description topic... [rviz2-3] [INFO] [1762510088.605421457] [rviz2]: Stereo is NOT SUPPORTED [rviz2-3] [INFO] [1762510088.605605758] [rviz2]: OpenGl version: 4.3 (GLSL 4.3) [rviz2-3] [INFO] [1762510088.638243716] [rviz2]: Stereo is NOT SUPPORTED

6.5 完善机器人执行器部件

在fishbot目录下新建actuator子目录,然后在actuator下新建wheel.urdf.wacro,编写以下代码

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:macro name="wheel_xacro" params="wheel_name xyz"> <link name="${wheel_name}_wheel_link"> <visual> <origin xyz="0 0 0" rpy="1.57079 0 0" /> <geometry> <cylinder length="0.04" radius="0.032" /> </geometry> <material name="yellow"> <color rgba="1.0 1.0 0.0 0.8" /> </material> </visual> </link> <joint name="${wheel_name}_wheel_joint" type="continuous"> <parent link="base_link" /> <child link="${wheel_name}_wheel_link" /> <origin xyz="${xyz}" /> <axis xyz="0.0 1.0 0.0"/> </joint> </xacro:macro> </robot>

完成驱动轮的定义,接着定义万向轮部分,在actuator中新建caster.urdf.xacro文件,代码如下

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:macro name="caster_xacro" params="caster_name xyz"> <link name="${caster_name}_caster_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <sphere radius="0.016" /> </geometry> <material name="yellow"> <color rgba="1.0 1.0 0.0 0.8" /> </material> </visual> </link> <joint name="${caster_name}_caster_joint" type="fixed"> <parent link="base_link" /> <child link="${caster_name}_caster_link" /> <origin xyz="${xyz}" /> <axis xyz="0 0 0"/> </joint> </xacro:macro> </robot>

完成后再次修改fishbot.urdf.xacro,添加代码如下,

 <xacro:include filename="$(find fishbot_description)/urdf/fishbot/actuator/caster.urdf.xacro" /> <xacro:include filename="$(find fishbot_description)/urdf/fishbot/actuator/wheel.urdf.xacro" /> <xacro:wheel_xacro wheel_name="left" xyz="0 0.10 -0.06" /> <xacro:wheel_xacro wheel_name="right" xyz="0 -0.10 -0.06" /> <xacro:caster_xacro caster_name="front" xyz="0.08 0.0 -0.076" /> <xacro:caster_xacro caster_name="back" xyz="-0.08 0.0 -0.076" />

在rviz中观察机器人,发现机器人轮子在地面以下,通过添加虚拟关节来解决这一问题,在src/fishbot_description/urdf/fishbot/base.urdf.xacro中添加以下代码,

 <link name="base_footprint" /> <joint name="base_joint" type="fixed"> <parent link="base_footprint" /> <child link="base_link" /> <origin xyz="0.0 0.0 ${length/2.0+0.032-0.001}" rpy="0 0 0" /> </joint> 

保存好后构建运行,修改fixed frame 为base_footprint,代码及结果展示如下:

ros2 launch fishbot_description display_robot.launch.py model:=/home/cwq/chapt6/chapt6_ws/src/fishbot_description/urdf/fishbot/fishbot.urdf.xacro [INFO] [launch]: All log files can be found below /home/cwq/.ros/log/2025-11-07-20-22-50-038490-cwq-virtual-machine-22899 [INFO] [launch]: Default logging verbosity is set to INFO [INFO] [joint_state_publisher-1]: process started with pid [22901] [INFO] [robot_state_publisher-2]: process started with pid [22903] [INFO] [rviz2-3]: process started with pid [22905] [rviz2-3] qt.qpa.plugin: Could not find the Qt platform plugin "wayland" in "" [robot_state_publisher-2] [INFO] [1762518170.255450518] [robot_state_publisher]: got segment back_caster_link [robot_state_publisher-2] [INFO] [1762518170.255583911] [robot_state_publisher]: got segment base_footprint [robot_state_publisher-2] [INFO] [1762518170.255595068] [robot_state_publisher]: got segment base_link [robot_state_publisher-2] [INFO] [1762518170.255601575] [robot_state_publisher]: got segment camera_link [robot_state_publisher-2] [INFO] [1762518170.255607770] [robot_state_publisher]: got segment front_caster_link [robot_state_publisher-2] [INFO] [1762518170.255613439] [robot_state_publisher]: got segment imu_link [robot_state_publisher-2] [INFO] [1762518170.255619158] [robot_state_publisher]: got segment laser_cylinder_link [robot_state_publisher-2] [INFO] [1762518170.255624824] [robot_state_publisher]: got segment laser_link [robot_state_publisher-2] [INFO] [1762518170.255630704] [robot_state_publisher]: got segment left_wheel_link [robot_state_publisher-2] [INFO] [1762518170.255636445] [robot_state_publisher]: got segment right_wheel_link [joint_state_publisher-1] [INFO] [1762518170.778521917] [joint_state_publisher]: Waiting for robot_description to be published on the robot_description topic...

6.6 添加物理属性让机器人更真实

6.6.1 为机器人添加碰撞属性

为每个部件都添加一份碰撞属性,与visual同级,添加<collision>,将visual的内容直接复制粘贴即可,base , laser , wheel , caster 都添加一次。

 </visual> <collision> <origin xyz="0 0 0" rpy="0 0 0" /> <geometry> <sphere radius="0.016" /> </geometry> <material name="yellow"> <color rgba="1.0 1.0 0.0 0.8" /> </material> </collision> </link>

在终端运行,打开rviz后,修改RobotModel配置,去掉VIsual Enabled的勾选,再勾选上Collsion Enabled即可显示出碰撞模型。.

6.6.2 为机器人部件添加质量与惯性

使用xacro结合惯性公式,编写一个惯性和质量专用的宏定义,在urdf/fishbot目录下新建common_inertia.xacro文件,编写以下代码

<?xml version="1.0"?> <robot xmlns:xacro="http://ros.org/wiki/xacro"> <xacro:macro name="box_inertia" params="m w h d"> <inertial> <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> <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> 

编写完成后,就可以在其它xacro文件导入并使用该宏,修改base.urdf.xacro,添加导入对该宏的调用,

<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:include filename="$(find fishbot_description)/urdf/fishbot/common_inertia.xacro" /> <xacro:macro name="base_xacro" params="length radius"> <link name="base_footprint" /> <joint name="base_joint" type="fixed"> <parent link="base_footprint" /> <child link="base_link" /> <origin xyz="0.0 0.0 ${length/2.0+0.032-0.001}" rpy="0 0 0" /> </joint> <link name="base_link"> <visual> <origin xyz="0 0 0.0" rpy="0 0 0" /> <geometry> <cylinder length="${length}" radius="${length}" /> </geometry> <material name="blue"> <color rgba="0.1 0.1 1.0 0.5"/> </material> </visual> <collision> <origin xyz="0 0 0.0" rpy="0 0 0" /> <geometry> <cylinder length="${length}" radius="${length}" /> </geometry> <material name="blue"> <color rgba="0.1 0.1 1.0 0.5"/> </material> </collision> <xacro:cylinder_inertia m="1.0" r="${radius}" h="${length}"/> </link> </xacro:macro> </robot> 

这里给出的完整代码,读者可对照修改。再次构建并运行launch,在rviz中显示机器人模型。

接着修改robotmodel配置,取消visual enabled的勾选,然后勾选mass properties选项中的mass,即可看到质量配置视图,取消mass勾选,勾选inertia视图,即可看到惯性视图。

下一章写如何在gazebo中仿真

Read more

【Actix Web】Rust Web开发实战:Actix Web框架全面指南

【Actix Web】Rust Web开发实战:Actix Web框架全面指南

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,ZEEKLOG全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Rust开发,Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。 所属的专栏:Rust语言通关之路 景天的主页:景天科技苑 文章目录 * Rust Web开发 * 一、Actix Web框架概述 * 1.1 Actix Web的特点 * 1.2 Actix Web与其他Rust框架比较

【指南】Vibe Coding 前端搭建的最后一块拼图

【指南】Vibe Coding 前端搭建的最后一块拼图

Playwright,Vibe Coding前端搭建最好的测试伙伴 在2025年的今天,Vibe Coding(氛围编程)已经成为了最时髦的开发方式。作为开发者,我们只需要专注于提供创意和方向(Vibe),剩下的繁琐代码实现全部交给诸如 Claude Code、Cursor 等 AI 编程智能体来完成。 在后端开发中,Vibe Coding 体验极佳:只要逻辑正确、测试用例跑通,万事大吉。但在前端开发中,这套流程却经常“翻车”。 原因很简单:大模型(LLM)是“瞎子”。 它们能写出逻辑完美、毫无语法错误的 React/Vue 组件,也能熟练使用 Tailwind CSS,但它们看不到最终渲染出来的页面长什么样。于是我们经常遇到这样的灾难场景: * 按钮飞到了屏幕边缘; * 弹窗的 z-index 不对,被背后的元素遮挡; * Flex 布局元素挤在一起,

2025 WAIC探展合合信息展台:AI鉴伪技术洞察“看不见”的伪造痕迹

2025 WAIC探展合合信息展台:AI鉴伪技术洞察“看不见”的伪造痕迹

2025 WAIC探展合合信息展台:AI鉴伪技术洞察“看不见”的伪造痕迹 七月迎来了一年一度的WAIC世界人工智能大会,猫头虎有幸受邀参会,首次踏上魔都上海,亲身感受到前沿AI科技带来的震撼。在展会现场,各类炫酷的AI应用令人目不暇接,其中合合信息的展位格外亮眼。他们展示的“AI鉴伪”黑科技,为观众奉上了一场视觉安全领域的精彩科技秀。 背景:从传统PS到AI伪造的新时代 过去两年,随着AI大模型技术的爆发式发展,图像和视频的生成及篡改技术变得愈发简单和隐秘,传统的图像处理软件如PS已难以满足新时代的安全鉴伪需求。合合信息早在2022年便领先行业推出了PS篡改检测技术,并迅速更新迭代,跨越了从单一静态图像到复杂多模态数据的鉴伪技术瓶颈。 本次展会探访分为上午的展位参观和下午的技术交流会两个部分,猫头虎带大家一起来深入体验。 文章目录 * 2025 WAIC探展合合信息展台:AI鉴伪技术洞察“看不见”的伪造痕迹 * 背景:从传统PS到AI伪造的新时代 * 展位体验篇 * 人脸视频篡改检测:毫秒级识破逼真的“数字假面” * AIGC图像鉴别

在 OpenClaw 中安装 baidu-web-search skill(百度网页搜索技能)

在 OpenClaw 中安装 baidu-web-search skill(百度网页搜索技能),最推荐用 ClawHub CLI 一键安装,再配置百度千帆 API Key 即可使用。 一、前置准备 1. 安装 Node.js(v20+)与 npm/pnpm 验证安装 clawhub --version 全局安装 ClawHub CLI(OpenClaw 官方技能管理器) npminstall-g clawhub # 或国内加速pnpmadd-g clawhub 二、一键安装百度搜索技能 # 安装 baidu-search(百度网页搜索) clawhub install baidu-search --no-input * 安装路径:~/.openclaw/workspace/skills/baidu-search/