【ROS教程 007】3D建模與模擬

在所有開始之前請安裝erratic_robot功能包集。我們需要在Gazebo中使用

erratic_robot功能包集中的差分不定式機器人驅動來移動機器人模型。

$ sudo apt-get install ros-fuerte-erratic-robotn

沒有機會真正接觸到一個機器人時,模擬不失為最好的選擇。本節我們將學習創建機器人3D模型、為機器人提供運動 物理控制 慣性 和其他物理響應、為機器人3D模型添加模擬感測器、在模擬環境中使用該模型。

(1)自定義機器人在ROS中的3D模型

在ROS中使用機器人3D模型或部分結構模型主要是用於模擬機器人或者是為了幫助開發者簡化他們的日常工作,當然具體的方法都是通過URDF文件。標準化機器人描述格式(URDF)是一種用於描述機器人、其部分結構、關節、自由度等的XML格式文件。每次在ROS系統中看到3D的機器人都會有對應的URDF文件與之對應,例如PR2(Willow Garage)或者是Robonaut(NASA)。

(2)創建第一個URDF文件

我們將在下面建立的機器人是一種常見的移動機器人,它有四個輪子、一個帶有抓取器的手臂。為了打好基礎我們先創建一個帶有四個輪子的機器人底座。在chapter5_tutorials/urdf文件夾下創建一個新文件robot1.urdf,內容如下:

