SimpleFOCでブラシレスモーターを回す

この記事は

学ロボ Advent Calendar 2023

の4日目の記事となります.

adventar.org

目次

ソースコード

github.com

自己紹介

電気通信大学 2020年入学のpizac(ぴざっく)と申します.

電通大ロボメカ工房で学ロボ20~23の電装を担当してました.

はじめに

近年の学ロボではブラシレスモーター(BLDC)を使うチームが増えています.BLDCはアウトローターにできるため,大きなトルクを得ることができます.そのため,ギアヘッドを小さくして小型化&軽量化ができます.ブラシツキに比べて制御が大変ですが,Odriveなど安価なモータードライバー(MD)があり,誰でも簡単にBLDCを回すことができます.

odriverobotics.com

 

また,DJI社のロボマスモーターが人気です.これはBLDCとMDがセット販売されていて,CANで電流指令値を送れば電流追従してくれる代物です.電流,速度,位置も返してくれるため,PIDカスケード制御で速度制御や位置制御ができます.

store.dji.com

store.dji.com

 

これらの安価で高性能なMDにより,自作MDを作る回路班も減ってきました.

ロボコン自作MD界隈は界隈の消滅の危機に対し,ロボマスモタドラ買ったら負け教という謎の宗教を立ち上げるほどです.

pic.twitter.com/88Wltzpdx6

 

界隈の繁栄のため,今回は誰でもできるBLDCのベクトル制御を記事にしました.

ベクトル制御とは,BLDCの制御方法の1つで迷ったらこれを使いましょう.

準備

ベクトル制御にはSimpleFOCを使います.OdriveやVescなど他のオープソースのライブラリに比べて読みやすいので採用しました.

github.com

ハードはB-G431B-ESC1を使います.DigikeyやMouserで約3千円で買えます.

マイコン,書き込み機,MDが入っていて,回路図も公開されています.

CANFD@1Mbpsも搭載されてるため上記のC610/C620を作ることもできます.

www.st.com

回転子の角度を読み取るために,インクリメンタルのロータリーエンコーダーAMT-102-Vを使います.

www.cuidevices.com

ブラシレスモーターにはC5055-400KVを使います.PMSMであればなんでも構わないです.

OSはUbuntu 22.04ですが,Windowsでも大丈夫だと思います.

配線

エンコーダーの信号線などをはんだ付けします.この作業が一番大変です.

コツは,導線と基板にはんだを先に塗っておき,繋げるイメージです.

Lチカ

VSCode拡張機能のPlatformIO IDEとSerial Monitorを入れます.

marketplace.visualstudio.com

marketplace.visualstudio.com

 

ボードを指定してプロジェクトを作成します.

 

src/main.cppを書き換えます.

https://github.com/pizacl/B-G431B-ESC1/blob/main/test/L_chika.cpp

platformio.iniで設定を追加します.

https://github.com/pizacl/B-G431B-ESC1/blob/main/platformio.ini

 

下の水色のバーの"→"で書き込みます.

LEDが点滅すれば成功です.

エンコーダー読み取り

src/main.cppを書き換えます.

https://github.com/pizacl/B-G431B-ESC1/blob/main/test/Encoder.cpp

Serial Monitorでシリアル通信します.

モーターをぐりぐり動かして角度が変わったら成功です.

ベクトル制御

src/main.cppを書き換えます.

https://github.com/pizacl/B-G431B-ESC1/blob/main/src/main.cpp

シリアルモニターでBaud rateを115200 bpsに設定します.

T100と入力してEnterを押します.これは,100 rad/sで回す指示です.

BLDCが回れば成功です.

ソースコードの解説

上から解説します.

VSCodeはCtrl+クリックで実装部分に飛べます.内部実装を読み解くと理解が深まります.

 

BLDCMotor motor = BLDCMotor(7);

モーターの極数/2を設定します.極数はデータシートに書いてあります.モーター名のP14とかP36とかは14極,36極という意味です.

 

Encoder encoder = Encoder(A_HALL1, A_HALL2, 2048, A_HALL3);

