在ROS中,机器人建模和仿真是非常重要的一部分。通过建模和仿真,开发人员可以在不使用实际机器人的情况下进行开发和测试,从而节省时间和成本。ROS使用URDF (Unified Robot Description Format)作为机器人建模语言,并提供了一些工具来创建和编辑URDF文件,例如RViz和Gazebo等。
URDF文件:URDF文件描述了机器人的物理特性,包括链接和关节,以及传感器和执行器等。开发人员可以使用URDF文件来创建机器人模型,并在仿真环境中运行。
Gazebo仿真器:Gazebo是一款用于机器人仿真的强大工具,可以模拟机器人的物理特性和环境条件。Gazebo支持ROS,并且可以与ROS进行集成,使得开发人员可以使用ROS中的节点和消息来控制机器人模型。
RViz可视化工具:RViz是ROS的一个可视化工具,可以用于可视化机器人模型、传感器数据和控制输出等。开发人员可以使用RViz来调试机器人模型,并进行可视化分析。
ROS控制器:ROS提供了一些控制器,例如关节控制器和力控制器等,可以用于控制机器人模型的关节和执行器等。
通过使用上述工具和技术,开发人员可以轻松地创建和仿真机器人模型,并进行开发和测试。这使得机器人应用开发更加高效、灵活和可靠。
URDF是一种用于描述机器人模型的XML文件格式。URDF(Unified Robot Description Format)它是ROS中使用的标准格式之一。URDF包含机器人的几何形状、传感器、关节和链接等信息,可以用于构建机器人模型、仿真和控制。
URDF文件通常由文本编辑器编写,但也可以使用各种URDF编辑器和可视化工具来创建和编辑。URDF的常见编辑器包括Robotics Toolbox for MATLAB、Blender、SolidWorks和OpenRAVE等。
在ROS中,URDF文件可以与其他ROS工具和程序集成,例如ROS控制器和Gazebo仿真器。下面讲讲URDF的语法详解
urdf 中为了保证 xml 语法的完整性,使用了robot标签作为根标签,所有的 link 和 joint 以及其他标签都必须包含在 robot 标签内
<robot name="car_robot">
robot>
在根标签内可以通过 name 属性设置机器人模型的名称,其他标签都是子级标签
< l i n k > <link> 标签用于描述一个物体或机器人的连接器。每个连接器都有其自己的坐标系,可以用于描述连接的相对位置和方向。每个 < l i n k > <link> 标签都必须拥有一个独特的名称,并且可以包含多个 < v i s u a l >
<link name="base_link">
<visual>
<geometry>
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black">
<color rgba="0.7 0.5 0 0.5" />
material>
连杆的碰撞属性 -->
连杆的惯性矩阵 -->
visual>
link>
< j o i n t >
<robot name="mycar">
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="blue">
<color rgba="0 0 1.0 0.5" />
material>
visual>
link>
<link name="camera">
<visual>
<geometry>
<box size="0.02 0.05 0.05" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="red">
<color rgba="1 0 0 0.5" />
material>
visual>
link>
<joint name="camera2baselink" type="continuous">
<parent link="base_link"/>
<child link="camera" />
<origin xyz="0.2 0 0.075" rpy="0 0 0" />
<axis xyz="0 0 1" />
joint>
robot>
下面我们来实操一下URDF机器人建模,我们先建立一个简单的机器人底盘,再加上两个驱动轮和一个支撑轮,这样机器人就可以通过运动控制器运动了。首先右键src目录选择Create Catkin Package,添加几个依赖包roscpp,rospy,urdf,xacro,新建urdf文件夹,里面新建urdf文件夹,里面创建一个model.urdf文件
<robot name="mycar">
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="0.001" />
geometry>
visual>
link>
<link name="base_link">
<visual>
<geometry>
<cylinder radius="0.1" length="0.08" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="yellow">
<color rgba="0.8 0.3 0.1 0.5" />
material>
visual>
link>
<link name="left_wheel">
<visual>
<geometry>
<cylinder radius="0.0325" length="0.015" />
geometry>
<origin xyz="0 0 0" rpy="1.5705 0 0" />
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
material>
visual>
link>
<link name="right_wheel">
<visual>
<geometry>
<cylinder radius="0.0325" length="0.015" />
geometry>
<origin xyz="0 0 0" rpy="1.5705 0 0" />
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
material>
visual>
link>
<link name="back_wheel">
<visual>
<geometry>
<sphere radius="0.0075" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
material>
visual>
link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link"/>
<origin xyz="0 0 0.055" />
joint>
<joint name="left_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="left_wheel" />
<origin xyz="0 0.1 -0.0225" />
<axis xyz="0 1 0" />
joint>
<joint name="right_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="right_wheel" />
<origin xyz="0 -0.1 -0.0225" />
<axis xyz="0 1 0" />
joint>
<joint name="back_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="back_wheel" />
<origin xyz="-0.0925 0 -0.0475" />
<axis xyz="1 1 1" />
joint>
接着在功能包下创建launch文件夹,新建xxx.launch文件,然后根据文件路径修改以下代码并复制进去
<launch>
<param name="robot_description" textfile="$(find my_robot)/urdf/urdf/model.urdf" />
<node pkg="rviz" type="rviz" name="rviz" />
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" />
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" />
launch>
最后在打开终端,运行下面的命令
roslaunch xxx(功能包) xxx.launch(launch文件)
只要在rviz配置好就能显示机器人模型,rviz里面的配置我们后面会提到
xacro是一个基于XML的宏语言,可以用来描述机器人模型的结构和参数。xacro文件可以通过编写简单的XML代码来生成URDF模型文件。在机器人模型复杂的情况下,xacro可以减少代码的重复,提高代码的可读性和可维护性,以提高机器人模型的性能和效率。
属性 property 用于封装 URDF 中的一些字段,比如: PAI 值,小车的尺寸,轮子半径,也可以用于算数计算,设置一些坐标偏移量
<xacro:property name="xxxx" value="yyyy" />
Xacro宏定义类似于函数定义实现,可提高代码复用率,优化代码结构,提高安全性,需要填写宏名称和可用参数列表信息
<xacro:macro name="宏名称" params="参数列表(多参数之间使用空格分隔)">
.....
参数调用格式: ${参数名}
xacro:macro>
Xacro宏调用类似于函数调用实现,需要填写宏名称和对应参数值
<xacro:宏名称 参数1=xxx 参数2=xxx/>
机器人由多部件组成,不同部件可能封装为单独的 xacro 文件,最后再将不同的文件集成,组合为完整机器人,可以使用文件包含实现
<robot name="xxx" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="my_base.xacro" />
....
robot>
现在我们用xacro宏来优化URDF建模的实操过程,这次我们先建造机器人底盘,摄像头,激光雷达,然后把这几个部件拼起来,首先现在xxx.urdf文件同级目录下新建xxx.urdf.xacro文件,接着编写摄像头和激光雷达的 xacro 文件
<robot name="my_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:property name="camera_length" value="0.01" />
<xacro:property name="camera_width" value="0.025" />
<xacro:property name="camera_height" value="0.025" />
<xacro:property name="camera_x" value="0.08" />
<xacro:property name="camera_y" value="0.0" />
<xacro:property name="camera_z" value="${base_link_length / 2 + camera_height / 2}" />
<link name="camera">
<visual>
<geometry>
<box size="${camera_length} ${camera_width} ${camera_height}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="black" />
visual>
link>
<joint name="camera2base_link" type="fixed">
<parent link="base_link" />
<child link="camera" />
<origin xyz="${camera_x} ${camera_y} ${camera_z}" />
joint>
robot>
<robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:property name="support_length" value="0.15" />
<xacro:property name="support_radius" value="0.01" />
<xacro:property name="support_x" value="0.0" />
<xacro:property name="support_y" value="0.0" />
<xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" />
<link name="support">
<visual>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="red">
<color rgba="0.8 0.2 0.0 0.8" />
material>
visual>
link>
<joint name="support2base_link" type="fixed">
<parent link="base_link" />
<child link="support" />
<origin xyz="${support_x} ${support_y} ${support_z}" />
joint>
<xacro:property name="laser_length" value="0.05" />
<xacro:property name="laser_radius" value="0.03" />
<xacro:property name="laser_x" value="0.0" />
<xacro:property name="laser_y" value="0.0" />
<xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" />
<link name="laser">
<visual>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="black" />
visual>
link>
<joint name="laser2support" type="fixed">
<parent link="support" />
<child link="laser" />
<origin xyz="${laser_x} ${laser_y} ${laser_z}" />
joint>
robot>
接着再编写机器人底盘的xacro文件
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="PI" value="3.141"/>
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
material>
<xacro:property name="base_footprint_radius" value="0.001" />
<xacro:property name="base_link_radius" value="0.1" />
<xacro:property name="base_link_length" value="0.08" />
<xacro:property name="earth_space" value="0.015" />
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="${base_footprint_radius}" />
geometry>
visual>
link>
<link name="base_link">
<visual>
<geometry>
<cylinder radius="${base_link_radius}" length="${base_link_length}" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="yellow">
<color rgba="0.5 0.3 0.0 0.5" />
material>
visual>
link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
joint>
<xacro:property name="wheel_radius" value="0.0325" />
<xacro:property name="wheel_length" value="0.015" />
<xacro:macro name="add_wheels" params="name flag">
<link name="${name}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
<material name="black" />
visual>
link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
<axis xyz="0 1 0" />
joint>
xacro:macro>
<xacro:add_wheels name="left" flag="1" />
<xacro:add_wheels name="right" flag="-1" />
<xacro:property name="support_wheel_radius" value="0.0075" />
<xacro:macro name="add_support_wheel" params="name flag" >
<link name="${name}_wheel">
<visual>
<geometry>
<sphere radius="${support_wheel_radius}" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black" />
visual>
link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
<axis xyz="1 1 1" />
joint>
xacro:macro>
<xacro:add_support_wheel name="front" flag="1" />
<xacro:add_support_wheel name="back" flag="-1" />
robot>
然后再编写一个my_robot.urdf.xacro文件,把上面的几个机器人部件的xacro文件include一下,,就可以把所以机器人部件拼起来
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="my_base.urdf.xacro" />
<xacro:include filename="my_camera.urdf.xacro" />
<xacro:include filename="my_laser.urdf.xacro" />
robot>
最后在launch文件夹下面新建my_robot.launch文件,该launch文件用于加载机器人模型并启动rviz
<launch>
<param name="robot_description" command="$(find xacro)/xacro $(find demo01_urdf_helloworld)/urdf/xacro/my_robot.urdf.xacro" />
<node pkg="rviz" type="rviz" name="rviz" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" output="screen" />
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen" />
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" output="screen" />
launch>
最后打开终端,执行下面命令,并在rviz中配置好RobotModel就可以看到机器人模型
roslaunch xxx(功能包) my_robot.launch(launch文件)
rviz是ROS中的一个可视化工具,用于显示机器人的状态、传感器数据和运动规划等信息。它可以显示3D模型、点云、激光雷达数据、图像、路径等,可以通过交互界面进行操作,如平移、旋转、缩放等。rviz还可以与其他ROS节点进行通信,例如与机器人控制节点通信,实现机器人运动规划控制。
Gazebo是ROS中的一个强大的模拟器,用于模拟机器人在虚拟环境中的运动和传感器数据。它可以模拟各种类型的机器人,包括移动机器人、人形机器人和无人机等,同时支持多种传感器类型,如摄像头、激光雷达和IMU等。在Gazebo中,用户可以创建一个虚拟环境,包括地形、障碍物和物体等,并将机器人放置在其中。通过控制机器人的运动,用户可以观察机器人在虚拟环境中的行为,并进行算法测试和优化等工作。Gazebo还可以与其他ROS节点进行通信,例如与机器人控制节点通信,实现机器人的运动控制。
Gazebo仿真环境加载URDF模型文件,要求使用 collision 碰撞标签,因为在仿真环境中必然涉及到碰撞检测,collision 提供碰撞检测的依据;还需要提供使用 inertial 惯性矩阵标签,此标签标注了当前机器人某个刚体部分的惯性矩阵,用于一些力学相关的仿真计算。
碰撞标签collision设置时,如果机器人的连接器是标准的几何体形状,设置与geometry形状属性一致即可
惯性矩阵标签inertial的设置需要结合连接器的质量分布与形状参数动态生成,下面是惯性矩阵的计算公式, J J J是转动惯量, r i r_{i} ri 是质点到转轴的距离
J = ∑ m i r i 2 J = \sum m_{i}r_{i}^{2} J=∑miri2
<xacro:macro name="sphere_inertial_matrix" params="m r">
<inertial>
<mass value="${m}" />
<inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
iyy="${2*m*r*r/5}" iyz="0"
izz="${2*m*r*r/5}" />
inertial>
xacro:macro>
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
izz="${m*r*r/2}" />
inertial>
xacro:macro>
<xacro:macro name="Box_inertial_matrix" params="m l w h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
iyy="${m*(w*w + l*l)/12}" iyz= "0"
izz="${m*(w*w + h*h)/12}" />
inertial>
xacro:macro>
除了 base_footprint 外,机器人的每个刚体部分都需要设置惯性矩阵,惯性矩阵是依据转动定律计算得出,如果随意定义刚体部分的惯性矩阵,那么可能会导致机器人在 Gazebo 中出现抖动,移动等现象,其它地方基本和之前的URDF建模一样
为了在Gazebo里面显示机器人模型,需要在之前xacro宏文件里面加入碰撞标签、惯性矩阵标签、颜色标签,其他操作基本与前面一致,首先编写机器人惯性矩阵算法的 xacro 文件
<robot name="base" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:macro name="sphere_inertial_matrix" params="m r">
<inertial>
<mass value="${m}" />
<inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
iyy="${2*m*r*r/5}" iyz="0"
izz="${2*m*r*r/5}" />
inertial>
xacro:macro>
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
izz="${m*r*r/2}" />
inertial>
xacro:macro>
<xacro:macro name="Box_inertial_matrix" params="m l w h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
iyy="${m*(w*w + l*l)/12}" iyz= "0"
izz="${m*(w*w + h*h)/12}" />
inertial>
xacro:macro>
robot>
接着编写机器人底盘的xacro文件
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="PI" value="3.1415926"/>
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
material>
<xacro:property name="base_footprint_radius" value="0.001" />
<xacro:property name="base_link_radius" value="0.1" />
<xacro:property name="base_link_length" value="0.08" />
<xacro:property name="earth_space" value="0.015" />
<xacro:property name="base_link_m" value="0.5" />
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="${base_footprint_radius}" />
geometry>
visual>
link>
<link name="base_link">
<visual>
<geometry>
<cylinder radius="${base_link_radius}" length="${base_link_length}" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="yellow">
<color rgba="0.5 0.3 0.0 0.5" />
material>
visual>
<collision>
<geometry>
<cylinder radius="${base_link_radius}" length="${base_link_length}" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
collision>
<xacro:cylinder_inertial_matrix m="${base_link_m}" r="${base_link_radius}" h="${base_link_length}" />
link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
joint>
<gazebo reference="base_link">
<material>Gazebo/Yellowmaterial>
gazebo>
<xacro:property name="wheel_radius" value="0.0325" />
<xacro:property name="wheel_length" value="0.015" />
<xacro:property name="wheel_m" value="0.05" />
<xacro:macro name="add_wheels" params="name flag">
<link name="${name}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
<material name="black" />
visual>
<collision>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
collision>
<xacro:cylinder_inertial_matrix m="${wheel_m}" r="${wheel_radius}" h="${wheel_length}" />
link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
<axis xyz="0 1 0" />
joint>
<gazebo reference="${name}_wheel">
<material>Gazebo/Redmaterial>
gazebo>
xacro:macro>
<xacro:add_wheels name="left" flag="1" />
<xacro:add_wheels name="right" flag="-1" />
<xacro:property name="support_wheel_radius" value="0.0075" />
<xacro:property name="support_wheel_m" value="0.03" />
<xacro:macro name="add_support_wheel" params="name flag" >
<link name="${name}_wheel">
<visual>
<geometry>
<sphere radius="${support_wheel_radius}" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black" />
visual>
<collision>
<geometry>
<sphere radius="${support_wheel_radius}" />
geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
collision>
<xacro:sphere_inertial_matrix m="${support_wheel_m}" r="${support_wheel_radius}" />
link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
<axis xyz="1 1 1" />
joint>
<gazebo reference="${name}_wheel">
<material>Gazebo/Redmaterial>
gazebo>
xacro:macro>
<xacro:add_support_wheel name="front" flag="1" />
<xacro:add_support_wheel name="back" flag="-1" />
robot>
接着编写机器人摄像头的xacro文件
<robot name="my_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:property name="camera_length" value="0.01" />
<xacro:property name="camera_width" value="0.025" />
<xacro:property name="camera_height" value="0.025" />
<xacro:property name="camera_x" value="0.08" />
<xacro:property name="camera_y" value="0.0" />
<xacro:property name="camera_z" value="${base_link_length / 2 + camera_height / 2}" />
<xacro:property name="camera_m" value="0.01" />
<link name="camera">
<visual>
<geometry>
<box size="${camera_length} ${camera_width} ${camera_height}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="black" />
visual>
<collision>
<geometry>
<box size="${camera_length} ${camera_width} ${camera_height}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
collision>
<xacro:Box_inertial_matrix m="${camera_m}" l="${camera_length}" w="${camera_width}" h="${camera_height}" />
link>
<joint name="camera2base_link" type="fixed">
<parent link="base_link" />
<child link="camera" />
<origin xyz="${camera_x} ${camera_y} ${camera_z}" />
joint>
<gazebo reference="camera">
<material>Gazebo/Bluematerial>
gazebo>
robot>
接着编写机器人激光雷达的xacro文件
<robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:property name="support_length" value="0.15" />
<xacro:property name="support_radius" value="0.01" />
<xacro:property name="support_x" value="0.0" />
<xacro:property name="support_y" value="0.0" />
<xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" />
<xacro:property name="support_m" value="0.02" />
<link name="support">
<visual>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="red">
<color rgba="0.8 0.2 0.0 0.8" />
material>
visual>
<collision>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
collision>
<xacro:cylinder_inertial_matrix m="${support_m}" r="${support_radius}" h="${support_length}" />
link>
<joint name="support2base_link" type="fixed">
<parent link="base_link" />
<child link="support" />
<origin xyz="${support_x} ${support_y} ${support_z}" />
joint>
<gazebo reference="support">
<material>Gazebo/Whitematerial>
gazebo>
<xacro:property name="laser_length" value="0.05" />
<xacro:property name="laser_radius" value="0.03" />
<xacro:property name="laser_x" value="0.0" />
<xacro:property name="laser_y" value="0.0" />
<xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" />
<xacro:property name="laser_m" value="0.1" />
<link name="laser">
<visual>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="black" />
visual>
<collision>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
collision>
<xacro:cylinder_inertial_matrix m="${laser_m}" r="${laser_radius}" h="${laser_length}" />
link>
<joint name="laser2support" type="fixed">
<parent link="support" />
<child link="laser" />
<origin xyz="${laser_x} ${laser_y} ${laser_z}" />
joint>
<gazebo reference="laser">
<material>Gazebo/Blackmaterial>
gazebo>
robot>
接下来将惯性矩阵算法文件导入,并组合机器人底盘、摄像头和激光雷达
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="my_head.urdf.xacro" />
<xacro:include filename="my_base.urdf.xacro" />
<xacro:include filename="my_camera.urdf.xacro" />
<xacro:include filename="my_laser.urdf.xacro" />
robot>
最后编写好launch文件并打开终端运行launch文件,配置好rviz和gazebo就可以看到机器人模型
<launch>
<param name="robot_description" command="$(find xacro)/xacro $(find demo02_urdf_gazebo)/urdf/xacro/my_robot.urdf.xacro" />
<node pkg="rviz" type="rviz" name="rviz" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" output="screen" />
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen" />
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" output="screen" />
<include file="$(find gazebo_ros)/launch/empty_world.launch" />
<node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" />
launch>
以上就是ROS机器人建模与仿真学习笔记的内容。通过使用ROS进行机器人建模和仿真,可以更好地理解机器人的行为和性能,并且可以更好地优化机器人的设计。此外,ROS还提供了一系列的仿真工具,如Gazebo和Stage,可以帮助工程师模拟不同环境下的机器人行为,从而更好地理解机器人在不同条件下的表现。
机器人建模和仿真还可以帮助工程师开发和测试机器人的控制算法,以及评估机器人的性能和鲁棒性。此外,通过使用ROS进行机器人建模和仿真,可以更好地理解机器人系统的各个组件之间的交互和通信,从而更好地设计和调试机器人系统的软件架构。
另外,机器人建模和仿真还可以帮助工程师实现快速迭代和开发,因为在虚拟环境中进行测试和验证比在实际机器人上进行测试和验证更加高效和灵活。通过使用ROS进行机器人建模和仿真,可以更快速地识别和解决机器人系统中的问题,从而提高开发效率和机器人的性能和可靠性。