<?xml version="1.0"?>n<robot name=" Robot1 ">n<link name="base_link">n <visual>n <geometry>n <box size="0.2 .3 .1"/>n </geometry>n<origin rpy="0 0 0" xyz="0 0 0.05"/>n<material name="white">n<color rgba="1 1 1 1"/>n</material>n </visual>n<collision>n<geometry>n <box size="0.2 .3 0.1"/>n</geometry>n</collision>n<inertial>n<mass value="100"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>nn </link>nn <link name="wheel_1">n <visual>n <geometry>n <cylinder length="0.05" radius="0.05"/>n </geometry>n<origin rpy="0 1.5 0" xyz="0.1 0.1 0"/>n <material name="black">n<color rgba="0 0 0 1"/>n</material>n</visual>n<collision>n<geometry>n <cylinder length="0.05" radius="0.05"/>n</geometry>n</collision>n<inertial>n<mass value="10"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>n </link>nn <link name="wheel_2">n <visual>n <geometry>n <cylinder length="0.05" radius="0.05"/>n </geometry>n<origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/>n <material name="black"/>n </visual>n<collision>n<geometry>n <cylinder length="0.05" radius="0.05"/>n</geometry>n</collision>n<inertial>n<mass value="10"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>nn </link>nn <link name="wheel_3">n <visual>n <geometry>n <cylinder length="0.05" radius="0.05"/>n </geometry>n<origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/>n <material name="black"/>n </visual>n<collision>n<geometry>n <cylinder length="0.05" radius="0.05"/>n</geometry>n</collision>n<inertial>n<mass value="10"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>n </link>nn <link name="wheel_4">n <visual>n <geometry>n <cylinder length="0.05" radius="0.05"/>n </geometry>n<origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/>n <material name="black"/>n </visual>n<collision>n<geometry>n <cylinder length="0.05" radius="0.05"/>n</geometry>n</collision>n<inertial>n<mass value="10"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>nn </link>nn <joint name="base_to_wheel1" type="fixed">n <parent link="base_link"/>n <child link="wheel_1"/>n <origin xyz="0 0 0"/>n </joint>nn <joint name="base_to_wheel2" type="fixed">n <parent link="base_link"/>n <child link="wheel_2"/>n <origin xyz="0 0 0"/>n </joint>nn <joint name="base_to_wheel3" type="fixed">n <parent link="base_link"/>n <child link="wheel_3"/>n <origin xyz="0 0 0"/>n </joint>nn <joint name="base_to_wheel4" type="fixed">n <parent link="base_link"/>n <child link="wheel_4"/>n <origin xyz="0 0 0"/>n </joint>nn<link name="arm_base">n <visual>n <geometry>n <box size="0.1 .1 .1"/>n </geometry>n<origin rpy="0 0 0" xyz="0 0 0.1"/>n<material name="white">n<color rgba="1 1 1 1"/>n</material>n </visual>n<collision>n<geometry>n <box size="0.1 .1 .1"/>n</geometry>n</collision>n<inertial>n<mass value="1"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>n </link>nn<joint name="base_to_arm_base" type="continuous">n<parent link="base_link"/>n<child link="arm_base"/>n<axis xyz="0 0 1"/>n<origin xyz="0 0 0"/>n</joint>nn<link name="arm_1">n <visual>n <geometry>n <box size="0.05 .05 0.5"/>n </geometry>n<origin rpy="0 0 0" xyz="0 0 0.25"/>n<material name="white">n<color rgba="1 1 1 1"/>n</material>n </visual>n<collision>n<geometry>n <box size="0.05 .05 0.5"/>n</geometry>n</collision>n<inertial>n<mass value="1"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>n </link>nn<joint name="arm_1_to_arm_base" type="revolute">n<parent link="arm_base"/>n<child link="arm_1"/>n<axis xyz="1 0 0"/>n<origin xyz="0 0 0.15"/>n<limit effort ="1000.0" lower="-1.0" upper="1.0" velocity="0.5"/>n</joint>nn<link name="arm_2">n <visual>n <geometry>n <box size="0.05 0.05 0.5"/>n </geometry>n<origin rpy="0 0 0" xyz="0.06 0 0.15"/>n<material name="white">n<color rgba="1 1 1 1"/>n</material>n </visual>n<collision>n<geometry>n <box size="0.05 .05 0.5"/>n</geometry>n</collision>n<inertial>n<mass value="1"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>n </link>nn<joint name="arm_2_to_arm_1" type="revolute">n<parent link="arm_1"/>n<child link="arm_2"/>n<axis xyz="1 0 0"/>n<origin xyz="0.0 0 0.45"/>n<limit effort ="1000.0" lower="-2.5" upper="2.5" velocity="0.5"/>n</joint>nn <joint name="left_gripper_joint" type="revolute">n <axis xyz="0 0 1"/>n <limit effort="1000.0" lower="0.0" upper="0.548" velocity="0.5"/>n <origin rpy="0 -1.57 0" xyz="0.06 0 0.4"/>n <parent link="arm_2"/>n <child link="left_gripper"/>n </joint>nn <link name="left_gripper">n <visual>n <origin rpy="0 0 0" xyz="0 0 0"/>n <geometry>n <mesh filename="package://pr2_description/meshes/gripper_v0/l_finger.dae"/>n </geometry>n </visual>n<collision>n<geometry>n <box size="0.1 .1 .1"/>n</geometry>n</collision>n<inertial>n<mass value="1"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>n </link>nn <joint name="left_tip_joint" type="fixed">n <parent link="left_gripper"/>n <child link="left_tip"/>n </joint>nn <link name="left_tip">n <visual>n <origin rpy="0.0 0 0" xyz="0.09137 0.00495 0"/>n <geometry>n <mesh filename="package://pr2_description/meshes/gripper_v0/l_finger_tip.dae"/>n </geometry>n </visual>n<collision>n<geometry>n <box size="0.1 .1 .1"/>n</geometry>n</collision>n<inertial>n<mass value="1"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>n </link>nn <joint name="right_gripper_joint" type="revolute">n <axis xyz="0 0 -1"/>n <limit effort="1000.0" lower="0.0" upper="0.548" velocity="0.5"/>n <origin rpy="0 -1.57 0" xyz="0.06 0 0.4"/>n <parent link="arm_2"/>n <child link="right_gripper"/>n </joint>nn <link name="right_gripper">n <visual>n <origin rpy="-3.1415 0 0" xyz="0 0 0"/>n <geometry>n <mesh filename="package://pr2_description/meshes/gripper_v0/l_finger.dae"/>n </geometry>n </visual>n<collision>n<geometry>n <box size="0.1 .1 .1"/>n</geometry>n</collision>n<inertial>n<mass value="1"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>nn </link>nn <joint name="right_tip_joint" type="fixed">n <parent link="right_gripper"/>n <child link="right_tip"/>n </joint>nn <link name="right_tip">n <visual>n <origin rpy="-3.1415 0 0" xyz="0.09137 0.00495 0"/>n <geometry>n <mesh filename="package://pr2_description/meshes/gripper_v0/l_finger_tip.dae"/>n </geometry>n </visual>n<collision>n<geometry>n <box size="0.1 .1 .1"/>n</geometry>n</collision>n<inertial>n<mass value="1"/>n<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>n</inertial>nn </link>n</robot>n

在代碼中有兩種用於描述機器人幾何結構的基本欄位:連接(link)和關節(joint)。檢查我們的配置是否正確可以使用

$ rosrun urdf_parser check_urdf robot1.urdfn

