2022年3月19日土曜日

M5Atomでバランスロボット

 M5ATOM MATRIXとTailBATでバランスロボットを作ってみました。


 

TailBATの中には若干スペースの余裕があるので、そこにモータードライバ(共立エレショップのKP-DRV8830)を入れました。GROVE端子の基板接続部分からモータードライバへ、i2c信号と電源5VおよびGNDを配線してあります。i2cのプルアップ抵抗は追加せず、ESP32の内部プルアップのみを使っています。i2c(Wire)のクロックを50kHzに落として使っています。


モーターは、「ちっちゃいものくらぶ」の「ちびギアモータ+プーリー・タイヤセット」(https://tiisaishop.dip.jp/product/sg/)です。



モーターへの電線を通すために、やすりでTrailBatのケースを一部削りました。

 
 
 
 カバーを付けたところです。



2つのモータは、厚めの両面テープで貼り付けました。M5ATOMを取り付けた全体像の写真です。


 

裏側です。


 

M5Stack の Timer Camera X に付属のマウンターを使って、M5CAMERAに付属のスタンドを取り付けると、腕のようになります。(格好だけです)


回路図です。TailBATは省略してあります。


ビデオです。


 

TailBATについての注意。手元にあるTailBATには2種類あって、古いタイプ(写真左)は、Grove端子のソケットがATOMのピンに届きませんでした。新しいタイプ(写真右)ならば、大丈夫でした。


 

ソースコードはこちらです。

 

22 件のコメント:

  1. 木楽らぼ様
     倒立振子作りでは参考にさせて頂きました。ありがとうございます。

    M5stickなどとSG90HVサーボ、タイヤはちっちゃいものクラブのサイズで
    倒立振子を作る場合の制御でのコツなど教えて頂けませんでしょうか。

    ギヤモータ+モータドライバでは簡単に立つのですが
    連続回転型サーボのSG90HVサーボ+M5stick+サーボホーンOリングタイヤでは
    安定して立たせ続けられません。

    直径5cmくらいまで大きなタイヤにすれば問題なく立ちます。
    SG90HVは応答が遅く小さなタイヤ、振子周期が短くなってくると
    うまく立たせられなくて。。。
    ご教授頂ければ幸いです。

    返信削除
    返信
    1. ブログを見ていただきありがとうございます。
      5cm程度のタイヤで立つのであれば、小さいタイヤでも早く回せば立つはずですが、サーボの回転が追い付かないのでしょうね。
      それほど高速に動かなくても立ち続けることができるように私が工夫したことは、倒立振子の角度の積分を使っていることです。
      だいぶ前に投稿したものですが、連続回転サーボとGR-KURUMI(Arduino ProMiniに似ているマイコンです)を使った倒立振子が参考になるかもしれません。
      http://kirakulabo.blogspot.com/2018/07/blog-post.html
      ビデオが撮れたら追加します。

      削除
    2. 早速の回答、ありがとうございます!
      連続回転サーボで立たせてたんですね。それもサーボホーンサイズタイヤで。やりたいことに近いです!
      そのページには気づきませんでした。
      角度の積分、、、エンコーダとかは使われてないですよね・・・?
      自分はおよそ駆動パルスが回転速度に比例関係にあるとしてPWMパルス積分を角度積分の比例値として使ってはいます。が、いまいちです。

      ぼくのはこんな感じの構成です。これのAタイプ です。
      https://n-shinichi.hatenablog.com/entry/2022/03/30/005230

      削除
    3. SG90HVと木楽らぼさんの上記ページで使われてるFS90R・・・
      ぱっと見ほぼ仕様的には同じかなとは思うのですが
      FS90Rは応答がちょっといいとかで選択したとかありますでしょうか?

      他、反転時の応答遅れ補正のパンチ制御?的なのは自分も入れてます。

      削除
    4. 舌足らずですみません。角度というのは、ボディーの傾き角度のことです。加速度と角速度から相補フィルターで計算しています。この傾き角度の積分を使っています。
      エンコーダーは使ってないです。
      n_shinichiさんの大径ホイール倒立振子のビデオ見ました。すごく安定していますね。あれはDRV8830を使ったタイプですか?

      削除
    5. FS90Rは、当時秋月ではそれしかなかったので使ったのだと思います。仕様的には同じに見えますね。比較実験をしたことがないので何とも言えませんが、今だったらSG90HVを使うと思います。若干安いので。
      パンチ制御的な方法は、M5StickCのバランスロボでは入れていましたが、M5Atomのバランスロボからは削除しました。連続回転サーボのバランスロボには入れていません。ギヤのバックラッシュが大きい時には効果がありそうですが。

      削除
  2. FS90Rサーボでの倒立ロボ動画、拝見させていただきました。
    ありがとうございます!安定感、すごい。。。
    想像してたよりずっと低周期バランス動作です。

    タイヤが粘着テープで滑らかな円形ではない、ところ、
    電池4本で重心が若干高く慣性が大きいところなどで
    多少制御がしやすくなってる?とかありますでしょうか。

    自分の経験では滑らかなタイヤより多少ざらついたタイヤや、
    滑らかなタイヤでもフローリングよりカーペットの上とかの方が
    制御は安定する傾向がありました。
    また、小さい倒立ロボになってくると重心高さがちょっと下がると
    固有周期がかなり上がって難しくなる傾向があったので。。。

    返信削除
    返信
    1. 重心の位置とタイヤの形についての実験のために、低重心でOリングを使ったものを作ってみました。パラメータの調整はいい加減ですが、とりあえず立ったのでビデオを撮ってブログに載せました。
      https://youtu.be/8wpzE-4YlYQ

      削除
  3. 自分のブログで紹介させていただきました。
    問題があるようなら言ってください。
    https://n-shinichi.hatenablog.com/entry/2022/04/01/075804

    返信削除
    返信
    1. 紹介していただきありがとうございます!
      私も n_shinichi さんのブログを見て、勉強させていただきます。

      削除
  4. 連続サーボのソース拝見させて頂きました。
    サーボの指令パルスledcWriteでやると簡単ですが
    digitalWriteでポート立ち上げ時間チェックしながら指令時間でポートを下げる...
    かなり手間を掛けて指令パルス作られてますが
    理由を教えて頂けませんでしょうか。
    ひょっとしてledcWriteの方はパルス幅変更しても実際に反映されるのが遅い?
     そういえばそこの遅れ、測ったことはないです。。。
    digitalWriteの方はそのコードが実行されたら即ポートがパルスを出し始める?

    データシートでは 700~ 1500 ~2300 ±800usほどあるのに
    パルス幅を1000~約1500~2000・・・・±500usに削ってますが
    使用範囲を狭めてるのはなんででしょうか...

    よろしければお暇な時にでも教えて頂ければ幸いです。

    返信削除
    返信
    1. ledcWriteですが、これはESP32に特有の命令で、GR-KURUMIにはないと思います。ではなぜServo.hを使わなかったか・・・4年近く前のことなのでよく覚えてないですが、Servo.hでは20msec周期のパルスになるのがいやだったのではないかと思います(倒立の制御は10msec周期で行っているので)。
      パルス幅をなぜ1000usecから2000usecに制限しているか・・・これもよく覚えてないですが、高速回転はメカにも負担になるし、ノイズも出るし、ということできりのよい数字で制限したのだと思います。それで動いたので、そのままに・・
      そもそも、連続サーボの回転スピードが端から端までリニアな特性になってはいないかもしれませんね(実験してはいませんが)。
      答えになってなくてすみません。

      削除
  5. m5stick+サーボでの倒立ロボ、見ました!素敵です♪
    既に作ってたんじゃないですよね?
    お願いしてからあっという間に作っちゃったんですよね・・・すごいぃ...

    GR-KURUMI・・・ledcWrite、使えないのですか...
    Servo.h・・・50Hzでしたね。。。

    ±500us・・・なるほど、、、 
          実際うまくバランス取れてる時はそんなに必要ないですしね。。。

    連続サーボ、リニア・・・自分もちゃんと測ったことないですが
               リニアじゃない感じです。CW,CCWでも感度違いますよね。
               じりじり回っていくのでぼくは1個はモータ配線逆にして
               使ってます。木楽さんのは曲がってく感じないですね。。。
               左右,cw,ccwで感度補正を制御で入れてたりしたでしょうか。



    返信削除
    返信
    1. GR-KURUMIに付いていたサーボを外してきて、M5StickCと両面テープでくっつけただけですから。(n_shinichiさんのは3Dプリンタできれい作ってますね)

      連続サーボは0点が正確に1500usecになっているわけではないので、個体ごとに0点のパルス幅を、
      pulseZeroL=1460;
      pulseZeroR=1490;
      というように定義して、それにスピード(パワー)を加算、減算しているだけです。CW/CCWは気にしてません。

      直進性については、ジャイロから垂直軸回りの角速度を持ってきて、これを積分してロボットの向きを計算し、それが一定になるように左右の車輪を制御しています。

      削除
  6. varSpd += power ・・・物理学的には力積分で速度という感じで扱ってられますが...
              実際はpower・・・パルス幅はすでに速度比例値ですよね。
              パルス幅の積分は距離、位置、これでvarIdst的に使える気がします。。。
    自分の経験ではパルス幅の積分で位置推定相当に使えてる感じなのですが。

              モータ制御で電流指令値ならトルク、力の比例値になって
              積分で速度比例値になる感じのイメージが持てるのですが...
              
       今までパルス幅の積分で
       なんか理解が間違ってますでしょうか。。。
       なんか間違ってるからうまくいってないのだとは思いますが...

    返信削除
    返信
    1. DCモーターをPWMで回す場合、(角)速度がPWM値に比例するか、(角)加速度がPWM値に比例するかは、微妙なところだと思います。モーターが停止(またはゆっくり回転)している状態で電圧をかけると、電圧にほぼ比例した電流が流れ(電気的過渡現象は無視して)、それがトルクとなるので、PWMと加速度がほぼ比例すると考えます。モーターが定常的に回転している状態だと、負荷が同じなら電圧と回転速度が比例するはずです。実際は、回転速度は常に変わりますし、負荷も変わるので、どちらとも言えない状態になっていると思います。
      プログラムを作るにあたり、安定して立っている状態では、モーターの回転速度は低い、したがってPWM値と加速度が比例すると仮定し、それを積分したものを速度、さらに積分したものを位置と考えました。いずれにしても、非常にラフな推定値でしかありませんが。

      削除
    2. 上のような考え方で作ったDCモータ用プログラムを、あまり考えずにほぼそのまま連続サーボに流用しました。サーボモーターも低速回転時(立ち上がり時)には、パルス幅に比例したトルクが発生し、定常的に回転する状態になると、速度がパルス幅に比例するようになると考えれば、一応理屈がとおるようにも思えますが、いかがでしょうか?

      削除
  7. 気が向いたら・・・
     m5stick+サーボ、ledcWriteでやってみて頂けませんか...

    返信削除
    返信
    1. あの・・・ブログ以外の通信方法(メールアドレスとか、SNSとか)ありませんでしょうか? 公開しませんので。

      削除
    2. いただいたTwitterのリンクはヘッダー画像へのリンクのようで、私はTwitter初心者なので、このリンクからどうやってダイレクトメッセージを送るのか知識がありません。できたら、私のTwitterアカウント @kirakulabo をフォローしていただけませんでしょうか? そうすればダイレクトメッセージでやり取りできると思うのですが・・

      削除
  8. digitalWrite、なんかよさそうです!
    https://n-shinichi.hatenablog.com/entry/2022/04/03/094041

    返信削除
    返信
    1. 私もledcを試してみました。おっしゃるように遅れがあるみたいです。回避策として、ledcSetupで周波数を300Hz(分解能16ビット)にしてみたところ、周波数100Hzよりだいぶ良くなりました。たぶん連続サーボの仕様上無理な使い方だと思いますので、n_shinichiさんのサーボで動くかどうかはわかりませんが・・・
      詳細は、できればダイレクトメッセージでやりとりしたいです。

      削除