みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoでROS2に入門する(その2)

はじめに

前回はkasを使用してビルド環境を構築した。kasが強力なので使いやすい反面、実際に何が行われているか分かりづらく、トラブルシュートやカスタマイズをするための知識が得づらくなっている。

今回はkasを使用せずにビルド環境を構築する。

環境構築

pokyの取得

pokyを取得する。

$ mkdir -p ~/yocto/ros
$ cd ~/yocto/ros
$ git clone https://git.yoctoproject.org/poky
$ cd poky
$ git checkout tags/scarthgap-5.0.3 -b scarthgap-5.0.3
$ cd ../

環境変数の設定

oe-init-build-envの読み込み

$ source poky/oe-init-build-env

レイヤの取得

ROS2(humble)を構築するために必要なレイヤを取得する。追加するレイヤはkasで生成されたbblayers.confを参考にしている。

$ bitbake-layers layerindex-fetch meta-ros2-humble
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-filesystem
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-networking
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-gnome
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-initramfs
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-multimedia
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-perl
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-python
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-webserver
$ bitbake-layers add-layer ../poky/meta-openembedded/meta-xfce

local.confの修正

前回はqemux86-64を使用したが今回はqemuarm64を使用する。

meta-rosを使う環境ではDISTROにpokyではなくros1ros2を設定することでROSを使用することができる。 kasで作成した環境ではsystemdが使用されていたのでINIT_MANAGERにsystemdを設定している。

MACHINE ?= "qemuarm64"

DISTRO = "ros2"
INIT_MANAGER = "systemd"

ビルド対象のレイヤ

ビルド対象のレイヤを改めて確認する。

$ bitbake-layers show-layers
NOTE: Starting bitbake server...
layer                 path                                                                    priority
========================================================================================================
core                  /home/ubuntu/yocto/ros/poky/meta                                        5
yocto                 /home/ubuntu/yocto/ros/poky/meta-poky                                   5
yoctobsp              /home/ubuntu/yocto/ros/poky/meta-yocto-bsp                              5
openembedded-layer    /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-oe                   5
meta-python           /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-python               5
ros-common-layer      /home/ubuntu/yocto/ros/poky/meta-ros/meta-ros-common                    10
ros2-layer            /home/ubuntu/yocto/ros/poky/meta-ros/meta-ros2                          11
ros2-humble-layer     /home/ubuntu/yocto/ros/poky/meta-ros/meta-ros2-humble                   12
networking-layer      /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-networking           5
gnome-layer           /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-gnome                5
meta-initramfs        /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-initramfs            5
multimedia-layer      /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-multimedia           5
perl-layer            /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-perl                 5
webserver             /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-webserver            5
xfce-layer            /home/ubuntu/yocto/ros/poky/meta-openembedded/meta-xfce                 5

ROSディストリビューション

meta-rosはYoctoProject/OpenEmbeddedが提供するレイヤモデルをうまく使用して、 meta-ros-commonにプラスしてmeta-ros1meta-ros2を組み合わせることでROSのバージョンを切り替えている。 また、meta-ros2meta-ros2-humblemeta-ros2-jazzyを組み合わせることでROSディストリビューションを切り替えている。

ビルド

bitbakeでros-image-coreをビルドする。

$ bitbake ros-image-core

ros-image-core自体はmeta-ros-commonの持ち物だが、先述の通りレイヤとの組み合わせによって、実際に出来上がるイメージが適切なROSディストリビューションとなるようになっている。

動作確認

QEMUを起動し動作を確認する。

$ runqemu nographic

ログインしてOSバージョンを確認。

Robot Operating System 2 (ROS 2) with OpenEmbedded Linux 2.humble.2024-06-20.3-0 qemuarm64 ttyAMA0