cd進入到chapter5_tutorials文件夾下( 注意路徑問題) , 以圖形的方式來查看它, 可以看到如下圖所示

$ rosrun urdf_parser urdf_to_graphiz "./urdf/robot1.urdf"n

這個工具將會在Fuerte之後被棄用,如果使用的版本比較新,應該使用urdfdom功能包。

num1:在rivz里查看3D模型。

現在我們有了自己的機器人,使用rviz查看它的3D展示以及它關節的運行。在launch文件夾下創建display.launch文件,並在文件中輸入以下代碼:

<launch>n<arg name="model" />n<arg name="gui" default="False" />n<param name="robot_description" textfile="$(arg model)" />n<param name="use_gui" value="$(arg gui)"/>n<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>n<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />n<node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.vcg" />n</launch>n

cd進入到chapter5_tutorials文件夾下( 注意路徑問題) ,使用以下命令啟動它

$ roslaunch chapter5_tutorials display.launch model:="./urdf/robot1.urdf"n

有時希望自己構建的模型更加真實,通過添加更多的元素使模型變得更加豐富和細緻,這就需要載入我們自行創建的圖形或者是使用其他機器人模型的圖形。

(3)寫機器人模型方法xacro

xacro可幫助我們減小URDF文件的尺寸,並增加文件的可讀性和可維護性,我們可以方便地使用常量、數學方法、宏等進行編程。 我們可以使用 SketchUp之類的3D建模程序來創建模型。 SketchUp只能在Windows或Mac系統下運行。

(4)使用Gazebo在ROS中模擬

要想在ROS系統中對我們的模型進行模擬,需要使用Gazebo。Gazebo是一種適用於機器人和室外環境的模擬環境。它能夠在三維環境中對多個機器人、感測器及物體進行模擬,產生實際感測器反饋和物體之間的物理響應。

  • num1:在Gazebo中使用URDF3D模型

在urdf/robot1_base_01.xacro找到修改後的文件:

<?xml version="1.0"?>nn<robot xmlns:xacro="http://www.ros.org/wiki/xacro"n xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"n xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"n xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"nname="robot1_xacro">nn<xacro:property name="length_wheel" value="0.05" />n<xacro:property name="radius_wheel" value="0.05" />n<xacro:macro name="default_inertial" params="mass">n <inertial>n <mass value="${mass}" />n <inertia ixx="1.0" ixy="0.0" ixz="0.0"n iyy="1.0" iyz="0.0"n izz="1.0" />n </inertial>n</xacro:macro>nn<link name="base_footprint">n <visual>n<geometry>n <box size="0.001 0.001 0.001"/>n </geometry>n<origin rpy="0 0 0" xyz="0 0 0"/>n </visual>n<xacro:default_inertial mass="0.0001"/>n </link>nn<gazebo reference="base_footprint">n<material>Gazebo/Green</material>n<turnGravityOff>false</turnGravityOff>n</gazebo>nn<joint name="base_footprint_joint" type="fixed">n<origin xyz="0 0 0" />n<parent link="base_footprint" />n<child link="base_link" />n</joint>nn<link name="base_link">n <visual>n<geometry>n <box size="0.2 .3 .1"/>n </geometry>n<origin rpy="0 0 1.54" xyz="0 0 0.05"/>n<material name="white">n<color rgba="1 1 1 1"/>n</material>n </visual>n<collision>n<geometry>n <box size="0.2 .3 0.1"/>n</geometry>n</collision>n<xacro:default_inertial mass="10"/>n </link>nn <link name="wheel_1">n <visual>n <geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n </geometry>n<!-- <origin rpy="0 1.5 0" xyz="0.1 0.1 0"/> -->n<origin rpy="0 0 0" xyz="0 0 0"/>n <material name="black">n<color rgba="0 0 0 1"/>n</material>n</visual>n<collision>n<geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n</geometry>n</collision>n<xacro:default_inertial mass="1"/>n </link>nn <link name="wheel_2">n <visual>n <geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n </geometry>n<!-- <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/> -->n<origin rpy="0 0 0" xyz="0 0 0"/>n <material name="black"/>n </visual>n<collision>n<geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n</geometry>n</collision>n<xacro:default_inertial mass="1"/>nn </link>nn <link name="wheel_3">n <visual>n <geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n </geometry>n<!-- <origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/> -->nn<origin rpy="0 0 0" xyz="0 0 0"/>n <material name="black"/>n </visual>n<collision>n<geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n</geometry>n</collision>n<xacro:default_inertial mass="1"/>n </link>nn <link name="wheel_4">n <visual>n <geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n </geometry>n<!-- <origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/> -->n<origin rpy="0 0 0" xyz="0 0 0" />n <material name="black"/>n </visual>n<collision>n<geometry>n <cylinder length="${length_wheel}" radius="${radius_wheel}"/>n</geometry>n</collision>n<xacro:default_inertial mass="1"/>nn </link>nn <joint name="base_to_wheel1" type="continuous">n <parent link="base_link"/>n <child link="wheel_1"/>n <origin rpy="1.5707 0 0" xyz="0.1 0.15 0"/>n <axis xyz="0 0 1" />n </joint>nn <joint name="base_to_wheel2" type="continuous">n <axis xyz="0 0 1" />n <anchor xyz="0 0 0" />n <limit effort="100" velocity="100" />n <parent link="base_link"/>n <child link="wheel_2"/>n <origin rpy="1.5707 0 0" xyz="-0.1 0.15 0"/>n</joint>nn <joint name="base_to_wheel3" type="continuous">n <parent link="base_link"/>n <axis xyz="0 0 1" />n <child link="wheel_3"/>n <origin rpy="1.5707 0 0" xyz="0.1 -0.15 0"/>n </joint>nn <joint name="base_to_wheel4" type="continuous">n <parent link="base_link"/>n <axis xyz="0 0 1" />n <child link="wheel_4"/>n <origin rpy="1.5707 0 0" xyz="-0.1 -0.15 0"/>n </joint>n</robot>n

