B3Mサーボモータを動かそう(Python編(2))
この記事では、B3MサーボをPythonで制御する方法を紹介します。前回に引き続き、今回もWRITEコマンドについての解説です。
WRITEコマンドは、B3MのRAMに展開された各パラメータを書き換えるためのコマンドです。これにより、B3Mの動作モードや特性を好きなように変更することができます。
WRITEコマンドで変更したデータはRAM上で書き換えるため、電源を一度OFFにするとリセットされてしまいますが、SAVEコマンドを実行することによりROMに保存することができます。毎度WRITEコマンドで設定を変更するのは不便ですので、この記事の最後にSAVEコマンドについても解説したいと思います。
【過去の記事】
第1回 B3Mサーボモータを動かそう(準備編(1))(改訂版)
第5回 B3Mサーボモータを動かそう(Arduino制御編)(改訂版)
第6回 B3Mサーボモータを動かそう(Python編(1))(改訂版)
B3Mの通信プロトコルについては『B3Mソフトウェアマニュアル』をご参照ください。
B3Mサーボの紹介、制御に必要な製品については『B3Mサーボモータを動かそう(Python編(1))』
をご参照ください。
【B3Mの設定】
以下のサンプルプログラムでは、B3Mサーボの設定は工場出荷状態のID0、通信速度1500000bps、個数は1個とします。
ID番号を変更することで複数のサーボをデイジーチェーン接続して制御することができますが、通信速度はすべて同じである必要があります。
■WRITEコマンドで書き換えることができるパラメータ
B3Mサーボは、ユーザーが変更できる多数のパラメータを持っています。書き換えるパラメータはアドレスにより指定することができます。下記では、多くのパラメータから代表的な項目を抜粋してご紹介します。
各機能について詳しくは、『B3Mソフトウェアマニュアル』をご参照ください。
・ID番号、通信速度
サーボのID番号と通信速度を設定できます。(通信速度の書き換え後、リセットにより設定が反映されます。通信速度の変更は、B3Mマネージャーからの書き換えをお勧めします。)
・動作モード切替
トルクオンの状態、脱力した状態、その場で保持する状態を指定できます。
・制御モード切替
位置制御モード、速度制御モード、電流制御モード、フィードフォワードモードに切り替えることができます。
・軌道生成タイプ
位置制御モードにおいて、多様な動作タイプに切り替えることができます。
(ノーマル、直線補間、3次多項式補間、4-1-4多項式補間、5次多項式補間)
・比例ゲイン、微分ゲイン、積分ゲイン、静止摩擦係数、動作摩擦係数
PIDゲインを任意の値に変更することができます。
・MCU温度リミット、モーター温度リミット、電流制限値
B3M内で検出した温度、電流値によりリミッターの閾値を設定することができます。また、リミッターが発動した際のモーターパワーも任意に設定することができます。例えば、リミッター発動時に完全に脱力した状態にもできますし、アームが転落しないように出力を50%に設定することもできます。
・モーターロックと認識されるまでの時間
ロボットが動作中は、なにかしらの外乱によりサーボがロックしてしまう可能性があります。B3Mは、サーボ内部のカウンターにより自身のロックを検知する機能があります。このアドレスでは、ロックと認識するまでの時間を設定することができます。また、ロックと認識される基準の出力と、その際に回避策として脱力したときのモーターパワーの状態も設定可能です。
・最小位置制限、最大位置制限
サーボの動作範囲を制限することができます。搭載個所によりフレームやボディにぶつからないように角度の制限をかけることでロックを防止できます。
・中央値オフセット
通常は0地点が中央値ですが、搭載個所により中央値を任意の角度に変更することができます。
・PWM制限
サーボ内部のモータを駆動するPWMディーティに上限を設定することができます。
・リバース
指定した回転方向に対して逆方向に回転するように設定できます。
・クローン
自身のIDの指示を受け取った後、サーボからの返事を返さないように設定できます。これにより、デイジーチェーン接続の同じライン内に同じIDを複数個つなぐことができます。
※PIDゲインなど、サーボの特性を変更した場合の動作は保証していません。変更する場合は、サーボ搭載個所に対して適切なPIDゲインを設定してください。
■WRITEコマンドに複数のバイトデータを送信できるように改造する
各パラメータにより書き換える値のバイト数が異なります。下記の解説では、前回の記事で作成したWRITEコマンドを元に、2Byte、4Byteのデータを送信できるように改造します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
def B3M_Write_CMD(servo_id, txData, Data_size, Address): #txDataがマイナスの場合はsigned=Trueを記述する必要がある if txData < 0: txByte = txData.to_bytes(Data_size, 'little', signed=True) else: txByte = txData.to_bytes(Data_size, 'little') #送信コマンドを作成 txCmd = [0x07+len(txByte), #SIZE 0x04, #CMD 0x00, #OPTION servo_id] #ID for i in txByte: #Data txCmd.append(i) txCmd.append(Address) #ADDRESS txCmd.append(0x01) #COUNT #チェックサムを作成 checksum = 0 for i in txCmd: checksum += i #リストの最後にチェックサムを挿入する txCmd.append(checksum & 0xff) #WRITEコマンドを送信 b3m.write(txCmd) #サーボからの返事を受け取る rxCmd = b3m.read(5) #もしリスト何になにも入っていなかったら正常に受信できていないと判断 if len(rxCmd) == 0: return False #問題なければ返事を返す return True |
以下の解説は、前回のWRITEコマンドから異なる個所のみ解説します。
def B3M_Write_CMD(servo_id, txData, Data_size, Address):
引数にData_sizeを追加しました。Data_sizeは、書き込むデータのバイト数を受け取ります。
if txData < 0:
txByte = txData.to_bytes(Data_size, 'little', signed=True)
else:
txByte = txData.to_bytes(Data_size, 'little')
B3Mサーボ内で2バイト以上のデータはリトルエンディアンにより格納されています。この個所で書き込むデータをリトルエンディアンに変換し、txByteにリストとして代入しています。pySerialのto_bytes関数を使用することで、値を簡単にリトルエンディアンに変換することが可能です。送信するデータがマイナスの場合は、to_bytes関数の引数にsigned=Trueを記述する必要がありますのでif文でマイナスの場合とプラスの場合で処理を分けています。
リトルエンディアンについて詳しくは、『B3Mソフトウェアマニュアル』のP.24をご参照ください。
データができましたら、前回と同様にpySerialのwrite関数で送信します。
■SAVEコマンドを作成する
各パラメータを好きな値に設定した後に、SAVEコマンドを送信することでB3MのROMに保存することができます。SAVEコマンドは下記のように作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
def B3M_Save_CMD(servo_id): #送信コマンドを作成 txCmd = [0x05, #SIZE 0x02, #CMD 0x00, #OPTION servo_id] #ID #チェックサムを作成 checksum = 0 for i in txCmd: checksum += i #リストの最後にチェックサムを挿入する txCmd.append(checksum & 0xff) #WRITEコマンドを送信 b3m.write(txCmd) #サーボからの返事を受け取る rxCmd = b3m.read(5) #もしリスト何になにも入っていなかったら正常に受信できていないと判断 if len(rxCmd) == 0: return False #問題なければ返事を返す return True |
SAVEコマンドはデータがなく、コマンドのみを送るだけですので非常に簡単です。SIZEを0x05、CMDを0x02に指定し、OPTION、サーボID、チェックサムと一緒に送信するだけです。送信が成功しますと、サーボの電源を入り切りしても設定が残るようになります。
※SAVEコマンドは、アドレスを指定して一部のみ保存することができません。RAMのパラメータをすべて保存しますので、SAVEコマンドを実行する場合は事前にRAMの状態を確認をしてから実行してください。
■WRITEコマンドとSAVEコマンドを使用してみる
1 2 3 4 5 6 7 8 9 10 11 |
#COMポートを開く b3m = serial.Serial('COM4', baudrate=1500000, parity=serial.PARITY_NONE, timeout=0.5) #B3M_Write_CMD(servo_id, TxData, Data_size, Address) #MCU温度リミット(0x0B)を7000(70℃)に書き換える reData = B3M_Write_CMD(0, 7000, 2, 0x0B) #B3M_Save_CMD(servo_id): #RAMのデータをROMに保存する #※RAMのすべてのデータが一括でROMに保存されます。 reData = B3M_Save_CMD(0) |
今回は、例としてWRITEコマンドでMCU温度リミットの閾値を書き換えてみます。
MCU温度リミットとは、MCUの温度が上がりすぎたときにエラーを発生させる温度閾値です。指定温度を超えると出力トルクに制限がかかります。初期値の温度閾値は、8000(80.00℃)です。70℃に設定する場合は、7000を書き込みます。MCU温度リミットは2バイトのデータですので、3番目の引数Data_sizeに2を渡します。アドレスは、0x0Bなので4番目の引数と0x0Bにしました。
B3Mを起動しプログラムを実行してください。実行後、正しくMCU温度リミットが変更されているか、B3Mマネージャーソフトウェアで確認します。
B3Mマネージャーは、下記のページからダウンロードしてください。
①COM番号と②通信速度を選択し、③「Read All」ボタンを押します。サーボのIDを0以外に書き換えている場合は、「Read All」ボタンを押す前に「ID」も選択してください。読み込みが成功すると左下のステータスバーに「Reading Done」と表示されます。
「MCU Temp.Limit」が指定した通り7000になっていれば成功です。
プログラムの全体は、下記からダウンロードしてください。
以上で、WRITEコマンドとSAVEコマンドの解説は終了です。次回はREADコマンドについて解説します。今回のように、書き込んだデータが正しいかを確認するため、毎度マネージャソフトを使用するのは手間がかかります。そこで、READコマンドを使用します。READコマンドはB3MのRAMデータを読み込むことができ、Pythonのprint関数でパラメータを表示できるようになりますので作業が楽になります。また、サーボの現在値、温度、電流も読み込むことができますので一緒に解説したいと思います。
次の記事『B3Mサーボモータを動かそう(Python編(3))』
前の記事『B3Mサーボモータを動かそう(Python編(1))』
B3M-SB-1040-Aの詳細をみる B3M-SC-1040-Aの詳細をみる B3M-SC-1170-Aの詳細をみる