ROS学习——移动机器人导航仿真(一)

——————————————————————————————————————————————————

一、模型的建立、rviz显示与gazebo仿真

1、工作空间的建立

建立一个工作空间,并在src目录下创建功能包如slam_sim_demo,在功能包下创建urdf与laucn文件夹。

2、xacro文件的编写

(1)、robot_model.xacro——四轮小车

在urdf文件下编写robot_model.xacro

<?xml version="1.0"?>

<robot xmlns:xacro="http://www.ros.org/wiki/xacro"
  		xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
  		xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
  		xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
  		name="robot1_xacro">

	<xacro:property name="length_wheel" value="0.05" />
	<xacro:property name="radius_wheel" value="0.05" />
	<xacro:macro name="default_inertial" params="mass">  //质量与惯性的宏定义
  		<inertial>
  			<mass value="${mass}" />
  			<inertia ixx="1.0" ixy="0.0" ixz="0.0"  //inertiam没有少l
  				 	 iyy="1.0" iyz="0.0"
  					 izz="1.0" />
  			</inertial>
	</xacro:macro>

  <link name="base_footprint">
  	<visual>
      		<geometry>
        		<box size="0.001 0.001 0.001"/>
      		</geometry>  
		<origin rpy="0 0 0" xyz="0 0 0"/>
     	</visual>
     <xacro:default_inertial mass="0.0001"/>
  </link>

  <gazebo reference="base_footprint">
  	<material>Gazebo/Green</material>
  	<turnGravityOff>false</turnGravityOff>
  </gazebo>

  <joint name="base_footprint_joint" type="fixed">
  	<origin xyz="0 0 0" />
     	<parent link="base_footprint" />
     	<child link="base_link" />
  </joint>

  <link name="base_link">
    	<visual>
      		<geometry>
          		<box size="0.2 .3 .1"/>
      		</geometry>
      		<origin rpy="0 0 1.54" xyz="0 0 0.05"/>
      		<material name="Blue">
  			<color rgba="0.0 0.0 0.8 1.0"/>
		</material>
    	</visual>
    	<collision>
    		<geometry>
         		<box size="0.2 .3 0.1"/>
    		</geometry>
    	</collision>
    	<xacro:default_inertial mass="25"/>  //输入的为质量 可以根据仿真情况自行调节
  </link>

  <gazebo reference="base_link">
        <material>Gazebo/Blue</material>
        <turnGravityOff>false</turnGravityOff>
  </gazebo>


  <link name="wheel_1">
    	<visual>
      		<geometry>
         		<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
   		   </geometry>
         	<!-- <origin rpy="0 1.5 0" xyz="0.1 0.1 0"/> -->
     		<origin rpy="0 0 0" xyz="0 0 0"/>
      		<material name="black">
         		<color rgba="0 0 0 1"/>
      		</material>
    	</visual>
    	<collision>
      		<geometry>
         		<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
    		  </geometry>
    	</collision>
    	<xacro:default_inertial mass="1"/>
  </link>

  <gazebo reference="wheel_1">
  	<material>Gazebo/Black</material>
	<turnGravityOff>false</turnGravityOff>
  </gazebo>

  <link name="wheel_2">
    	<visual>
      		<geometry>
         		<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
      		</geometry>
     		<!-- <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/> -->
		<origin rpy="0 0 0" xyz="0 0 0"/>
      		<material name="black"/>
    	</visual>
      	<collision>
      		<geometry>
         		<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
     		 </geometry>
    	</collision>
    	<xacro:default_inertial mass="1"/>

  </link>

  <gazebo reference="wheel_2">
 	 <material>Gazebo/Black</material>
	 <turnGravityOff>false</turnGravityOff>
  </gazebo>

  <link name="wheel_3">
  	<visual>
  		<geometry>
			<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
 		</geometry>
		<!-- <origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/> -->
		<origin rpy="0 0 0" xyz="0 0 0"/>
  		<material name="black"/>
 	</visual>
	<collision>
		<geometry>
 			<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
		</geometry>
	</collision>
	<xacro:default_inertial mass="1"/>
  </link>

  <gazebo reference="wheel_3">
 	 <material>Gazebo/Black</material>
	 <turnGravityOff>false</turnGravityOff>
  </gazebo>

  <link name="wheel_4">
  	<visual>
 		<geometry>
  			<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
  		</geometry>
		<!-- <origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/> -->
		<origin rpy="0 0 0" xyz="0 0 0" />
  		<material name="black"/>
  	</visual>
	<collision>
		<geometry>
  			<cylinder length="${length_wheel}" radius="${radius_wheel}"/>
		</geometry>
	</collision>
	<xacro:default_inertial mass="1"/>

  </link>

  <gazebo reference="wheel_4">
 	 <material>Gazebo/Black</material>
	 <turnGravityOff>false</turnGravityOff>
  </gazebo>

  <joint name="base_to_wheel1" type="continuous">
  	<parent link="base_link"/>
  	<child link="wheel_1"/>
  	<origin rpy="-1.5707 0 0" xyz="0.1 0.15 0"/>
  	<axis xyz="0 0 1" />
  </joint>

  <joint name="base_to_wheel2" type="continuous">
 	<axis xyz="0 0 1" />
  	<anchor xyz="0 0 0" />
  	<limit effort="100" velocity="100" />
  	<parent link="base_link"/>
  	<child link="wheel_2"/>
  	<origin rpy="-1.5707 0 0" xyz="-0.1 0.15 0"/>
 </joint>

 <joint name="base_to_wheel3" type="continuous">
  	<parent link="base_link"/>
  	<axis xyz="0 0 1" />
  	<child link="wheel_3"/>
  	<origin rpy="-1.5707 0 0" xyz="0.1 -0.15 0"/>
 </joint>

 <joint name="base_to_wheel4" type="continuous">
  	<parent link="base_link"/>
  	<axis xyz="0 0 1" />
  	<child link="wheel_4"/>
  	<origin rpy="-1.5707 0 0" xyz="-0.1 -0.15 0"/>
 </joint>
