ElixirによるROS2クライアントライブラリRclexを、DDS観点で試す

## はじめに (ROS2って、DDSって、Rclexってなに？)
ROS2(Robot Operating System)はロボット開発支援フレームワークです。ROS2環境ではプログラムコードはC++やPythonで書かれることが主に想定されているようですが、これをElixirでも開発したい！ということでElixirのROS2クライアントライブラリ(=RCL)、Rclexが開発されています。

https://github.com/rclex/rclex

ROS2は通信レイヤにDDS(Data Distribution Service)という通信プロトコル/ライブラリ/パッケージが採用されていて、開発言語を問わず実装にDDSを用いていれば、ノード間で簡単に通信することが可能です（C++で書かれたROS2ノードとPythonで書かれたROS2ノード間で簡単に通信可能）。このRclexを用いればElixirで書いたコードで他のROS2ノードと通信することが可能です。

この記事はRclexを試してみましたので、そのノウハウを紹介するものです。

（将来的に、Elixir+DDS(ROS2なし)で相互通信できるようになる/することを想定しています。なおこの記事(Rclex）はElixir+ROS2(within DDS)環境です。)

DDSについては(ROS2観点ですが)こちらの記事が参考になります。
https://ros.youtalk.jp/2017/05/28/dds.html

なお本記事は、2021年5月時点の内容です。

## 環境とバージョン

Rclexは環境を選びます。以下の環境で動かしました。

- Ubuntu 18.04.5 LTS （amd64)
- ROS2 Dashing Diademata - Patch Release 8
- Elixir 1.11.2
- Erlang/OTP 24

![スクリーンショット 2021-05-25 11.35.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172921/47e9d896-1db9-f0fd-fdf2-d054f36037ad.png)

当初Macでトライしましたが、ROS2は入るのですがRclexがビルドできず断念しました。
Ubuntuは、Ubuntu 20.04.2.0 LTS (Focal Fossa)ではROS2 Dashingがインストールできません。ROS2の新しいリリース(Galactic Geochelone)あたりは入るのですが、今度はROS2 GGではRclexがビルドできません。そのため18.04が必要です。
そういう訳でROS2はDashingでなければなりません。前述のように現状のRclexはDashingのライブラリ構造に依存しているためです。(コードをすごく頑張って直せば対応できるはずですが...。)
ErlangとElixirはUbuntu環境でパッケージインストールしました。特に問題ありませんでした。

## 環境構築、インストール

### Ubuntu 18.04.5環境の構築
私はUbuntuをintel Mac(10.15 Catalina)上にVirtualBoxをインストールしその上で動かしました。ROS2に不慣れなのでGUIツール(rviz2など)も使うかなと思ったためですが、今回のようにDDSで通信を試すだけであればGUIは不要です。たぶんクラウド上のVMでも大丈夫だと思います。

VirtualBoxのインストール、またUbuntuのインストールは割愛します。調べればすぐに見つかるでしょう。
OS本体のインストールが完了したら、VirtualBoxのGuest Additionsもインストールしておきましょう。Guest AddtionsはROS2/Rclexトライアル的には不要ですが、入れたほうが便利です。

```terminal:bash
% sudo apt-get update
% sudo apt-get install virtualbox-guest-dkms
```
このあたりを参考にしました。
https://www.linuxmania.jp/virtualbox_02.html

### ROS2 Dashingのインストール
Ubuntu環境ができたら、ROS2 Dashingをインストールしていきます。ROS2はバイナリパッケージインストールと自前構築の２つの方法がありますが、ここではソースコードから自前で構築しました。後述のRclexのビルドのために、includeファイルとライブラリの場所を把握しておきたかったためです。(バイナリパッケージでインストールしてもうまくできるかもしれませんが、未試用です。)

基本的な手順はROS2のドキュメント通りです。簡単に解説していきます。
https://docs.ros.org/en/dashing/Installation/Ubuntu-Development-Setup.html
(なおROS2のドキュメントは、バージョンが異なっても全般的には非常に似ていますので注意が必要です。)

以下の手順では、ROS2のフルセットをインストールしていますが、多分、いらない物がたくさんあるはずなので、ROS2に詳しい方は不要なもののインストールは省略できるはずです。RclexのビルドにはROS２の開発環境があればよいはず。

#### ロケールをセット

```terminal:bash
% sudo apt update && sudo apt install locales
% sudo locale-gen en_US en_US.UTF-8
% sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
% export LANG=en_US.UTF-8
```