這是機器人底盤base_link的新代碼。請注意 collision和 inertial部分對於在Gazebo中運行模型是必需的,這樣才能計算機器人的物理響應。

想要啟動這一切,我們需要創建一個名為gazebo.launch

<?xml version="1.0"?>n<launch>n <!-- this launch file corresponds to robot model in ros-pkg/robot_descriptions/pr2/erratic_defs/robots for full erratic -->nn <param name="/use_sim_time" value="true" />nn <!-- start up wg world -->n <include file="$(find gazebo_worlds)/launch/empty_world.launch"/>nn <arg name="model" />n <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />nn <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>n <!-- start robot state publisher -->n <node pkg="robot_state_publisher" type="state_publisher" name="robot_state_publisher" output="screen" >n <param name="publish_frequency" type="double" value="50.0" />n </node>nn <node name="spawn_robot" pkg="gazebo" type="spawn_model" args="-urdf -param robot_description -z 0.1 -model robot_model" respawn="false" output="screen" />nn</launch>n

想要啟動文件,需要使用以下命令:

$ roslaunch chapter5_tutorials gazebo.launch model:="./urdf/robot1_base_01.xacro"n

現在在Gazebo中看到機器人,祝賀,已在虛擬世界中邁出第一步!

正如上圖所見,模型並沒有任何的紋理渲染。在rviz中能看到URDF文件中聲明的紋理,但是在Gazebo中卻看不到。將robot1_base_01.xacro文件另存為robot1_base_02.xacro並添加以下代碼:

<gazebo reference="base_link">n <material>Erratic/BlueBrushedAluminum</material>n </gazebo>nn <gazebo reference="wheel_1">n <material>Erratic/Black</material>n </gazebo>nn <gazebo reference="wheel_2">n <material>Erratic/Black</material>n </gazebo>nn <gazebo reference="wheel_3">n <material>Erratic/Black</material>n </gazebo>nn <gazebo reference="wheel_4">n <material>Erratic/Black</material>n </gazebo>n

啟動這個新文件將會看到一個帶有紋理的機器人。

  • num2:在Gazebo中添加感測器

在Gazebo中能夠對機器人的物理運行進行模擬,同樣還能模擬它的感測器,本節我們將會向模型中添加一個激光雷達感測器。這個感測器將會成為機器人你的一個新部件,你要選好它的安裝位置。在Gazebo中你會看到一個新的3D模型,它很像Hokuyo激光雷達。我們會從erratic_gazebo_plugins功能包中調用激光雷達。唯一需要做的就是向.xacro文件中增加這些行變為robot1_base_03.xacro:

<include filename="$(find erratic_description)/urdf/erratic_hokuyo_laser.xacro" />nn <!-- BASE LASER ATTACHMENT -->n <erratic_hokuyo_laser parent="base_link">n <origin xyz="0.18 0 0.11" rpy="0 0 0" />n </erratic_hokuyo_laser>n