//轮子在gazebo中的属性配置,里程计数据的由来
 <gazebo>
  	<plugin name="skid_steer_drive_controller" filename="libgazebo_ros_skid_steer_drive.so">
    		<updateRate>100.0</updateRate>
   			<robotNamespace>/</robotNamespace>
   			<leftFrontJoint>base_to_wheel1</leftFrontJoint>
   			<rightFrontJoint>base_to_wheel3</rightFrontJoint>
    		<leftRearJoint>base_to_wheel2</leftRearJoint>
    		<rightRearJoint>base_to_wheel4</rightRearJoint>
    		<wheelSeparation>0.2</wheelSeparation>
    		<wheelDiameter>0.1</wheelDiameter>
			<torque>2</torque> //扭矩
			<odometryTopic>odom</odometryTopic> 
    		<odometryFrame>odom</odometryFrame> 
    		<robotBaseFrame>base_footprint</robotBaseFrame>
    		<topicName>cmd_vel</topicName>
    		<broadcastTF>1</broadcastTF>  //开启tf转换
 	</plugin>
 </gazebo>

</robot>

(2)、lidar_model.xacro——激光雷达

在urdf文件下编写lidar_model.xacro

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="laser">

    <xacro:macro name="rplidar" params="prefix:=laser">
        <!-- Create laser reference frame -->
        <link name="${prefix}_link">
            <inertial>
                <mass value="0.1" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.01" ixy="0.0" ixz="0.0"
                         iyy="0.01" iyz="0.0"
                         izz="0.01" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <cylinder length="0.05" radius="0.05"/>
                </geometry>
                <material name="black"/>
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="0.06" radius="0.05"/>
                </geometry>
            </collision>
        </link>
        <gazebo reference="${prefix}_link">
            <material>Gazebo/Black</material>
        </gazebo>

        <gazebo reference="${prefix}_link">
            <sensor type="ray" name="rplidar">
                <pose>0 0 0 0 0 0</pose>
                <visualize>false</visualize>
                <update_rate>5.5</update_rate>
                <ray>
                    <scan>
                      <horizontal>
                        <samples>360</samples>
                        <resolution>1</resolution>
                        <min_angle>-3</min_angle>
                        <max_angle>3</max_angle>
                      </horizontal>
                    </scan>
                    <range>
                      <min>0.10</min>
                      <max>6.0</max>
                      <resolution>0.01</resolution>
                    </range>
                    <noise>
                      <type>gaussian</type>
                      <mean>0.0</mean>
                      <stddev>0.01</stddev>
                    </noise>
                </ray>
                <plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
                    <topicName>/scan</topicName>
                    <frameName>laser_link</frameName>
                </plugin>
            </sensor>
        </gazebo>

    </xacro:macro>
