ROS中階筆記(四):機器人仿真—Gazebo物理仿真環境搭建(重點)node
Controller_manager 與不少controller都已經很完善了,須要寫的就是robothw部分shell
ros_control的功能主要經過controller來實現的bash
ros_control須要apt-get命令安裝一下,不然這裏的launch文件運行不起來,能夠經過下列命令安裝:less
$ sudo apt-get install ros-kinetic-gazebo-ros-control
在~/catkin_ws/src/mbot_description/urdf/xacro/gazebo下,找到mbot_base_gazebo.xacro
文件dom
以前咱們建立xacro文件的時候,每一個物體只有一個簡單的可視化屬性,若是要在Gazebo中實現的話,須要對這些可視化模型的每一個link添加碰撞屬性以及慣性參數。工具
以base_link爲例:ui
<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> <collision> <origin xyz=" 0 0 0" rpy="0 0 0" /> <geometry> <cylinder length="${base_length}" radius="${base_radius}"/> </geometry> </collision> <cylinder_inertial_matrix m="${base_mass}" r="${base_radius}" h="${base_length}" /> </link>
對比一下前面的base_link,會發現其下面多了一個collision以及cylinder_inertial_matrix,這裏須要對每個link都添加這些屬性。關於慣性矩陣的運算,能夠自行百度。這裏也經過宏定義的形式給出了一個慣性矩陣的計算方式:spa
<xacro:macro name="sphere_inertial_matrix" params="m r"> <inertial> <mass value="${m}" /> <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0" iyy="${2*m*r*r/5}" iyz="0" izz="${2*m*r*r/5}" /> </inertial> </xacro:macro> <xacro:macro name="cylinder_inertial_matrix" params="m r h"> <inertial> <mass value="${m}" /> <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0" iyy="${m*(3*r*r+h*h)/12}" iyz = "0" izz="${m*r*r/2}" /> </inertial> </xacro:macro>
上面一個爲球體的慣性矩陣計算公式,下面爲柱體的計算公式。而後在後面經過調用這些宏來實現慣性矩陣的計算。
一樣的,須要給全部的link添加慣性參數和碰撞屬性。.net
標籤的主要內容是爲了配置每一個link在gazebo中的顏色(gazebo與rivz顏色設置不兼容)例如:插件
給base_link設置了藍色:
<gazebo reference="base_link"> <material>Gazebo/Blue</material> </gazebo>
因爲gazebo的控制是針對於joint作控制的;
例如:我有一個真實的機器人,若是我想讓它的輪子動起來,那麼我須要一個電機驅動這個輪子作運動。這一步的內容就至關於給咱們的機器人模型添加一個電機,也就是一個傳動裝置:
<!-- 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> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <!-- gazebo提供得差速控制器插件 --> <!-- 控制器所需參數 --> <rosDebugLevel>Debug</rosDebugLevel> <publishWheelTF>true</publishWheelTF> <robotNamespace>/</robotNamespace><!-- 機器人命名空間 訂閱和發佈得話題 前面 會加上命名空間 /說明沒有添加--> <publishTf>1</publishTf> <publishWheelJointState>true</publishWheelJointState> <alwaysOn>true</alwaysOn> <updateRate>100.0</updateRate> <legacyMode>true</legacyMode> <leftJoint>left_wheel_joint</leftJoint> <!-- 控制得joint在哪裏,必須和上面得joint名稱一致 --> <rightJoint>right_wheel_joint</rightJoint><!-- 控制得joint在哪裏,必須和上面得joint名稱一致 --> <wheelSeparation>${wheel_joint_y*2}</wheelSeparation><!-- 兩個輪子得間距 --> <wheelDiameter>${2*wheel_radius}</wheelDiameter> <broadcastTF>1</broadcastTF> <wheelTorque>30</wheelTorque> <wheelAcceleration>1.8</wheelAcceleration> <commandTopic>cmd_vel</commandTopic> <!-- 訂閱得話題:速度控制指令 --> <odometryFrame>odom</odometryFrame> <odometryTopic>odom</odometryTopic> <!-- 發佈里程計信息 --> <robotBaseFrame>base_footprint</robotBaseFrame><!-- 設置controler所控制的機器人的座標系是哪一個座標系 --> </plugin> </gazebo>
注意:我加入註釋是爲了更好的理解;xacro中最好不要出現中文,不然可能會報參數問題致使沒法正常啓動。
在~/catkin_ws/src/mbot_gazebo/launch/下建立view_mbot_gazebo_empty_world.launch
文件
<launch> <!-- 設置launch文件的參數 --> <arg name="paused" default="false"/> <arg name="use_sim_time" default="true"/> <arg name="gui" default="true"/> <arg name="headless" default="false"/> <arg name="debug" default="false"/> <!-- 運行gazebo仿真環境 --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="debug" value="$(arg debug)" /> <arg name="gui" value="$(arg gui)" /> <arg name="paused" value="$(arg paused)"/> <arg name="use_sim_time" value="$(arg use_sim_time)"/> <arg name="headless" value="$(arg headless)"/> </include> <!-- 加載機器人模型描述參數 --> <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/gazebo/mbot_gazebo.xacro'" /> <!-- 運行joint_state_publisher節點,發佈機器人的關節狀態 --> <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node> <!-- 運行robot_state_publisher節點,發佈tf --> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" > <param name="publish_frequency" type="double" value="50.0" /> </node> <!-- 在gazebo中加載機器人模型--> <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen" args="-urdf -model mrobot -param robot_description"/> </launch>
$ roslaunch mbot_gazebo view_mbot_gazebo_empty_world.launch # 在空環境中可看到機器人模型
建議:爲保證模型順利加載,請提早將模型文件庫下載並放置到 ~/.gazebo/models 下 在home文件夾下,ctrl + h 能夠查找到全部的隱藏文件 下載地址: https://bitbucket.org/osrf/gazebo_models/downloads/
當機器人出如今gazebo的時候,能夠看到咱們加載的文件裏面只有一個機器人,那咱們但願能給它添加一些障礙物,這時應該怎麼作呢?
①插入模型
模型放置到~/.gazebo/models 文件夾下——在gazebo的左側列表點擊「insert」(能夠看到裏面有不少的模型,咱們只須要從列表中拖出咱們須要的模型放置到仿真環境中就能夠)
②保存仿真環境
File——Save World As——放置在功能包~/catkin_ws/src/mbot_gazebo/worlds下面(路徑本身選擇,主要是在 ~/catkin_ws/src/)
③關閉gazebo界面
若是這些模型不能知足建模需求也能夠經過三維設計軟件搭建模型放到文件夾中使用。例如solidworks建模
①建立模型
Editor——Building Editor,上面界面用於圖形編輯,下面是仿真環境;好比說繪製三維場景中的一堵牆或者一個門。
File——Save保存咱們的模型文件(本身設置模型文件名字)——Exit Building Editor(退出編輯界面),能夠看到咱們的仿真環境已經在gazebo中顯示;
②保存仿真環境
File——Save World As——放置在功能包~/catkin_ws/src/mbot_gazebo/worlds下面(路徑本身選擇,主要是在 ~/catkin_ws/src/)
③關閉gazebo界面
在~/catkin_ws/src/mbot_gazebo/launch下 view_mbot_gazebo_room.launch
若是啓動gazebo時但願加載這個模型,能夠在launch文件最前面添加:
<!-- 設置launch文件的參數 --> <arg name="world_name" value="$(find mbot_gazebo)/worlds/room.world"/>
<!-- 運行gazebo仿真環境 --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="world_name" value="$(arg world_name)" />
$ roslaunch mbot_gazebo view_mbot_gazebo_room.launch # 啓動仿真環境
下面你們能夠進行一些仿真功能的實現
咱們但願它能動起來,那麼打開一個鍵盤控制節點:
$ roslaunch mbot_teleop mbot_teleop.launch
同時也能夠經過監聽odom數據觀察機器人的位置。
$ rostopic echo /odom orientation: # 四元數描述機器人的姿態 x:-2.51798726555e-05 y:-7.59817327643e-06 Z:-0.954841297132 w:0.297116301471
只有機器人的話,並不能作具體的實驗,咱們但願它能與環境交互,那麼咱們須要給機器人添加傳感器。
相似於以前的控制器插件,gazebo一樣擁有不少的傳感器插件。
在~/catkin_ws/src/mbot_description/urdf/xacro/sensors/下
在~/catkin_ws/src/mbot_description/urdf/xacro/sensors/下camera_gazebo.xacro
文件
須要一個攝像頭的xacro文件,它須要添加碰撞屬性以及慣性屬性外,還須要添加攝像頭傳感器插件,具體代碼以下:
<?xml version="1.0"?> <robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="camera"> <xacro:macro name="usb_camera" params="prefix:=camera"> <!-- 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> <box size="0.01 0.04 0.04" /> </geometry> <material name="black"/> </visual> <collision> <origin xyz="0.0 0.0 0.0" rpy="0 0 0" /> <geometry> <box size="0.01 0.04 0.04" /> </geometry> </collision> </link> <gazebo reference="${prefix}_link"> <material>Gazebo/Black</material> </gazebo> <gazebo reference="${prefix}_link"> <sensor type="camera" name="camera_node"> <update_rate>30.0</update_rate> <camera name="head"> <horizontal_fov>1.3962634</horizontal_fov> <image> <width>1280</width> <height>720</height> <format>R8G8B8</format> </image> <clip> <near>0.02</near> <far>300</far> </clip> <noise> <type>gaussian</type> <mean>0.0</mean> <stddev>0.007</stddev> </noise> </camera> <plugin name="gazebo_camera" filename="libgazebo_ros_camera.so"> <alwaysOn>true</alwaysOn> <updateRate>0.0</updateRate> <cameraName>/camera</cameraName> <imageTopicName>image_raw</imageTopicName> <cameraInfoTopicName>camera_info</cameraInfoTopicName> <frameName>camera_link</frameName> <hackBaseline>0.07</hackBaseline> <distortionK1>0.0</distortionK1> <distortionK2>0.0</distortionK2> <distortionK3>0.0</distortionK3> <distortionT1>0.0</distortionT1> <distortionT2>0.0</distortionT2> </plugin> </sensor> </gazebo> </xacro:macro> </robot>
啓動這個帶攝像頭的模型的launch文件(只是改變機器人模型文件和仿真環境文件路徑便可):
$ roslaunch mbot_gazebo view_mbot_with_camera_gazebo.launch
<launch> <!-- 設置launch文件的參數 --> <arg name="world_name" value="$(find mbot_gazebo)/worlds/playground.world"/><!-- 改這個就行 --> <arg name="paused" default="false"/> <arg name="use_sim_time" default="true"/> <arg name="gui" default="true"/> <arg name="headless" default="false"/> <arg name="debug" default="false"/> <!-- 運行gazebo仿真環境 --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="world_name" value="$(arg world_name)" /> <arg name="debug" value="$(arg debug)" /> <arg name="gui" value="$(arg gui)" /> <arg name="paused" value="$(arg paused)"/> <arg name="use_sim_time" value="$(arg use_sim_time)"/> <arg name="headless" value="$(arg headless)"/> </include> <!-- 加載機器人模型描述參數 --> <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/gazebo/mbot_with_camera_gazebo.xacro'" /> <!-- 改這 --> <!-- 運行joint_state_publisher節點,發佈機器人的關節狀態 --> <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node> <!-- 運行robot_state_publisher節點,發佈tf --> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" > <param name="publish_frequency" type="double" value="50.0" /> </node> <!-- 在gazebo中加載機器人模型--> <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen" args="-urdf -model mrobot -param robot_description"/> </launch>
$ rqt_image_view # 查看攝像頭仿真圖像
再啓動一個鍵盤控制節點:
$ roslaunch mbot_teleop mbot_teleop.launch
移動機器人的位置咱們會發現圖像也是會隨之改變。
加載另一個launch文件:
$ roslaunch mbot_gazebo view_mbot_with_kinect_gazebo.launch
啓動rviz界面查看攝像頭的效果:
$ rosrun rviz rviz
添加一個pointcloud2,topic選擇/kinect/depth/points。fixed frame選擇Kinect_link就能夠看到相應的點雲信息了。
一樣也能夠選擇添加一個image顯示圖像信息。
啓動激光雷達launch文件:
$ roslaunch mbot_gazebo view_mbot_with_laser_gazebo.launch
一樣能夠啓動rviz可視化界面查看參數:
$ rosrun rviz rviz #點擊Add一個robotmodel,fixed frame選擇odom,能夠顯示一個機器人模型。 #再添加一個laserscan,topic選擇scan。就能夠在rviz中顯示出激光信息了。size設置激光點大小。
在官網下載models文件放在./gazebo文件夾下出現錯誤,Gazebo閃退及沒法運行,提示問題
VMware: vmw_ioctl_command error 無效的參數. Aborted (core dumped) [gazebo_gui-3] process has died [pid 3469, exit code 134, cmd /opt/ros/kinetic/lib/gazebo_ros/gzclient __name:=gazebo_gui __log:=/home/ggk/.ros/log/29a04806-93bd-11ea-950a-000c298133c0/gazebo_gui-3.log]. log file: /home/ggk/.ros/log/29a04806-93bd-11ea-950a-000c298133c0/gazebo_gui-3*.log
解決方法:
第一步,關閉虛擬機的3D圖形加速:
虛擬機設置—顯示器—關閉3D圖形加速;
緣由:由於虛擬機開啓3D圖形加速,圖形內存不夠用,加載不出來。
第二步,關閉硬件加速:
echo "export SVGA_VGPU10=0" >> ~/.bashrc source ~/.bashrc
詳細解決方法:https://blog.csdn.net/wangguchao/article/details/88777162
ros_control http://www.guyuehome.com/890
http://wiki.ros.org/ros_control
rviz與Gazebo的區別 https://www.zhihu.com/question/268658280/answer/340190866
Gazebo仿真教程 http://www.gazebosim.org/tutorials
使用gazebo中的插件 http://www.guyuehome.com/388