【从零开始的ROS四轴机械臂控制】(二) - ROS与Gazebo连接,Gazebo仿真及urdf文件修改
【從零開始的ROS四軸機械臂控制(二)】
- 四、urdf文件及gazebo仿真
- 1.simple_arm示例
- (1)config文件夾
- (2)launch文件夾
- (3)meshes文件夾
- (4)urdf文件夾
- (5)worlds文件夾
- (6)文件間聯系
- 2.根據simple_arm示例改進arm0文件夾
- (1)urdf文件夾
- ①arm1.gazebo.xacro
- ②arm1.urdf.xacro
- (2)config文件夾
- (3)launch文件夾
- ①robot_control.xml
- ②robot_description.xml
- ③gazebo.launch
- (4)scripts文件夾
四、urdf文件及gazebo仿真
首先先忽略硬件部分,來看一下gazebo仿真部分。這一個部分的目標是,實現使用arm_mover節點和look_away服務節點來控制gazebo中的機器人。
本部分完成后如上圖所示,使用simple_mover控制機械臂移動。
我找了很多關于urdf資料后發現,很多人講urdf說的比較模糊,而且沒有實際例子來驗證。或者介紹的比較模糊,并不是很能理解從Solidworks導出urdf文件后如何進行實際的應用。很多博客都是以導入到rviz中能使用作為結束,但是這樣的話對我們這個項目來說是遠遠不夠的。
所以為了能順利地進行項目,所以重點來研究一下urdf文件和包。 我在改進我的arm0的包的時候主要參考了simple_arm這個示例,如果不想看simple_arm示例可以直接跳到四、2根據simple_arm 示例改進arm0文件夾,其主要詳細說明了四軸機械臂項目的arm0包。
1.simple_arm示例
有關于工作區可以參考博客【Udacity機器人軟件工程師課程筆記(九)-ROS-Catkin包、工作空間和目錄結構】
有關simple_arm和gazebo可以參考【Udacity機器人軟件工程師課程筆記(十)-ROS-Catkin-包(package)和gazebo】
以下是從github倉庫克隆的 simple_arm 的包。
接下來要針對每一個文件來分析其作用。當時我在學習使用simple_arm這個包時,沒有很好的研究其文件內容。但是現在要搭建針對于自己項目的gazebo文件,還是很有必要好好的看一下其中文件的結構及內容的。
(1)config文件夾
config文件夾:配置文件
controllers.yaml
simple_arm:#list of controllersjoint_state_controller:type: joint_state_controller/JointStateControllerpublish_rate: 50joint_1_position_controller:type: effort_controllers/JointPositionControllerjoint: joint_1pid: {p: 100.0, i: 0.01, d: 10.0}joint_2_position_controller:type: effort_controllers/JointPositionControllerjoint: joint_2pid: {p: 100.0, i: 0.01, d: 10.0}
(2)launch文件夾
launch:提供更自動化的啟動節點的方式
robot_control.xml:
<launch><!--將關節控制器加載到param服務器--><rosparam file="$(find simple_arm)/config/controllers.yaml" command="load"/><!--Load controllers--><node name="spawner" pkg="controller_manager" type="spawner" respawn="false"output="screen" ns="/simple_arm" args="joint_state_controllerjoint_1_position_controllerjoint_2_position_controller"/>
</launch>
```xml
robot_description.xml:
``` robot_spawn.launch ```xml ```
(3)meshes文件夾
meshes中包含了相機的3d模型文件。
meshes 中文件可以包括meshes(.dae(Collada)或.stl(STereoLithography)格式的CAD文件)。
(4)urdf文件夾
urdf:通用機器人描述文件。
simple_arm.gazebo.xacro:
定義gazebo中的的模型,其中包括
- (1)定義gazebo
- (2)定義link
- 1)base link
- 2)link_1
- 3)link_2
- 4)camera_link
- (3)定義攝像頭
<?xml version="1.0"?>
<robot><!-- ros_control插件 --><gazebo><plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so"><robotNamespace>/simple_arm</robotNamespace><robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType></plugin></gazebo><!--base_link--><gazebo reference="base_link"><material>Gazebo/White</material></gazebo><!--link_1--><gazebo reference="link_1"><mu1>0.2</mu1><mu2>0.2</mu2><material>Gazebo/Orange</material></gazebo><!--link_2--><gazebo reference="link_2"><mu1>0.2</mu1><mu2>0.2</mu2><material>Gazebo/White</material></gazebo><!--camera_link--><gazebo reference="camera_link"><material>Gazebo/Grey</material></gazebo><!-- 攝像頭--><gazebo reference="camera_link"><sensor type="camera" name="rgb_camera"><update_rate>30.0</update_rate><camera name="rgb_camera"><horizontal_fov>1.4</horizontal_fov><image><width>640</width><height>480</height><format>R8G8B8</format></image><clip><near>0.02</near><far>300</far></clip></camera><plugin name="camera_controller" filename="libgazebo_ros_camera.so"><alwaysOn>true</alwaysOn><updateRate>0.0</updateRate><cameraName>rgb_camera</cameraName><imageTopicName>image_raw</imageTopicName><cameraInfoTopicName>camera_info</cameraInfoTopicName><frameName>camera_link</frameName><hackBaseline>0.0</hackBaseline><distortionK1>0.0</distortionK1><distortionK2>0.0</distortionK2><distortionK3>0.0</distortionK3><distortionT1>0.0</distortionT1><distortionT2>0.0</distortionT2></plugin></sensor></gazebo></robot>
simple_arm.urdf.xacro:其中...為省略部分:
這個部分定義link、joint和transmission
<?xml version="1.0"?>
<robot name="simple_arm" xmlns:xacro="http://www.ros.org/wiki/xacro"><!--Define constants--><xacro:property name="link_type" value="cuboidal" /><xacro:property name="PI" value="3.14159"/>...<!--Import gazebo elements--><xacro:include filename="$(find simple_arm)/urdf/simple_arm.gazebo.xacro" /><!--Links--><link name="world"/><link name="base_link"><visual><origin xyz="0 0 ${length1/2}" rpy="0 0 0"/><geometry><cylinder length="${length1}" radius="${radius1}"/></geometry><material name="white"><color rgba="1.0 1.0 1.0 1.0"/></material></visual><collision><origin xyz="0 0 ${length1/2}" rpy="0 0 0"/><geometry><cylinder length="${length1}" radius="${radius1}"/></geometry></collision><inertial><origin xyz="0 0 ${length1/2}" rpy="0 0 0"/><mass value="${mass1}"/><inertiaixx="${mass1 / 12.0 * (2*radius1*2*radius1 + length1*length1)}" ixy="0.0" ixz="0.0"iyy="${mass1 / 12.0 * (length1*length1 + 2*radius1*2*radius1)}" iyz="0.0"izz="${mass1 / 12.0 * (2*radius1*2*radius1 + 2*radius1*2*radius1)}"/></inertial></link>...<!--camera_link--><link name="camera_link"><collision><origin xyz="0 0 0" rpy="0 0 0"/><geometry><!--mesh filename="package://simple_arm/meshes/camera.dae"/--><sphere radius="${camera_size}"/></geometry></collision><visual><origin xyz="0 0 0" rpy="0 0 0"/><geometry><!--mesh filename="package://simple_arm/meshes/camera.dae"/--><sphere radius="${camera_size}"/></geometry><material name="red"><color rgba="1.0 0 0 1.0"/></material></visual><inertial><mass value="1e-5" /><origin xyz="0 0 0" rpy="0 0 0"/><inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6" /></inertial></link><!--Joints--><joint name="fixed_base_joint" type="fixed"><parent link="world"/><child link="base_link"/></joint>...<joint name="camera_joint" type="fixed"><axis xyz="0 0 1" /><origin xyz="0 0 ${length3}" rpy="0 -${PI/2} 0"/><parent link="link_2"/><child link="camera_link"/></joint><!--轉換和執行器--><transmission name="tran1"><type>transmission_interface/SimpleTransmission</type><joint name="joint_1"><hardwareInterface>EffortJointInterface</hardwareInterface></joint><actuator name="motor1"><hardwareInterface>EffortJointInterface</hardwareInterface><mechanicalReduction>1</mechanicalReduction></actuator></transmission><transmission name="tran2"><type>transmission_interface/SimpleTransmission</type><joint name="joint_2"><hardwareInterface>EffortJointInterface</hardwareInterface></joint><actuator name="motor2"><hardwareInterface>EffortJointInterface</hardwareInterface><mechanicalReduction>1</mechanicalReduction></actuator></transmission>
</robot>
(5)worlds文件夾
willow_garage.world是用于Gazebo仿真環境的XML文件,如果不定義可以使用空白世界。所以這個文件為可選文件。
(6)文件間聯系
從框圖中我們可以比較清楚的的除了文件的框架結構。所有的文件都指向到robot_spawn.launch文件。要實現搭建自己的包,就要按照框圖一步步的修改從solidworks導出的urdf文件。
各文件夾功能如下所示
? script(python可執行文件)
? src(C ++源文件)
? msg(用于自定義消息定義)
? srv(用于服務消息定義)
? include - >作為依賴項所需的頭文件/庫
? config - >配置文件
? launch - >提供更自動化的啟動節點的方式
其他文件夾可能包括
? urdf(通用機器人描述文件)
? meshes(.dae(Collada)或.stl(STereoLithography)格式的CAD文件)
? worlds(用于Gazebo仿真環境的XML文件)
2.根據simple_arm示例改進arm0文件夾
由于某些原因(導出了多次urdf文件),我的文件夾實際名稱為arm1,在此特別說明一下,在接下來也會以arm1作為例子。
以上是arm1包中的所有內容,我已經將它上傳至github,其版本號定為Robot arm 0.1.1,功能是通過simple_mover.py實現了最基本機械臂的運動 。
arm1包(arm version 0.1.1)結構如下
arm1|-config| |-controllers.yaml|-launch| |-gazebo.launch| |-robot_control.xml| |-robot_description.xml|-meshes(未更改)| |-base_link.STL| |-link1.STL| |-link2.STL| |-link3.STL| |-link4.STL|-scripts| |-simple_mover|-urdf| |-arm1.urdf.xacro| |-arm1.gazebo.xacro|-worlds| |-willow_garage.world|-CMakeLists.txt(未更改)|-export.log(未更改)|-package.xml(未更改)
其中 CMakeLists.txt、export.log、package.xml和meshes文件夾中內容為solidworks轉出的自帶內容,其它文件都進行了更改。
(1)urdf文件夾
這部分使用Xacro(XML宏)。
Xacro是一種XML宏語言。使用xacro,可以使用擴展較大的XML表達式的宏來構造更短,更易讀的XML文件。
有關xacro的更多信息可以參考ROS Wiki
①arm1.gazebo.xacro
arm1.gazebo.xacro的主要功能是,添加gazebo_ros_control插件,將ros和gazebo連接起來。
<?xml version="1.0"?><robot><!-- ros_control plugin --><gazebo><plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so"><robotNamespace>/arm1</robotNamespace><robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType></plugin></gazebo><!--base_link--><gazebo reference="base_link"><material>Gazebo/White</material></gazebo><!--link_1--><gazebo reference="link1"><mu1>0.2</mu1><mu2>0.2</mu2><material>Gazebo/Orange</material></gazebo><!--link_2--><gazebo reference="link2"><mu1>0.2</mu1><mu2>0.2</mu2><material>Gazebo/White</material></gazebo><!--link_3--><gazebo reference="link3"><mu1>0.2</mu1><mu2>0.2</mu2><material>Gazebo/Orange</material></gazebo> <!--link_4--><gazebo reference="link4"><mu1>0.2</mu1><mu2>0.2</mu2><material>Gazebo/White</material></gazebo></robot>
②arm1.urdf.xacro
為了方便閱讀,我在其中刪除了一部分的內容,完整部分可以查看github。
這個文件主要定義了arm的urdf文件。其中包括link,joint和Transmission。link和joint 在solidworks轉換出來的文件中已經給出了,在這里不在贅述。
主要注意的有三個地方。
一、我們在urdf文件中,需要對joint打上gazebo使用的transmission標簽,transmission把TF(ros)的連接關系與仿真平臺上的驅動設備(gazebo)聯系在了一起,有了執行器,gazebo就可以在物理層面上對模型進行驅動了。
更多關于transmission標簽可以參考此處。
二、我們需要定義world link,然后再將base link 和world link連接起來,這樣模型才能在gazebo世界中固定。
三、需要導入arm1.gazebo.xacro文件。
<?xml version="1.0" encoding="utf-8"?><!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com) Commit Version: 1.5.1-0-g916b5db Build Version: 1.5.7152.31018For more information, please see http://wiki.ros.org/sw_urdf_exporter --><robotname="arm1" xmlns:xacro="http://www.ros.org/wiki/xacro"><!--Import gazebo elements--><xacro:include filename="$(find arm1)/urdf/arm1.gazebo.xacro" /><!--Links and joints--><link name="world"/><link name="base_link"><inertial><originxyz="0.000877732518704125 -6.1202787414609E-05 0.0136416983965608"rpy="0 0 0" /><massvalue="0.0149906128541691" /><inertiaixx="9.0485354260676E-07"ixy="9.67790693248534E-12"ixz="-1.26661641226237E-08"iyy="1.3035966603116E-06"iyz="-4.46725888473771E-12"izz="1.62723345073819E-06" /></inertial><visual><originxyz="0 0 0"rpy="0 0 0" /><geometry><meshfilename="package://arm1/meshes/base_link.STL" /></geometry><materialname=""><colorrgba="1 1 1 1" /></material></visual><collision><originxyz="0 0 0"rpy="0 0 0" /><geometry><meshfilename="package://arm1/meshes/base_link.STL" /></geometry></collision></link><!--this joint used to fix model--><joint name="fixed_base_joint" type="fixed"><parent link="world"/><child link="base_link"/></joint>...(省略部分)<!--Transmission and actuators--><transmission name="tran1">...(省略部分)</transmission></robot>
(2)config文件夾
為每個joint添加控制器controller,保存為controllers.yaml文件。
arm1:#list of controllersjoint_state_controller:type: joint_state_controller/JointStateControllerpublish_rate: 50joint1_position_controller:type: effort_controllers/JointPositionControllerjoint: joint1pid: {p: 1, i: 0.001, d: 0.002}joint2_position_controller:type: effort_controllers/JointPositionControllerjoint: joint2pid: {p: 1, i: 0.001, d: 0.002}joint3_position_controller:type: effort_controllers/JointPositionControllerjoint: joint3pid: {p: 1, i: 0.001, d: 0.002}joint4_position_controller:type: effort_controllers/JointPositionControllerjoint: joint4pid: {p: 1, i: 0.001, d: 0.002}
(3)launch文件夾
①robot_control.xml
該xml文件負責加載控制器。
<launch><!--Load the joint controllers to param server--><rosparam file="$(find arm1)/config/controllers.yaml" command="load"/><!--Load controllers--><node name="spawner" pkg="controller_manager" type="spawner" respawn="false"output="screen" ns="/arm1" args="joint_state_controllerjoint1_position_controllerjoint2_position_controllerjoint3_position_controllerjoint4_position_controller"/>
</launch>
②robot_description.xml
機器人描述文件,其每個部分的功能見注釋。
<launch><!--Load urdf to param server--><param name="robot_description" command="$(find xacro)/xacro --inorder '$(find arm1)/urdf/arm1.urdf.xacro'"/><!--GUI used to send fake joint values--><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"><param name="use_gui" value="false"/></node><!--Publish robot state to TF--><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"><remap from="/joint_states" to="/arm1/joint_states" /></node>
</launch>
③gazebo.launch
最終的運行文件,加載gazebo和相關節點。
<launch><include file="$(find arm1)/launch/robot_description.xml"/><include file="$(find arm1)/launch/robot_control.xml"/><!--Launch a gazebo world--><include file="$(find gazebo_ros)/launch/empty_world.launch"/><arg name="world_name" value="$(find arm1)/worlds/willow_garage.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"/><node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"args="-urdf -param robot_description -x 0 -y 0 -z 0 -R 0 -P 0 -Y 0 -model arm1"/></launch>
打開一個新的終端
source ~/catkin_ws/devel/setup.bash
roslaunch arm1 gazebo.launch
然后我們就可以看到gazebo成功打開了,模型成功加載如下。
若gazebo中模型出現抖動,則考慮controllers.yaml中的pid參數的設置。我當時按照pid默認值來運行gazebo模型,結果造成了非常嚴重的模型抖動。猜測可能是因為模型尺寸和simple_arm的尺寸相差較大而導致的。
確定了只是因為pid參數的問題之后,那就需要調參了。調參可是門藝術啊。我調整完的參數已經在controllers.yaml中給出了,其效果比默認值好上很多了,但是還是有抖動。
每次調參數,需要重新開啟新的終端加載gazebo。如果有必要,可以輸入以下命令,來關閉所有的gazevo服務。
$ killall gzserver
(4)scripts文件夾
scripts文件夾中存放python的可執行文件,我們需要把我們的simple_mover放到這里邊。
若不存在scripts文件夾,則首先創建它
$ cd ~/catkin_ws/src/arm1/
$ mkdir scripts
$ cd ~/catkin_ws/src/arm1/scripts
創建simple_mover 文件
$ sudo touch simple_mover
使文件可執行
$ sudo chmod 777 simple_mover
編寫simple_mover文件,也可以直接打開文件進行編輯。
nano simple_mover
以下內容可以參考博客【Udacity機器人軟件工程師課程筆記(十一)-ROS-編寫ROS節點】
#!/usr/bin/env pythonimport math
import rospy
from std_msgs.msg import Float64def mover():pub_j1 = rospy.Publisher('/arm1/joint1_position_controller/command',Float64, queue_size=10)pub_j2 = rospy.Publisher('/arm1/joint2_position_controller/command',Float64, queue_size=10)pub_j3 = rospy.Publisher('/arm1/joint3_position_controller/command',Float64, queue_size=10)pub_j4 = rospy.Publisher('/arm1/joint4_position_controller/command',Float64, queue_size=10)rospy.init_node('arm_mover')rate = rospy.Rate(10)start_time = 0while not start_time:start_time = rospy.Time.now().to_sec()while not rospy.is_shutdown():elapsed = rospy.Time.now().to_sec() - start_timepub_j1.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))pub_j2.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))pub_j3.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))pub_j4.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))rate.sleep()if __name__ == '__main__':try:mover()except rospy.ROSInterruptException:pass
在gazebo運行的條件下,新建一個終端。
source ~/catkin_ws/devel/setup.bash
rosrun arm1 simple_mover
運行如下:
總結
以上是生活随笔為你收集整理的【从零开始的ROS四轴机械臂控制】(二) - ROS与Gazebo连接,Gazebo仿真及urdf文件修改的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【从零开始的ROS四轴机械臂控制】(一)
- 下一篇: 【从零开始的ROS四轴机械臂控制】(三)