ちなみに、この設定をしたのに、あとの方でコケました。

#### ROS2レポジトリを追加

```terminal:bash
% sudo apt update && sudo apt install curl gnupg2 lsb-release
% 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 $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
```

この手順に失敗すると、次の手順のパッケージインストールの際に謎のエラーが出るので、間違えないように注意しましょう。

#### 環境構築に必要なパッケージをインストール

```terminal:bash
% sudo apt update && sudo apt install -y \
  build-essential \
  cmake \
  git \
  python3-colcon-common-extensions \
  python3-pip \
  python-rosdep \
  python3-vcstool \
  wget
% python3 -m pip install -U \
  argcomplete \
  flake8 \
  flake8-blind-except \
  flake8-builtins \
  flake8-class-newline \
  flake8-comprehensions \
  flake8-deprecated \
  flake8-docstrings \
  flake8-import-order \
  flake8-quotes \
  pytest-repeat \
  pytest-rerunfailures \
  pytest \
  pytest-cov \
  pytest-runner \
  setuptools
% sudo apt install --no-install-recommends -y \
  libasio-dev \
  libtinyxml2-dev
% sudo apt install --no-install-recommends -y \
  libcunit1-dev
```

#### ROS2 Dashing本体コードをダウンロード

```terminal:bash
% mkdir -p ~/ros2_dashing/src
% cd ~/ros2_dashing
% wget https://raw.githubusercontent.com/ros2/ros2/dashing/ros2.repos
% vcs import src < ros2.repos
```

続いて、rosdepコマンドで依存関係パッケージをインストールしていきます。

```terminal:bash
% sudo rosdep init
% rosdep update
% rosdep install --from-paths src --ignore-src --rosdistro dashing -y --skip-keys "console_bridge fastcdr fastrtps libopensplice67 libopensplice69 rti-connext-dds-5.3.1 urdfdom_headers"
```

ドキュメントではこの後、独自のDDS環境をインストールしたい場合には入れよ、と書いてあるのですが、ここではそれはしません。

#### コンパイル
いよいよROS2本体をビルドしていきます。

```terminal:bash
% cd ~/ros2_dashing/
% colcon build --symlinck-install
```

非常に時間がかかります。Corei7/32GBのMac、VirtualBox 4GBメモリ環境で、1時間半くらいかかりました。

#### 環境変数をセット
ビルドが終わった時点で、ROS2環境が ~/ros2_dashing/install配下にできています。ROS2環境を使う(動かす)ためには環境変数(PATH等)をセットする必要があり、それをするためのスクリプトが用意されています。ターミナル実行時に都度環境変数をセットするか(下記)、.bashrc等でシェル起動時に自動で読み込ませるかします。

```terminal:bash
% . ~/ros2_dashing/install/setup.bash
```
bash以外のシェル用のスクリプトもあります。(sh, zah, powershell)

#### 簡単にサンプルを動かしてみる
ROS2の環境構築ができたところで、ドキドキしながらサンプルを動かしてみます。
ターミナルを２つ起動し、双方でsetup.bashを実行させてros2コマンドが動くようにしておきます（下記には含んでいます）。その状態で、

```:ターミナル1
% . ~/ros2_dashing/install/local_setup.bash
% ros2 run demo_nodes_cpp talker
```

```:ターミナル２
% . ~/ros2_dashing/install/local_setup.bash
% ros2 run demo_nodes_py listener
```

とすると、ターミナル1側でpublishした文字列が、ターミナル2側のsubscriber側で受信できています。やりました！

実際の実行時の画面はこんな感じです。

![スクリーンショット 2021-05-25 12.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172921/c58a04e5-bfb2-cb0b-91cb-77d5ffddd7e3.png)

なお、実行時にエラーが出る可能性があります。% export LANG=en_US.UTF-8 を再度設定する必要がありました。
(新しいターミナルを起動して、そちらではLANGが設定されていなかったからなのかもしれません。ログがなく詳細不明です。)

### Elixir環境の構築
ROS2環境ができたので、ようやくRclexですが、前提となるElixirを入れます。

Elixirのドキュメントに従います。
https://elixir-lang.jp/install.html

ddstest２という作業ディレクトリを掘ってやりました。

```terminal:bash
% mkdir ddstest２
% cd ddstest２
% wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && sudo dpkg -i erlang-solutions_1.0_all.deb
% sudo apt-get update
% sudo apt-get install esl-erlang
% sudo apt-get install elixir
```

