manvaのエンジニアリング魂

エンジニアリング・ものづくり・DIYをもっと身近にするためのブログ。インスピレーションを刺激します。

ODriveで低価格サーボ

大きさは正義(力こそパワー)であるが,個人でロボットを作ろうとする場合や,企業等で個人向けにロボットを作って販売しようとする場合,たいていは小さいものしかできず,(オタクではない)一般人には,おもちゃ扱いされがちである。

なぜ小さいものになってしまうかといえば,大抵は資金の問題が大きい。例えば手足6軸ずつのヒューマノイドを作ろうと思えば,それだけで24軸必要なので,だいたい1軸1万円くらいが個人で出せる限界であろう。そのため個人のロボットでは1軸1万円くらいのラジコンサーボがよく使われる。大きなラジコンサーボもあるが,それだと1軸3万円くらいになる。大きいロボットを個人で作ったり買ったりするのは資金的にきつい。

ところが数年前くらいから,ドローン用のブラシレスDCモータを使って比較的低価格で大きめのロボットを実現している事例が多く見られるようになってきた。

例えば ↓ UCBerkeley  Blue

新しい汎用型協働ロボット「Blue」 値段は破格の5000ドル | Forbes JAPAN(フォーブス ジャパン)

↓Unitree Go1 air

中国製の犬型ロボがもっと安価に。「Go1 air」なら30万円でお釣りが来る | ギズモード・ジャパン

 

というような状況から,特に何が作りたいわけでもないのだが,大きめのロボット等をいつでも作れるようしておきたくなり,1軸1万円程度を目安に,ハイパワーのサーボを作れる方策を探ってみることにした。こういうことやってるうちに何かやりたいことが見つかるのを期待している。

モータドライバを選ぶ

調べてみると,ブラシレスDCモータのドライバとして,速度制御だけで良ければラジコン用のESC (Electric Speed Controller)というのが安い。

もう少し深入りして,トルク(電流)のレベルで制御をしたい場合等は,オープンソースで中のソフトまでいじれるODriveやMoteusというのが人気がありそうだった。まずは↓のサイト(以下「参考サイト※」とする)を参考にODriveで一式揃えてみることにした。

BLDC制御実験キットの製作 - Qiita

モータドライバ ODrive v3.6(の模造品)↓を購入。AliExpressで9194円ja.aliexpress.com

到着したものを見てみると,基板が緑色(本家は黒)なので模造品らしい。本家の写真を使って堂々と販売しているので購入時に模造品だと気づかなかった。エンコーダのコネクタに本家ではあるはずの3.3Vピンがなかったり,細かいところが本家とは違う。本家に還元する意味でも,本家のサイト↓から買うべきだった。

odriverobotics.com

モータを選ぶ

ロボット用途で考えると,一番気になるのはトルクなのだが,ドローン用のBLDCモータの仕様ではトルクが書いていない事が多い。以下の式で計算できるようだ。

BLDCモータの最大トルク計算方法

最大トルク[Nm] = 8.27 / KV値[min^{-1}/V] * 最大電流[A]

8.27という数字は↓の値。
\displaystyle\frac{3}{2\sqrt{3}}\cdot\frac{60}{2\pi}=8.27

ODriveの公式サイトでモータの表がある。最もトルクが大きいのはホバーボード(取手のないセグウェイ)用の物であるが、具体的な型式ではなくジャンルとしてひとまとめにされている。その他で最もトルクが大きいのは「9235-100KV Turnigy Multistar」で4.7Nmとある。マブチの540が最大0.2Nmくらいなのでこれでも結構なトルクである。参考サイト※で選ばれたモータの型式はX8318Sとなっているが,画像等から判断して,これもどうやら9235と同じものらしい。これを選ぼうと思ったが、既に製造中止っぽい。AliExpressで検索すると、見た目やスペックが同じ、たぶん模造品がいろんな会社から出てる。

モータ 8318(の模造品の中古)AliExpressで6320円のもの↓を購入。(価格は変動するし,無くなることも多いが,多くの業者が出品しているので検索すればまだしばらくは出てくるだろう。)

ja.aliexpress.com

↓到着。

f:id:manva:20211108064506j:image

「second hand」(中古)とは書かれていたが、想像以上にボロい。あと,線,短すぎ!

エンコーダを選ぶ

磁気式エンコーダ評価基板 AS5047P-TS_EK_AB(参考サイト※と同じもの)にする。ODrive公式サイトの対応エンコーダの表にも挙がっている。SPI通信で使えば14bit,AB相パルスで使うなら4逓倍で4000パルス/rev。表では,「Supported in SPI AMS mode」と書かれており,Quadrature(AB相パルスのこと)が「n」となっているがAB相パルスでもできた(分解能は落ちるが)。

