ホーム > RT-Python
No | 項目 | 詳細 |
---|---|---|
1 | 動作環境 | INtime 7 以降 Windows 10以降 |
2 | プログラミング言語 | Python3標準構文準拠 |
3 | 制御周期 | 最速100usec |
4 | 実行モード | インタラクティブモード / スクリプトモード |
No | 項目 | 詳細 |
---|---|---|
1 | 連携機能用モジュール | 様々な機能を扱うためのRT-Python専用モジュールです。 利用できる機能については 連携機能 を参照ください。 |
2 | リアルタイム処理用モジュール | RT-Python専用モジュールです。制御周期を生成するためのSleep機能を提供します。 |
3 | mathモジュール | 数学演算関数機能を提供します。 |
4 | sysモジュール | インタプリタや実行環境に関する情報を扱うためのモジュールデです。以下の3つの機能に対応しています。
sys.path / sys.argv / sys.version
|
No | 項目 | 内容 |
---|---|---|
1 | モーション制御 | Pythonプログラムからモーション制御が行なえます。 |
2 | データベース接続 | 制御データをデータベースへ保存できます。 |
3 | HMI連携 | 市販のHMIや弊社のHMIとの連携が容易に出来ます。 |
4 | 挙動監視 ※1 | 映像や入出力を監視し、条件に応じてイベントを検知し、アクションを実行する機能です。 |
5 | マルチメディア ※1 | 動画、静止画、音声で通知、メール送受信、遠隔操作の3つの機能を提供します。 |
6 | INtimeアプリケーション | INtimeアプリケーション側から連携機能を利用することで、RT-Python処理との通信が可能になります。 |
7 | Windowsアプリケーション | ユーザーが作成するWindowsアプリケーション側から連携機能を利用することで、RT-Python処理との通信が可能になります。 また、DDE通信やOPC UA通信などに対応している市販アプリケーションからも接続可能です。 |
8 | Pythonアプリケーション | Windows上で動作するPythonアプリケーションから連携機能を利用することで、RT-Python処理との通信が可能になります。 |
No | 項目 | 対応方式 |
---|---|---|
1 | 外部I/O | PCI/PCIeボード (デジタル、アナログなど) EtherCAT |
2 | コントローラ間通信 | FL-net EtherNet/IP CC-LinkIE Control 三菱MCプロトコル通信 オムロンFINS通信 |
3 | 外部通信 | Ethernet シリアル通信 OPC UA MQTT FTP |
PC | PHOENIC CONTACT VL2 BPC 9000 |
---|---|
CPU | Intel Core i7 6822EQ |
INtime | 7.1.25030.3 |
サーボアンプ/モーター | Panasonic社 MINAS A6B
サーボアンプ : MADLN11BE
サーボモーター : MHMF011L1A2 |
通信 | EtherCAT |
---|---|
制御周期 | 125usec (polling mode) |
制御モード | CiA402 CSP(Cyclic Synchronous Position) mode |
import INtime import RTedge import math g_Interval = 0.125 """ CiA402 サーボドライバ制御プログラム(Python版) """ # 目標位置を順次生成する #-------------------------------------- def generate_wave(): ctrl = [ ( 1000, 1), #/* 0 */ ( 2000, 0), #/* 1 */ ( 3000, 2), #/* 2 */ ( 4000, 0), #/* 3 */ ( 5000, -1), #/* 4 */ ( 6000, 0), #/* 5 */ ( 7000, 3), #/* 6 */ ( 9000, 0), #/* 7 */ (10000, -5), #/* 8 */ (11500, -6), #/* 9 */ (13000, 0), #/* 10 */ (14500, 6), #/* 11 */ ] phase = 0 vel = 0 pos = 0 t_ms = 0 while (phase < len(ctrl)): while (t_ms < (ctrl[phase])[0]): vel += ( (ctrl[phase])[1] * g_Interval) pos += vel*g_Interval t_ms += g_Interval yield int(pos) phase += 1 # CSPモードへの変更処理 #-------------------------------------- def ReqChangeCSPmode(): val = 8 # 8:CSP mode RTedge.EgTagWrite("Motor1_ModesOfOperation", bytes([val])) # 現在のサーボステートの取得 #-------------------------------------- def GetServoState(): data = RTedge.EgTagRead("Motor1_Statusword", 2) status_word = int.from_bytes(data, byteorder='little') return status_word # サーボステート変更要求 #-------------------------------------- def ReqServoState(newval): data = newval.to_bytes(2, byteorder='little') RTedge.EgTagWrite("Motor1_Controlword", data) # 目標位置変更要求 #-------------------------------------- def UpdateTargetPos(pos): data = pos.to_bytes(4, byteorder='little', signed=True) RTedge.EgTagWrite("Motor1_TargetPosition", data) # 動作開始要求確認 #-------------------------------------- def IsReqStartRun(): data = RTedge.EgTagRead("DEMO_RUN", 1) isRun = int.from_bytes(data, byteorder='little') return True if isRun else False # 動作終了要求の確認 #-------------------------------------- def IsReqStop(): data = RTedge.EgTagRead("Stop_set", 1) isRun = int.from_bytes(data, byteorder='little') data = RTedge.EgTagRead("DEMO_SHUTDOWN", 1) isRun |= int.from_bytes(data, byteorder='little') return True if isRun else False def IsReqShutdown(): data = RTedge.EgTagRead("DEMO_SHUTDOWN", 1) isRun = int.from_bytes(data, byteorder='little') return True if isRun else False def ClearReqStartRun(): data = 0 RTedge.EgTagWrite("DEMO_RUN", bytes([data])) # タグへの書き込み def ClearReqStop(): data = 0 RTedge.EgTagWrite("Stop_set", bytes([data])) # タグへの書き込み def ClearReqShutdown(): data = 0 RTedge.EgTagWrite("DEMO_SHUTDOWN", bytes([data])) # タグへの書き込み # HMI 表示情報の更新 #-------------------------------------- def UpdateDispTotalMoment(newval): data = newval.to_bytes(4, byteorder='little', signed=True) RTedge.EgTagWrite("TotalMovement", data) # HMI 表示情報の更新 #-------------------------------------- def UpdateDispSpeed(newval): data = newval.to_bytes(4, byteorder='little', signed=True) RTedge.EgTagWrite("Speed", data) # 現在のステートから、次のステート要求値を算出 #-------------------------------------- def ChangeMotionState(status_word, control_word): """ CiA402 サーボドライバ状態遷移処理 Args: status_word (unsigned short): 現在のステータスワード control_word (unsigned short): 制御ワード(参照渡し相当) Returns: tuple: (新しい制御ワード, 状態) """ state = status_word & 0x6F new_control_word = control_word if state == 0x00: # 未初期化状態 -> 初期化要求 new_control_word = (control_word & 0xFF70) | 0x00 elif state == 0x40: # 初期化完了状態 -> 主回路電源OFF要求 new_control_word = 0x06 elif state == 0x60: # 初期化完了状態 -> 主回路電源OFF要求 new_control_word = (control_word & 0xFF70) | 0x06 elif state == 0x21: # 主回路電源OFF状態 -> サーボレディ要求 new_control_word = (control_word & 0xFF70) | 0x07 elif state == 0x23: # サーボレディ状態 -> サーボON要求 new_control_word = (control_word & 0xFF70) | 0x0F elif state == 0x27: # サーボON状態 (運転開始OK状態) pass elif state == 0x2F: # 異常処理動作中状態 pass elif state == 0x28: # 異常状態 -> 初期化要求 new_control_word = (control_word & 0xFF70) | 0x80 return new_control_word, state # 開始要求の待機 #-------------------------------------- def WaitForReqStart(): while True: if IsReqStartRun(): break INtime.RtSleep(100) # (デバッグ用関数) #-------------------------------------- def Break(prompt): print(prompt) input() # メインエントリー #-------------------------------------- def main(): # CiA402 動作モードの変更 # サイクリック同期位置モード へ変更要求 ReqChangeCSPmode(); # CiA402 サーボドライバ状態を、サーボONに遷移 control_word = 0 status_word = 0 while True: # ポーリングモード: 1msec周期 INtime.RtSleep(1) # 現在のサーボドライバ状態取得 status_word = GetServoState() # 現在のサーボドライバ状態から、次のサーボドライバ状態へ遷移 control_word, state = ChangeMotionState(status_word, control_word) if state == 0x27: # サーボON状態 break # 次のサーボドライバ遷移値を書き込み ReqServoState(control_word) # サーボON後 100msec待機する(メーカー仕様) INtime.RtSleep(100) # モーター動作処理 target_pos = 0 target_pos_old = 0 counter = 0 is_req_shutdown = False # モーション制御処理ループ while is_req_shutdown == False: while True: # 終了要求の確認 if IsReqStop(): break for next_target_pos in generate_wave(): # ループ毎に100分移動要求 UpdateTargetPos(target_pos) # HMI表示データ更新 UpdateDispTotalMoment(next_target_pos) UpdateDispSpeed(int((next_target_pos - target_pos) / g_Interval)) # ポーリングモード: 1tick周期 INtime.knRtSleep(1) target_pos = next_target_pos # クリア処理 ClearReqStartRun() ClearReqStop() # 開始要求の待機 while True: # デモプログラム終了要求の確認 if IsReqShutdown(): is_req_shutdown = True break if IsReqStartRun(): break INtime.RtSleep(100) # サーボOFF INtime.RtSleep(100) # ちょっと待つ ReqServoState(0) # 終了 UpdateDispTotalMoment(0) UpdateDispSpeed(0) ClearReqShutdown() if __name__ == "__main__": main()