Pythonでのモーション制御はどんな感じ?
WMXのConsoleTOOL(標準ツール)では軸の動作が物足りない場合や、操作ミスを防ぎたい場合、WMXのPythonを活用することが便利です。以下の理由から、Pythonが有用なツールとなります
効率的な実行管理
C#のプロジェクトを作成して管理するのは規模が大きいですが、Pythonコードならば簡単に実験的な動作を実行できます。
ユーザーアプリの同時実行
WMXの良い仕様として、複数のユーザーアプリを同時に実行することが可能です。これにより、メインアプリケーションで原点復帰や主要な動作を行いながら、追加の実験的操作をPythonコードで行うことができます。
実験的な操作のサポート
例えば、メインのプロセスが進行中でも、Pythonコードを使って新たな軌道や動作を試すことができるため、操作の柔軟性が大きく向上します。
単軸の移動を行う方法
Pythonで軸移動の直線補間を行うには、Motion_PosCommandクラスに移動情報をセットし、StartPos関数で動作を行います。 クラス内の構造やパラメータ名はC#とほぼ同じです。
単軸の絶対位置移動と相対位置移動のサンプル
絶対位置移動(StartPos関数)で移動後、相対位置移動(StartMov関数)を行いました。
移動を行っているコードはdef 絶対位置移動(): と def 相対位置移動(): 関数です。ここの部分をコピペして使用してください。
※WMX3.6で検証したコード
# WMXに必要なコード
from WMX3ApiPython import *
from time import *
INFINITE = int(0xFFFFFFFF)
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
def 絶対位置移動():
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
AXIS_NO = 0
print('絶対位置移動')
posCommand = Motion_PosCommand()
posCommand.profile.type = ProfileType.Trapezoidal
posCommand.axis = AXIS_NO #制御したい軸番号の設定
posCommand.target = 123 #移動先の座標設定
posCommand.profile.velocity = 100000 #スピード設定
posCommand.profile.acc = 1000000
posCommand.profile.dec = 1000000
Wmx3Lib_cm.motion.StartPos(posCommand)
#移動命令の完了待ち(サーボの位置決め完了ではありません)
Wmx3Lib_cm.motion.Wait(0)
return
def 相対位置移動():
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
AXIS_NO = 0
print('相対位置移動')
posCommand = Motion_PosCommand()
posCommand.profile.type = ProfileType.Trapezoidal
posCommand.axis = AXIS_NO #制御したい軸番号の設定
posCommand.target = 10000 #移動先の座標設定
posCommand.profile.velocity = 100000 #スピード設定
posCommand.profile.acc = 1000000
posCommand.profile.dec = 1000000
Wmx3Lib_cm.motion.StartMov(posCommand)
#移動命令の完了待ち(サーボの位置決め完了ではありません)
Wmx3Lib_cm.motion.Wait(0)
return
def main():
# 制御する軸番号(0から始まります。)
AXIS_NO = 0
print('WMXプログラムスタート ディバイスを作成します')
# WMXを使用するおまじない
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
Wmx3Lib = WMX3Api()
Wmx3Lib.CreateDevice('C:\\Program Files\\SoftServo\\WMX3\\', DeviceType.DeviceTypeNormal, INFINITE)
Wmx3Lib.SetDeviceName('devicePython')
Wmx3Lib_cm = CoreMotion(Wmx3Lib)
#スレーブとの通信開始
ret = Wmx3Lib.StartCommunication(INFINITE)
#ここでユーザーの処理を記述します。
print('WMXサーボオン')
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO, 1)
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO+1, 1)
# サーボがONするまで待機
while True:
ret, CmStatus = Wmx3Lib_cm.GetStatus()
if (CmStatus.GetAxesStatus(AXIS_NO).servoOn):
break
sleep(0.1)
# 原点復帰
homeParam = Config_HomeParam()
ret, homeParam = Wmx3Lib_cm.config.GetHomeParam(0)
homeParam.homeType = Config_HomeType.CurrentPos
Wmx3Lib_cm.config.SetHomeParam(0, homeParam)
Wmx3Lib_cm.home.StartHome(0)
Wmx3Lib_cm.motion.Wait(0)
print('待機中。何かキーを押すと絶対位置移動を開始します。')
input()
絶対位置移動()
print('待機中。何かキーを押すと相対位置移動を開始します。')
input()
相対位置移動()
print('待機中。何かキーを押すと終了します。')
input()
print('WMXサーボオフ')
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO, 0)
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO+1, 0)
# サーボがOFFするまで待機
while True:
ret, CmStatus = Wmx3Lib_cm.GetStatus()
if (not CmStatus.GetAxesStatus(0).servoOn):
break
sleep(0.1)
#スレーブとの通信終了
Wmx3Lib.StopCommunication(INFINITE)
#WMXの終了
Wmx3Lib.CloseDevice()
print('WMXプログラム終了')
sleep(3)
return 0
if __name__ == '__main__':
main()
2軸以上の線形補間移動を行う方法
Pythonで直線補間を行うにはMotion_LinearIntplCommandクラスに移動情報をセットし、StartLinearIntplMov関数で動作を行います。
C#やC++のコードで軸番号の指定は
lin.axis[0] = 0;
lin.axis[1] = 1;
と記載しますが、Pythonではこの方法は出来ません。以下のように関数で指定する必要があります。
posCommand.SetAxis(0,0) # (1つ目の軸,対象の軸番号0)とする
posCommand.SetAxis(1,1) # (2つ目の軸,対象の軸番号1)とする
,の前が0から始まる配列の番号です。
絶対位置で移動の後、相対移動
絶対位置移動はStartLinearIntplPos関数になります。 行先は以下のコードで指定しています。
posCommand.SetTarget(0,567)
posCommand.SetTarget(1,789)
相対位置移動はStartLinearIntplMov関数になります。 オフセット量は以下のコードで指定しています。
posCommand.SetTarget(0,234)
posCommand.SetTarget(1,-321)
サンプルコード
動作開始時は座標0の位置としています。
※WMX3.6で検証したコード
# WMXに必要なコード
from WMX3ApiPython import *
from time import *
INFINITE = int(0xFFFFFFFF)
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
def 直接補間_絶対位置移動():
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
print('絶対位置移動')
posCommand = Motion_LinearIntplCommand()
posCommand.profile.type = ProfileType.Trapezoidal
posCommand.axisCount = 2 # 同期させる軸数
#制御したい軸番号の設定
posCommand.SetAxis(0,0) # (1つ目の軸,対象の軸番号0)とする
posCommand.SetAxis(1,1) # (2つ目の軸,対象の軸番号1)とする
#移動先の座標設定
posCommand.SetTarget(0,567)
posCommand.SetTarget(1,789)
#スピード設定
posCommand.profile.velocity = 100000
posCommand.profile.acc = 1000000
posCommand.profile.dec = 1000000
Wmx3Lib_cm.motion.StartLinearIntplPos(posCommand)
#移動命令の完了待ち(サーボの位置決め完了ではありません)
Wmx3Lib_cm.motion.Wait(0)
return
def 直接補間_相対位置移動():
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
print('絶対位置移動')
posCommand = Motion_LinearIntplCommand()
posCommand.profile.type = ProfileType.Trapezoidal
posCommand.axisCount = 2 # 同期させる軸数
#制御したい軸番号の設定
posCommand.SetAxis(0,0) # (1つ目の軸,対象の軸番号0)とする
posCommand.SetAxis(1,1) # (2つ目の軸,対象の軸番号1)とする
#移動先の座標設定
posCommand.SetTarget(0,234)
posCommand.SetTarget(1,-321)
#スピード設定
posCommand.profile.velocity = 100000
posCommand.profile.acc = 1000000
posCommand.profile.dec = 1000000
Wmx3Lib_cm.motion.StartLinearIntplMov(posCommand)
#移動命令の完了待ち(サーボの位置決め完了ではありません)
Wmx3Lib_cm.motion.Wait(0)
return
def main():
# 制御する軸番号(0から始まります。)
AXIS_NO = 0
print('WMXプログラムスタート ディバイスを作成します')
# WMXを使用するおまじない
global Wmx3Lib_cm # 軸動作命令クラス(グローバル変数)
Wmx3Lib = WMX3Api()
Wmx3Lib.CreateDevice('C:\\Program Files\\SoftServo\\WMX3\\', DeviceType.DeviceTypeNormal, INFINITE)
Wmx3Lib.SetDeviceName('devicePython')
Wmx3Lib_cm = CoreMotion(Wmx3Lib)
#スレーブとの通信開始
ret = Wmx3Lib.StartCommunication(INFINITE)
#ここでユーザーの処理を記述します。
print('WMXサーボオン')
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO, 1)
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO+1, 1)
# サーボがONするまで待機
while True:
ret, CmStatus = Wmx3Lib_cm.GetStatus()
if (CmStatus.GetAxesStatus(AXIS_NO).servoOn):
break
sleep(0.1)
# 原点復帰
homeParam = Config_HomeParam()
ret, homeParam = Wmx3Lib_cm.config.GetHomeParam(0)
homeParam.homeType = Config_HomeType.CurrentPos
Wmx3Lib_cm.config.SetHomeParam(0, homeParam)
Wmx3Lib_cm.home.StartHome(0)
Wmx3Lib_cm.motion.Wait(0)
print('待機中。何かキーを押すと絶対位置移動を開始します。')
input()
直接補間_絶対位置移動()
print('待機中。何かキーを押すと相対位置移動を開始します。')
input()
直接補間_相対位置移動()
print('待機中。何かキーを押すと終了します。')
input()
print('WMXサーボオフ')
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO, 0)
Wmx3Lib_cm.axisControl.SetServoOn(AXIS_NO+1, 0)
# サーボがOFFするまで待機
while True:
ret, CmStatus = Wmx3Lib_cm.GetStatus()
if (not CmStatus.GetAxesStatus(0).servoOn):
break
sleep(0.1)
#スレーブとの通信終了
Wmx3Lib.StopCommunication(INFINITE)
#WMXの終了
Wmx3Lib.CloseDevice()
print('WMXプログラム終了')
sleep(3)
return 0
if __name__ == '__main__':
main()
補足
サンプルで軸の指令完了は Wmx3Lib_cm.motion.Wait(0) としておりますが、実機では位置決め完了を待って次の動作を行う必要があると思います。 位置決め完了確認を行わない場合は、軸の軌跡がショートカットされた動きになります。参考:WMX | サーボの位置決め完了幅
の処理が必要になります。
コーディングの感想
最近、Pythonでのコーディングにだんだん慣れてきました。普段は主にC#やC++を使ってコーディングを行っていますが、Pythonを使うことによって新しい発見や便利さを感じています。特に、Pythonはコードを少し変更して、すぐにその結果を確認できるという点が非常に魅力的です。この点において、PythonはC#やC++とは異なり、コンパイルを必要としないため、開発サイクルが格段にスムーズになります。
実験コードなど、使い捨て機能(お試し機能)の検証で使うなどにご活用ください。特に、プロジェクトの初期段階やアイデアの検証段階では、この柔軟性が非常に役立ちます。
コメント