見出し画像

サーボコマンドの中間プロトコル草案

Meridian計画。
一つのロボットの中にメーカーの違うサーボを混在させても自由に動かせるように、コマンドの共通項を調べて中間プロトコルを考えていきます。
まず、各社のサーボについていろいろと調べてみます。

どんなサーボがあるのか?

現在国内の競技会で見るホビーロボット用のコマンドサーボとして主だったものとしては、近藤科学双葉電子工業Dynamixelが挙げられます。
他には JR PROPO, Hitecなどが使われることもあるようです。独自のコマンド式サーボを開発されている方もいらっしゃるようです(スゴイ)。

Meridianでは制御基板としてTeensy4.0もしくはESP32を使うことを想定しています。
これらはサーボコマンド用として2系統以上のシリアル通信を同時に行うことができるので、上記2種以上のサーボを1枚の基盤で使い分けることができます。
前者3種のサーボはどれも半二重という通信方式なので、同じ回路を使い回すこともできそうです。
また翻訳機のコードを用意すれば理論上はどんなサーボでも扱うことができるようになります。


各社のコマンドはどうなっている?


各社のサーボの通信コマンドについて、「通信パケットの規格」と「設定できる項目」をざっと調べてみました。
各社とも、サーボの位置の指示だけでなく、保持特性やトルク(電流値)などを個別に指示できるようになっています。おおむね設定できる項目は20項目前後となるようです。

コマンドの最小公倍数を見つける

共通項を探っていくと、結論からすると1サーボあたり

「移動時間」「サーボID」「コマンド」「数値データ」

の4つの項目があれば、基本的な命令には対応できそうです。


このうち「移動時間」については、ロボット全体としてそのコマンドをどれくらいの時間で実行するかを決めるものなので、複数サーボでも全体として1つだけ数値データがあればOKのはずです。
たとえばコマドリアニメーション的なモーション作成であれば、これら4つの情報を時間単位でズラズラと送信するだけで、モーションを実行できるようになるはずです。
コマドリではなく動作毎に計算して出力する場合も、移動時間を固定して計算結果を移動位置の数値として流し込めばよさそうです。

「サーボID」については、データを配列に入れて送信することを考えれば、配列の順番をIDに変換していけばデータに書き込まなくても大丈夫です。
とすると、配列の中に実際に入れるのは「コマンド」と「数値」の1ペアのみになります。


「コマンド」の部分にもデータを割り当てますので、必要があれば各社最大255種類のコマンドを出し分けることができます。このコマンドは0がサーボオフ、1がサーボオンという命令を共通とし、あとは追って割り当てていく予定です。コマンドが1の時の「数値データ」はそのサーボの移動量を示すという感じにしておけば問題なさそうです。より厳密には何社のサーボのコマンドかもここで判別させることができますが、今回は見送りでよいでしょう。
一回のコマンドで複数のパラメータを変更したい場合にはカスタム領域を使うかもしくは別途の定義が必要ですが、草案段階ではこれも割愛しておきます。
ということで30サーボを動かすことを想定しますと、サーボ用の配列のサイズは60個となります。

他にどんなデータを格納する?

下図のように中間プロトコルが使われるのはサーボに対する指示の他に、母艦となるPCやシミュレーターとのやりとりにも使うことになります。

画像1

なのである程度のセンサー情報も入力できるようにすると良さそうです。
姿勢や加速度を示すIMUのセンサ情報を9軸分、ほかには足裏の圧力情報や距離センサの情報なども想定しておきます。

あまり積み込みすぎてもデータ量や取り回しの点で困ったことになるので、必要そうなデータのバッファを見て前半20個近くのデータをセンサリング用に開けておこうと思います。それ以上の情報が必要な場合にはカスタマイズで追加ということにしようと思います。


Meridian100のパケット内容

ということで2番目から19番目がセンサ等の基本情報、20番目から79番目までが30個のサーボ制御用。80-98までを追加のデータ用と想定してみます。

画像2

また0番目は全体のコマンド用として使ってみようと思います。コマンドを送るぞというときは100,それ以外は0。他のコマンドも送れますが後で考えます。

99番目はチェックサム用としてキープしようと思います。
チェックサムというのは、送られた配列のデータが正しいかどうかを判断するための数値です。
単純な合計値だとデータがすべて0でもデータが正解となってしまい都合がわるいので、0番〜98番までの数字を合計し、合計値の下位8ビットをビット反転したものをチェックサムにすることを考えています。こうするとデータが全部0の場合は間違ったデータであるという判断が可能で、誤動作の可能性を減らせます。
また、データサイズやデータ型については議論がわかれるところかもしれませんが、配列1個に格納するデータ型は2バイトのshort int型(-32767〜32767)、小数点は100倍などで格納することを今のところは考えています。最低限、オイラー角を-327.67度〜+327.67度まで扱えるようになります。


この草案ではデータの数を合計100個の配列に格納。このプロトコル名はMeridian100としておきます。
コマンド実行時に0番目に入れる100という番号はこの配列の長さも示すようにしてみています。

データの送受信方法

たった100個のデータですが、このデータをシリアル通信経由、カンマ区切りの文字列データで渡そうとすると1パケットが7000bitぐらいになります。標準的な通信速度115200bpsで実行したとすると1秒間に16回ほど更新が可能ですが、もうちょっと絞っておいた方が良さそうです。

Teensy4.0は通信速度に余裕がありますが、ESP32の方の通信速度の上限が500000bpsほどのようです。ここで毎秒100回の更新を行うことを想定すると、送受信を行うことを考えれば1パケットあたり2000bit内に収めておく必要があります。データは軽ければ軽いほどよく、その分、計算やセンサ取得などのリソースに割り当てることができます。

そこでデータの送受信についてはバイナリ形式、COBSという変換を用いてデータ量を減らしてみます。こうすると1616ビットまでデータ量を減らせそうです。ここまで減らせればTeensy側の計算リソースもかなり軽減できそうです。ESP32のみでの運用ということも視野に入ってきます。

Wifi通信に使うESP32はの2.4 GHzIEEE 802.11b/g/nに対応しているとのこと。b/g/nの順に11Mbps,54Mbps,300Mbpsのスピードが出るようですが、11Mbpsを目安に計算しても通信速度には余裕がありそうです。

この範疇にて、サーボの個数をさらに増やしたいとか、センサーの数をもっと増やしたいいった場合はカスタマイズ領域に。
それでも足りなくなってきたらMeridian1000等として順次拡張的に再定義してけば良いと考えています。
今後より速い送信スピードに対応する小型CPU基板が出てくれば、データの詰め込みにもあまり気を使わなくてもよくなるかもしれません。

画像や音声の転送は考えなくてよいのか?

Meridianは基本的にロボットの制御部分を司るものと考えているので、画像や音声、空間認識、会話、インターネット接続等は別のプロジェクトとして切り離します。ただし、その外部プロジェクトと柔軟に自由に通信できる準備はとても大事です。

次はこの中間プロトコル草案を実際に組み込んでいきます。

次の記事:

前の記事:

目次:


この記事が気に入ったらサポートをしてみませんか?