その他、Rclexのビルドに必要なパッケージを入れておきます。

```terminal:bash
% sudo apt-get install build-essential
% sudo apt-get install erlang-dev
```

### Rclexをインストールする
ここからがようやく本番です！
Rclexはライブラリであり、単体で使用するものではないので、ここでは同じ開発者から提供されているサンプルコードを使います。Rclex本体はサンプルコードの中で依存パッケージとして指定されており、サンプルコードをビルドするときに自動的に、インストール・ビルドされます。

https://github.com/rclex/rclex_samples

```terminal:bash
% git clone https://github.com/rclex/rclex_samples.git
% cd rclex_samples
```

今回はただサンプルコードをそのまま使います。Elixirの流儀に従って作業します。

```shell-session:bash
kikuzo@kikuzo-VirtualBox:~/ddstest２/rclex_samples$ mix deps.get
Resolving Hex dependencies...
Dependency resolution completed:
Unchanged:
  elixir_make 0.6.2
  rclex 0.3.1
* Getting rclex (Hex package)
* Getting elixir_make (Hex package)
kikuzo@kikuzo-VirtualBox:~/ddstest２/rclex_samples$ 
```

すかさずmixコマンドを実行してみると、

```shell-session:bash
kikuzo@kikuzo-VirtualBox:~/ddstest２/rclex_samples$ mix
==> elixir_make
Compiling 1 file (.ex)
Generated elixir_make app
==> rclex
mkdir -p /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/priv
mkdir -p /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj
gcc -c -I/usr/lib/erlang/usr/include -I/opt/ros/dashing/include -g -O2 -Wall -Wextra -Wno-unused-parameter -pedantic -fPIC -o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/total_nif.o src/total_nif.c
gcc -c -I/usr/lib/erlang/usr/include -I/opt/ros/dashing/include -g -O2 -Wall -Wextra -Wno-unused-parameter -pedantic -fPIC -o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o src/init_nif.c
src/init_nif.c:10:10: fatal error: rcl/rcl.h: No such file or directory
 #include "rcl/rcl.h"
          ^~~~~~~~~~~
compilation terminated.
Makefile:43: recipe for target '/home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o' failed
make: *** [/home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o] Error 1
could not compile dependency :rclex, "mix compile" failed. You can recompile this dependency with "mix deps.compile rclex", update it with "mix deps.update rclex" or clean it with "mix deps.clean rclex"
==> rclex_samples
** (Mix) Could not compile with "make" (exit status: 2).
You need to have gcc and make installed. If you are using
Ubuntu or any other Debian-based system, install the packages
"build-essential". Also install "erlang-dev" package if not
included in your Erlang/OTP version. If you're on Fedora, run
"dnf group install 'Development Tools'".

kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ 
```

コンパイルエラーです。これは、RclexをコンパイルするのにROS2環境側のインクルードファイルが見つからないのが原因です。Rclexが期待するROS2環境のディレクトリ構成と↑で作業したディレクトリ構成が異なっているためで、ここでは、RclexのMakefileの該当部分を修正してしまいます。

```makefile:~/ddstest2/rclex_samples/deps/rclex/Makefile
# set directory for ROSDISTRO
ROSDIR = /opt/ros/dashing

CC = gcc
LD = ld
RM = rm

PREFIX = $(MIX_APP_PATH)/priv
BUILD  = $(MIX_APP_PATH)/obj

NIF = $(PREFIX)/rclex.so

CFLAGS  ?= -g -O2 -Wall -Wextra -Wno-unused-parameter -pedantic -fPIC
LDFLAGS ?= -g -shared

# Set Erlang-specific compile and linker flags
ERL_CFLAGS  ?= -I$(ERL_EI_INCLUDE_DIR)
ERL_LDFLAGS ?= -L$(ERL_EI_LIBDIR)

# for ROS libs
ROS_CFLAGS  ?= -I$(ROSDIR)/include
ROS_LDFLAGS ?= -L$(ROSDIR)/lib
ROS_LDFLAGS += -lrcl -lrmw -lrcutils \
        -lrosidl_generator_c -lrosidl_typesupport_c \
        -lrosidl_typesupport_introspection_c \
        -lstd_msgs__rosidl_generator_c -lstd_msgs__rosidl_typesupport_c \
        -lfastcdr -lfastrtps -lrmw_fastrtps_cpp
# if you want to use OpenSplice DDS
#ROS_LDFLAGS    += -lrmw_opensplice_cpp -lrosidl_typesupport_opensplice_cpp

SRC ?= src/total_nif.c src/init_nif.c src/node_nif.c src/publisher_nif.c src/subscription_nif.c src/wait_nif.c
SRC += src/msg_int16_nif.c src/msg_string_nif.c
HEADERS =$(wildcard src/*.h)
OBJ = $(SRC:src/%.c=$(BUILD)/%.o)

all: install

install: $(PREFIX) $(BUILD) $(NIF)

$(OBJ): $(HEADERS) Makefile

$(BUILD)/%.o: src/%.c
        $(CC) -c $(ERL_CFLAGS) $(ROS_CFLAGS) $(CFLAGS) -o $@ $<

$(NIF): $(OBJ)
        $(CC) -o $@ $(ERL_LDFLAGS) $(LDFLAGS) $^ $(ROS_LDFLAGS)

$(PREFIX):
        mkdir -p $@

$(BUILD):
        mkdir -p $@

clean:
        $(RM) $(NIF) $(BUILD)/*.o

.PHONY: all clean install

```