使用以下命令啟動新的模型將會看到附帶有雷達模塊的機器人:

num3:在Gazebo中載入和使用地圖

在本小節中我們將會使用一張柳樹車庫公司辦公室地圖,這張圖在我們的ROS軟體中默認安裝了。這個3D模型保存在gazebo_words功能包中,為了檢查模型,需要使用以下命令啟動.launch文件

$ roslaunch gazebo_worlds wg_collada_world.launchn

我們需要創建一個新的.launch文件來同時載入地圖和機器人。在launch文件夾下創建gazebo_map_robot.launch,內容如下:

<?xml version="1.0"?>n<launch>n <!-- this launch file corresponds to robot model in ros-pkg/robot_descriptions/pr2/erratic_defs/robots for full erratic -->nn <param name="/use_sim_time" value="true" />nn <!-- start up wg world -->n <include file="$(find gazebo_worlds)/launch/wg_collada_world.launch"/>nn <arg name="model" />n <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />nn <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>n <!-- start robot state publisher -->n <node pkg="robot_state_publisher" type="state_publisher" name="robot_state_publisher" output="screen" >n <param name="publish_frequency" type="double" value="50.0" />n </node>nn <node name="spawn_robot" pkg="gazebo" type="spawn_model" args="-urdf -param robot_description -z 0.1 -model robot_model" respawn="false" output="screen" />nn</launch>n

現在運行帶有激光雷達的模型文件,你會在Gazebo GUI中看到機器人和地圖。

$ roslaunch chapter5_tutorials gazebo_map_robot.launch model:="./urdf/robot1_base_03.xacro"n

num4: 在Gazebo中移動機器人

差分輪式機器人是一種對機身兩側輪子分別進行驅動的移動機器人。它通過將兩側的輪子控制在不同的轉速進行轉向,而不需要輪子有任何轉向運動。差分驅動通常意味著機器人有2個驅動輪,而我們的機器人有4個輪子,因此在運動中會出現問題,所以要進行一些修改。修改後的文件為robot1_base_04.xacro,內容如下:

