Arduinoでスタックチャン アールティver.のDynamixelサーボを操作する手順と注意点
スタックチャン アールティver. は、株式会社アールティが開発・販売する手のひらサイズの小型ロボットで2024年6月上旬に発売された。 このロボットは、オリジナルのスタックチャン(通称ししかわ版)をベースに、さまざまな改良が加えられている。(β版は2023年に少量販売されたが仕様が異なる)
アールティver.の特徴として、DYNAMIXELサーボと M5Stack CoreS3 を採用していることが挙げられる。 資料がネット上にもそう多くなく自作コードに書き換えて動作させるときにたいへん苦労したのでここに記すものとする。
ピン配置
スタックチャン アールティver. で使用される M5Stack CoreS3 のピン配置について、 M-BUS の 2x15 ピンの配列に合わせて記載すると下記のようになる。 ここでは M5Stack の回路図に従い、背面から覗く方向で左上を1番ピン、その右を2番ピンのように記載した。
Note | GPIO | Analog | Analog | GPIO | Note | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
GND | 1 | 2 | ADC | G10 | ADC1_CH9/T10 | I/O/T | |||||
GND | 3 | 4 | PB_IN | G8 | ADC1_CH7/T8 | I/O/T | PortB | ||||
GND | 5 | 6 | RST/EN | ||||||||
LCD,SD | I/O/T | G37 | MOSI | 7 | 8 | GPIO | G5 | ADC1_CH4/T5 | I/O/T | ||
LCD,SD | I/O/T | G35 | MISO | 9 | 10 | PB_OUT | G9 | ADC1_CH8/T9 | I/O/T | PortB | |
LCD,SD | I/O/T | G36 | SCK | 11 | 12 | 3.3V | |||||
I1 | G44 | RXD0 | 13 | 14 | TXD0 | G43 | O | ||||
PortC | I/O/T | ADC2_CH7 | G18 | PC_RX | 15 | 16 | PC_TX | G17 | ADC2_CH6 | I/O/T | PortC |
I2C_SYS | I/O/T | ADC2_CH1/T12 | G12 | intSDA | 17 | 18 | intSCL | G11 | ADC2_CH0/T11 | I/O/T | I2C_SYS |
PortA | I/O/T | ADC1_CH1/T2 | G2 | PA_SDA | 19 | 20 | PA_SCL | G1 | ADC1_CH0/T1 | I/O/T | PortA |
I/O/T | ADC1_CH5/T6 | G6 | GPIO | 21 | 22 | GPIO | G7 | ADC1_CH6/T7 | I/O/T | ||
I/O/T | ADC2_CH2/T13 | G13 | I2S_DOUT | 23 | 24 | I2S_LRCK | G0 | I/O/T | |||
NC | 25 | 26 | I2S_DIN | G14 | ADC2_CH3/T14 | I/O/T | |||||
NC | 27 | 28 | 5V | ||||||||
NC | 29 | 30 | BATTERY |
スタックチャン アールティver. の基板(RT-Stackchan v1.0.0 PCB)は、オリジナル版のスタックチャン基板と若干異なる。 アールティ社のロゴであるうさぎさんの絵がシルクで描かれているなどの外見上の差はすぐに気づくが、回路の違いも一部見られた。
PCB のピン配置は下記の通りであった。M-BUS のピン番号と M5Stack CoreS3 の GPIO ピン番号を記載した。
M-BUS pin # | S3 | |
---|---|---|
- | 4 | G8 |
- | 10 | G9 |
5V | 28 | |
G | 1 |
M-BUS pin # | S3 | |
---|---|---|
R | 15 | G18 |
T | 16 | G17 |
5V | 28 | |
G | 1 |
M-BUS pin # | S3 | |
---|---|---|
RXD2 | 21 | G6 |
TXD2 | 22 | G7 |
シリアルサーボ制御用のこのピンは RS485ドライバー MAX3485 (筆者の PCB に実装されていたのは STMicro の ST3485EI であった)を介して、 TTL に変換されているようだ。 これらがDYNAMIXELサーボ用の 3P Molex コネクタに接続してあった。
Molex コネクタ付近でそれぞれの3番ピン(信号ピン、「SIG」とシルク印刷あり)はR13で0オーム抵抗接続によって短絡している。 だから、組み立てマニュアルにはスタックチャンの頭側のコネクタに接続するよう指示されているが電気的には下側(バッテリー側)のコネクタに接続しても同じである。
注意すべき点として、オリジナル版のスタックチャン基板の回路配線に従うと G5,G7はPWM用、G18,G17はシリアルサーボ用と勘違いしてしまいそうだが、アールティ版と配線が異なっていた。 特に G18,G17とサーボの制御側とは接続していなかった (R17,R18が実装されておらず開放されていたのでつながっていない)。
DYNAMIXEL サーボの配線改良
アールティ出荷時には各DYNAMIXELサーボにID=1とID=2が設定されている(そのIDの値がシールで貼られている)。 組み立てマニュアルではこれらのIDに対応した配線コネクタの繋げ方が指示してある。
筆者はこの配線で最初使用したが、この方法でロール軸(ID=2のDYNAMIXELサーボ)のサーボホーンとケーブルが干渉する問題に直面した(下の写真の左)。 そこで、ID=2のDYNAMIXELサーボの接続コネクタを変えることで干渉しないようにすることした(下の写真の右)。
メインコントローラ(M5Stack CoreS3)とDYNAMIXELサーボは、コマンドデータ(パケット)を送受信することで通信を行う。 信号線はバスになっており、複数の機器が共通の線を使って通信を行うことができる。 スタックチャン アールティver.の場合は2つのDYNAMIXELサーボが接続される。 各DYNAMIXELサーボには、機器の識別番号であるIDが割り当てられており、このIDを指定することで、 特定のサーボだけを制御することができる。
このバス配線の特徴から、組み立てマニュアルの配線(下図の Recommended Connection)から ID=2の接続コネクタを変えた配線(下図の Alternative Connection)でも電気的には同じであり、 制御プログラムも変更なしで使うことができる。`
図の説明:
- Recommended Connection: 組み立てマニュアルに記載されている標準的な配線方法
- Alternative Connection: 筆者が採用した、サーボホーンとの干渉を避けるための配線方法。この方法では、ID=2のDYNAMIXELサーボの接続コネクタを変更している。
ESP32/Arduino から DYNAMIXEL サーボの制御方法
robotis-git/Dynamixel2Arduino を使う。
Dynamixel2Arduinoは、DYNAMIXEL の製造元である ROBOTIS社が提供する公式ライブラリであり、 このライブラリを使用するのが無難であろう。
このライブラリは、ROBOTIS 社製の OpenCM などの専用ボードを主要ユーザとして想定した作りになっているため、 サンプルコードをそのままでは初期化ができない(コンパイルも通らない)。
結論から言うと下記のような流れで初期化処理をすれば良い。
- Dynamixel2Arduino ライブラリの外側で一旦ハードウェアシリアルをボーレートやピン番号を指定して初期化する (
DXL_SERIAL.begin(...)
) - Dynamixel2Arduino の初期化にはハードウェアシリアルの参照を渡す (
Dynamixel2Arduino(DXL_SERIAL)
) - その後で Dynamixel2Arduino を
begin()
する
#include <Dynamixel2Arduino.h>
// ハードウェアシリアルを定義
#define DXL_RX_PIN 6
#define DXL_TX_PIN 7
#define DXL_BAUD 1000000
HardwareSerial &DXL_SERIAL = Serial1;
// Dynamixel2Arduinoオブジェクトを生成
Dynamixel2Arduino dxl;
void setup(void) {
// ...
// ハードウェアシリアルを初期化
DXL_SERIAL.begin(DXL_BAUD, SERIAL_8N1, DXL_RX_PIN, DXL_TX_PIN);
delay(1000); // ここのウエイトの妥当性は未調査
// Dynamixel2Arduinoライブラリを初期化
dxl = Dynamixel2Arduino(DXL_SERIAL);
dxl.setPortProtocolVersion(2.0f); // 通信プロトコルバージョンを設定
dxl.begin(DXL_BAUD); // DYNAMIXELとの通信を開始
dxl.torqueOn(1); // サーボのトルクをオンにする
// ...
}
ポイントとしては Dynamixel2Arduino ライブラリ自身でハードウェアシリアルの初期化コードが入っているのだけれども、 これを使わずに自力でハードウェアシリアルを用意する。
スタックチャンをDynamixel2Arduinoで制御するにおける注意事項
座標系はオリジナルのスタックチャンと同様に右手系で、 スタックチャンが左を向く方向がID=1(ロール軸)のDYNAMIXELサーボの正の向き、 スタックチャンが下を向く方向がID=2(ピッチ軸)のDYNAMIXELサーボの正の向きである。
スタックチャンが真正面を向いたとき、 ID=1(ロール軸)のDYNAMIXELサーボが0度、 ID=2(ピッチ軸)のDYNAMIXELサーボが180度であった。
スタックチャンを右に向かせるにはID=1(ロール軸)のDYNAMIXELサーボに負の値を指定する必要があるので、
オペレーションモードが 0〜360 の範囲内でしか使えない OP_POSITION
モードを使うと右に向かせることはできない。
そこで OP_EXTENDED_POSITION
モードに変えるとスタックチャンの真正面のときにDYNAMIXELサーボが認識する角度が
ID=1(ロール軸)のDYNAMIXELサーボが180度、
ID=2(ピッチ軸)のDYNAMIXELサーボが180度となる現象が発生した。
なぜこのような挙動になるのかはわからなかったが、DYNAMIXELサーボが認識する角度をログ表示して確認するのが確実であろう。
const auto pos = dxl.getPresentPosition(1, UNIT_DEGREE);
M5_LOGI("pos %f", pos);
スタックチャンを指定の角度に向けさせるには setGoalPosition()
関数を使えばよい。
dxl.setOperatingMode(1, OP_EXTENDED_POSITION);
dxl.setGoalPosition(1, -90 + 180, UNIT_DEGREE); // スタックチャンを右90度 = -90度に回転
これでDYNAMIXELサーボが回転しはじめる。しかしDYNAMIXELサーボの動作が停止したかどうかを取得するための関数はない。
Dynamixel2Arduino ライブラリは必ずしもすべての DYNAMIXEL のコマンドを関数として提供しておらず、 XL330-M288-Tの電子マニュアルなどを参照して任意コマンド( Control Table Item )実行する関数を実行する必要がある。
この場合はXL330-M288-Tの電子マニュアルのMoving Statusによると、 Moving Status の結果の値について、bit1 (Profile Ongoing) が0のとき Profile completed 状態を示す、 つまり動作を完了していることを示すのでこれで確認した。
何らかの理由で目標位置に到着しない(モノにぶつかってサーボが目標位置まで回らなかった場合も含む)ときには bit0(最下位ビット)は 0 ( Arrived 状態 ) にならないので注意が必要だ。
auto status = dxl.readControlTableItem(ControlTableItem::MOVING_STATUS, 1);
bool is_moving = (status & 0x02) != 0x00; // Arrived かつ Profile completed 状態
設定系のコマンドも同様に任意コマンド( Control Table Item )実行する関数を実行する必要があるものがある。
dxl.writeControlTableItem(ControlTableItem::PROFILE_ACCELERATION, 1, 20);
dxl.writeControlTableItem(ControlTableItem::PROFILE_VELOCITY, 1, 100);
おわりに
Dynamixel2Arduinoライブラリを使って、スタックチャン アールティver. を制御する方法について解説した。 座標系や初期角度など、ややこしいところについては具体的な手順を踏んで説明した。
この記事が、スタックチャン アールティver. を Arduino で動かそうとする人の助けになれば幸いである。
参考文献
- スタックチャン stack-chan/stack-chan: A JavaScript-driven M5Stack-embedded super-kawaii robot.
- スタックチャン アールティver rt-net/stack-chan: This is the repository for Stack-chan RT ver.
- アールティロボットショップ(販売サイト)
- スタックチャン アールティver. 組み立てマニュアル stack-chan/docs/assembly_ja.md at main · rt-net/stack-chan
- 量産スタックチャン試作基板の動作テスト · rt-net/stack-chan@f1f901c (コミットログ)
- M5Stack CoreS3
- ESP32-S3 Series Datasheet
- ROBOTIS DYNAMIXEL
- XL330-M288-T (ROBOTIS e-Manual)
- DYNAMIXEL Protocol 2.0 (ROBOTIS e-Manual)
- Besttechnology - Dynamixel通信プロトコルV2マニュアル [DYNAMIXEL Communiation Protocol 2.0] - ナレッジベース
- ROBOTIS-GIT/Dynamixel2Arduino: DYNAMIXEL protocol library for Arduino
- ESP32 S3 + DXL MKR Shield Mash-Up in ARDUINO - Projects and Learning - ROBOTIS