自作ロボットのDocker環境を作る(#03 hostネットワークで再構築。motor用コンテナ作成、Android端末との連携)
前回記事で、rviz用コンテナとrplidar用コンテナを作り、docker networkで通信させることができました。
最終的にはやはりAndroid端末と連携させたいので、色々構成を試行錯誤しました。
そしてようやくコンテナ内のROSとAndroid端末との通信もうまくいきましたので、ブログにまとめます。(
目次
構成
まずは、前回追加していなかった、motor駆動用のコンテナを追加します。
また、前回はbridgeネットワークを使ってrplidarコンテナとrviz用コンテナをつなげていましたが、
別端末(Android)との通信を実現させるため、rplidar用コンテナ、motor用コンテナは、hostネットワークモード。rviz用コンテナのみbridgeネットワークで構成しています。
※rviz用コンテナをhostネットワークにしなかったのは、vncのポート設定とhostネットワークが同時に設定できないためです。
hostネットワークでは、Dockerコンテナがホストマシンのネットワーク設定を共有します。要はjetsonNano側(ホスト)と同じIPアドレスが使用できます。
したがって、コンテナ内のroscoreのIPアドレスが、jetsonNano(ホスト)のIPと同じになるので、外部のAndroid端末からコンテナ内のroscoreに接続できます。
またjetsonnano側(ホスト)の/etc/hostsファイルにAndroid端末のIPを記載することで、Android端末とのトピック通信も可能になりました。おそらく、コンテナ内のroscoreは、/etc/hostsに記載されたIPアドレスを持つ端末(Android端末)にトピックを送信できる仕組みなのだと予想します。
では、上記のような構成になるように具体的にコンテナを立ち上げていきます。
rplidar用コンテナをhostネットワークで起動
[jetsonNano(ホストPC)内]
docker run --net=host --runtime nvidia -it --device /dev/ttyUSB0 --name rplidar_container ros:melodic-ros-base-l4t-r32.6.1
rplidarコンテナ内の~/.bashrcに以下を追記します。
[rplidarコンテナ内の~/.bashrc]
export ROS_IP=JetsonNano(ホストPC)のIPアドレス
export ROS_MASTER_URI=http://JetsonNano(ホストPC)のIPアドレス:11311
前回記事の「
自作ロボットのDocker環境を作る(#02 lidar用コンテナとrviz用コンテナを作ってみた)
motor用コンテナをhostネットワークで起動
自ロボットのmotorは、uart通信を使って、raspi-picoから制御します。したがって、’/dev/ttyTHS1’デバイスへのアクセスを有効にする必要があります。
そこで、jetsonNano側(ホストPC)で以下を行い、uartを有効化しておきます。
[jetsonNano(ホストPC)内]
systemctl stop nvgetty
systemctl disable nvgetty
udevadm trigger
sudo usermod -aG dialout $USER
以下でdockerコンテナを起動します。コンテナ内から’/dev/ttyTHS1’にアクセスさせるため、deviceオプションを指定します。
netオプションは、hostネットワークモードを指定します。
[jetsonNano(ホストPC)内]
docker run --net=host --runtime nvidia -it --device /dev/ttyTHS1 --name motor_container ros:melodic-ros-base-l4t-r32.6.1
コンテナが起動できたら、以降、コンテナ内で以下コマンド入力していきます。
pythonでserialを使うため、以下をインストールします。(※私のロボットは、ROS Melodicなので、python3-serialではなく、Python2系のserialを入れます。)
[motorコンテナ内]
apt-get update
apt-get install -y python-pip
pip install pyserial
motorを動かすためのパッケージを作ります。
私はgitにmotorを動かすノードを作ってますので、そちらを落としてきます。
[motorコンテナ内]
source /opt/ros/melodic/setup.bash
mkdir -p ~/ros_workspace/src
git clone https://github.com/InomaCreate/inobo_motor_send.git
cd ~/ros_workspace
catkin build
source devel/setup.bash
ここで、viが入っていないので、以下コマンドでインストールしました。
[motorコンテナ内]
apt-get update
apt-get install -y vim
motorコンテナ内の~/.bashrcに以下を追記します。
[motorコンテナ内の~/.bashrc]
export ROS_IP=JetsonNano(ホストPC)のIPアドレス
export ROS_MASTER_URI=http://JetsonNano(ホストPC)のIPアドレス:11311
rviz用コンテナをbridgeネットワークで起動
rviz用コンテナは、vncポートの設定があるので、hostネットワークでは起動できません。なので、前回同様bridgeネットワークで起動します。
[jetsonNano(ホストPC)内]
docker run --net=bridge -p 6080:80 --shm-size=1024m --name rviz_container tiryoh/ros-desktop-vnc:melodic-arm64
rvizコンテナ内の~/.bashrcに以下を追記します。
[rvizコンテナ内の~/.bashrc]
export ROS_IP=rvizコンテンのIPアドレス
export ROS_MASTER_URI=http://JetsonNano(ホストPC)のIPアドレス:11311
hostsファイルにAndroid端末のIPを追加
Android端末とのROS通信を行うため、jetsonNano(ホストPC)の/etc/hosts にAndroid端末のIPアドレスを追記します。
[jetsonNano(ホストPC)内の/etc/hostsファイル]
192.168.xx.yy android_device
動かしてみる
さて、各コンテナからrosノードを起動し、Android端末からcmd_velを通知してみました。
rplidarコンテナ
roscoreとrplidarのノードを起動します。
[rplidarコンテナ内]
roscore &
roslaunch rplidar_ros rplidar_a1.launch
motorコンテナ
uart通信用のmotorノードを起動します。
[motorコンテナ内]
rosrun inobo_motor_send inobo_motor_send.py
Android端末
ROS接続できるアプリ「ROS Control」を使って確認してみます。
rosmaster接続画面で、http://jetsonNanoのIPアドレス:11311を指定し、接続します。
lidarノードから出力されている/scanトピックがちゃんと表示されています。
Android端末でtopicが問題なく受信できてますね。
次にジョイスティックを使って、cmd_velを通知してみます。
ちゃんとモーターが動きました。成功です。
最後に
今回、コンテナの構成をhostネットワークにして、motor用のコンテナを追加、そして、Android端末との通信も実現できました。
あとは、自律走行のコンテナを作れば、実際にDockerコンテナ内で自律走行が試せそうです。
普通にjestonNano内に環境作れば簡単なことなのですが、コンテナにすると色々複雑になりますね。でも一度構築してしまえば、色々メリットもありそうなので頑張って対応していこうと思います。
それでは!!
【Docker】コンテナネットワークの基礎知識(bridgeネットワークについて)
Docker の bridge と host ネットワークについて勉強する
Dockerを用いて異なるホスト間でROSネットワークを構築
スポンサーリンク