<?xml version="1.0"?>nn<robot xmlns:xacro="http://www.ros.org/wiki/xacro" n txmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"n txmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"n txmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"ntname="robot1_xacro">nnnt<include filename="$(find erratic_description)/urdf/erratic_hokuyo_laser.xacro" />nn <!-- BASE LASER ATTACHMENT -->n <erratic_hokuyo_laser parent="base_link">n <origin xyz="0.18 0 0.11" rpy="0 0 0" />n </erratic_hokuyo_laser>nnt<xacro:property name="length_wheel" value="0.05" />nt<xacro:property name="radius_wheel" value="0.05" />nt<xacro:macro name="default_inertial" params="mass">n <inertial>n <mass value="${mass}" />n <inertia ixx="1.0" ixy="0.0" ixz="0.0"n iyy="1.0" iyz="0.0"n izz="1.0" />n </inertial>nt</xacro:macro>nnt<link name="base_footprint">n tt<visual>nttt<geometry>n tttt<box size="0.001 0.001 0.001"/>n ttt</geometry>nttt<origin rpy="0 0 0" xyz="0 0 0"/>n tt</visual>ntt<xacro:default_inertial mass="0.0001"/>n t</link>nnt<gazebo reference="base_footprint">ntt<material>Gazebo/Green</material>ntt<turnGravityOff>false</turnGravityOff>nt</gazebo>nnt<joint name="base_footprint_joint" type="fixed">ntt<origin xyz="0 0 0" />ntt<parent link="base_footprint" />ntt<child link="base_link" />nt</joint>nnnt<link name="base_link">n tt<visual>nttt<geometry>n tttt<box size="0.2 .3 .1"/>n ttt</geometry>nttt<origin rpy="0 0 1.54" xyz="0 0 0.05"/>nttt<material name="white">ntttt<color rgba="1 1 1 1"/>nttt</material>n tt</visual>ntt<collision>nttt<geometry>n tttt<box size="0.2 .3 0.1"/>nttt</geometry>ntt</collision>ntt<xacro:default_inertial mass="10"/>n t</link>nn t<link name="wheel_1">n tt<visual>n ttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>n ttt</geometry>nttt<!-- <origin rpy="0 1.5 0" xyz="0.1 0.1 0"/> -->nttt<origin rpy="0 0 0" xyz="0 0 0"/>n ttt<material name="black">ntttt<color rgba="0 0 0 1"/>nttt</material>ntt</visual>ntt<collision>nttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>nttt</geometry>ntt</collision>ntt<xacro:default_inertial mass="1"/>n t</link>nn t<link name="wheel_2">n tt<visual>n ttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>n ttt</geometry>nttt<!-- <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/> -->nttt<origin rpy="0 0 0" xyz="0 0 0"/>n ttt<material name="black"/>n tt</visual>ntt<collision>nttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>nttt</geometry>ntt</collision>ntt<xacro:default_inertial mass="1"/>nn t</link>n n t<link name="wheel_3">n tt<visual>n ttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>n ttt</geometry>nttt<!-- <origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/> -->nnttt<origin rpy="0 0 0" xyz="0 0 0"/>n ttt<material name="black"/>n tt</visual>ntt<collision>nttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>nttt</geometry>ntt</collision>ntt<xacro:default_inertial mass="1"/>n t</link>nn t<link name="wheel_4">n tt<visual>n ttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>n ttt</geometry>ntt<!--t<origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/> -->nttt<origin rpy="0 0 0" xyz="0 0 0" />n ttt<material name="black"/>n tt</visual>ntt<collision>nttt<geometry>n tttt<cylinder length="${length_wheel}" radius="${radius_wheel}"/>nttt</geometry>ntt</collision>ntt<xacro:default_inertial mass="1"/>nn t</link>nnnn <joint name="base_to_wheel1" type="continuous">n <parent link="base_link"/>n <child link="wheel_1"/>n <origin rpy="1.5707 0 0" xyz="0.1 0.15 0"/>n <axis xyz="0 0 1" />n </joint>nn <joint name="base_to_wheel2" type="continuous">n <axis xyz="0 0 1" />n <anchor xyz="0 0 0" />n <limit effort="100" velocity="100" />n <parent link="base_link"/>n <child link="wheel_2"/>n <origin rpy="1.5707 0 0" xyz="-0.1 0.15 0"/>n</joint>nn <joint name="base_to_wheel3" type="continuous">n <parent link="base_link"/>n <axis xyz="0 0 1" />n <child link="wheel_3"/>n <origin rpy="1.5707 0 0" xyz="0.1 -0.15 0"/>n </joint>nn <joint name="base_to_wheel4" type="continuous">n <parent link="base_link"/>n <axis xyz="0 0 1" />n <child link="wheel_4"/>n <origin rpy="1.5707 0 0" xyz="-0.1 -0.15 0"/>n </joint>nn <gazebo reference="base_link">n <material>Erratic/BlueBrushedAluminum</material>n </gazebo>n n <gazebo reference="wheel_1">n <material>Erratic/Black</material>n </gazebo>nn <gazebo reference="wheel_2">n <material>Erratic/Black</material>n </gazebo>nn <gazebo reference="wheel_3">n <material>Erratic/Black</material>n </gazebo>nn <gazebo reference="wheel_4">n <material>Erratic/Black</material>n </gazebo>nn <gazebo>nn <controller:diffdrive_plugin name="differential_drive_controller" plugin="libdiffdrive_plugin.so">n <alwaysOn>true</alwaysOn>n <update>100</update>n <updateRate>100.0</updateRate>n <leftJoint>base_to_wheel4</leftJoint>n <rightJoint>base_to_wheel1</rightJoint>n <wheelSeparation>0.33</wheelSeparation>n <wheelDiameter>0.1</wheelDiameter>n <torque>5</torque>n <interface:position name="position_iface_0"/>n t<topicName>cmd_vel</topicName>n </controller:diffdrive_plugin>nn</gazebo>n</robot>n

現在我們使用以下命令啟動帶有控制器和地圖的模型:

$ roslaunch chapter5_tutorials gazebo_map_robot.launch model:="./urdf/robot1_base_04.xacro"n

現在我們將使用節點來移動那個機器人,這個節點在erratic_teleop功能包中,運行以下命令,你可以使用W/A/S/D按鍵來移動機器人。

$ rosrun erratic_teleop erratic_keyboard_teleopn

Refrences:

[1]. Aaron Martinez Enrique Fern andez, ROS機器人程序設計[B], P104-125, 2014.

answers.ros.org/questio

推薦閱讀:

怎樣用ROS打造機器人建圖導航
ROS和ROS2.0現在到底該學習哪個呢?
基於ROS的自主導航小車Plantbot--SLAM
ROS機器人操作系統相關書籍、資料和學習路徑
ROS 2正式版來了,到底有哪些新變化?

TAG:机器人操作平台ROS | 3D建模 |