ホーム > 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()