*20250626:ros-ign-bridgeをros-gz-bridgeに修正
Ignition Gazeboで移動ロボットのサンプルを実行する例を紹介します。
まずは下記コマンドでインストール.
sudo apt update
sudo apt install -y ros-humble-ros-gz-bridge
sudo apt install ignition-fortress -y
インストールが終わったら下記コマンドでIgnition Gazeboが立ち上がります.
ign gazebo
上記コマンドを入力すると「guick start」の下記画面が出てくるので好きなサンプルを選びます.
下記コマンドを使えば右のリストにあるsdfファイルは起動できます.「Tugbot In Warehouse」はここからダウンロードしないとだめ?なぜか.(実行してみると,もともと入っている環境と少し違う...)
ign gazebo dff_drive.sdf
空のign gazeboを立ち上げたいなら下記
ign gazebo empty.sdf
先程のリンク先のTugbot_warehouseのものを直接引数にしても立ち上げられます.ダウンロードしたsdfファイルを直接指定したほうが早い.
ign gazebo https://fuel.gazebosim.org/1.0/Fahadalbahoth/worlds/tugbot_depot
2024年5月9日現在:Windwos11のWSL上のUbuntu22.04ではign gazeboがグラフィックドライバエラーで立ち上がりませんでした.Classic Gazeboなら普通に立ち上がります...また、VMWare上にUbuntu22.04をインストールしてもignition gazeboの表示ができませんでした。
VNCサーバ対応のDockerイメージでは表示ができました。
Classic Gazeboなら問題ないのですが,ignition gazeboはグラボがうまく使えないので(classicが使っていないだけかもしれませんが)
グラフィックカード系のエラーで表示ができない場合は下記のコマンドを入力。
export LIBGL_ALWAYS_SOFTWARE=1
ハードウェアアクセラレーションせずにソフトウェア描画になるので表示ができるようになるはず。
毎回いれるの面倒なら,下記で.bashrcへ記入しておくと良いです.
WSLやVMWare上のUbuntu22.04でIgnition Gazeboが表示できることを確認済み。(2024年5月14日)
echo "export LIBGL_ALWAYS_SOFTWARE=1" >> ~/.bashrc
下記コマンドで立ち上げたあとに「Tugbot In Warehouse」を選択したことを前提に説明をします.
ign gazebo
「Tugbot In Warehouse」を選んで「RUN」を押すと下記の画面が出てきます.
画面が出たときは,まだ動力学シミュレーションが始まっていないので,左下にあるシミュレーション開始の「▶」ボタンを押します.
シミュレーションが始まると,ロボット上部に搭載された3D-Lidarがくるくる回っているようなアニメーションが始まります.
右側のウィンドウにある,「Teleop」の項目にある一番下の「Buttons」が選ばれていると,GUI上に進行方向を指示できるボタンが表示され,ボタン操作で画面内の移動ロボットを動かすことができます.
試しに,下方向矢印「▼」を押してみると壁から移動ロボットが離れていきます.
停止させるときは中央の「Stop」ボタンを押します.
「Buttons」の横にある「Keyboard」のタブを押すとキーボードに割り当てられた進行方向ボタンを押すことで,移動ロボットを操作することができます.キーを押している間だけ動いてくれるので,こちらのほうが動かしやすいと思います.
上図の通りKeyboardタブを押すと,どのキーを押すとどの方向へ動くのかわかるようになっています.
一番右の「Sliders」はスライダで進行方向速度を指定できますが,操作しにくいと思います.
視点が固定されていると移動ロボットがすぐに画面外へ行ってしまうので,ロボットを右クリックして出てくるメニューから「Follow」を選びましょう.すると,移動ロボットの後ろをカメラが付いてきてくれるようになります.微妙に遅れてついてくるので,キーボードで動かしたり停止したりしながらカメラが追いつくのを待てば,倉庫内を比較的簡単に周回できると思います.
移動ロボットを選択すると白い枠で囲まれるので,その後に右クリックして出てくるメニューの「Follow」を選択.
選択後は,ゆっくりとロボット後方斜め上からの見下ろし視点にゆっくり視点が移動していきます.
下図の状態がしばらくすると移動してくる視点になります.この視点で前後左右のKeyboard操作が楽になると思います.ただし,カメラの追従はかなり遅いです.
下図はKeyboardで操作中の様子.キーボード操作のTeleopのトピックは,右メニューのTeleopタブのしたにTopicと書いてある下に記載の名前がトピックとして利用できる名前になります.
/model/tugbot/cmd_vel
ただし,このトピックはROS 2のコマンドラインでros2 topic listと入力しても出てきません.
Ignition Gazebo内だけのトピックなのでブリッジをしてROS 2に引き渡す必要があります.
Ignition Gazebo内には移動ロボットの速度司令だけでなく,さまざまなトピックが存在しています.
どのようなトピックがあるか確認するために画面内の右上にある点が3つ縦に並んでいるアイコン「︙」をクリックします.
ちなみに,右にあるメニューのタブが邪魔なので,一旦全部各タブの右側の☓マークを押して閉じておきます.
「︙」を押すと,様々なメニューが出てきますので,Teleopを再度表示したいときはTeleopをクリックすれば再び表示されます.
移動ロボットを動かしたいだけなのに,かなり右側を専有するので,邪魔だと思うときは,右のタブの「Teleop」と記載されている青いバーの一番右の☓マークの左の「□」アイコンをクリックすると画面上にTeleopのアイコンがオーバーレイされて表示されます.
画面上では左上に「Teleop」の青いバーがありますが,ドラッグして好きな場所に移動可能です.もとに戻したいときは,Teleopの青いバーの「_」アイコンを押せば3D画像の右側に戻ります.
Ignition Gazebo内のTopicのリストを確認したいときは,画面右上の「︙」アイコンを押して,虫眼鏡マークの横の検索エリアで「topic」と記載すると「Topic Viewer」がすぐ見つかるので,「Topic Viewer」をクリック.
エリアが狭いとトピックの名前が確認しにくいので,枠の左側をドラッグして広げて確認してください.
ロボット上部にある3D-Lidarのトピックは,「/world/world_demo/model/tugbot/link/scan_omnin/sensor/scan_omni/scan」としてpublishされています.
また,2D-Lidarも前後1つづつついていて下記の名前でPublishされています.
「/world/world_demo/model/tugbot/link/scan_front/sensor/scan_front/scan」:前方の2D-Lidar
「/world/world_demo/model/tugbot/link/scan_back/sensor/scan_back/scan」:後方の2D-Lidar
各Lidarの計測状況を画面内に表示したいときは,「︙」を押して「Visualize lidar」のツールを選択してください.
表示された「Visualize lidar」のタブの上から3番目のアイコンの横にあるトグルボタンを押すと候補となるscanトピックの一覧が現れるので,見たいscan topicを選択してください.
上図は,後ろの2DLidarを表示した例.
上図は,3D-Lidarを選択した例.
なお,Visualize Lidarタブの下から2番目にある「Visual Type」がデフォルトで「Triangle Strips」となっているので,トグルボタンを押して表示タイプを変更することも可能.
「Rays」に変えると少しはマシになりますが,3D-Lidarだと環境が見えなくなります.
(注意)「Points」を選択すると,GPUを積んでいないPCではGazeboがクラッシュします.
後ろカメラのRGB画像と深度画像,前カメラのRGB画像と深度画像があるので,右上の「︙」から「Image display」のツールを選択して表示することができます.
各カメラのトピック名は下記.
「/world/world_demo/model/tugbot/link/camera_front/sensor/color/image」:前方のRGB画像
「/world/world_demo/model/tugbot/link/camera_front/sensor/depth/depth_image」:前方の深度画像
「/world/world_demo/model/tugbot/link/camera_back/sensor/color/image」:後方のRGB画像
「/world/world_demo/model/tugbot/link/camera_back/sensor/depth/depth_image」:後方の深度画像
上図は,後ろカメラのRGB画像.
上図は,後ろカメラの深度画像.
前のカメラも同様に,表示するTopic名をトグルボタンを押して出てくる候補のTopic名を指定すればよいだけ.
「ign topic」というコマンドを端末で入力するとGazebo内のトピックに対して情報を直接与えることができる.
トピックリストに移動ロボットの速度司令のトピック「/model/tugbot/cmd_vel」があるので,ポインタをオーバレイさせてみるとトピックの型がわかる.
「ignition.msgs.Twist」型でcmd_velを受信できるので,端末から下記のように記載すると速度司令を端末から指示できることを確認できる.
ign topic -t "/model/tugbot/cmd_vel" -m ignition.msgs.Twist -p "linear: {x: 1.0}"
これらのTopicはあくまでGazebo内だけなので,ROS 2にブリッジして通信できるようにする.
ROS 2とIgnition GAZEBOをブリッジして通信するためにros-ign-bridgeをインストールする.
sudo apt install ros-humble-ros-gz-bridge
ros_gz_bridgeの記載の方法は
ros2 run ros_gz_bridge parameter_bridge "Ign Gazeboのトピック名"@"ROS2のトピックの型"@"Ign Gazeboのトピックの型"
となります.
移動ロボットのコマンドをROS 2にブリッジするときは,下記となります.
ros2 run ros_gz_bridge parameter_bridge /model/tugbot/cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist
ROS 2のトピックリストを確認すると/model/vehicle/cmd_velがあることが確認できます.
ros2 topic list
/model/tugbot/cmd_vel
/parameter_events
/rosout
上記が表示されるはず.
ROS 2のteleop_twist_keyboardを使って指示してみる.
ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args --remap cmd_vel:=/model/tugbot/cmd_vel
--remapのオプションでcmd_vel:=でIgn Gazeboのトピック名「/mode/tugbot/cmd_vel」を指定している.
端末に表示されている案内の通り" i "を押すと前進の速度司令,"<"を押すと後退の速度司令をすることができる.
"k"を押さないと停止しないので注意.
端末のコマンドでros2 pubで速度を送信する例は下記.
ros2 topic pub --once /model/tugbot/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1.0}}"
ros2のトピックで移動ロボットの速度指示ができていると思います.
Ignition Gazebo内で確認した,2D,3D-Lidarやカメラ画像のデータをブリッジしてRviz2で表示してみます.
下記コマンドでブリッジする.
ros2 run ros_gz_bridge parameter_bridge /world/world_demo/model/tugbot/link/scan_omni/sensor/scan_omni/scan/points@sensor_msgs/msg/PointCloud2@ignition.msgs.PointCloudPacked
長いので改行されてしまっているが,1行での記載です.
ROS 2のRvizでPointCloud2で表示するために型をsensor_msgs/msg/PointCloud2で指定しています.
rviz2を立ち上げて確認してみてください.
rviz2の左下の「Add」ボタンを押して表示の追加をします.
出てきたウィンドウの「By topic」を選んで,下図のように/worldの下に続く最後のPointCloud2を選択して「OK」を押します.
PointCloud2のトピックを選択しても,Global OptionsのFixed Frameが3D-Lidarのフレームとつながっていないため下図のとおり表示がされません.
Fixed Flameを手書きで書き直して「tugbot/scan_omni/scan_omni 」を記載します.
すると下図のようにLidarの点群情報が表示されます
Tugbotのフレームの名前は,Ignition Gazeboのツール「Entity tree」から下図のようにフレーム名を確認することができます.
他の2D-Lidarやカメラは同じ方法で表示できるので割愛.
次にTFのブリッジを確認します.
このサンプルで動いている移動ロボットはDiff Drive pluginで作動二輪の移動が実現されており,odomからbase_linkまでの相対座標情報を出力しています.
これをROS 2に送信することで,ROS 2 側のSLAMアルゴリズムを利用することができるようになります.
Ignition Gazeboのトピック名「/model/tugbot/tf」をこれまで同様にブリッジjして型を変換すると同時に「/tf」に名前を変更(remap)します.
具体的には下記のコマンド.
ros2 run ros_gz_bridge parameter_bridge /model/tugbot/tf@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V --ros-args --remap /model/tugbot/tf:=/tf
別の端末で,ros2のtfを確認してみます.
ros2 run tf2_ros tf2_echo odom base_link
Ignition Gazeboの移動ロボットをTeleopなどで移動させて値が更新されることを確認してみてください.
rviz2でも「Add」で「TF」を選んで表示させると,odomとbase_linkのTFが通信できていることが確認できます.
RvizのTFの項目内にある「Tree」を開いてみるとodomとbase_linkしか存在していない.
移動ロボットの移動とともに3D-Lidarなどのセンサ情報を表示させたい場合,別ターミナルで下記TFの静的情報を定義すれば,移動ロボットの動きとともに3D-Lidarの点群も表示できる.
ros2 run tf2_ros static_transform_publisher 0.1 0 0.2 0 0 0 base_link tugbot/scan_omni/scan_omni
設定すると,下記の図のようにodom -> base_link -> tugbot/scan_omni/scan_omni のようにTFが繋がり,3D-LidarのPointCloud2も表示されることが確認できる.
複数のトピックをIgn GazeboとROS 2でブリッジを追加のたびにターミナルを立ち上げると大変面倒なのでLaunchを作成して複数のブリッジを同時に行うことを考える.
ブリッジするトピックを設定するYAMLファイルを作成します。例えば、bridge_config.yamlという名前で以下の内容を含むファイルを作成する.
今回は3D-Lidarと前2D-Lidar,後ろ2D-Lidarの3つ.2D-LidarもIgn Gazeboではignition.msgs.PointCloudPackedだったので,ROS 2にもPointCloud2型にした.
ROS 2で受信後にpointcloud_to_laserscanパッケージでlaserscan型に変換すれば良い.
bridge_config.yaml
topics:
- topic_name: /world/world_demo/model/tugbot/link/scan_omni/sensor/scan_omni/scan/points
ros_type: sensor_msgs/msg/PointCloud2
ign_type: ignition.msgs.PointCloudPacked
- topic_name: /world/world_demo/model/tugbot/link/scan_front/sensor/scan_front/scan/points
ros_type: sensor_msgs/msg/PointCloud2
ign_type: ignition.msgs.PointCloudPacked
- topic_name: /world/world_demo/model/tugbot/link/scan_back/sensor/scan_back/scan/points
ros_type: sensor_msgs/msg/PointCloud2
ign_type: ignition.msgs.PointCloudPacked
上記の設定ファイルを読み込み、ブリッジを起動するlaunchファイルを作成する.
今回は、bridge.launch.pyという名前で以下のファイルを作成する.
from launch import LaunchDescription
from launch_ros.actions import Node
import yaml
import launch_ros
import os
def generate_launch_description():
pkg_share = launch_ros.substitutions.FindPackageShare(package='sam_bot_description').find('sam_bot_description')
default_config_path = os.path.join(pkg_share, 'config/bridge_config.yaml')
with open(default_config_path, 'r') as file:
bridge_config = yaml.safe_load(file)
bridge_nodes = []
for topic in bridge_config['topics']:
bridge_node = Node(
package='ros_gz_bridge',
executable='parameter_bridge',
arguments=[
f'{topic["topic_name"]}@{topic["ros_type"]}@{topic["ign_type"]}',
],
output='screen'
)
bridge_nodes.append(bridge_node)
return LaunchDescription(bridge_nodes)
Lanuchファイルを自分のパッケージのLaunchディレクトリに作成してあることを前提に,以下のコマンドをターミナルに入力して実行する.
ここでは,sam_bot_description/launchに入れてあるとする
ros2 launch sam_bot_description bridge.launch.py
これにより、bridge_config.yamlで定義した複数のトピックが同時にブリッジされるはず.
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake test_bridge
cd test_bridge
mkdir launch
mkdir config
test_bridge内にできたCMakefiles.txtを修正.
CMakefiles.tx内の「if(BUILD_TESTING)」が書いてある上に書きをペースト
install(DIRECTORY launch config DESTINATION share/${PROJECT_NAME}) #追加
package.xmlに下記の1行を追加
<exec_depend>launch_ros</exec_depend> #この行を追加
まず下記でPointcloud_to_laserScanをインストール.
sudo apt install ros-humble-pointcloud-to-laserscan
前記のIgnition GazeboからROS 2へトピックを変換している状態で,3D-Lidarの点群をLaserScan型に変換するために下記のコマンドを実行.
ros2 run pointcloud_to_laserscan pointcloud_to_laserscan_node --ros-args --remap cloud_in:=/world/world_demo/model/tugbot/link/scan_omni/sensor/scan_omni/scan/points
コマンドでトピックが出ているか確認.
ros2 topic echo /scan
出ているので,Rvizで下図のように確認.Reliability PolicyをBestEffortにしないと表示されない.
同じ要領でscan_frontとscan_backを実施したがなぜか/scanトピックでinfのデータばかりで表示されなかった...
個別に機能を確認してきましたが、tugbotのサンプルをまとめている人がいるので自分のワークスペースのsrcにダウンロード(ここまで書いて自分で書いていないのでそのうち書きます。)
cd ~/ros2_ws/src
git clone https://github.com/porizou/tugbot_ros2_pkgs.git
ダウンロードしたパッケージ内の下記ファイルが間違っているので編集
ign_ros2_bridge.launch.pyを編集するためにvscodeを使う例:
code ~/ros2_ws/src/tugbot_ros2_pkgs/tugbot_gazebo/launch/ign_ros2_bridge.launch.py
Node(
package='ros_ign_bridge', # ← 古い
下記に変更
Node(
package='ros_gz_bridge', # ← 新しいパッケージ名
修正が終わったらビルドしたいが
tugbot_navigation2のなかにmapのディレクトリがないとエラーが出るはずなので、先にtugbot_navigation2に移動してmapディレクトリを作成しておくこと。
cd ~/ros2_ws/src/tugbot_ros2_pkgs/tugbot_navigation2
colcon build --packages-select tugbot_gazebo
mkdir map
msource install/setup.bash
そのあとビルド
cd ~/ros2_ws
colcon build --packages-select tugbot_gazebo
source install/setup.bash
パッケージをビルドするとき
1つ目のターミナル:tugbotをgazeboに表示
ros2 launch tugbot_gazebo tugbot_depot.launch.py
2つ目のターミナル:gazeboからのトピックのブリッジ
ros2 run ros_gz_bridge parameter_bridge /model/tugbot/cmd_vel@geometry_msgs/msg/Twist[ignition.msgs.Twist /model/tugbot/scan@sensor_msgs/msg/LaserScan[ignition.msgs.LaserScan
3つ目のターミナル:キーボードテレオペレーション起動
ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -r /cmd_vel:=/model/tugbot/cmd_vel
4つ目のターミナル:Slam toolbox起動
ros2 launch tugbot_slam slam_toolbox.launch.py
キーボードで移動させて地図を作っていきましょう。
大体作り終えたら下記コマンドで地図を保存
ros2 run nav2_map_server map_saver_cli -f map
map.yaml と map.pgm ファイルが作成される。
ナビゲーションは、同じくダウンロードしてきたtugbot_navigation2を使えばできるので、mapディレクトリの中に先ほど保存したmap.yamlとmap.pgmファイルをコピーする。
そのあとビルドしてパスを通す。
cd ~/ros2_ws
colcon build --packages-select tugbot_navigation2
source install/setup.bash
実行するときは下記
一つ目のターミナル:
二つ目のターミナル:
Nav2 を使えば、自律航行のための地図としても活用可能となる。