見出し画像

ルンバをUbuntu22.04(ROS2 Humble)とNavigation2で自動運転する【全まとめ】


はじめに

今回はがっつり、開発者のためのノウハウメモです。
とはいえ興味のある方は、DIYも可能なのでまとめてみました。

本記事は、こちらの動画に登場した、「目標地点に自動で移動するルンバ」を自作するための手順を、すべてまとめています。


概要

今回はルンバを自由な場所に自動運転させる仕組みをセットアップします。イメージは「ガスト」の猫型配膳ロボットみたいな感じです。

ルンバにはラズパイ4Bを載せて、制御していきます。

ラズパイだけではCPUパワーが足りなそう?な気がしたので、windowsPCのwslにも同じくros2-humbleを入れて、リモートブレイン化します。(LinuxPCがあれば多分wsl使うより簡単にできると思います)

2台のPCは以下の役割分担を行います。

  • ラズパイ:LiDAR入力、コントローラ入力、ルンバ出力制御を担当

  • WSL:SLAM、Navigaton2、GUI表示を担当

SLAMで地図を作成し、Navigation2で目標地点への経路計画や自動運転を行います。
Navigation2に渡す現在位置や目標地点の指示については、PythonやC++を使ってROSパッケージを作成すれば自動化することも可能です。(本記事では対象外)


部品

  • ラズパイ4B

  • LiDAR (okdo Ld06 が安くて、遊びには性能も十分)

  • ラズパイ用モバイルバッテリー(10000mAh以上、出力電流の高いもの)

  • FTDI usb変換ケーブル

  • ミニdinプラグオス(7pin)

  • ルンバ 600系 or 700系 or 800系(掃除機能いらないならcreate2, 3でも可)今回使用したのは893モデル。

  • リモート制御用PC(Windows11)

  • ルンバにラズパイ等を固定する台座(以下の3Dモデルをプリントアウトするか、両面テープ等で適当にルンバに張り付けても問題ありません)


ラズパイのセットアップ

OSを入れる

Raspberry Pi Imagerを使ってUbuntu Desktop 22.04.3 64bit版を導入します。

参考にできそうなサイト

SSHを使えるようにする

Terminalを起動し、以下のコマンドを実行します。

sudo apt update
sudo apt upgrade 
sudo apt install openssh-server

これで以下のようにSSHを使ってリモートPCからログインできるようになります。リモートPCから、VS code等を使ってアクセスすると、開発がはかどりますね。

ssh "インストール時に決めたユーザ名"@"インストール時に決めたコンピュータの名前".local

また、ラズパイをHDMIでディスプレイにつないで、GUIを使うかどうかに応じて以下で設定を変えておきましょう。

sudo systemctl set-default multi-user  # GUI起動を停止したくなったら実行
sudo systemctl set-default graphical  # GUI起動を再開したくなったら実行

ROSのインストール

続いて、ラズパイにROS2を入れていきます。

sudo apt install build-essential cmake git locales curl wget gnupg lsb-release python3 python3-pip vim

sudo locale-gen en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
locale  # verify settings

apt-cache policy | grep universe

# 出力
# 500 http://us.archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
#     release v=22.04,o=Ubuntu,a=jammy,n=jammy,l=Ubuntu,c=universe,b=amd64

↑のように出力されなければ以下を実行してください。

sudo apt install software-properties-common
sudo add-apt-repository universe

セットアップを続けていきます。

sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

sudo apt update
sudo apt upgrade 
sudo apt install ros-humble-desktop python3-rosdep2 python3-colcon-common-extensions

sudo nano ~/.bashrc   # 以下3つを追記

「~/.bashrc」には以下の3行を追記します。

source /opt/ros/humble/setup.bash
source /usr/share/colcon_cd/function/colcon_cd.sh
export _colcon_cd_root=/opt/ros/humble/

ROS2の動作確認

2つのターミナルを新規に立ち上げて、それぞれで以下を実行して、ROS2が正常にインストールされたか確認してみましょう。
それぞれ、新しいターミナルを起動して、確認します。(ROSコマンドを実行するときは、この後も新しいターミナルを立ち上げる必要があります。~/.bashrcにsetup.sh系を追記しない場合は、これをターミナル起動時に毎回実行する必要があります。)

「talker」で送られた通信が「listener」側で確認できたらOKです。

ros2 run demo_nodes_cpp talker  # 新しいターミナル
ros2 run demo_nodes_cpp listener  # 新しいターミナル

ルンバ用ROSパッケージのインストール

ルンバには有線でのシリアル通信が必要です。

以下2つを半田づけしてケーブルを作成してください。
FTDI usbシリアル変換機
ミニDIN(7pin)

はんだ付けの際には、変換機の説明書を読みながら線をつないでください。以下のサイトがとても参考になりそうです。(はんだ付けが必要なのはTXD, RXD, GNDの3本だけです)

そして、ラズパイに、ルンバと通信するための仕組みをセットアップします。

mkdir -p create_ws/src
cd ~/create_ws/src
git clone -b humble https://github.com/AutonomyLab/create_robot.git
git clone https://github.com/AutonomyLab/libcreate.git

