URDF小车创建及可视化
准备工作
名称 | 版本 |
---|---|
ROS | Noetic |
Gazebo | 11.11.0 |
小车俯视图
1. 创建workspace和package
mkdir -p ~/robot_four/src
cd ..
sudo apt-get install python3-catkin-tools (如果 `catkin:command not found`)
catkin build
# source ~/robot_four/devel/setup.bash (等同于以下)
echo "source ~/robot_four/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
cd ~/robot_four/src
catkin_create_pkg robot_model_pkg_zoe gazebo_msgs gazebo_plugins gazebo_ros
2. URDF文件创建
URDF
和 Xacro
文件关系:
Xacro
(XML Macros)是一种用于生成URDF
(Unified Robot Description Format)文件的工具,它可以简化URDF
文件的编写过程。
URDF
是一种用于描述机器人模型的XML文件格式。
所以我们写xacro
文件就可以了。
cd ~/roboT_four/src/robot_model_pkg_zoe
mkdir urdf
mkdir launch
cd urdf
touch robot.xacro
robot.xacro
具体内容如下
<?xml version="1.0"?>
<!--##########################################-->
<!--DESCRIPTION OF THE 4-WHEELED ROBOT-->
<!--##########################################-->
<robot name="differential_drive_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!--Body dimensions-->
<xacro:property name="body_link_x_dim" value="1"/>
<xacro:property name="body_link_y_dim" value="0.6"/>
<xacro:property name="body_link_z_dim" value="0.3"/>
<!--Wheel dimensions-->
<xacro:property name="wheel_link_radius" value="0.15"/>
<xacro:property name="wheel_link_length" value="0.1"/>
<xacro:property name="wheel_link_z_location" value="-0.1"/>
<!--Material density-->
<xacro:property name="body_density" value="2710.0"/>
<xacro:property name="wheel_density" value="2710.0"/>
<!--Pi constant-->
<xacro:property name="pi_constant" value="3.14159265" />
<!--Robot body and wheel mass-->
<xacro:property name="body_mass" value="${body_density*body_link_x_dim*body_link_y_dim*body_link_z_dim}"/>
<xacro:property name="wheel_mass" value="${wheel_density*wheel_link_radius*wheel_link_radius*pi_constant*wheel_link_length}"/>
<!--Moments of inertia of the wheel-->
<xacro:property name="Iz_wheel" value="${0.5*wheel_mass*wheel_link_radius*wheel_link_radius}"/>
<xacro:property name="I_wheel" value="${(1.0/12.0)*wheel_mass*(3.0*wheel_link_radius*wheel_link_radius+wheel_link_length*wheel_link_length)}"/>
<!--This macro defines the complete inertial section of the wheel-->
<!--It is used later in the code-->
<xacro:macro name="inertial_wheel">
<inertial>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
<mass value="${wheel_mass}"/>
<inertia ixx="${I_wheel}" ixy="0.0" ixz="0.0" iyy="${I_wheel}" iyz="0.0" izz="${Iz_wheel}"/>
</inertial>
</xacro:macro>
<!--Over here we include the file that defines extra Gazebo options and motion control driver-->
<xacro:include filename="$(find robot_model_pkg_zoe)/urdf/robot.gazebo"/>
<!--######################################################-->
<!--FROM HERE WE DEFINE LINKS, JOINTS-->
<!--######################################################-->
<!--we need to have this dummy link otherwise Gazebo will complain-->
<link name="dummy">
</link>
<joint name="dummy_joint" type="fixed">
<parent link="dummy"/>
<child link="body_link"/>
</joint>
<!--######################################################-->
<!--START: BODY LINK OF THE ROBOT-->
<!--######################################################-->
<link name="body_link">
<visual>
<geometry>
<box size="${body_link_x_dim} ${body_link_y_dim} ${body_link_z_dim}"/>
</geometry>
<origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
</visual>
<collision>
<geometry>
<box size="${body_link_x_dim} ${body_link_y_dim} ${body_link_z_dim}"/>
</geometry>
<origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
</collision>
<inertial>
<origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
<mass value="${body_mass}"/>
<inertia ixx="${(1/12)*body_mass*(body_link_y_dim*body_link_y_dim+body_link_z_dim*body_link_z_dim)}" ixy="0"
ixz="0" iyy="${(1/12)*body_mass*(body_link_x_dim*body_link_x_dim+body_link_z_dim*body_link_z_dim)}"
iyz="0"
izz="${(1/12)*body_mass*(body_link_y_dim*body_link_y_dim+body_link_x_dim*body_link_x_dim)}"/>
</inertial>
</link>
<!--######################################################-->
<!--END: BODY LINK OF THE ROBOT-->
<!--######################################################-->
<!--######################################################-->
<!--START: BACK RIGHT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
<joint name="wheel1_joint" type="continuous">
<parent link="body_link"/>
<child link="wheel1_link"/>
<origin xyz="${-body_link_x_dim/2+1.2*wheel_link_radius} ${-body_link_y_dim/2-wheel_link_length/2} ${wheel_link_z_location}" rpy="0.0 0.0 0.0"/>
<axis xyz="0.0 1.0 0.0"/>
<limit effort="1000.0" velocity="1000.0"/>
<dynamics damping="1.0" friction="1.0"/>
</joint>
<link name="wheel1_link">
<visual>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</visual>
<collision>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</collision>
<xacro:inertial_wheel/>
</link>
<!--######################################################-->
<!--END: BACK RIGHT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
<!--######################################################-->
<!--START: BACK LEFT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
<joint name="wheel2_joint" type="continuous">
<parent link="body_link"/>
<child link="wheel2_link"/>
<origin xyz="${-body_link_x_dim/2+1.2*wheel_link_radius} ${body_link_y_dim/2+wheel_link_length/2} ${wheel_link_z_location}" rpy="0.0 0.0 0.0"/>
<axis xyz="0.0 1.0 0.0"/>
<limit effort="1000.0" velocity="1000.0"/>
<dynamics damping="1.0" friction="1.0"/>
</joint>
<link name="wheel2_link">
<visual>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</visual>
<collision>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</collision>
<xacro:inertial_wheel/>
</link>
<!--######################################################-->
<!--END: BACK LEFT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
<!--######################################################-->
<!--START: FRONT RIGHT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
<joint name="wheel3_joint" type="continuous">
<parent link="body_link"/>
<child link="wheel3_link"/>
<origin xyz="${body_link_x_dim/2-1.2*wheel_link_radius} ${-body_link_y_dim/2-wheel_link_length/2} ${wheel_link_z_location}" rpy="0.0 0.0 0.0"/>
<axis xyz="0.0 1.0 0.0"/>
<limit effort="1000.0" velocity="1000.0"/>
<dynamics damping="1.0" friction="1.0"/>
</joint>
<link name="wheel3_link">
<visual>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</visual>
<collision>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</collision>
<xacro:inertial_wheel/>
</link>
<!--######################################################-->
<!--END: FRONT RIGHT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
<!--######################################################-->
<!--START: FRONT LEFT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
<joint name="wheel4_joint" type="continuous">
<parent link="body_link"/>
<child link="wheel4_link"/>
<origin xyz="${body_link_x_dim/2-1.2*wheel_link_radius} ${body_link_y_dim/2+wheel_link_length/2} ${wheel_link_z_location}" rpy="0.0 0.0 0.0"/>
<axis xyz="0.0 1.0 0.0"/>
<limit effort="1000.0" velocity="1000.0"/>
<dynamics damping="1.0" friction="1.0"/>
</joint>
<link name="wheel4_link">
<visual>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</visual>
<collision>
<origin rpy="1.570795 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<cylinder radius="${wheel_link_radius}" length="${wheel_link_length}"/>
</geometry>
</collision>
<xacro:inertial_wheel/>
</link>
<!--######################################################-->
<!--END: FRONT LEFT WHEEL OF THE ROBOT AND THE JOINT-->
<!--######################################################-->
</robot>
robot.gazebo
文件 -> 规定了robot
各部件在gazebo
中显示的颜色。
<?xml version="1.0"?>
<!--###########################################-->
<!--GAZEBO ADDITIONAL DESCRIPTION OF THE 4-WHELLED ROBOT-->
<!--MADE BY ZOE, FOLLOW ALEKSANDAR HABER-->
<!--MAY 2024-->
<!--###########################################-->
<robot>
<!--mu1 and mu2 are friction coefficients-->
<gazebo reference="body_link">
<mu1>0.2</mu1>
<mu2>0.2</mu2>
<material>Gazebo/Red</material>
</gazebo>
<gazebo reference="wheel1_link">
<mu1>0.2</mu1>
<mu2>0.2</mu2>
<material>Gazebo/Yellow</material>
</gazebo>
<gazebo reference="wheel2_link">
<mu1>0.2</mu1>
<mu2>0.2</mu2>
<material>Gazebo/Yellow</material>
</gazebo>
<gazebo reference="wheel3_link">
<mu1>0.2</mu1>
<mu2>0.2</mu2>
<material>Gazebo/Yellow</material>
</gazebo>
<gazebo reference="wheel4_link">
<mu1>0.2</mu1>
<mu2>0.2</mu2>
<material>Gazebo/Yellow</material>
</gazebo>
<!--Controller for the 4-wheeled robot-->
<gazebo>
<plugin name="skid_steer_drive_controller" filename="libgazebo_ros_skid_steer_drive.so">
<!--Control update rate in Hz-->
<updateRate>100.0</updateRate>
<!--Leave this empty otherwise, there will be problems with sending control commands-->
<robotNamespace> </robotNamespace>
<!--Robot kinematics-->
<leftFrontJoint>wheel4_joint</leftFrontJoint>
<rightFrontJoint>wheel3_joint</rightFrontJoint>
<leftRearJoint>wheel2_joint</leftRearJoint>
<rightRearJoint>wheel1_joint</rightRearJoint>
<wheelSeparation>${body_link_y_dim+wheel_link_length}</wheelSeparation>
<wheelDiameter>${2*wheel_link_radius}</wheelDiameter>
<!--Maxium torque which the wheels can produce, in Nm, defaults to 5 Nm-->
<torque>1000</torque>
<!--Topic to receive geometry_msgs/Twist message commands, defaults to 'cmd_vel'-->
<commandTopic>cmd_vel</commandTopic>
<!--Topic to publish nav_msgs/Odometry messages, defaults to 'odom'-->
<odometryTopic>odom</odometryTopic>
<!--Odometry frame, defaults to 'odom'-->
<odometryFrame>odom</odometryFrame>
<!--Robot frame to calculabte odometry from, defaults to 'base_footprint'-->
<robotBaseFrame>dummy</robotBaseFrame>
<!--Set to true to publish transfroms for the wheel links, defaults to false-->
<publishWheelTF>true</publishWheelTF>
<!--Set to true to publish transforms for the odometry, defaults to true-->
<publishOdom>true</publishOdom>
<!--Set to true to publish sensor_msgs/JointState on /joint_states for the wheel joints, defaults to false-->
<publishWheelJointState>true</publishWheelJointState>
<!--This part is requeired by Gazebo-->
<covariance_x>0.0001</covariance_x>
<covariance_y>0.0001</covariance_y>
<covariance_yaw>0.01</covariance_yaw>
</plugin>
</gazebo>
</robot>
3. 将xacro
文件转换成urdf
cd ~/robot_four/src/robot_model_pkg_zoe/urdf
rosrun xacro xacro robot.xacro > robot.urdf
4. URDF
可视化
4.1 用launch文件来可视化urdf
cd ~/robot_four/src/robot_model_pkg_zoe/launch
touch robot_show.launch
robot_show.launch
文件如下
<launch>
<arg name="model" />
<arg name="gui" default="False" />
<param name="robot_description" textfile="$(find robot_model_pkg_zoe)/urdf/robot.urdf" />
<param name="use_gui" value="$(arg gui)"/>
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find robot_model_pkg_zoe)/rviz/robot.rviz" />
</launch>
cd ~/robot_four
roslaunch robot_model_pkg_zoe robot_show.launch
4.2 命令行可视化
roslaunch urdf_tutorial display.launch model:='$(find robot_model_pkg_zoe)/urdf
这时候可能会显示错误,只要把Fixed Frame
改成我们自己定义的dummy
就会正常显示。
其中的颜色信息会在gazebo
中体现,在rviz
中还看不到。