冒頭部分のROSDIRを修正します。

```makefile:~/ddstest2/rclex_samples/deps/rclex/Makefile
# set directory for ROSDISTRO
#ROSDIR = /opt/ros/dashing
ROSDIR = /home/kikuzo/ros2_dashing/install

CC = gcc
LD = ld
RM = rm

PREFIX = $(MIX_APP_PATH)/priv
BUILD  = $(MIX_APP_PATH)/obj

(..省略..)
```

できたら、rclexをビルドします。↑のエラーメッセージ内にありましたが、rclex本体を作るためには

```terminal:bash
% mix deps.compile rclex
```

とやります。

```terminal:bash
kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ mix deps.compile rclex
==> rclex
mkdir -p /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/priv
mkdir -p /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj
gcc -c -I/usr/lib/erlang/usr/include -I/home/kikuzo/ros2_dashing/install/include -g -O2 -Wall -Wextra -Wno-unused-parameter -pedantic -fPIC -o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/total_nif.o src/total_nif.c
gcc -c -I/usr/lib/erlang/usr/include -I/home/kikuzo/ros2_dashing/install/include -g -O2 -Wall -Wextra -Wno-unused-parameter -pedantic -fPIC -o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o src/init_nif.c
src/init_nif.c:10:10: fatal error: rcl/rcl.h: No such file or directory
 #include "rcl/rcl.h"
          ^~~~~~~~~~~
compilation terminated.
Makefile:45: recipe for target '/home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o' failed
make: *** [/home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o] Error 1
could not compile dependency :rclex, "mix compile" failed. You can recompile this dependency with "mix deps.compile rclex", update it with "mix deps.update rclex" or clean it with "mix deps.clean rclex"
==> rclex_samples
** (Mix) Could not compile with "make" (exit status: 2).
You need to have gcc and make installed. If you are using
Ubuntu or any other Debian-based system, install the packages
"build-essential". Also install "erlang-dev" package if not
included in your Erlang/OTP version. If you're on Fedora, run
"dnf group install 'Development Tools'".

kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ 
```
再びエラー。依然としてファイルがないと言われます。

本来はMakefileを直したほうが良いのですが、どうやら前提とするディレクトリ構成が異なっているようで修正が大きそうなので、ROS2環境側でシンボリックリンクを張って回避することにします。(このあたり、Rclex開発時はどうだったのかちょっと謎です。ROS2 Dashingのパッチレベルが上ってディレクトリ構成が変わったのかな？)

```terminal:bash
% cd ~/ros2_dashing/install
% mkdir include
% cd include
% ln -s ../rcl/include/rcl rcl
(同様に、rcutils, rmw, rosidl_generator_c, rosidl_typesupport_interface, std_msgsについても市リンクを張ります)
```
このようになります。
![スクリーンショット 2021-05-25 13.42.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172921/914eb3ed-bb4a-5051-e033-ee04046bb2ad.png)

さて今度こそ。