cd ~/create_ws
rosdep update
rosdep install --from-paths src -i
colcon build  # ラズパイ4 4GBでスタックを確認。GUI停止で完了確認。
sudo usermod -a -G dialout $USER  # USBの使用許可
sudo chmod a+rw /dev/ttyUSB0  # USBの今すぐ使用許可
printenv | grep -i ROS  # ROSの設定確認

ラズパイ⇔ルンバの通信開始

作成したケーブルを使って、ルンバとラズパイを接続し、以下を実行します。ルンバの電源が入っていれば通信が始まってログが流れます。

source ~/create_ws/install/setup.bash
ros2 launch create_bringup create_2.launch

移動のテストコマンド

本当に通信されているか、テストでルンバのモーターを動かしてみます。

こちらは前に進み続けるコマンドです。ルンバが走り出して壁に激突しないように、筐体をひっくり返すなどしてから実行してください。

ros2 topic pub /cmd_vel geometry_msgs/Twist '{linear: {x: 0.2}, angular: {z: 0.0}}' -r 100

LiDAR(ld06)をセットアップ

ラズパイのuartを有効化します。
以下を実行して、1行だけの表示であれば、設定の必要があります。

ls -l /dev/ttyAMA*  # 以下1行の出力を確認
# crw-rw---- 1 root dialout 204, 64 Jan 10 13:56 /dev/ttyAMA0

設定するには以下のconfigを書き換えます。

sudo nano /boot/firmware/config.txt

内容は以下を追記。

// Enable the UART port
enable_uart=1
dtoverlay=uart0  # gpio10,11を使う場合はuart=0を有効化
dtoverlay=miniuart-bt  # bluetoothを使う予定がある場合はこれも

もう一度以下を実行して、Ld06が使用可能になったか確認します。(2行表示されれま成功)

ls -l /dev/ttyAMA*

うまくいけば、LD06のROSパッケージを使用してみましょう。

mkdir -p ~/ros2_ws/src

git clone -b ros2 https://github.com/linoroot/ldlidar src/ldlidar
rosdep update && rosdep install --from-path src --ignore-src -y
colcon build --symlink-install
source install/setup.bash

source ~/ros2_ws/install/setup.bash
ros2 launch ldlidar ldlidar.launch.py  serial_port:=/dev/ttyAMA0  # uart0のシリアルポートを使って実行

# scanトピックを確認
ros2 topic echo /scan

# GUIで確認したい場合はrvizを起動
rviz2

rvizを起動する際、LD06の場合はrviz2画面のFixedFrameにlaserを入力、ADDからLaserScanを選択してTopic名は /scanを選ぶと点群が表示されます。

JoyStickの使用

PS4などのJoyStickコントローラをROSに接続していきます。(今回はコントローラをラズパイにUSB接続します。)

以下のコマンドでコントローラ用のセットアップをしていきます。

sudo apt install joystick
sudo apt install ros-humble-joy*
sudo apt install ros-humble--teleop-tools

ls -l /dev/input/js0  # 接続確認
jstest /dev/input/js0  # データ確認

ros2 run joy_linux joy_linux_node  # コントローラ入力をrosに受ける(joyトピック)
ros2 launch teleop_twist_joy teleop-launch.py  # コントローラ入力を移動命令(cmd_velトピック)に変換

# それぞれトピックを確認
ros2 topic echo /joy
ros2 topic echo /cmd_vel

JoyStickのボタン入力・スティック入力すると、数値が変化します。
以下の画面は「ros2 topic echo /cmd_vel」成功時のもの。cmd_velはpsボタンを押しながらスティック入力することで反応します。

WSL2をセットアップする

ここからは、リモートPCをセットアップしていきます。
Windows11OSを例に説明していきます。

以下のサイトが参考になります。

Hyper-Vを有効化

rosでは設定変更しない限り、接続しているネットワーク内へトピック通信を垂れ流します。
そのため同ネットワーク内に接続したPCにrosが入っていれば通信を受け取ることが出来ます。
しかしながら、wsl使用の場合はルーターにアドレスを割り当てて貰っていないため通信に参加出来ません。それをhyper-vを使って解決していきます。

Windows 11 Pro の場合

「スタート」>「設定」>「アプリ」>「オプション機能」>「Windowsのその他の機能」からHyper-Vを有効化します。

Windows 11 homeの場合

BIOSで仮想化機能を有効化後、以下の内容でbatファイルを作成して管理者で実行します。

pushd "%~dp0"
dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt
for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
del hyper-v.txt
Dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL

仮想スイッチの作成

Hyper-Vマネージャーから「仮想スイッチマネージャー」を選択し,新しい仮想ネットワークスイッチを作成。

.wslconfigを作成します。(C:\Users\<USERNAME>\ に配置)

[wsl2]
networkingMode=bridged
vmSwitch=myswitch
dhcp=true
localhostForwarding=True

IPv6の無効化(しないと通信が遅い?)

「スタート」>「ncpa.cpl」で検索し、ネットワーク接続の「vEthernet」をクリック、「プロパティ」からIPv6のチェックを外します。
ホストのwindowsマシンで「wsl --shutdown」を実行しておく
ubuntu立ち上げて「ip a」実行でネット接続できたらOK。