qemuarm64 login: root
root@qemuarm64:~# cat /etc/os-release
ID=ros2
NAME="Robot Operating System 2 (ROS 2) with OpenEmbedded Linux"
VERSION="2.humble.2024-06-20.3-0 (humble)"
VERSION_ID=2.humble.2024-06-20.3-0
VERSION_CODENAME="humble"
PRETTY_NAME="Robot Operating System 2 (ROS 2) with OpenEmbedded Linux 2.humble.2024-06-20.3-0 (humble)"
CPE_NAME="cpe:/o:openembedded:ros2:2.humble.2024-06-20.3-0"

ros2コマンドを確認する。

root@qemuarm64:~# which ros2
root@qemuarm64:~#

kasで作成したkirkstone+humbleだと/usr/bin/ros2に配置されていたが、scarthgap+humbleでは見つからない。

一般的なROS2の環境と同じようにsource /opt/ros/humble/setup.shを実行することで、ros2コマンドが使用可能になる。

root@qemuarm64:~# source /opt/ros/humble/setup.sh
head: invalid option -- 'c'
BusyBox v1.36.1 () multi-call binary.

Usage: head [OPTIONS] [FILE]...
head: invalid option -- 'c'
BusyBox v1.36.1 () multi-call binary.

Usage: head [OPTIONS] [FILE]...
head: invalid option -- 'c'
BusyBox v1.36.1 () multi-call binary.

Usage: head [OPTIONS] [FILE]...
head: invalid option -- 'c'
BusyBox v1.36.1 () multi-call binary.

Usage: head [OPTIONS] [FILE]...
head: invalid option -- 'c'
BusyBox v1.36.1 () multi-call binary.

Usage: head [OPTIONS] [FILE]...
head: invalid option -- 'c'
BusyBox v1.36.1 () multi-call binary.

Usage: head [OPTIONS] [FILE]...

エラーメッセージがたくさん出るが、ros2の環境設定は行われている。

root@qemuarm64:~# which ros2
/opt/ros/humble/bin/ros2
root@qemuarm64:~# ros2
/opt/ros/humble/lib/python3.12/site-packages/sros2/__init__.py:26: UserWarning: Share directory for sros2 (/opt/ros/humble/share/sros2) does not exist.
  ament_index_python.get_package_share_directory('sros2'),
usage: ros2 [-h] [--use-python-default-buffering] Call `ros2 <command> -h` for more detailed usage. ...

ros2 is an extensible command-line tool for ROS 2.

options:
  -h, --help            show this help message and exit
  --use-python-default-buffering
                        Do not force line buffering in stdout and instead use the python default buffering, which might be affected by PYTHONUNBUFFERED/-u and depends on whatever stdout is interactive
                        or not

Commands:
  action     Various action related sub-commands
  component  Various component related sub-commands
  daemon     Various daemon related sub-commands
  doctor     Check ROS setup and other potential issues
  interface  Show information about ROS interfaces
  launch     Run a launch file
  lifecycle  Various lifecycle related sub-commands
  multicast  Various multicast related sub-commands
  node       Various node related sub-commands
  param      Various param related sub-commands
  pkg        Various package related sub-commands
  run        Run a package specific executable
  security   Various security related sub-commands
  service    Various service related sub-commands
  topic      Various topic related sub-commands
  wtf        Use `wtf` as alias to `doctor`

  Call `ros2 <command> -h` for more detailed usage.

上記のheadコマンドのエラーメッセージはbusyboxのheadコマンドが-cオプションを受け付けないためとなる。 これはcoreutilsをインストールすることで表示されなくなる。

シェルもbusyboxなので、bashを入れたい。

また、デモ用ノードのtalker、listenerの動作を確認するために 複数の端末を開けるようにしたい。GUI環境がないためSSHで複数シェルを開けるようにする。

最終的なlocal.conf

今回作成する環境の最終的なlocal.confは下記のようになる。

MACHINE ?= "qemuarm64"

DISTRO = "ros2"
INIT_MANAGER = "systemd"
IMAGE_INSTALL:append = " coreutils bash"

IMAGE_INSTALL:append = " demo-nodes-cpp"
EXTRA_IMAGE_FEATURES += "ssh-server-openssh"

ROSノードの動作確認

QEMUの起動

下記でQEMUを起動する。