エンコーダーのA, B, Zのピンと,ppr(解像度)を設定します.

SimpleFOCでは他に磁気センサやホールセンサを選べます.

 

void doTarget(char* cmd) { command.motion(&motor, cmd); }

T100とか送った際に呼ばれる関数です.内部ではmotor.targetを変えてます.

motor.targetに向かって速度制御や位置制御します.

 

driver.voltage_power_supply = 12;

駆動用の電源電圧です.今回は12 Vを使用しました.

 

motor.voltage_sensor_align = 1;

電気角(motor.electrical_angle)の原点とモーターの原点を合わせる時の電圧です.

電圧を大きくするとMDが燃える可能性があります.

BLDCを回す際にUVW相に順番に電流を流しますが,1回転する間に何回か往復します.電気角とは,その1周内の角度です.つまり0から2πを往復します.

 

motor.velocity_index_search = 3;

エンコーダーのZ相で原点出しを行います.角度(motor.shaft_angle)の原点です.

 

motor.voltage_limit = 6;

電圧はSin波で入力しますが,その最大値です.

例えば,停止してる状態は全ての相に半分の3 Vがかかります.回転時は0 Vから6 Vまで動かして交流を作ります.

モーターはこの電圧と逆起電力がつりあう速度まで回ります.つまり,この値を電源電圧ギリギリまで上げると最大速度が上がります.同じにするのは回路的に良くないです.

 

motor.controller = MotionControlType::velocity;

位置センサを使わない強制転流,トルク制御,速度制御,位置制御を選べます.

 

motor.torque_controller = TorqueControlType::foc_current;

電流制御するかどうかです.

 

その後にPID関係がいろいろとありますが,これはPIDループが重なっているカスケード制御のためです.位置制御の場合3つのPIDループが重なっています.

docs.simplefoc.com

 

motor.PID_current_q.P = motor.PID_current_d.P = 0.1;
motor.PID_current_q.I = motor.PID_current_d.I = 10;

電流のPIゲインです.ベクトル制御は回転に影響するq軸電流を追従して,影響しないd軸電流を0にして効率を上げる方法です.基本的にq軸とd軸は同じゲインでいいです.

このゲインはモーターの抵抗とインダクタンスから計算できますが,今回は適当に入れました.

 

motor.PID_velocity.P = 0.5;
motor.PID_velocity.I = 1;
motor.PID_velocity.output_ramp = 1000;
motor.LPF_velocity.Tf = 0.01;

速度のPIゲインです.

output_rampは台形に電流を入力する際の傾きです.低くすれば緩やかにトルク(加速度)が変動します.

LPF_velocity.Tfは速度にかかるローパスフィルタ(LPF)の時定数です.速度は角度の微分なので高周波成分が増幅されます.これを除くためにLPFを入れます.時定数を大きくすると追従性能が落ちるため,なるべく低い方が良いです.

 

motor.P_angle.P = 20;

位置のPゲインです.大きくすると素早く追従しますが発振します.

 

motor.init();

ドライバーの初期化がうまくいったか,パラメーターが正しいかどうかを調べます.

 

motor.initFOC();

原点出しやエンコーダーとモーターの回転の方向を合わせたりします.

途中にcurrentSense.skip_align = true;とありましたが,電流センサの位置を特定するのをスキップしてます.

 

 motor.move();

速度と位置のPIDを更新します.電流に比べて遅いためmotor.motion_downsampleで制御周期を遅くできます.

 

motor.loopFOC();

電流のPIを更新して,電圧入力を行います.

 

おわりに

BLDCのベクトル制御についてなんとなくわかったと思います.

よりベクトル制御を理解するにはこの本がおすすめです.

 

あとは回路ですが,とりあえずB-G431B-ESC1がどういう構造なのかを勉強して,違うICでできないか考えれば良いと思います.また,Odrive v3.6や,ゲートドライバの評価ボードの回路図を参考にしましょう.ブラシツキMDが作れれば,そこまで難しくないと思います.

もしお役に立てたなら,電通大ロボメカ工房の可愛い後輩達と仲良くしていただけると幸いです.https://x.com/UECrmfNHK

 

