建模一块没有特别需要注意的地方:主要是理解URDF到xacro再到gazebo模型的演变过程;
常规URDF文件用户体验较差,采用xacro模型文件替换;
URDF模型文件的进阶xacro模型文件
- 精简模型代码
- 创建宏定义
- 文件包含
- 提供可编程接口
- 常量
- 变量
- 数学计算(所有数学运算都会转换成浮点数进行,以保证运算经度)
- 条件语句
模型显示
- 将xacro文件转换成URDF文件显示
$ rosrun xacro xacro.py mbot.xacro > mbot.urdf
- 直接调用xacro文件解析器
<arg name = "model" default = "$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/mbot.xacro'"/>
<param name = "robot_description" command = "$(arg model)"/>
URDF优化为XACRO
URDF例程
带摄像头的小车
<?xml version="1.0" ?>
<robot name="mbot">
<link name="base_link">
<visual>
<origin xyz=" 0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="0.16" radius="0.20"/>
</geometry>
<material name="yellow">
<color rgba="1 0.4 0 1"/>
</material>
</visual>
</link>
<joint name="left_wheel_joint" type="continuous">
<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="left_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="1.5707 0 0" />
<geometry>
<cylinder radius="0.06" length = "0.025"/>
</geometry>
<material name="white">
<color rgba="1 1 1 0.9"/>
</material>
</visual>
</link>
<joint name="right_wheel_joint" type="continuous">
<origin xyz="0 -0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="right_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="right_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="1.5707 0 0" />
<geometry>
<cylinder radius="0.06" length = "0.025"/>
</geometry>
<material name="white">
<color rgba="1 1 1 0.9"/>
</material>
</visual>
</link>
<joint name="front_caster_joint" type="continuous">
<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="front_caster_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="front_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
</visual>
</link>
<joint name="back_caster_joint" type="continuous">
<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="back_caster_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="back_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
</visual>
</link>
<link name="camera_link">
<visual>
<origin xyz=" 0 0 0 " rpy="0 0 0" />
<geometry>
<box size="0.03 0.04 0.04" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
</visual>
</link>
<joint name="camera_joint" type="fixed">
<origin xyz="0.17 0 0.10" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="camera_link"/>
</joint>
</robot>
可以分为几个小的xacro文件,并且其中一种变量也可以替换;
xacro例程
可以分解为小车和摄像头两个部分
<?xml version="1.0"?>
<robot name="arm" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find mbot_description)/urdf/xacro/mbot_base.xacro" />
<xacro:include filename="$(find mbot_description)/urdf/xacro/sensors/camera.xacro" />
<xacro:property name="camera_offset_x" value="0.17" />
<xacro:property name="camera_offset_y" value="0" />
<xacro:property name="camera_offset_z" value="0.10" />
<mbot_base/>
<!-- Camera -->
<joint name="camera_joint" type="fixed">
<origin xyz="${camera_offset_x} ${camera_offset_y} ${camera_offset_z}" rpy="0 0 0" />
<parent link="base_link"/>
<child link="camera_link"/>
</joint>
<xacro:usb_camera prefix="camera"/>
</robot>
摄像头的xacro文件
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="camera">
<xacro:macro name="usb_camera" params="prefix:=camera">
<link name="${prefix}_link">
<visual>
<origin xyz=" 0 0 0 " rpy="0 0 0" />
<geometry>
<box size="0.01 0.04 0.04" />
</geometry>
<material name="black"/>
</visual>
</link>
</xacro:macro>
</robot>
小车主体xacro文件
<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- PROPERTY LIST -->
<xacro:property name="M_PI" value="3.1415926"/>
<xacro:property name="base_radius" value="0.20"/>
<xacro:property name="base_length" value="0.16"/>
<xacro:property name="wheel_radius" value="0.06"/>
<xacro:property name="wheel_length" value="0.025"/>
<xacro:property name="wheel_joint_y" value="0.19"/>
<xacro:property name="wheel_joint_z" value="0.05"/>
<xacro:property name="caster_radius" value="0.015"/> <!-- wheel_radius - ( base_length/2 - wheel_joint_z) -->
<xacro:property name="caster_joint_x" value="0.18"/>
<!-- Defining the colors used in this robot -->
<material name="yellow">
<color rgba="1 0.4 0 1"/>
</material>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
<material name="gray">
<color rgba="0.75 0.75 0.75 1"/>
</material>
<!-- Macro for robot wheel -->
<xacro:macro name="wheel" params="prefix reflect">
<joint name="${prefix}_wheel_joint" type="continuous">
<origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="${prefix}_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
<geometry>
<cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
</geometry>
<material name="gray" />
</visual>
</link>
</xacro:macro>
<!-- Macro for robot caster -->
<xacro:macro name="caster" params="prefix reflect">
<joint name="${prefix}_caster_joint" type="continuous">
<origin xyz="${reflect*caster_joint_x} 0 ${-(base_length/2 + caster_radius)}" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="${prefix}_caster_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="${prefix}_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="${caster_radius}" />
</geometry>
<material name="black" />
</visual>
</link>
</xacro:macro>
<xacro:macro name="mbot_base">
<link name="base_footprint">
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link>
<joint name="base_footprint_joint" type="fixed">
<origin xyz="0 0 ${base_length/2 + caster_radius*2}" rpy="0 0 0" />
<parent link="base_footprint"/>
<child link="base_link" />
</joint>
<link name="base_link">
<visual>
<origin xyz=" 0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="${base_length}" radius="${base_radius}"/>
</geometry>
<material name="yellow" />
</visual>
</link>
<wheel prefix="left" reflect="-1"/>
<wheel prefix="right" reflect="1"/>
<caster prefix="front" reflect="-1"/>
<caster prefix="back" reflect="1"/>
</xacro:macro>
</robot>
以某一个轮子的模型为例,查看其由URDF模型到xacro模型再到gazebo模型的演化过程
URDF模型
<joint name="left_wheel_joint" type="continuous">
<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="left_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="1.5707 0 0" />
<geometry>
<cylinder radius="0.06" length = "0.025"/>
</geometry>
<material name="white">
<color rgba="1 1 1 0.9"/>
</material>
</visual>
</link>
xacro模型
其中把轮子模型改写为可复用的形式,其中一些数值采用变量的形式,方便复用和调用。
<!-- Macro for robot wheel -->
<xacro:macro name="wheel" params="prefix reflect">
<joint name="${prefix}_wheel_joint" type="continuous">
<origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="${prefix}_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
<geometry>
<cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
</geometry>
<material name="gray" />
</visual>
</link>
</xacro:macro>
gazebo模型
增加更加详细的属性参数、gazebo标签,以及传动参数,最后添加gazebo控制器插件。
<!-- Macro for robot wheel -->
<xacro:macro name="wheel" params="prefix reflect">
<joint name="${prefix}_wheel_joint" type="continuous">
<origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="${prefix}_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
<geometry>
<cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
</geometry>
<material name="gray" />
</visual>
<collision>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
<geometry>
<cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
</geometry>
</collision>
<cylinder_inertial_matrix m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}" />
</link>
<gazebo reference="${prefix}_wheel_link">
<material>Gazebo/Gray</material>
</gazebo>
<!-- Transmission is important to link the joints and the controller -->
<transmission name="${prefix}_wheel_joint_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${prefix}_wheel_joint" >
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="${prefix}_wheel_joint_motor">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
</xacro:macro>
Gazebo物理仿真环境搭建
相比较xacro模型文件需要补充:
- 为
link
添加惯性参数和碰撞属性 - 为
link
添加gazebo
标签 - 为
joint
添加传动装置 - 添加
gazebo
控制器插件
gazebo
控制器插件
- :机器人的命名空间
- 和:左右轮转动的关节joint
- 和:机器人模型的相关尺寸,计算差速参数时需用到
- :控制器订阅的速度控制指令,生成全局命名时需要结合中设置的命名空间。
- :里程计数据的参考坐标系,ROS中一般都命名为odom。
到目前为止,加载模型的方式两种:一种到rviz中加载模型,一种是在gazebo中加载模型;
在gazebo中加载模型的方法:直接添加环境模型,使用Building Editor;
gazebo传感器仿真
- 标签:描述传感器
- type:传感器类型,camera、depth、ray等
- name:传感器命名,自由设置
- 传感器类型标签:描述传感器参数
- 分辨率,编码格式,图像范围,噪声参数等
- 标签:加载传感器仿真插件
- 摄像头仿真插件
libgazebo_ros_camera.so
;RGB-D kinect摄像头libgazebo_ros_openni_kinect.so
;激光雷达libgazebo_ros_laser.so
; - 设置插件的命名空间、发布图像的话题、参考坐标系等。
- 摄像头仿真插件
遇到的问题
问题一: gazebo–SpawnModel: Failure - model name mrobot already exists.解决办法
原因:用gazebo打开机器人模型后,保存了world,此时的新world比原world多了机器人模型mrobot,所以重新运行launch时提示名字为mrobot的模型已经存在与world中
解决办法:将gazebo_ros功能包中的empty_world.launch复制到自己的功能包中,并把world_name的参数值改成保存后的world地址,运行empty_world.launch,将里面的机器人模型删除再重新保存即可。
问题二:Gazebo页面卡住黑屏,在终端出现Gazebo [Err] [REST.cc:205] Error in REST request
$ sudo gedit ~/.ignition/fuel/config.yaml
......
# url : https://api.ignitionfuel.org 用 # 注释掉
url: https://api.ignitionrobotics.org
问题三:打开gazebo闪退,报错:VMware: vmw_ioctl_command error Invalid argument.
关闭虚拟机硬件加速
echo " export SVGA_VGPU10=0" >> ~/.bashrc
source ~/.bashrc
问题四:下载gazebo模型
cd ~/.gazebo/
ls
mkdir -p models
ls
cd ~/.gazebo/models/
wget http://file.ncnynl.com/ros/gazebo_models.txt
ls
wget -i gazebo_models.txt
ls model.tar.g* | xargs -n1 tar xzvf