$ runqemu nographic

sshで接続

別の端末で下記のようにしてSSHQEMUに接続する。QEMUのアドレスは常に同じ。

$ ssh root@192.168.7.2

ノードの起動

QEMUの端末で下記を実行する。

root@qemuarm64:~# source /opt/ros/humble/setup.bash
root@qemuarm64:~# ros2 run demo_nodes_cpp talker
[INFO] [1727526996.561837142] [talker]: Publishing: 'Hello World: 1'
[INFO] [1727526997.560419904] [talker]: Publishing: 'Hello World: 2'
[INFO] [1727526998.560633584] [talker]: Publishing: 'Hello World: 3'
[INFO] [1727526999.560611776] [talker]: Publishing: 'Hello World: 4'
[INFO] [1727527000.560563748] [talker]: Publishing: 'Hello World: 5'
[INFO] [1727527001.560681565] [talker]: Publishing: 'Hello World: 6'
[INFO] [1727527002.560761342] [talker]: Publishing: 'Hello World: 7'
[INFO] [1727527003.560696830] [talker]: Publishing: 'Hello World: 8'
[INFO] [1727527004.560643432] [talker]: Publishing: 'Hello World: 9'
[INFO] [1727527005.560850621] [talker]: Publishing: 'Hello World: 10'
[INFO] [1727527006.560733346] [talker]: Publishing: 'Hello World: 11'
[INFO] [1727527007.560769019] [talker]: Publishing: 'Hello World: 12'
[INFO] [1727527008.561200052] [talker]: Publishing: 'Hello World: 13'
[INFO] [1727527009.560818866] [talker]: Publishing: 'Hello World: 14'
[INFO] [1727527010.560854185] [talker]: Publishing: 'Hello World: 15'
[INFO] [1727527011.560994356] [talker]: Publishing: 'Hello World: 16'
[INFO] [1727527012.560954000] [talker]: Publishing: 'Hello World: 17'
[INFO] [1727527013.561065750] [talker]: Publishing: 'Hello World: 18'
[INFO] [1727527014.561088563] [talker]: Publishing: 'Hello World: 19'
[INFO] [1727527015.560994808] [talker]: Publishing: 'Hello World: 20'
[INFO] [1727527016.561031546] [talker]: Publishing: 'Hello World: 21'

SSHの端末で下記を実行する。

root@qemuarm64:~# source /opt/ros/humble/setup.bash
root@qemuarm64:~# ros2 run demo_nodes_cpp listener
[INFO] [1727527008.564684607] [listener]: I heard: [Hello World: 13]
[INFO] [1727527009.563394995] [listener]: I heard: [Hello World: 14]
[INFO] [1727527010.563196515] [listener]: I heard: [Hello World: 15]
[INFO] [1727527011.564015325] [listener]: I heard: [Hello World: 16]
[INFO] [1727527012.564640807] [listener]: I heard: [Hello World: 17]
[INFO] [1727527013.563380651] [listener]: I heard: [Hello World: 18]
[INFO] [1727527014.563401623] [listener]: I heard: [Hello World: 19]
[INFO] [1727527015.563069301] [listener]: I heard: [Hello World: 20]
[INFO] [1727527016.563527248] [listener]: I heard: [Hello World: 21]
[INFO] [1727527017.563485978] [listener]: I heard: [Hello World: 22]
[INFO] [1727527018.563759558] [listener]: I heard: [Hello World: 23]
[INFO] [1727527019.563241419] [listener]: I heard: [Hello World: 24]
[INFO] [1727527020.563793663] [listener]: I heard: [Hello World: 25]
[INFO] [1727527021.563547049] [listener]: I heard: [Hello World: 26]
[INFO] [1727527022.563921908] [listener]: I heard: [Hello World: 27]

きちんと通信できているようだ。

まとめ

kasを使用せずにmeta-rosの環境を構築した。 demo_nodes_cppパッケージのtalkderとlisnerを実行し、Yocto Project環境でもROS2がきちんと動作することを確認した。