それでは,良きBLDCMD自作ライフを.

回路設計ミスまとめ

この記事は

  • 学ロボ Advent Calendar 2022
  • UEC 2 Advent Calendar 2022

の18日目の記事となります.


adventar.org


adventar.org

1. 自己紹介

 どうも,pizac(ぴざっく)と申します.電気通信大学ロボメカ工房NHK部隊というサークルで,回路と制御を担当しているB3です.ロボメカ工房については,後輩のLazuly(らずり)の記事が参考になると思います.らずり君真面目すぎないか?凄すぎる.

ロボコンでの設計の話 - らずりのひとりごと - らずりのひとりごと

 

今年4月に製作したCAN対応MD

 そもそもB2まで制御班でしたが,らずりが作ったMD(モーターを制御する回路)が動かないということで,手伝っているうちに回路班になってました.MDを設計開始した時期が昨年の同じ時期なので,回路班歴は1年となります.最近は,マイコンと周辺回路が一体となった回路を作っているため,制御班の知識がかなり役に立っています.制御班の人は回路を作り,回路班の人は制御をしましょう.実際両方兼任すると地獄だけどね!

 さて現在は,後輩の協力もありますが,回路を6種類設計製作,ROSや組み込みなど,ほとんどの制御システムの設計製作してます.そこで気をつけたいのが設計ミスです.ソフトウェアの場合,後から変更が効くのでどうでもいいですが,回路の場合,プリント基板を再発注することとなり,費用や時間がかさみます.というか,特に何も考えずに設計すると大抵動きません.そこで,今年と昨年に起きたミスをまとめてみました.ちなみに,Kicad6で設計しています.U buntuのKicad6が軽量でいいゾ〜

2. 回路図設計で起きたミス

2-1. ネットからパクってきた回路が動かない

 一番やってはいけないミスです(昨年MDはこれで動かなかった).ネットに転がっている回路図には3種類あると考えています.

  1. 個人で製作した回路図
  2. オープンソースの回路図
  3. リファレンスボードの回路図

 1や2は逆に動いたらラッキーです(下で回路図を貼っていますが,絶対に参考にしないでください).というのも,そもそも間違っていたり,同じ回路を設計することができないためです.基本3を参考にしましょう.例えば,今は入手できませんが,回路班が大好きなゲトドラA3921は公式サイトの一番下の方にリファレンスボードの回路図が掲載されています.

Allegro MicroSystems - A3921 自動車用フル ブリッジ MOSFET ドライバ

 STMマイコンを利用している場合は,Nucleoの回路図が参考になります.

NUCLEO-F303K8 - STM32 Nucleo-32 development board with STM32F303K8 MCU, supports Arduino nano connectivity - STMicroelectronics

 MDを作る場合,ゲートドライバICのリファレンスボード参考にすると良いです.レイアウトもある場合があります.プロが作った基板なので,真似するだけで回路スキルが上達します.Schematic(回路図),BOM(部品表),Layoutは必ず確認しましょう.

2-2. シンボルとフットプリントが一致しない

3端子レギュレーターNJM78L05を使った降圧回路

 例えば,上の回路図です.NJM7805L05のシンボルがKicadになく,別のシンボルにフットプリントを貼ったため起こりました.このICは1ピンがVoutでした.ICを入れた場合は必ずピン番号をデータシートで確認しましょう.これは別の話ですが,コンデンサは耐電圧とサイズ(DCバイアス特性に影響)は記入するとミスが減ります.

2-3. 電源が違う

A3921の周辺回路

 これはうっかりしてました.上の回路図の赤丸で示した+5VAはVCCが正解でした.電源を複数使う場合には,必ず気をつけましょう.これも別の話ですが,FF1,FF2はトランジスタ挟むか抵抗を大きくした方がいいですね.A3921のV5は非常に貧弱です.

3. PCB設計で起きたミス

3-1. 部品間隔が狭すぎる