</robot>

(3)、lidar_robot.xacro——机器人整合

urdf文件下编写lidar_robot.xacro

<?xml version="1.0"?>
<robot name="arm" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename="$(find slam_sim_demo)/urdf/robot_model.xacro"/>
    <xacro:include filename="$(find slam_sim_demo)/urdf/lidar_model.xacro"/>
	
    <xacro:property name="lidar_offset_x" value="0" />
    <xacro:property name="lidar_offset_y" value="0" />
    <xacro:property name="lidar_offset_z" value="0.12" />

    <robot_base/>

    <!-- lidar -->
    <joint name="lidar_joint" type="fixed">
        <origin xyz="${lidar_offset_x} ${lidar_offset_y} ${lidar_offset_z}" rpy="0 0 0" />
        <parent link="base_link"/>
        <child link="laser_link"/>
    </joint>

    <xacro:rplidar prefix="laser"/>
   
</robot>

至此机器人模型建立完毕

3、launch文件的编写

(1)view_robot.launch的编写

在launch文件下编写view_robot.launch用于运行rviz

<launch>
        <arg name="Robot_model" />
        <arg name="gui" default="False" />
        <param name="robot_description" command="$(find xacro)/xacro.py $(find slam_sim_demo)/urdf/lidar_robot.xacro" />
        <param name="use_gui" value="$(arg gui)"/>
        <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>
        <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
        <node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" />
</launch>

运行后添加相应属性得到结果如图ROS学习——移动机器人导航仿真(一)_第1张图片

(2)gazebo.launch的编写

注意地图文件

<?xml version="1.0"?>
<launch>

  <!-- these are the arguments you can pass this launch file, for example paused:=true -->
  <arg name="paused" default="true"/>
  <arg name="use_sim_time" default="false"/>
  <arg name="gui" default="true"/>
  <arg name="headless" default="false"/>
  <arg name="debug" default="true"/>
//empty_world.lauch已经被写好,my_house.world自己创建
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="worlds/my_house.world"/>  //自己画的房间
    <arg name="paused" value="false"/>
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="true"/>
    <arg name="headless" value="false"/>
    <arg name="debug" value="false"/>
  </include>

<!-- Load the URDF into the ROS Parameter Server -->
  <arg name="model" default="$(find slam_sim_demo)/urdf/lidar_robot.xacro" />//导入创建好的xacro文件
  <param name="robot_description" 
     command="$(find xacro)/xacro.py $(arg model)" />

  <!-- Run a python script to the send a service call to gazebo_ros to spawn a URDF robot -->
   <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
    args="-urdf -model robot1 -param robot_description -z 0.05"/>

</launch>

运行结果如图
ROS学习——移动机器人导航仿真(一)_第2张图片
在gazebo中点击play按钮(最底下状态栏中)后同时运行view_robot.launch并添加激光雷达数据可看到
ROS学习——移动机器人导航仿真(一)_第3张图片
环境:gazebo7.16+ubuntu16.04+vmware+ros kinetic

4、总结

最开始创立模型时一顾的找源码复制粘贴导致经常出错时看不太懂,后来主动去了解urdf和xacro文件的编写规则语法,直至基本看得懂的模型文件,主要是看的懂模型参数。
通过对urdf模型文件的接触,学习到了tf相关的知识,了解到了机器人各个部件的联系。

5、参考

1、移动机器人导航仿真(1)——3D建模与简单移动.

下一篇
ROS学习——移动机器人导航仿真(二).

你可能感兴趣的:(ROS)