PMXサーボを使ってみよう マイコンボードから制御「MotorWRITE (組み合わせ制御)編」
今回の記事は、前回ご紹介したサーボに動作指示を送ることができる「MotorWRITE」の組み合わせ制御についてです。
【関連記事】
PMXサーボを使ってみよう マイコンボードから制御「準備編」
PMXサーボを使ってみよう マイコンボードから制御「MemREAD編」
PMXサーボを使ってみよう マイコンボードから制御「MemWRITE編」
PMXサーボを使ってみよう マイコンボードから制御「MotorWRITE (位置制御)編」
この記事で解説するArduino向けライブラリ、及びサンプルプログラムは、下記のページからダウンロードしてください。
PMXシリーズのサーボモータを制御するためのオンラインマニュアルを公開しています。PMXサーボを制御するための詳しい情報が記載されていますので、下記の解説と一緒にご一読ください。
■制御の組み合わせについて
PMXサーボは、位置制御に電流制御や移動時間を組み合わせて使用することができます。これにより、シンプルに移動するだけのサーボではなく、負荷により動作が停止したり、移動する時間を指定することができます。
組み合わせ例
・位置制御+トルク制御:指定されたトルク値を超えないように出力を制御しつつ、指定した目標角度まで移動します。トルク制御と組み合わせていない場合は、最大トルクで動作します。
動画のデモは90度と0度の位置指令の往復動作に、100mAの電流指令を指定しました。 指で抑えても止まりますので、トルクリミットとしても使用できます。
PMXサーボは、位置制御と電流制御を組み合わせることができます。
動画のデモは90度と0度の位置指令の往復動作に、100mAの電流指令を指定しました。
指で抑えても止まりますので、トルクリミットとしても使用できます。 pic.twitter.com/7jP4UIXE4E— KONDO_ROBOT (@KONDO_ROBOT) September 13, 2023
・位置制御+移動時間:指定した角度まで、指定した時間で到着するように動作します。「移動時間」を組み合わせることで補間制御による位置制御になります。また、補間制御の種類を選択することにより加減速のパターンを変更することが可能です。
PMX #サーボ を搭載した #アームロボット を動かしました!
台座からPMX-SCR-9204HVを3個、PMX-SCR-5204HVを2個使用しています。https://t.co/yJ7KuXHdtF位置制御に移動時間を組み合わせ、補完モードの5次多項式で動いていますので、位置のみを指定するより滑らかに動作しています。 pic.twitter.com/HUeSUtl3gl
— KONDO_ROBOT (@KONDO_ROBOT) April 9, 2024
2024年11月現在(Ver.1.1.0.0)で、組み合わせができる制御は下記になります。この組み合わせ以外を指定すると、ステータスの「データエラー」が返ってきます。
■制御方法
制御方法は、前回の記事で解説した流れから全く変わりません。制御のポイントとなる部分は、前回の記事の「①「制御モード」を指定する」と「④「MotorWRITE」コマンドで動作指示をする」ですので、下記の「プログラム解説」ではこの個所を解説します。
■制御モードを指定する方法
前回解説した通り、まずは「制御モード」を指定します。PMXサーボの制御方法は、メモリマップの「制御モード」をMemWRITEコマンドで書き換えることで選択することができます。
1 2 3 4 5 |
byte writeOpt = 1; byte controlMode = PMX::ControlMode::Position; // 位置制御モード値 flag = pmx.setControlMode(ServoID, controlMode, writeOpt); Serial.print("setControlMode="); Serial.println(flag, HEX); |
Bit0:位置制御
Bit1:速度制御
Bit2:電流制御
Bit3:トルク制御
Bit4:PWM制御
Bit5:移動時間指示
各ビットを1にすることでモードを選択することができます。
例えば位置制御と電流制御を組み合わせる場合は0x05(0b00000101)を指定します。位置制御のみの時は0x01でしたが、電流制御の0x04が加わり、指令値が0x05になります。
同じように、位置制御と移動時間を組み合わせた場合も0x01+0x20になり、指令値は0x21になります。
ライブラリ内に予め宣言された変数がありますので、サンプルでは「PMX.ControlMode.Position + PMX.ControlMode.Current」としていますが、数値で直接指定しても同じように処理されます。
ライブラリでは、setControlMode()という制御モードを変更するための専用の関数を用意しています。
「制御モード」のデータは、後のMotorWRITEコマンドやMotorREADコマンドでも使用しますので、「controlMode」変数に代入してから引数にしています。直接数値を記入しても同様の処理を実行できます。
制御モードの組み合わせは制限があります。「制御モード」について詳しくはオンラインマニュアルの『制御モード』をご参照ください。
■位置制御+電流制御の動作を指示する方法
サンプルプログラム:MotorWRITE_PosCurrentMove_Sample20231219
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 制御モードを指定する byte controlMode = PMX::ControlMode::Position + PMX::ControlMode::Current; // 位置制御モード値+電流制御モード値 byte writeOpt = 1; flag = pmx.setControlMode(ServoID, controlMode, writeOpt); // 応答データを指定する byte receiveMode = PMX::ReceiveDataOption::Full; // すべて返す flag = pmx.setMotorReceive(ServoID, receiveMode, writeOpt); // サーボのトルクをオンにします long receiveData[8]; flag = pmx.setMotorTorqueOn(ServoID, receiveMode, receiveData, controlMode); // MotorWRITEDouble(組合せ2個)で動作指令 long targetVal1 = -18000; // 目標位置 long targetVal2 = 100; // 目標電流値 flag = pmx.MotorWRITEDouble(ServoID, targetVal1, targetVal2, receiveMode, receiveData, controlMode); // 目標地点に到達するまで待ちます delay(5000); |
まず最初に制御モードを指定します。この例では、位置制御+電流制御を実行しますので制御モードの設定値はPMX.ControlMode.PositionCurrentとしました。上記の解説の通り0x05を送信しても同じ処理が実行されます。こちらをsetControlMode()関数でサーボに送信します。
応答モード、トルクONに関しましては変更ありませんので前回の記事をご参照ください。
最後にサーボへ動作指示を送信します。制御を組み合わせた場合のMotorWRITE()関数が用意されています。二つの制御モードの時に使用するMotorWRITEDouble()と、制御モードが三つの時のMotorWRITETriple()です。
1 2 3 4 |
// MotorWRITEDouble(組合せ2個)で動作指令 long targetVal1 = -18000; // 目標位置 long targetVal2 = 100; // 目標電流値 flag = pmx.MotorWRITEDouble(ServoID, targetVal1, targetVal2, receiveMode, receiveData, controlMode); |
上記は二つ組み合わせた例です。使い方は前回の記事で紹介したSingleと同じです。組み合わせによる指令値が増えた分、引数を一つ増やしたこと以外の変更点はありません。
第一引数は、対象となるサーボのID番号です。
第二引数、第三引数は「制御モード」と「応答データ指定」です。「制御モード」の内容と、「応答データ指定」で返ってくるデータの内容を関数に伝えるために引数として渡します。プログラム内で用意した「controlMode」「receiveMode」変数の内容を変えずにそのまま使用します。
第四引数、第五引数は、「動作指示データ」です。組み合わせた場合の指令値の順番は、「制御モード」のBit0からの順番に指定します。位置、速度、電流・・・の順で早い方を先の指令値として下さい。
位置制御と電流制御を組み合わせた場合、第四引数は、位置制御の指令値です。位置制御の場合は角度を送ります。例えば、PMX-SCR-5204HVは-320°~320°の範囲で角度を指示できますが、単位は1/100[°]ですので、サーボに送信する「動作指示データ」は-32000~32000の範囲になります。サーボに100°を指示する場合は10000を送信します。
第五引数は、電流制御の指令値です。電流制御の指令値の単位は[mA]ですので、100を指令値とすると100[mA]を指示することができます。
こちらを実行すると、1000[mA]の消費電流を超えないように100[°]の位置へ移動します。
■位置制御+移動時間の動作を指示する方法
サンプルプログラム:MotorWRITE_PosTimeMove_Sample20231219
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// 制御モードを指定する byte controlMode = PMX::ControlMode::Position + PMX::ControlMode::Time; // 位置制御モード値+電流制御モード値 byte writeOpt = 1; flag = pmx.setControlMode(ServoID, controlMode, writeOpt); // 応答データを指定する byte receiveMode = PMX::ReceiveDataOption::Full; // すべて返す flag = pmx.setMotorReceive(ServoID, receiveMode, writeOpt); // 補間モードを指定します。 byte trajecrotyData = 5; flag = pmx.setTrajectory(ServoID, trajecrotyData, writeOpt); // サーボのトルクをオンにします long receiveData[8]; flag = pmx.setMotorTorqueOn(ServoID, receiveMode, receiveData, controlMode); // MotorWRITEDouble(組合せ2個)で動作指令 long targetVal1 = -18000; // 目標位置 long targetVal2 = 2000; // 移動時間 flag = pmx.MotorWRITEDouble(ServoID, targetVal1, targetVal2, receiveMode, receiveData, controlMode); // 目標地点に到達するまで待ちます delay(3000); |
「位置制御」に「移動時間」を組み合わせることにより、動作開始から到着までの時間を指定することができます。また、「移動時間」を組み合わせることにより、位置制御は補間制御で動作します。補間制御は「均等補間(ランプ)」「5次多項式補間」から選ぶことが可能です。
まず最初に制御モードを指定します。この例では、位置制御+移動時間を実行しますので制御モードの設定値はPMX.ControlMode.PositionTimeとしました。上記の解説の通り0x21を送信しても同じ処理が実行されます。こちらをsetControlMode()関数でサーボに送信します。
応答モード、トルクONに関しましては変更ありませんので前回の記事をご参照ください。
次に補間制御の種類を指定します。
1 2 3 |
// 補間モードを指定します。 byte trajecrotyData = 0x05; flag = pmx.setTrajectory(ServoID, trajecrotyData, writeOpt); |
補間制御を指定する場合は、メモリマップの「補間制御軌道生成タイプ指定(アドレス:503)」をMemWRITEコマンドで書き換えます。ライブラリでは補間制御のモードを指定するsetTrajectory()関数を用意しています。こちらの第二引数に0x01、または0x05を渡してモードを指定できます。
引数の「writeOpt=0」は、サーボがトルクオンの状態でMemWRITEコマンドの実行を許可するかを指定できます。1の場合は許可です。Free状態でMemWRITEを実行する場合は、「writeOpt」の省略が可能です。
工場出荷時では「均等補間(ランプ)」になっていますので、このまま使用する場合はこの手順を省略してかまいません。
動作指令方法は、位置制御+電流制御と変わりません。
1 2 3 4 |
// MotorWRITEDouble(組合せ2個)で動作指令 long targetVal1 = -18000; // 目標位置 long targetVal2 = 2000; // 移動時間 flag = pmx.MotorWRITEDouble(ServoID, targetVal1, targetVal2, receiveMode, receiveData, controlMode); |
第三引数が、移動時間を指定する引数になります。単位は[ms]ですので、1000を指定した場合は1000[ms]で目標地点に到着するようになります。
【参考】制御の組み合わせが3つの場合
制御の組み合わせが3つの場合はMotorWRITETriple()関数を使用します。この場合、第二引数、第三引数に加えて、第四引数で3つ目の制御の指令値を送ります。
1 2 3 4 |
long targetVal1 = 10000; long targetVal2 = 1000; long targetVal3 = 1000; flag = pmx.MotorWRITETriple(ServoID, targetVal1, targetVal2, targetVal3, receiveMode, receiveData, controlMode); |
以上で組み合わせ制御の解説は終わりです。PMXサーボは、このように制御を組み合わせても手軽に使用できますので、組み込む場所に合わせて多彩な機能をご利用ください。
次回は、速度制御、電流制御など、位置制御以外の制御について解説します。
前回の記事『PMXサーボを使ってみよう マイコンボードから制御「MotorWRITE (位置制御)編」』
PMX-SCR-9203HVの詳細をみる PMX-SCR-9204HVの詳細をみる PMX-SCR-5203HVの詳細をみる PMX-SCR-5204HVの詳細をみる