部品の間隔が狭すぎる

 人間が実装する場合は,必ず部品の間隔を考慮しましょう.おすすめは,グリッドを0.25mmにして,Courtyard(ピンク枠)を2グリッド分離すことです.部品どうしは1mmほど空き,ピンセット(TS-15)が余裕で入るようになります.

部品の間隔を広くした

 大量の部品が並んでいますが,実装できます.ムズいけど!

3-2. ノイズ対策がされていない

 ノイズ対策.COMさんがわかりやすいです.学ロボ基板でノイズがシビアになる部分は少ないですが,対策しないよりかはマシです.シミュレーションとかは面倒なので,対策を出来る限りして,実機で動かなかったときは考えるで良いと思います.

ノイズ対策.COM|プリント基板の回路設計者・開発者のための技術サイト

3-3. 基板の製造許容寸法(Capabilities)を考慮していない

 私は小さい基板を作るのが好きなんですが,プリント基板には製造限界があります.発注先のサイトに必ず掲載されているので確認しましょう.

PCB Manufacturing & Assembly Capabilities - JLCPCB

JLCPCB用のデザインルール

 また,Kicad6ではデザインルールを設定してチェックすることができます.参考までに,私がJLCPCBさんで発注した際のデザインルールを掲載しておきます.動いたので問題無いと思いますが,何か問題点があれば教えてほしいです.

4. あとがき

 近年は某マスモーターの登場により,回路開発は必要なくなってきます.私はただの自己満足でやっているのでほぼ自腹です.しかし,回路を製作してみるとわかるのですが,たとえ既成品に性能が劣っていても回路が動いたときの感動は大きいので,この文化が無くなるのはとても残念に感じます.基板への愛着がわきすぎて美少女に見えたり声が聞こえます!

 学ロボは結果が全てではないと思っていて,大学生にしかできないものづくりを楽しむのが目的だと思っています.実際,同年代の人が大人数集まって,社会の何の役にもたたないくそでかロボットを作るのは,これが最後だと思っています.ぜひ,基板を作って友達やTwitterに自慢しましょう.私が作った回路達の公開は大会後になりそうです.大量にミスがあって現在修正中です.私のために一生懸命頑張る基板達もかわいいです!

 最後になりますが,ここまで閲覧いただきありがとうございました.てか,基板できたら,基板愛を語る記事でも書こうかな.今年はマジでヤバイ基板ができてる!

外付けSSDにUbuntuをインストールした話

この記事はUEC 2 Advent Calendar 2021の13日目の記事です。

adventar.org

この記事はインストールする方法を書いていません。

こちらの記事が参考になります。

qiita.com

ただし、こちらの記事では通常版のUbuntuをインストールしていますが、

日本語Remix版の方が日本語設定がいらないのでおすすめです。

1. 自己紹介

ロボメカ工房でNHKロボコンに向けてロボット(?)を作っています。

主に制御を担当していて、開発がしやすいのでUbuntuを使っています。

sites.google.com

2. なぜ外付けSSDなのか

Ubuntuは便利ですが、Windowsでしか動かないソフトも多いです。

Windowsを消さずにUbuntuをインストールする方法が何種類かあります。

それぞれのデメリットとメリットをまとめました。

No. 方法 デメリット メリット
1 WSL2 GUI, USBが使えない 動作が軽い
2 仮想環境 (VirtualBoxVMware) 動作が重い 簡単
3 本体にインストール データを壊しやすい 動作が軽い
4 外付けSSDにインストール 難しい 動作が軽い

外付けSSDにインストールするのは比較的難しい方法ですが、

GUIやUSBが使えて動作が軽いです。

また、データが壊れてもまたSSDにインストールすればいいだけです。

Ubuntu初心者の私は10回以上入れ直しました(笑)。

このようにとても素晴らしい方法ですが、

さらに他の方法では真似できない利点があります。

3. 世界最軽量PC!?

さて、最初に紹介した方法では、ブートローダーをSSDにインストールしています。

実は他のPCでも、SSDからUbuntuが起動できます。

つまり、外出先にPCを設置すれば数十gのSSDだけ持っていけばいいです。

実質、世界最軽量PC(?)の爆誕です!!