PMXサーボを使ってみよう PCから制御「MotorWRITE (位置制御)編」
前回までの解説で、サーボからデータを読み出す「MemREAD」コマンド、データを書き込む「MemWRITE」コマンドの解説が終わりました。今回から、サーボの動作を制御する「MotorWRITE」コマンドを解説し、実際にPMXサーボを動かしたいと思います。
【関連記事】
PMXサーボを使ってみよう PCから制御「MemREAD編」
PMXサーボを使ってみよう PCから制御「MemWRITE編」
この記事で解説するPython向けライブラリ、及びサンプルプログラムは、下記のページからダウンロードしてください。
PMXシリーズのサーボモータを制御するためのオンラインマニュアルを公開しています。PMXサーボを制御するための詳しい情報が記載されていますので、下記の解説と一緒にご一読ください。
■MotorWRITEコマンドについて
MotorWRITEコマンドは、PMXサーボの動作を指示するためのコマンドです。このコマンドを使用することで、命令を受け取ったサーボは設定された「制御モード」に合わせて動作します。また、パケットを受け取った返事として「応答データ指定」で指定したデータを含んで返事を返します。
■サーボの電源投入から動作までの手順
PMXサーボは、多彩な機能を実行するためにサーボの電源投入から動作開始まで各モードの設定が必要です。
①「制御モード」を指定する
②「応答データ指定」を指定する
③「トルクスイッチ」の設定をTorqueONに指定する
④「MotorWRITE」コマンドで動作指示をする
■プログラム解説
ここからPythonライブラリのサンプルプログラム「MotorWRITE_Single_Sample」を使用してMotorWRITEコマンドを実行し、PMXサーボを制御する方法を解説します。
MotorWRITEコマンドには多彩な機能が備わっていますが、実例に沿って解説した方がわかりやすいため、プログラムの解説と同時にコマンドについて解説します。
ファイルの参照やライブラリのインスタンス化は『PMXサーボを使ってみよう PCから制御「MemREAD編」』をご参照ください。
「サーボの電源投入から動作までの手順」①~④の流れは下記になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# ①制御モードの設定します controlMode = PMX.ControlMode.Position # 位置制御モード値 status = pmx.setControlMode(ServoID, controlMode, writeOpt=0x01) # ②応答データ指定します receiveMode = PMX.ReceiveDataOption.Full # すべて返す status = pmx.setMotorReceive(ServoID, receiveMode, writeOpt=0x01) # ③サーボのトルクをオンにします status, torqueswitch, reData = pmx.setMotorTorqueOn(ServoID, receiveMode) # ④MotorWRITE関数で動作指令 pos = -32000 # 位置の第1引数は位置 status, torqueswitch, reData = pmx.MotorWRITE(ServoID, 0, controlMode, receiveMode, [pos]) print("MotorWRITE", hex(status), torqueswitch, reData) # 目標地点に到達するまで待ちます time.sleep(2) |
1 2 3 |
controlMode = PMX.ControlMode.Position # 位置制御モード値 status = pmx.setControlMode(ServoID, controlMode, writeOpt=0x01) print("setControlMode", hex(status)) |
まず、制御モードを指定します。制御モードは、PMXサーボがどの制御で動作するかを指定することができます。PMXサーボは工場出荷状態で位置制御が選択されていますので、位置制御のみで使用する場合は処理を飛ばしても問題ありません。
Bit0:位置制御
Bit1:速度制御
Bit2:電流制御
Bit3:トルク制御
Bit4:PWM制御
Bit5:移動時間指示
各ビットを1にすることでモードを選択することができます。例えば、位置制御のみの場合は0x01(0b00000001)、位置制御と電流制御を組み合わせる場合は、0x05(0b00000101)となります。こちらのデータをMemWRITEコマンドを使用し、アドレス501の「制御モード」に書き込みます。
ライブラリでは、setControlMode()という制御モードを変更するための専用の関数を用意しています。
第一引数の「ServoID」は、書き込みの対象となるサーボのID番号です。
第二引数の「controlMode」は「制御モード」に書き込むデータです。「制御モード」のデータは、後のMotorWRITEコマンドやMotorREADコマンドでも使用しますので、「controlMode」変数に代入してから引数にしています。直接数値を記入しても同様の処理を実行できます。
第三引数の「writeOpt」は、PMXサーボのトルクスイッチがTorqueONの状態でもMemWRITEコマンドの実行を許可するかを指定します。0は禁止、1は許可になります。デフォルトは0が設定されますので、0を指定する場合は省略は可能です。動作環境に合わせて選択してください。
制御モードの組み合わせは制限があります。「制御モード」について詳しくはオンラインマニュアルの『制御モード』をご参照ください。
1 2 3 4 |
receiveMode = PMX.ReceiveDataOption.Full # すべて返す # receiveMode = 0xFF # 数値でも指定できます。 status = pmx.setMotorReceive(ServoID, receiveMode, writeOpt=0x01) print("setMotorReceive", hex(status)) |
次に、応答データを指定します。PMXサーボは、MotorWRITEコマンドやMotorREADコマンドを受け取った返事のパケットに、サーボの状態を示すデータを含めて返すことができます。これを応答データと呼びます。
応答データは下記の8種類です。
Bit0:現在位置
Bit1:現在速度
Bit2:現在電流値
Bit3:現在推定トルク
Bit4:PWM出力割合
Bit5:モータ温度
Bit6:CPU温度
Bit7:入力電圧
各ビットを1にすることで指定することができます。0xFFで8種類すべての応答データを受け取ることもできますし、0を指定すれば応答データを含めずに最小のバイト数で返事のパケットを受け取ることができます。制御に必要なデータを選択してください。
ライブラリのsetMotorReceive()関数を使用することで「応答データ指定」を書き換えることができます。
第一引数の「ServoID」は、書き込みの対象となるサーボのID番号です。
第二引数の「receiveMode」は「応答データ指定」に書き込むデータです。「応答データ指定」の指定データは、後のMotorWRITEコマンドやMotorREADコマンドでも使用しますので、「receiveMode」変数に代入してから引数にしています。直接数値を記入しても同様の処理を実行できます。
第三引数の「writeOpt」は、PMXサーボのトルクスイッチがTorqueONの状態でもMemWRITEコマンドの実行を許可するかを指定します。0は禁止、1は許可になります。デフォルトは0が設定されますので、0を指定する場合は省略は可能です。動作環境に合わせて選択してください。
「応答データ指定」について詳しくはオンラインマニュアルの『応答データ指定』をご参照ください。
【設定を保存する】
以上①②の設定は、SAVEコマンドを実行することでサーボに保存することができます。保存が完了しましたら、以降は電源投入後③のトルクをオンにする手順からスタートすることでき、トルクオンから即動作することが可能です。
1 2 |
status, torqueswitch, reData = pmx.setMotorTorqueOn(ServoID, receiveMode) print("setMotorTorqueOn", hex(status)) |
「トルクスイッチ」にデータを書き込んで、サーボをTorqueONモードにします。「トルクスイッチ」には下記の4種類のモードがあります。
・TorqueON setMotorTorqueOn()関数
・Free setMotorFree()関数
・Brake setMotorBrake()関数
・Hold setMotorHold()関数
サーボに電源が入った直後の脱力した状態が「Free」です。サーボが動作するためには必ず「TorqueON」に設定します。「Free」「Brake」「Hold」でMotorWRITEコマンドを受け取ってもサーボは動作しませんのでご注意ください。各モードの詳細は、オンラインマニュアルの『トルクスイッチ』をご参照ください。
ライブラリのsetMotorTorqueOn()関数を使用することでサーボを「TorqueON」の状態にできます。また、それぞれのモードに設定するための関数も用意されています。
第一引数の「ServoID」は、書き込みの対象となるサーボのID番号です。
第二引数の「receiveMode」は、応答データの内容を関数に伝えるために渡します。トルクスイッチの前に処理した「応答データ指定」と同じ内容のまま引数として渡してください。setMotorTorqueOn()関数の内部ではMotorWRITEコマンドを実行しているため、返事のパケットに「応答データ指定」で指定したデータが含まれます。
ここまでの処理でPMXサーボを動作させる準備が整いました。次の処理からMotorWRITEコマンドを使用してサーボを動かします。
●基本のMotorWRITE()関数
1 2 3 4 5 6 |
pos = -32000 # 位置の第1引数は位置 status, torqueswitch, reData = pmx.MotorWRITE(ServoID, 0, controlMode, receiveMode, [pos]) print("MotorWRITE", hex(status), torqueswitch, reData) # 目標地点に到達するまで待ちます time.sleep(2) |
MotorWRITEコマンドを使用するための基本的な関数はMotorWRITE()です。
第一引数は、対象となるサーボのID番号です。
第二引数は、「オプション」です。MotorWRITEコマンドはオプションにより実行する機能を指定することができます。
機能1:トルクスイッチを設定する
一つ目は、トルクスイッチです。サーボをTorqueON、Free、Brake、Holdの状態に設定することができます。これは、アドレス500の「トルクスイッチ」にデータを書き込んでも同じ処理を実行することができます。また、このライブラリを使用する場合は、③で解説した通り各モードの関数をご用意してありますので、関数を使用することをお勧めします。
機能2:サーボに動作指示をする
二つ目は、サーボの動作指示です。この場合は「オプション」を0に指定します。今回は動作指示の為にMotorWRITEコマンドを実行しますので「オプション」の引数は0にします。
第三引数、第四引数は「制御モード」と「応答データ指定」です。「制御モード」の内容と、「応答データ指定」で返ってくるデータの内容を関数に伝えるために引数として渡します。上記のプログラムで用意した「controlMode」「receiveMode」変数の内容を変えずにそのまま使用します。
第五引数は、「動作指示データ」です。各制御モードに合わせた数値を送り、サーボを動かします。位置制御の場合は角度を送ります。例えば、PMX-SCR-5204HVは-320°~320°の範囲で角度を指示できますが、単位は1/100[°]ですので、サーボに送信する「動作指示データ」は-32000~32000の範囲になります。サーボに100°を指示する場合は10000を送信します。
PMXサーボの特徴として、制御を組み合わせることができます。このためMotorWRITE()関数の第五引数の「動作指示データ」はリストになっています。組み合わせが一つの場合はデータも一つ、組み合わせが二つの場合は二つのデータを送ります。今回は組み合わせが一つですので[pos]として一つのデータを引数にしています。二つの場合は[0, 0]のように二つ用意します。
以上の引数を持ったMotorWRITE()関数を、サンプルの通り-32000を指定して実行すると、サーボが-320°の位置に移動します。
サーボがMotorWRITE()を受け取った返事として返信パケットが返ってきます。このパケットの中に「応答データ指定」で指定したデータが含まれています。サンプルでは、次の行のprint()の「reData」で表示されますので内容を確認してください。
●制御の組み合わせで使い分けることができるMotorWRITE()関数
以上でMotorWRITEコマンドの基本的な使い方を解説しました。この方法でサーボを動作させることが可能ですが、より簡単にMotorWRITEコマンドを使用するために以下の関数をご用意しました。
1 2 3 4 5 6 |
pos = -18000 status, torqueswitch, reData = pmx.MotorWRITESingle(ServoID, controlMode, receiveMode, pos) print("MotorWRITE(Single)", hex(status), torqueswitch, reData) # 目標地点に到達するまで待ちます time.sleep(1) |
MotorWRITESingle()関数は、制御モードが一つの時に特化した関数です。MotorWRITE()では「動作指示データ」をリストで渡していましたが、この関数では数値のまま渡すことができます。
このほかに、二つの制御モードの時に使用するMotorWRITEDouble()と、制御モードが三つの時のMotorWRITETriple()があります。制御モードの数に合わせて使い分けてください。
●位置制御モードに便利なsetPosition()関数
1 2 3 4 5 6 7 8 9 |
pos = 0 status, torqueswitch, reData = pmx.setPosition(ServoID, receiveMode, pos) print("SetPositon", hex(status), torqueswitch, reData) if status == 0: # エラーではなかった場合は現在位置を表示する print("Position>>", reData[0]) # 位置が入るのは0番目 # 目標地点に到達するまで待ちます time.sleep(1) |
setPosition()関数は、位置制御に特化した関数です。位置制御のみの場合も使用できますし、位置制御と他の制御の組み合わせにも使用できます。
第二引数は、上記と同じ「応答データ指定」です。第三引数に「動作指示データ」を入れます。
制御を組み合わせている場合は、組み合わせる制御を指定し、引数として渡します。
速度制御:speed=xxx
電流制御:current=xxx
トルク制御:torque=xxx
移動時間:time=xxx (xxxは指令値)
例えば、位置制御と電流制御を組み合わせている場合は下記のように書きます。
1 2 3 |
pos = 10000 crt = 100 pmx.setPosition(ServoID, receiveMode, pos, current=crt) |
※setPosition()関数の引数を増やしただけでは制御モードを変更することはできません。まず制御モードを任意のモードに設定してからsetPosition()関数をご利用ください。
setPosition()関数を使用することにより、必要な引数を削減できますので、より簡単にプログラムを書くことが可能になります。
●サーボの状態を読み出せるMotorREAD()関数
1 2 |
status, tq, data = pmx.MotorREAD(ServoID, receiveMode, controlMode=controlMode) print("MotorREAD", hex(status), data) |
最後に、MotorREADコマンドについて解説します。MotorREADコマンドは、「応答データ指定」で指定したデータを読み出すことができます。MotorWRITEコマンドでは、サーボの動作指示が処理に含まれますが、MotorREADコマンドはデータの読み出し処理のみ実行されます。サーボの状態を知りたい場合に便利なコマンドです。
第三引数の「controlMode」は、現在位置のデータ処理に使用します。PMXサーボは、現在位置のデータの仕様が位置制御とそれ以外で異なります。位置制御を含めた制御モードの場合は-32000~32000の範囲になりますが、位置制御を含めない(速度制御、電流制御のみなど)場合は0~35999の範囲になります。これは角度指令で動作する場合と、無限回転で動作する場合で必要な位置情報が異なるため、直感的にわかりやすい数値が返ってくる仕様になっています。
引数の「controlMode」はデフォルト値が0x01になっていますので、位置制御を含めた制御モードの場合は省略することができます。位置制御を含めていない場合(0~35999のデータが必要な場合)に指定してください。
■プログラム全体
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# 通信ログを表示させない pmx.logOutput = False # COMを開く serialPortOpen() # 制御モードの設定します # writeOpt=0x01のときはトルクONでも強制的に書き込めます(デフォルト値は0x00) # 以下の各ビットを1にすると制御モードとして指定できます # Bit7:0 Bit6:0 Bit5:移動時間 Bit4:PWM Bit3:トルク Bit2:電流 Bit1:速度 Bit0:位置 controlMode = PMX.ControlMode.Position # 位置制御モード値 status = pmx.setControlMode(ServoID, controlMode, writeOpt=0x01) print("setControlMode", hex(status)) # 応答データ指定します # writeOpt=0x01のときはトルクONでも強制的に書き込めます(デフォルト値は0x00) # 以下の各ビットを1にすると応答データとして指定できます # Bit7:入力電圧 Bit6:CPU温度 Bit5:モータ温度 Bit4:PWM出力 Bit3:推定トルク Bit2:電流 Bit1:速度 Bit0:位置 # receiveMode = PMX.ReceiveDataOption.Position # 位置情報を返す receiveMode = PMX.ReceiveDataOption.Full # すべて返す # receiveMode = 0xFF # 数値でも指定できます。 status = pmx.setMotorReceive(ServoID, receiveMode, writeOpt=0x01) print("setMotorReceive", hex(status)) # サーボのトルクをオンにします status, torqueswitch, reData = pmx.setMotorTorqueOn(ServoID, receiveMode) print("setMotorTorqueOn", hex(status)) # MotorWRITE関数で動作指令 pos = -32000 # 位置の第1引数は位置 status, torqueswitch, reData = pmx.MotorWRITE(ServoID, 0, controlMode, receiveMode, [pos]) print("MotorWRITE", hex(status), torqueswitch, reData) # 目標地点に到達するまで待ちます time.sleep(2) # MotorWRITESingle(組合せ1個)で動作指令 pos = -18000 status, torqueswitch, reData = pmx.MotorWRITESingle(ServoID, controlMode, receiveMode, pos) print("MotorWRITE(Single)", hex(status), torqueswitch, reData) # 目標地点に到達するまで待ちます time.sleep(1) # setPositon関数を使用した場合 pos = 0 status, torqueswitch, reData = pmx.setPosition(ServoID, receiveMode, pos) print("SetPositon", hex(status), torqueswitch, reData) if status == 0: # エラーではなかった場合は現在位置を表示する print("Position>>", reData[0]) # 位置が入るのは0番目 # 目標地点に到達するまで待ちます time.sleep(1) # MotorREADで現在の状態を確認 status, tq, data = pmx.MotorREAD(ServoID, receiveMode, controlMode=controlMode) print("MotorREAD", hex(status), data) # トルクスイッチ:Free status, torqueswitch, reData = pmx.setMotorFree(ServoID, receiveMode) print("setMotorFree", hex(status)) pmx.close() # COMを閉じます |
以上でMotorWRITEコマンドの解説を終わります。今回の記事は、位置制御を中心とした解説となっていますが、PMXサーボは速度制御や電流制御など多彩な制御方法を搭載しています。次回の記事では、位置制御以外の制御についても解説します。
次の記事『PMXサーボを使ってみよう PCから制御「MotorWRITE (組み合わせ制御)編」』
前の記事『PMXサーボを使ってみよう PCから制御「MemWRITE編」』
PMX-SCR-9204HVの詳細をみる PMX-SCR-9203HVの詳細をみる PMX-SCR-5204HVの詳細をみる PMX-SCR-5203HVの詳細をみる