```terminal:bash
kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ mix deps.compile rclex
==> rclex
(..省略..)
gcc -o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/priv/rclex.so -L/usr/lib/erlang/usr/lib -g -shared /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/total_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/node_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/publisher_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/subscription_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/wait_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/msg_int16_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/msg_string_nif.o -L/home/kikuzo/ros2_dashing/install/lib -lrcl -lrmw -lrcutils -lrosidl_generator_c -lrosidl_typesupport_c -lrosidl_typesupport_introspection_c -lstd_msgs__rosidl_generator_c -lstd_msgs__rosidl_typesupport_c -lfastcdr -lfastrtps -lrmw_fastrtps_cpp
/usr/bin/ld: cannot find -lrcl
collect2: error: ld returned 1 exit status
Makefile:48: recipe for target '/home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/priv/rclex.so' failed
make: *** [/home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/priv/rclex.so] Error 1
could not compile dependency :rclex, "mix compile" failed. You can recompile this dependency with "mix deps.compile rclex", update it with "mix deps.update rclex" or clean it with "mix deps.clean rclex"
==> rclex_samples
** (Mix) Could not compile with "make" (exit status: 2).
You need to have gcc and make installed. If you are using
Ubuntu or any other Debian-based system, install the packages
"build-essential". Also install "erlang-dev" package if not
included in your Erlang/OTP version. If you're on Fedora, run
"dnf group install 'Development Tools'".

kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ 
```
コンパイルは通りましたが、こんどはライブラリがないようです。上と同様にシンボリックリンクを貼ってしのぐことにします。

```terminal:bash
% cd ~/ros2_dashing/install
% mkdir lib
% cd lib
% ln -s ../rcl/lib/librcl.so  librcl.so

(
libfastcdr.so           librosidl_generator_c.so
libfastrtps.so          librosidl_typesupport_c.so
librcl.so               librosidl_typesupport_introspection_c.so
librcutils.so           libstd_msgs__rosidl_generator_c.so
librmw_fastrtps_cpp.so  libstd_msgs__rosidlgenerator_c.so
librmw.so               libstd_msgs__rosidl_typesupport_c.so
について同様にします。
)
```
ちょっと見にくいですがこのようになります。

![スクリーンショット 2021-05-25 14.01.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172921/b7fbfba4-c898-de06-5c0a-8ce9a09e70a7.png)

これでコンパイルが通ります。やりました！

```terminal:bash
kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ mix deps.compile rclex
==> rclex
(..省略..)
gcc -o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/priv/rclex.so -L/usr/lib/erlang/usr/lib -g -shared /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/total_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/init_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/node_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/publisher_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/subscription_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/wait_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/msg_int16_nif.o /home/kikuzo/ddstest2/rclex_samples/_build/dev/lib/rclex/obj/msg_string_nif.o -L/home/kikuzo/ros2_dashing/install/lib -lrcl -lrmw -lrcutils -lrosidl_generator_c -lrosidl_typesupport_c -lrosidl_typesupport_introspection_c -lstd_msgs__rosidl_generator_c -lstd_msgs__rosidl_typesupport_c -lfastcdr -lfastrtps -lrmw_fastrtps_cpp
Compiling 6 files (.ex)
warning: redefining @doc attribute previously set at line 435.

Please remove the duplicate docs. If instead you want to override a previously defined @doc, attach the @doc attribute to a function head:

    @doc """
    new docs
    """
    def initialize_msgs(...)

  lib/rclex.ex:445: Rclex.initialize_msgs/2

Generated rclex app
kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ 
```

## 動かしてみる
rclex_samplesにある、simple_pubを使ってみましょう。
ターミナルを２つ起動し、一つでrclex_samples/simple_pubを動かして送信しし、もう一つはROS2のコマンドでsubscriberを動かして受信してみます。

```terminal:bash
kikuzo@kikuzo-VirtualBox:~/ddstest2/rclex_samples$ iex -S mix
Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [jit]

Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> RclexSamples.SimplePub. 
callback/1    pub_main/1    
iex(1)> RclexSamples.SimplePub.pub_main 1
finished rcl_init
                 publish message:hello,world
publish ok

```
実際の様子。

![スクリーンショット 2021-05-25 14.50.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172921/83589f71-5aa8-1194-6657-ef9003a5a89d.png)

受信側はこうですね。

![スクリーンショット 2021-05-25 14.47.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172921/7b8adcfa-5698-f8ef-ea51-bab44b67777f.png)

なお、iexコマンドの起動に先立って、ros2環境のセットアップ(setup.bashの実行)をしておかないと実行時にエラーが出ます。

## まとめ
Rclexを動かしてみました。DDSでメッセージを送受信するだけですが、とりあえず動いていることは確認できました。

みなさんも、いろいろ試してみて、様子を教えて下さい。