カエデ自動機械

ちょっとしたものづくりや電子工作のメモなど。技術開発とは今は呼べないかな。

自律ローバーを作る(6)-ソフトウェア部分

前回は電装品を一通り組み上げました。
今日は正直説明しづらい部分で、ソフトウエアと言いつつ全くソフトウエアの話はしておらず、前回と被った内容な気もするものの、、、とにかく書いて公開しようと思います。

全体の構造

基本的には倒立振子ロボットを作った時の構造と変わらず、ROSが動いているPC(今回はJetson Nano)とマイコンArduino Mega)にプログラムを書き込みます。
PCが複雑な処理やUSB接続式の機器とのインターフェースを、マイコンの部分は主にセンサとのインターフェースを受け持ちます。
この役割分担はまあよくあるパターンかと思います。

ktd-prototype.hatenablog.com
ktd-prototype.hatenablog.com


各部位の機能割付けはこんな感じです。(一部は前回記事と被りますが)

f:id:ktd-prototype:20200627142506p:plain
部位別の機能割付

Jetson Nanoの機能

Jetson Nanoでは、マイコンArduino Mega)で実施する処理「以外」をさせています。

直接Arduinoで接続・処理し難いUSB接続式のゲームパッドやセンサなんかの処理がここに含まれます。
それらの情報を基にした走行計画や速度制御もJetson側です。

従ってホイールオドメトリなんかもJetson側で必要な情報ですので、計算はJetson側でやってしまいます。Arduino側ではエンコーダパルスのカウントアップのみを担当します。

センサについては、現状カメラやLiDARのような外界認識センサは積んでいませんので、Jetson Nanoはゲームパッドの情報を基にした遠隔操縦指令の処理、PIDによる速度制御とモータ指令値生成を担当します。

それぞれの機能をROSのノードとして実現していくと、大体以下のような構造になります。
rqt_graphを直接スクショして貼ろうかと思ったのですが、「それでは魂が込もっていない!」と自分の中の精神論者が鎌首を擡げた結果、かえってわかりにくい図になりました。

f:id:ktd-prototype:20200627154431p:plain
Jetson Nanoの中の機能構造

丸いかたまりがROSノード(点線はROS純正、実線はオリジナル)、四角いかたまりがやりとりしている情報です。最後にArduinoに渡す部分以外はROSメッセージを使います。

自律走行用のノード(環境認識など)は未実装ですが、実装された場合、速度制御ノードは複数の速度指令を購読することになります。これについては、遠隔操縦に基づく速度指令を最優先とするか、ローバー動作モードによって速度制御に使用する指令値を切り替えるか、また後で考える予定です。


また、ローバー動作モードに応じて(例えばゲームパッドの接続が切れた時など)速度指令を強制ゼロにしたりしていますが、この辺をどのノードで処理させるか、若干決めかねています。
現在は「安全のため」と称して複数のノードがローバー動作モードを示すメッセージを購読し、それぞれのレイヤでモータ指令値をゼロにしていますが・・・rqt_graphで見ても複雑だし、もう少し簡単にしようかとも思っています。


Arduinoの機能

ArduinoではI2Cで繋がるIMU(Adafruit BNO055)や、H/Lのパルスで検出するエンコーダの情報の処理を行います。

IMUは純正のライブラリで欲しい情報を全て100Hzで取得できますので簡単です。更新レートは100Hzが限界のようで、これがライブラリやセンサ側の都合なのか、マイコンの性能の限界なのかはよくわかりません・・・
github.com

エンコーダ情報については、以前紹介した方法と同じやり方で左右それぞれの車輪の回転数を検出します。
ktd-prototype.hatenablog.com

Arduino MegaはI/O割り込みピンが2、3、18、19、20、21の6本しか使えず、そのうち20、21はI2Cで使われてしまうので、エンコーダを2個使う場合はギリギリです。
この点についてはほぼ全てのピンを任意に割り込みピンとして設定できたESP32の方が良かったなあと思わなくもありません・・・



Arduinoのコードはそれほど特別なことをしておりません。
上記ライブラリを用いてIMU情報を、以前紹介した方式を用いて車輪回転数を検出します。

Jetson Nanoとの通信はUSBケーブルを通るシリアル通信です。この辺の通信についても、倒立振子ロボットの時に使ったやり方を踏襲しています。
若干送受信する情報の内容は変わりますが、Jetson Nanoからヘッダバイトを含む情報を送信し、Arduino側で受け取って1バイトずつ処理 → Arduino側はその受信完了をトリガーに自分が持つ情報をJetson Nano側へ送信・・・というやり方です。

ktd-prototype.hatenablog.com


まとめ

いかがでしたでしょうか(言ってみたかった)

結局口頭で説明しただけでよくわからないかも知れませんが、久々に記事を書けて僕は満足しました。
コードは一応GitHubに上がっています。が、この手のコードの作法があまりわかっていないのでかえってわかりにくいかも知れません。
github.com


一応、広く一般に使用可能な実験用プラットフォームという位置づけで,
readmeにも色々と使い方を書いて公開していますが、もう少しハードもソフトも整備しないととてもではないが広まらないだろう、という印象です。。。悔しいですが。

なにはともあれ、次回で実際に動作確認をして、このシリーズは一区切りです。ブログには書いていませんが、実作業では更にこの先の取り組みとして、カメラを用いた自律走行にチャレンジしようとしています。