マルツで2316円(Digi-Keyで2000円だが送料も2000円なのでこちらの方が安い)。

www.marutsu.co.jp

いざ使おうとすると,ICのすぐ横にある巨大なジャンパピンのタワーがめちゃ邪魔。磁石をICの0.5~3mmの距離に配置しなければいけないのに,どうやって使う想定なんだろうか。ハンダを溶かして引き抜こうとしたが結構固く,無理やり引き抜いたらスルーホールも取れてしまった。ニッパで切断したほうが良さそう。

3Dプリンタで作成

支持部品をFusion360で設計し,3DプリンタX-Makerで作成した。

↓ 磁気式エンコーダのマグネットホルダ

f:id:manva:20211106103320p:plainf:id:manva:20211106122602p:plain

↓ モータとエンコーダ基板の支持フレーム

f:id:manva:20211106103353p:plain

 

配線。組み立てた様子↓。エンコーダは,まずは参考サイト※のように,AB相パルスで読み取るようにした。セリアのすのこを使うというところまで真似させてもらった。電源は手持ちの第一電波工業の安定化電源を使った。

f:id:manva:20211107132544j:image

動作確認

ODrive公式サイトのGetting Startedの通りにやってみる。

Getting Started | ODrive

USBでODriveをパソコンに繋ぎ,電源を入れたら認識された。
Anacondaはもう入れていたので,WindowsスタートメニューからAnaconda Prompt (Anaconda3)起動
> pip install --upgrade odrive
> odrivetool

→エラー「Coud not open USB device」。
TroubleshootingページのUSB Connectivity Issuesに従って,zadig-2.6.exeをダウンロード,Odriveを起動して,Options - List All DevicesにチェックしてリストからOdriveを選択(ODrive 3.x CDC Interfaceではなく,ODrive 3.x Native Interfaceの方)。WinUSB(v10‥が入っていたが,WinUSB(v6‥にダウングレード(それしか選べないので)
→できた!
> odrv0.vbus_voltage
→15.5V。正しそう。
> odrv0.axis0.motor.config.calibration_current →10A
> odrv0.axis0.controller.config.vel_limit →2 [turn/s].
ちょうどよいのでそのまま。
odrv0.axis0.motor.config.pole_pairs →7 磁石の数数えたら40個。/2で20にする。
> odrv0.axis0.motor.config.pole_pairs=20
odrv0.axis0.motor.config.torque_constant →0.04   8.27/モータKVにする。KV=100なので,
> odrv0.axis0.motor.config.torque_constant = 0.0827
> odrv0.axis0.motor.config.motor_type=MOTOR_TYPE_GIMBAL
公式のDocのDeepL翻訳「ジンバルモーターを使用する場合、電流フィードバックを使用しないため、current_limとcalibration_currentは実際には「電圧制限」と「校正電圧」を意味します。つまり、10に設定した場合、パラメータ名とは裏腹に10Vを意味します。」
電流制限10Aじゃなく電圧制限10Vになっているらしい。まあいいか。

> odrv0.axis0.encoder.config.cpr = 4000
> odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
→一瞬動いたがダメ。

> dump_errors(odrv0)
でエラー確認できる。→ MOTOR_ERROR_MODULATION_MAGNITUDE

> odrv0.axis0.motor.config.calibration_current=1
にしたらそれっぽく動いた!しかし今度はエンコーダのエラー
→ENCODER_ERROR_NO_RESPONSE
上記のようにジャンパピン抜くときにスルーホール壊したせいか。もう一つ買っておいたエンコーダ基板に交換。ジャンパは抜くのではなく切断し、ハンダ付けでショートさせる。→Ok!
> odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
としてほんの少し触ったら暴走。発散していたのは速度ループのようで,速度ゲインを下げたらOk。デフォルト0.166だが,0.1だとブルブル振動する。0.05くらいの方がマシになる。
> odrv0.axis0.controller.config.vel_gain=0.05

止め方がわからん。
> odrv0.quit()

でodrivetoolごと終了。

 

まあまあ苦労したが動くようになった。産業用のロボットでは,バックラッシや剛性等,減速機がネックになる場合が多いので,ハイトルクのモータで低減速比にできるのがメリットになると期待したが,それ以前にモータのコギングがひどいので,指令通りのトルクが出てなさそう。少なくとも現時点では,正直,産業用サーボモータと比較できるレベルではなかった。エンコーダをSPI通信にして分解能を上げ,パラメータを調整して,リップル補正とかして,どこまで改善できるか。