3.使用gazebo加載URDF
寫(xiě)在前面
- 當(dāng)前平臺(tái)文章匯總地址:ROS2機(jī)器人從入門(mén)到實(shí)戰(zhàn)
- 獲取完整教程及配套資料代碼,請(qǐng)關(guān)注公眾號(hào)<魚(yú)香ROS>獲取
- 教程配套機(jī)器人開(kāi)發(fā)平臺(tái):兩驅(qū)版| 四驅(qū)版
- 為方便交流,搭建了機(jī)器人技術(shù)問(wèn)答社區(qū):地址 fishros.org.cn
1.Gazebo-ROS2插件介紹
在第六章中小魚(yú)曾介紹過(guò),gazebo是獨(dú)立于ROS/ROS2之外的仿真軟件,我們可以獨(dú)立使用Gazebo。如果我們想要通過(guò)ROS2和Gazebo進(jìn)行交互,需要通過(guò)gazebo_ros插件來(lái)進(jìn)行。
接下來(lái)小魚(yú)先帶你通過(guò)命令行的形式來(lái)啟動(dòng)gazebo-ros2插件以及使用插件提供的服務(wù)來(lái)將fishbot的urdf模型在gazebo中顯示出來(lái)。
1.1 安裝Gazebo插件
sudo apt install ros-humble-gazebo-ros
1.2 啟動(dòng)Gazebo并啟動(dòng)插件
安裝完成后,我們就可以通過(guò)下面的命令行來(lái)啟動(dòng)gazebo并加載ros2插件。
gazebo --verbose -s libgazebo_ros_init.so -s libgazebo_ros_factory.so
看到下面的日志和Gazebo界面代表啟動(dòng)成功
Gazebo multi-robot simulator, version 11.9.0
Copyright (C) 2012 Open Source Robotics Foundation.
Released under the Apache 2 License.
http://gazebosim.org
[Msg] Waiting for master.
Gazebo multi-robot simulator, version 11.9.0
Copyright (C) 2012 Open Source Robotics Foundation.
Released under the Apache 2 License.
http://gazebosim.org
[Msg] Waiting for master.
[Msg] Connected to gazebo master @ http://127.0.0.1:11345
[Msg] Publicized address: 192.168.2.103
[Msg] Loading world file [/usr/share/gazebo-11/worlds/empty.world]
[INFO] [1649151283.208884022] [gazebo_ros_node]: ROS was initialized without arguments.
[Msg] Connected to gazebo master @ http://127.0.0.1:11345
[Msg] Publicized address: 192.168.2.103
2.插件節(jié)點(diǎn)及其服務(wù)介紹
使用3.1中的指令啟動(dòng)Gazebo并加載gazebo_ros插件,我們使用下面的指令來(lái)看插件的節(jié)點(diǎn),以及改節(jié)點(diǎn)為我們提供的服務(wù)有哪些?
節(jié)點(diǎn)列表
ros2 node list
正確返回
/gazebo
然后我們看看這個(gè)節(jié)點(diǎn)對(duì)外提供的服務(wù)有哪些?
ros2 service list
/delete_entity
/get_model_list
/spawn_entity
/gazebo/describe_parameters
/gazebo/get_parameter_types
/gazebo/get_parameters
/gazebo/list_parameters
/gazebo/set_parameters
/gazebo/set_parameters_atomically
除去和參數(shù)相關(guān)的幾個(gè)服務(wù),我們可以看到另外三個(gè)特殊服務(wù):
- /spawn_entity,用于加載模型到gazebo中
- /get_model_list,用于獲取模型列表
- /delete_entity,用于刪除gazbeo中已經(jīng)加載的模型
我們想要讓gazebo顯示出我們配置好的fishbot使用/spawn_entity來(lái)加載即可。
接著我們可以來(lái)請(qǐng)求服務(wù)來(lái)加載模型,小魚(yú)先帶你看一下服務(wù)的接口類(lèi)型。
ros2 service type /spawn_entity
返回
gazebo_msgs/srv/SpawnEntity
指令
ros2 interface show gazebo_msgs/srv/SpawnEntity
返回
string name # Name of the entity to be spawned (optional).
string xml # Entity XML description as a string, either URDF or SDF.
string robot_namespace # Spawn robot and all ROS interfaces under this namespace
geometry_msgs/Pose initial_pose # Initial entity pose.
string reference_frame # initial_pose is defined relative to the frame of this entity.
# If left empty or "world" or "map", then gazebo world frame is
# used.
# If non-existent entity is specified, an error is returned
# and the entity is not spawned.
---
bool success # Return true if spawned successfully.
string status_message # Comments if available.
可以看到服務(wù)的請(qǐng)求內(nèi)容包括:
- string name ,需要加載的實(shí)體的名稱(chēng) (可選的)。
- string xml ,實(shí)體的XML描述字符串, URDF或者SDF。
- string robot_namespace ,產(chǎn)生的機(jī)器人和所有的ROS接口的命名空間,多機(jī)器人仿真的時(shí)候很有用。
- geometry_msgs/Pose initial_pose ,機(jī)器人的初始化位置
- string reference_frame ,初始姿態(tài)是相對(duì)于該實(shí)體的frame定義的。如果保持"empty"或"world"或“map”,則使用 gazebo的world作為frame。如果指定了不存在的實(shí)體,則會(huì)返回錯(cuò)誤
3.調(diào)用服務(wù)加載fishbot
看到這里你是不是迫不及待敲起來(lái)命令行來(lái)加載我們的機(jī)器人到gazebo了,別著急,小魚(yú)再推薦一個(gè)可視化服務(wù)請(qǐng)求工具,其實(shí)在第六章中小魚(yú)介紹過(guò),在rqt工具集里有一個(gè)叫服務(wù)請(qǐng)求工具。
命令行輸入rqt,在插件選項(xiàng)中選擇Services->Service Caller,然后再下拉框選擇/spawn_entity服務(wù),即可看到下面的界面。
接著我們把我們的FishBot的URDF模型復(fù)制粘貼,放到xml中(注意要把原來(lái)的’'刪掉哦?。?,然后拿起我們的小電話(huà),和小魚(yú)一起Call。
接著就可以看到工廠返回說(shuō)成功把機(jī)器人制作出來(lái)送入gazebo了。
此時(shí)再看我們的Gazebo,一個(gè)小小的,白白的機(jī)器人出現(xiàn)了。
按住Shift加鼠標(biāo)左鍵,拖動(dòng)一下,來(lái)好好的欣賞欣賞我們的機(jī)器人。
3.4 在不同位置加載多個(gè)機(jī)器人
欣賞完畢后,小魚(yú)再帶你生產(chǎn)一個(gè)fishbot(為了后面需要多機(jī)器人仿真的小伙伴)。
修改rqt中的參數(shù),增加一個(gè)命名空間,然后修改一個(gè)位置,讓第二個(gè)機(jī)器人和第一個(gè)相距1m的地方生產(chǎn),然后點(diǎn)擊Call。
返回成功,此時(shí)拖送Gazebo觀察一下,發(fā)現(xiàn)多出了一個(gè)機(jī)器人,距離剛好是在X軸(紅色)1米(一個(gè)小格子一米)處。
3.5 查詢(xún)和刪除機(jī)器人
利用rqt工具,我們?cè)賹?duì)另外兩個(gè)服務(wù)接口進(jìn)行請(qǐng)求。
查到了三個(gè)模型,一個(gè)大地,一個(gè)fishbot,一個(gè)fishbot_0。
我們接著嘗試把fishbot_0刪掉,選擇刪除實(shí)體,輸入fishbot_0的名字,拿起小電話(huà)通知工廠回收我們的0號(hào)fishbot。
調(diào)用成功,觀察gazebo發(fā)現(xiàn)機(jī)器人沒(méi)了
4. 將啟動(dòng)gazebo和生產(chǎn)fishbot寫(xiě)成launch文件
打開(kāi)fishbot工作空間,在src/fishbot_description/launch
中添加一個(gè)gazebo.launch.py
文件,我們開(kāi)始編寫(xiě)launch文件來(lái)在gazebo中加載機(jī)器人模型。
啟動(dòng)gazebo,我們可以將命令行寫(xiě)成一個(gè)launch節(jié)點(diǎn)
ExecuteProcess(
cmd=['gazebo', '--verbose','-s', 'libgazebo_ros_init.so', '-s', 'libgazebo_ros_factory.so', gazebo_world_path],
output='screen')
上面我們加載機(jī)器人是直接將XML格式的URDF復(fù)制過(guò)去進(jìn)行加載的,這樣很不方便,我們可以使用gazebo_ros為我們提供好的一個(gè)叫做spawn_entity.py
節(jié)點(diǎn),該節(jié)點(diǎn)支持從文件地址直接生產(chǎn)機(jī)器人到Gazebo。
其實(shí)該節(jié)點(diǎn)的原理也很簡(jiǎn)單,從URDF中讀取機(jī)器人模型,然后再調(diào)用服務(wù),和我們手動(dòng)操作一個(gè)樣子,小魚(yú)只道沒(méi)差別。
該節(jié)點(diǎn)需要兩個(gè)參數(shù),一個(gè)機(jī)器人的模型名字和urdf的文件地址,這個(gè)簡(jiǎn)單,前面我們?cè)?jīng)使用package_share來(lái)拼接過(guò)urdf路徑。
spawn_entity_cmd = Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-entity', robot_name_in_model, '-file', urdf_model_path ], output='screen')
最終寫(xiě)好的launch文件如下:
import os
from launch import LaunchDescription
from launch.actions import ExecuteProcess
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
def generate_launch_description():
robot_name_in_model = 'fishbot'
package_name = 'fishbot_description'
urdf_name = "fishbot_gazebo.urdf"
ld = LaunchDescription()
pkg_share = FindPackageShare(package=package_name).find(package_name)
urdf_model_path = os.path.join(pkg_share, f'urdf/{urdf_name}')
# Start Gazebo server
start_gazebo_cmd = ExecuteProcess(
cmd=['gazebo', '--verbose','-s', 'libgazebo_ros_init.so', '-s', 'libgazebo_ros_factory.so'],
output='screen')
# Launch the robot
spawn_entity_cmd = Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-entity', robot_name_in_model, '-file', urdf_model_path ], output='screen')
ld.add_action(start_gazebo_cmd)
ld.add_action(spawn_entity_cmd)
return ld
編譯運(yùn)行
colcon build --packages-select fishbot_description
source install/setup.bash
ros2 launch fishbot_description gazebo.launch.py
完美顯示
5.總結(jié)
這節(jié)課我們?yōu)镕ishbot注入了仿真必須的物理屬性,但是機(jī)器人還是不會(huì)動(dòng),下一節(jié)課我們就利用Gazebo的其他插件,讓我們的機(jī)器人動(dòng)起來(lái)。
最后再留一個(gè)課后作業(yè):
-
嘗試將fishbot的物理屬性去掉,再加載機(jī)器人看看會(huì)發(fā)生什么?
-
嘗試將fishbot的碰撞改成很小,再看看會(huì)發(fā)生什么?
-
gazebo還支持link的材料修改,在URDF中添加下面的代碼,給支撐輪一個(gè)不一樣的材質(zhì)吧,你也可以將reference改成其他link,裝點(diǎn)一下你的機(jī)器人。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-754653.html
<gazebo reference="caster_link"> <material>Gazebo/Black</material> </gazebo>
歡迎將你的實(shí)驗(yàn)結(jié)果在我們的fishros社區(qū)分享~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-754653.html
到了這里,關(guān)于【ROS2機(jī)器人入門(mén)到實(shí)戰(zhàn)】使用gazebo加載URDF的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!