Xサーバーのセットアップ

wslでGUIを使う場合は必要かも。
もしGUIが表示されなかったら、VcXsrvを入れる。

Turtlebot3 Simulationのセットアップ

ルンバ実機を動かす前に、シミュレーションでも遊んでみたいという方は、以下の手順でGazeboを入れましょう。
これを使えば、ルンバ(ラズパイ)を起動していなくても、SLAMや自動運転で遊ぶことができます。

# Slam用のモジュール
sudo apt install ros-humble-cartographer

# turtlebotモジュールをインストール&ビルド
mkdir -p ~/ros2_ws/src && cd ~/ros2_ws/src/
git clone -b humble-devel https://github.com/ROBOTIS-GIT/turtlebot3.git
cd ..
source /opt/ros/humble/setup.bash
sudo apt install python3-rosdep2
rosdep update
rosdep install --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y
colcon build --symlink-install

# シミュレーション系もインストール&ビルド
cd ~/projects/robotics/ros2_ws/src/
git clone -b humble-devel https://github.com/ROBOTIS-GIT/turtlebot3_simulations.git
cd .. && colcon build --symlink-install

# 自動運転系もインストール&ビルド
sudo apt install ros-humble-navigation2
sudo apt install ros-humble-nav2-bringup

以下でgazebo(シミュレーション)を起動できます。

# シミュレーションに使うロボットモデルを指定
source ~/projects/robotics/ros2_ws/install/setup.bash
export TURTLEBOT3_MODEL=burger

# Gazeboを起動
source /usr/share/gazebo/setup.sh
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

# SLAMをしてマップ作成をシミュレートしたい場合
source ~/projects/robotics/ros2_ws/install/setup.bash
ros2 launch turtlebot3_cartographer cartographer.launch.py use_sim_time:=True

# Navigation2を起動して自動運転をシミュレートしたい場合
ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=True

Gazeboを起動すると、現実のロボットを代替するシミュレーション環境が起動します。
使い方は次以降の章にて説明します。

使用時のコマンドまとめ

ここまでのセットアップが完了していれば、すでに準備は万端も同然です。
SLAMを使って地図を作成し、Navigation2で自動運転を行うことができます。

slam起動コマンドまとめ

ラズパイ

# コントローラの起動
ls -l /dev/input/js0
ros2 run joy_linux joy_linux_node
ros2 launch teleop_twist_joy teleop-launch.py

# LiDARの起動
source ~/ros2_ws/install/setup.bash
ros2 launch ldlidar ldlidar.launch.py  serial_port:=/dev/ttyAMA0

# ルンバ制御の起動
source ~/create_ws/install/setup.bash
ros2 launch create_bringup create_2.launch

リモートPC

cd ~/projects/robotics/ros2_ws/

# laserをbase_linkに変換する命令を送信しておく
ros2 run tf2_ros static_transform_publisher "0" "-0.105" "0" "-1.57" "0" "0" "base_link" "laser"

# cartographerの起動
ros2 launch turtlebot3_cartographer cartographer.launch.py use_sim_time:=True

# slamの起動(起動後、運転してmapを作成)
ros2 launch slam_toolbox online_async_launch.py

# 完成したmapを保存
ros2 run nav2_map_server map_saver_cli -f ~/map

Cartographerを起動するとrviz画面が立ち上がります。
JoyStickコントローラを使って操作し、下のように地図を埋めていきましょう。(LiDARの情報を使って、システムが自動的に地図埋めをしてくれます)

保存するときにmapは、pgmファイル(画像)とyamlファイル(パラメータ)が生成されます。

pgmファイルのイメージ

自動運転の実行まとめ

ラズパイ

# LiDARの起動
source ~/ros2_ws/install/setup.bash
ros2 launch ldlidar ldlidar.launch.py  serial_port:=/dev/ttyAMA0

# ルンバ制御の起動
source ~/create_ws/install/setup.bash
ros2 launch create_bringup create_2.launch

リモートPC

# データ系の変換
ros2 run tf2_ros static_transform_publisher "0" "0" "0" "1.57" "0" "0" "base_link" "laser"

# nav2の起動
export TURTLEBOT3_MODEL=burger
ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=True map:="/home/kit/projects/robotics/maps/map_3f.yaml"

mapが表示されない場合は、は/opt/ros/humble/share/turtlebot3_navigation2/param/burger.yamlの「robot_model_type」を「differential→nav2_amcl::DifferentialMotionModel」に変更します。

nav2を起動すると、rviz画面が起動します。
正しくマップが読み込まれれば、以下のような画面になります。
(この時エラーログっぽいのがターミナルで大量に表示されますが、次の操作で解決します)

2D Pose Estimateで「現在位置」と「現在姿勢(向き)」を指定します。

続いて、Nav2 Goalで「目標位置」と「目標姿勢(向き)」を指定します。

目標を設定すると直ちにロボットが動き始め、ゴールを目指してくれます。


この記事が参加している募集

やってみた

この記事が気に入ったらサポートをしてみませんか?