环境:ubuntu16.04 ros-kinetic gazebo7.16
基础要求:基础的urdf文件launch文件内容,能够理解并可以参考编写
问题来源:
仿真时候,机器人可能需要各种形式的世界环境,虽然gazebo里面有创建世界建模工具,弄出来也色彩挺好的.但是对于学机械工程的汪而言,仿真时候一般只要一个实体结构就OK了,对色彩要求基本上没有(除了做相机方面的仿真),并且在gazebo上面建模不如solidwork来的方便呀.当然,我们获取只有STL格式的文件.如果喜欢其他绚丽的dae格式文件,可以用其他的建模工具获取.
制作基本流程:
(1)从solidwork获取STL文件
(2)把世界的STL文件加载到urdf加载gazebo里面
(3)把gazebo世界中的模型文件另存为 .world文件比并处理
案例制作一个亭子(tingzi)世界.
(1)从solidwork获取STL文件
这里有一些地方要注意:
A.需要给solidwork添加一个sw2urdf
插件(链接http://wiki.ros.org/sw_urdf_exporter
),怎么安装,百度OK了,教程太多了,就不多说了.安装这个插件并不是为了获取urdf,而是拿里面的STL文件.
B.在solidwork
里面创建世界环境模型时候,我们要注意,采用的是 零件(.part/sldprt
) 格式 创建;第二点,建模时采用的坐标系和gazebo里面的坐标系xyz一致,一般选择前视基准面(0xy面)开始创建世界环境
模型得到的STL文件,后面到urdf里面角度一般不需要再修改了.
(2)把世界的STL文件加载到urdf加载gazebo里面
把STL放到一个包里面,创建以下两个文件:
tingzi.urdf:
<?xml version="1.0"?>
<robot name="tingzi">
<!--base_link-->
<link name="base_link">
<collision>
<geometry>
<box size="0.00001 0.00001 0.00001"/>
</geometry>
</collision>
<inertial>
<mass value="1" />
<origin xyz="0 0 0" rpy="0 0 0"/>
<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1" />
</inertial>
</link>
<!--tingzi-->
<joint name="tingzi_joint" type="fixed">
<origin xyz="0 0 0" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="tingzi"/>
</joint>
<link name="tingzi">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<mesh filename= "package://rpy/meshes/tingzi.STL"/>
</geometry>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<mesh filename= "package://rpy/meshes/tingzi.STL"/>
</geometry>
</collision>
</link>
<gazebo reference="tingzi">
<material>Gazebo/Orange</material>
</gazebo>
</robot>
tingzi.launch:
<?xml version="1.0"?>
<launch>
<arg name="model" default="$(find rpy)/urdf/tingzi.urdf"/>
<arg name="gui" default="true" />
<param name="robot_description" textfile="$(arg model)" />
<param name="use_gui" value="$(arg gui)" />
<!--take robot in gazebo-->
<include file="$(find gazebo_ros)/launch/empty_world.launch" />
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model"
args="-z 1.0 -unpause -urdf -model robot -param robot_description" respawn="false" output="screen" />
</launch>
把亭子加载到gazebo里面有如下效果图:
(3)把gazebo世界中的模型文件另存为 .world
文件并调整
在gazebo
左上角窗口点击 file-save world as
把文件保存为tingzi.world
初步的到文件如下:
<sdf version='1.6'>
<world name='default'>
<light name='sun' type='directional'>
<cast_shadows>1</cast_shadows>
<pose frame=''>0 0 10 0 -0 0</pose>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.2 0.2 0.2 1</specular>
<attenuation>
<range>1000</range>
<constant>0.9</constant>
<linear>0.01</linear>
<quadratic>0.001</quadratic>
</attenuation>
<direction>-0.5 0.1 -0.9</direction>
</light>
<model name='ground_plane'>
<static>1</static>
<link name='link'>
<collision name='collision'>
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
<surface>
<friction>
<ode>
<mu>100</mu>
<mu2>50</mu2>
</ode>
<torsional>
<ode/>
</torsional>
</friction>
<contact>
<ode/>
</contact>
<bounce/>
</surface>
<max_contacts>10</max_contacts>
</collision>
<visual name='visual'>
<cast_shadows>0</cast_shadows>
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
<material>
<script>
<uri>file://media/materials/scripts/gazebo.material</uri>
<name>Gazebo/Grey</name>
</script>
</material>
</visual>
<self_collide>0</self_collide>
<kinematic>0</kinematic>
</link>
</model>
<gravity>0 0 -9.8</gravity>
<magnetic_field>6e-06 2.3e-05 -4.2e-05</magnetic_field>
<atmosphere type='adiabatic'/>
<physics name='default_physics' default='0' type='ode'>
<max_step_size>0.001</max_step_size>
<real_time_factor>1</real_time_factor>
<real_time_update_rate>1000</real_time_update_rate>
</physics>
<scene>
<ambient>0.4 0.4 0.4 1</ambient>
<background>0.7 0.7 0.7 1</background>
<shadows>1</shadows>
</scene>
<spherical_coordinates>
<surface_model>EARTH_WGS84</surface_model>
<latitude_deg>0</latitude_deg>
<longitude_deg>0</longitude_deg>
<elevation>0</elevation>
<heading_deg>0</heading_deg>
</spherical_coordinates>
<model name='robot'>
<link name='base_link'>
<pose frame=''>0 0 0 0 -0 0</pose>
<inertial>
<pose frame=''>0 0 0 0 -0 0</pose>
<mass>1</mass>
<inertia>
<ixx>1</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>1</iyy>
<iyz>0</iyz>
<izz>1</izz>
</inertia>
</inertial>
<collision name='base_link_collision'>
<pose frame=''>0 0 0 0 -0 0</pose>
<geometry>
<box>
<size>1e-05 1e-05 1e-05</size>
</box>
</geometry>
<max_contacts>10</max_contacts>
<surface>
<contact>
<ode/>
</contact>
<bounce/>
<friction>
<torsional>
<ode/>
</torsional>
<ode/>
</friction>
</surface>
</collision>
<collision name='base_link_fixed_joint_lump__tingzi_collision_1'>
<pose frame=''>0 0 0 0 -0 0</pose>
<geometry>
<mesh>
<scale>1 1 1</scale>
<uri>/home/we/robot_ws/src/rpy/meshes/tingzi.STL</uri>
</mesh>
</geometry>
<surface>
<contact>
<ode/>
</contact>
<friction>
<ode/>
<torsional>
<ode/>
</torsional>
</friction>
<bounce/>
</surface>
<max_contacts>10</max_contacts>
</collision>
<visual name='base_link_fixed_joint_lump__tingzi_visual'>
<pose frame=''>0 0 0 0 -0 0</pose>
<geometry>
<mesh>
<scale>1 1 1</scale>
<uri>/home/we/robot_ws/src/rpy/meshes/tingzi.STL</uri>
</mesh>
</geometry>
<material>
<script>
<name>Gazebo/Orange</name>
<uri>file://media/materials/scripts/gazebo.material</uri>
</script>
</material>
</visual>
<gravity>1</gravity>
<velocity_decay/>
<self_collide>0</self_collide>
<kinematic>0</kinematic>
</link>
<pose frame=''>0 0 1 0 -0 0</pose>
</model>
<state world_name='default'>
<sim_time>26 775000000</sim_time>
<real_time>27 70954037</real_time>
<wall_time>1595225579 410294609</wall_time>
<iterations>26775</iterations>
<model name='ground_plane'>
<pose frame=''>0 0 0 0 -0 0</pose>
<scale>1 1 1</scale>
<link name='link'>
<pose frame=''>0 0 0 0 -0 0</pose>
<velocity>0 0 0 0 -0 0</velocity>
<acceleration>0 0 0 0 -0 0</acceleration>
<wrench>0 0 0 0 -0 0</wrench>
</link>
</model>
<model name='robot'>
<pose frame=''>0 0 5e-06 1e-06 -1e-06 0</pose>
<scale>1 1 1</scale>
<link name='base_link'>
<pose frame=''>0 0 5e-06 1e-06 -1e-06 0</pose>
<velocity>0 0 0 0 -0 0</velocity>
<acceleration>0 0 -2.6e-05 -4.9e-05 4.9e-05 0</acceleration>
<wrench>0 0 -2.6e-05 0 -0 0</wrench>
</link>
</model>
<light name='sun'>
<pose frame=''>0 0 10 0 -0 0</pose>
</light>
</state>
<gui fullscreen='0'>
<camera name='user_camera'>
<pose frame=''>13.1053 -12.6365 7.60592 0 0.275643 2.35619</pose>
<view_controller>orbit</view_controller>
<projection_type>perspective</projection_type>
</camera>
</gui>
</world>
</sdf>
因为要处理一些冲突问题,把文件进行部分删除(除了含有STL引用的model标签包含的内容以外,都删除)以及补充(补充sun和ground)处理如下:
<sdf version='1.6'>
<world name='default'>
<include>
<uri>model://ground_plane</uri>
</include>
<!-- A global light source -->
<include>
<uri>model://sun</uri>
</include>
<!--tingzi-->
<model name='tingzi'>
<static>true</static>//设置为true保证,我们的模型在gazebo里面绝对固定
<link name='base_link'>
<pose frame=''>0 0 -1 0 -0 0</pose>//这里需要调整一下z的大小,以保证亭子底部贴合地面
<inertial>
<pose frame=''>0 0 0 0 -0 0</pose>
<mass>1</mass>
<inertia>
<ixx>1</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>1</iyy>
<iyz>0</iyz>
<izz>1</izz>
</inertia>
</inertial>
<collision name='base_link_collision'>
<pose frame=''>0 0 0 0 -0 0</pose>
<geometry>
<box>
<size>1e-05 1e-05 1e-05</size>
</box>
</geometry>
<max_contacts>10</max_contacts>
<surface>
<contact>
<ode/>
</contact>
<bounce/>
<friction>
<torsional>
<ode/>
</torsional>
<ode/>
</friction>
</surface>
</collision>
<collision name='base_link_fixed_joint_lump__tingzi_collision_1'>
<pose frame=''>0 0 0 0 -0 0</pose>
<geometry>
<mesh>
<scale>1 1 1</scale>
<uri>/home/we/robot_ws/src/rpy/meshes/tingzi.STL</uri>//自动生成的是绝对路径(根据stl文件存放位置生成的),可以改写为 包+路径 引用样式的.
</mesh>
</geometry>
<surface>
<contact>
<ode/>
</contact>
<friction>
<ode/>
<torsional>
<ode/>
</torsional>
</friction>
<bounce/>
</surface>
<max_contacts>10</max_contacts>
</collision>
<visual name='base_link_fixed_joint_lump__tingzi_visual'>
<pose frame=''>0 0 0 0 -0 0</pose>
<geometry>
<mesh>
<scale>1 1 1</scale>
<uri>/home/we/robot_ws/src/rpy/meshes/tingzi.STL</uri>//含义同上
</mesh>
</geometry>
<material>
<script>
<name>Gazebo/Orange</name>//这里表示了model在gazebo里面显示为橙色的,当然,截图里面电脑显卡比较菜,可能gazebo色差比较严重
<uri>file://media/materials/scripts/gazebo.material</uri>
</script>
</material>
</visual>
<gravity>1</gravity>
<velocity_decay/>
<self_collide>0</self_collide>
<kinematic>0</kinematic>
</link>
<pose frame=''>0 0 1 0 -0 0</pose>
</model>
</world>
</sdf>
最后在终端使用 gazebo tingzi.world 启动该模型,效果如下:
总结:
(1)这个制作方式是可以拓展的,如直接替换的自己不同的STL文件;或者制作含有单独颜色地标线的工厂环境时,需要放不同的STL,套路都一样的,就在原来的urdf里面加多一个link,到时候在.world里面单独定义颜色就行了.
(2)至于调整物理属性啥的,就查找sdf里面的编写格式来改写就OK了,或者找些例子参考一些就贴上去也挺快的.要相信,我们不是第一个碰到这个问题的人,一定有人已经解决了,只是我们暂时没找到而已.
注意,代码中出现的中文注释,
使用时候一定要去掉,否则容易出现未知错误;或者把注释翻译成英文
,然后使用<!-- -->
包含起来也是可以的.
#####################
好记性不如烂笔头
–20200720