見出し画像

Meridim90 - 改220703

神奈川県青少年センターで行われた第20回ROBO-ONEカンファレンスにて、Meridianについて発表させていただきました。

45分の発表に対して内容てんこ盛りになりました

発表を期日としてデモ用にいろいろと整理することができ、また、Meridianについて改めて考えをまとめるよい機会になりました。
他の方の講演も刺激的で、ハードウェアの作り方やロボ剣のノウハウについていろいろとお話しを伺うことができ、非常に勉強になりました。
特に移動ロボ剣での画像処理の時短については、競技を通じて世の中に有意で実用的な技術が出てくる可能性もあり、面白そうだと感じました。

次回のMeridianの発表は10/19のROSConJPになります。こちらもがんばりたいと思います。
今回の発表内容はまた後日お伝えするとしまして、今回の集約にあたりいくつか気づいた点がありました。

1パケットの最小最適サイズってひょっとして…

UDP通信の1パケットに使えるサイズはヘッダを除いて1472バイトであるという情報があり、その数値におさまるようにと最初のMeridim配列の長さを決めていました。
はじめはキリのいい配列100個で作っていて合計1600だったのですが、90個に減らして1440に収めました。無駄を省いたことでなかなか使いやすい配列ができたと満足していました。

何の疑いもなくその後の開発を続けていたのですが、発表前日に資料をチェックしたぷくたいさんから「ビットとバイトが混ざっているのでは?」というご指摘が!
そんなはずは…と調べてみるとたしかに。1472バイトに対して、Meridim90は180バイト(1440ビット)になっていることが判明しました。

非常にお恥ずかしい話で、完全に勘違いしておりました。
実はこれまでも何度かこの指摘を受けていたようなのですが、思い込みのあまりどうしてもそれに気づくことができず、間違った論拠を説明していました。今思い返せば話がかみあっていないと感じた場面もあったような気がしますが、相手もマイコン側の事情かなにかでそこまで小さくしてるのかな、ぐらいの感じで受け止めてくれていたようで、発覚が遅れました。

怪我の功名だったかもしれない

short型配列90個に対して、サーボ30+センサー+リモコン値と、これまでのホビーロボットで通常使われているものや必要そうな値を埋め込みつつ、若干のユーザー定義も残すという目標。
勘違いが発端となった与件でしたが、このハードルのおかげで合理化が必要となりました。ビットフラグを使ったり配列番号もデータの一部として利用するなどの工夫をした結果、可読性を担保しつつ、サーボを30個フルに使ってもなお8つのユーザー定義領域を確保できるという配列ができました。
1パケットの条件である1472バイトにもそもそも収まっているので一応ヨシ。
むしろマイコン側で扱いやすくなっていることで、マイクロ時間単位の処理がしやすいという利点が際立ってきました。

ではどこまで長くして良いのか

Meridim90は1パケット1472バイトのうち180バイトしか使っていないため、データ量を8倍まで増やすことができます。突然使いきれないほどの余裕が生まれてしまいました。

まず、1472バイトが本当に最適値(=最小値)なのかを調べてみました。

通信系の話でよくみるMTU(Maximum Transmission Unit)について調べてみると、その最小値は、IPv4: 548バイト、Ethernet: 64バイトとのことでした。
基本的には1472バイトを一つの単位と捉えて全く問題ないと思いますが、548や64という数字も区切りの論拠としてよいかもしれません。

次にマイコン内ではどうでしょう。
一番気になるのはESP32のDMAですが、こちらは8192バイト(…バイトですよね?)の設定ができ余裕はありそうです。
またESP32の通信バッファについては64バイトと小さいですが、こちらも増やすことは可能です。ちなみにArduinoのシリアル通信デフォルトも64バイトのようです。64バイトはとても小さいですが、サーボ数個のアームロボなど、最小構成でよいときには、64バイトを単位としたMeridianを使うという選択肢もあり得るかもしれません。通信バッファとして256バイトという数字も見かけるのでこちらも目安になりそうです。Meridim90が180バイトなので、ちょっとだけ増やす場合にも良さそうです。

長さの根拠としては処理単位だけではなく、処理時間も決定の論拠となっていきます。
サーボ1個あたりのマイコンでの送受信処理時間(現在は100μ秒程度想定)やMeridian自体の通信時間、計算処理時間などを積み重ね、合計5msに収まることを目標に設定してみたいと思います。

いまのうちに可変長対応を進めておく

もともとMeridianは可変長のつもりで作っていますが、より可変長しやすい定義にしておくのもよさそうです。
そこで、配列の中で変数の予約領域にしておきたい項目を前の方に固めておき、ユーザー定義領域を後半の一箇所にまとめてみることにしました。
ついでに短すぎるかもと言われたインクリメントカウンタ(もとはフレーム同期確認用で1バイト)を2バイトに増やして予約領域に確保。
チェックサムとエラーについては配列番号の指定を末尾-nと定義することにしました。そうすると配列の長さの指定に応じてユーザー領域を自由に増やせるようになり、スッキリわかりやすくなります。またサーボ数が少なくてよいロボットの場合も、利用サーボ数ギリギリまで配列を短くすることができます。64バイトの最小Meridianでも実用性をキープできます。

Meridim配列の定義はいまこんな感じです

じわじわ見えてくるMeridianの強み

人に説明していると「あれ?そもそもMeridianは不要では???」となる場合もあれば、一方で「むむ、やっぱりMeridianは便利なのでは?」となる場合もあります。
Meridianの機能的な強みはいまのところ大きくわけて3つありそうです。

① パソコンOSとサーボのブリッジとして

ROSではOSから直接サーボなどにデータを送る方法もありますが、OSの処理時間単位が荒いという課題があります。OS側のライブラリでサーボの一つ一つに順繰りデータを送るとすると、サーボの数を増やすほど遅延が増えていきます。MeridianであればOSの最小処理単位時間で全サーボへの指示情報を送信できる(と思う)ので、マイコンの処理速度を生かすことができ、リアルタイム制御も実現しやすくなります。

② コンパクトなデータパケットとして

制御に必要な最小限の情報を一つの配列にコンパクトにまとめており、1パケットに収まっているので、有線・無線を問わず、通信に載せるには便利です。
可変長として小さなデータから比較的大きなデータまで臨機応変に載せることができます。
またCOBSで変換すれば規格のないシリアル通信にも載せることができます。

③ データのオーバーレイ機能

デバイス間でデータを受け取って書き換えて次に渡す。この方式があるため、たとえばビットフラグを足し上げることができます。
現在この仕組みはエラーメッセージとリモコンで使っています。
たとえばデバイスAとデバイスBのそれぞれにリモコンをつけた場合、設定でどちらかを一方を優先することもできますし、両方のボタン入力を有効にすることもできます。

この次やること

ESP32が1枚あれば動作するMeridian Board -LITE- が完成しました。
まずはこちらの頒布準備をすすめていきます。

次回記事:

前回記事:


目次:


いいなと思ったら応援しよう!