自作ロボットのDocker環境を作る(#02 lidar用コンテナとrviz用コンテナを作ってみた)
さて、ベースとなるDocker+ROS環境はできたので、これに自分が使っているROSノードを入れて環境を構築していくのですが、まず自分のロボットのROSノードの構成を一旦整理して、どのようなコンテナ構成にしたらいいかを検討してみようと思います。
目次
ROSノード整理
自身ロボットの構成はざっくり以下の様な感じです。
[センサー系]
・rplidarNode・・・USB接続必要
[モーター系]※UART通信(シリアル通信)
・/inobo_motor_send
・/odom_publisher
[ナビ関連]
・/pose_fusion_node
・/emcl2
・/map_server
・/move_base
コンテナ構成を考える
上記のノードを1つのコンテナ内に入れようかと考えましたが、色々なサイトを読んでいると、役割や機能でコンテナを複数立ててシステム化しているような記載を見ます。
1つのコンテナ内にすべてのノードを入れると管理は簡単そうです。しかし、dockerの特徴であるデータやプログラムを隔離できることを活かすなら複数コンテナで管理したほうがよいかもしれません。
ということで、今回は、機能ごとにコンテナを分けてシステムを作っていこうと思います。
(ただし、通信のオーバーヘッドが増えそうです。しかし、同一筐体内ですし、dockerは軽量なシステムなので、まずはやってみて問題なく動くかを検証しようと思います)
lidar用のコンテナとrviz用(debug用)のコンテナを立ち上げる
まずは、jetsonNano内でlidar用のコンテナとrviz用のコンテナを立ち上げ、lidarコンテナで発行する/scanトピックをrviz用コンテナで受信するような構成を検討してみます。
lidar用のコンテナの作成
lidar用のコンテナを作ります。
lidarはUSBで接続しますので、コンテナ内でUSBデバイスを扱えるようにしないといけません。
docker runコマンド時に、以下のオプションをつけることで、コンテナ内でUSBデバイスを認識できるようです。
--device /dev/ttyUSB0(例)
また、今回jetsonNano内でコンテナ同士(lidar用コンテナとrviz用コンテナ)で通信を行います。
同一筐体内で通信するには、ブリッジネットワークを作成します。
以下コマンドを実行します。
docker network create rosnet
以下コマンドでlidar用コンテナを起動してみます。--net=rosnet
で作成したブリッジネットワークを指定します。
sudo docker run --net=rosnet --runtime nvidia -it --device /dev/ttyUSB0 ros:melodic-ros-base-l4t-r32.6.1
rplidar用のrosノードを準備
lidar用コンテナが起動できたら、コンテナ内に入り、rplidarノードを準備します。
まずはrosのワークスペースの作成からです。
cd ~/ros-workspace
mkdir src
catkin build
次に、rplidarノードのソースをgithubから取得してビルドします
cd ~/ros-workspace
cd ~/ros_workspace/src
git clone https://github.com/Slamtec/rplidar_ros.git
cd ../
catkin build
source devel/setup.bash
さて、roscoreを立ち上げて、rplidarノードを動かしてみます。
roscore &
roslaunch rplidar_ros rplidar_a1.launch
一応、動きました。では次にrviz用のコンテナを作って、/scanトピックが出ているか確認します。
rviz用コンテナの作成
jetsonNanoはarm64系なので、以下のdockerイメージを使用しました。
docker run --net=rosnet -p 6080:80 --shm-size=1024m tiryoh/ros-desktop-vnc:melodic-arm64
ブラウザでlocalhost:6080にアクセスし、コンテナにアクセスします。
コンテナ内の~/.bashrcを以下のように編集します。
ROS_IPは、自分自身(rviz用コンテナ)のCONTAINER ID、ROS_MASTER_URIは、lidar用CONTAINER IDを指定します。
CONTAINER IDは
以下例:
#export ROS_IP=127.0.0.1
#export ROS_MASTER_URI=http://$ROS_IP:11311
export ROS_IP=xxxxxx(rviz用コンテナのID)
export ROS_MASTER_URI=http://yyyyy(lidar用コンテナのID):11311
編集後、以下コマンドを入力して設定を読み込み、rvizを起動してみます。
source ~/.bashrc
rviz
mapフレームとlaserフレームがつながっていないエラーが出ているので、以下のコマンドでフレームをつなげます。
rosrun tf static_transform_publisher 0 0 0 0 0 0 map laser 100
rvizでscanトピックを表示してみます。
おぉ~表示できました!
これで、vncサーバーでrviz表示できてるので、ロボットにモニターとかつけなくても、同一ネットワークにある他PCからブラウザアクセスでrvizや他のデバッグができそうですね。
最後に
とりあえず、今回はrviz用コンテナとlidar用コンテナ2つを作り、通信させてみました。
これでナビゲーションやモーター系など機能毎にコンテナを分けて、1つのシステムとして稼働させることができそう。
あと、懸念はAndroidアプリとの通信はどうなるのか?(おそらく、Androidにコンテナとかいう概念はないので、通信できなさそう。。)
ということは、別にAndroidのネイティブアプリじゃなくても、Webサーバーをdockerで立てて、Webアプリにしてもよさそうですね。
面白くなってきました。
また少しずつdocker環境を整えていきます。
それでは!!
補足
今回色々試行錯誤し、たくさんのdockerコマンドや設定を触ってので、とりあえず、メモとして残しておきます。
dockerの前に毎回sudoを付けるのをやめる
以下を実行後、再起動したらsudoつけなくてOKになった
sudo usermod -aG docker $USER
一度終了したコンテナを再度動かす時
sudo docker ps -a
でIDかNameを確認
以下を実行してコンテナ起動
docker start ID or Name
以下のコマンドでコンテナ内に入る
docker exec -it ID or Name /bin/bash
viが入ってなかったのでインストール
apt-get update
apt-get install vim
スポンサーリンク