Project#Integrate Ethernet/IP Into RoboDK and connect with Beckhoff TwinCAT3

今回は、RoboDK と Beckhoff TwinCAT を使って Etherent/IP ネットワークを構築してみます。スキャナ側がRoboDKで、TwinCAT側がAdapterになります。なお、この記事で紹介しているものはデモですので、実際の用途に適しているかどうかは、ご自身で評価してください。

よろしくお願いします。

RoboDK Side

Configure the Station and Program

RoboDK Softwareを起動し、Stationを作成します。

Configure it as Loop

いくつかポイントを教え、プログラムに追加したら、プログラムを右クリックし、Loop Option使用し無限Loopさせます。

Test it First

作成したステーションはこちらです。

Python Script

RoboDKは非常に優れたAPIも提供し、ユーザーがステーション内で独自のPythonスクリプトを作成し、アプリケーションに基づいてそれを実行することができます。

Add a new Python Program

RoboDK の Python アイコンを押して、Add new Python program を実行します。

ステーションの末尾にPythonスクリプトが挿入されているのがわかると思います。

Python Scriptを右クリック>「Edit Python Script」を選択するだけで、プログラムを編集することができます。

RoboDK ソフトウェアから Python スクリプトを生成する場合、必要なライブラリもすでにImportされたテンプレートとして作成されます。

Run>Runモジュールをクリックするだけで、Pythonスクリプトを実行してみます。

Done!

EIP Module

こちらは今回の記事で使用するライブラリです。

http://eeip-library.de/

eeipライブラリは、こちらのGithubリンクからダウンロードできます。

https://github.com/rossmann-engineering/eeip.py

eeipはこのチュートリアルで使用するライブラリです。

Program it!

こちらはPython Scriptです。

# Type help(“robodk.robolink”) or help(“robodk.robomath”) for more information
# Press F5 to run the script
# Documentation: https://robodk.com/doc/en/RoboDK-API.html
# Reference:     https://robodk.com/doc/en/PythonAPI/robodk.html
# Note: It is not required to keep a copy of this file, your Python script is saved with your RDK project

# You can also use the new version of the API:

import sys
sys.path.append(r”C:\Users\root\Desktop\eeip.py-master\eeip.py-master”)
from eeip import *

from robodk import robolink    # RoboDK API
from robodk import robomath    # Robot toolbox
RDK = robolink.Robolink()

# Forward and backwards compatible use of the RoboDK API:
# Remove these 2 lines to follow python programming guidelines
from robodk import *      # RoboDK API
from robolink import *    # Robot toolbox
# Link to RoboDK
# RDK = Robolink()
import struct


# Notify user:
print(‘To edit this program:\nright click on the Python program, then, select “Edit Python script”‘)

print(‘Creating EEIP..’)
eeipclient=EEIPClient()
print(‘Register session…’)
eeipclient.register_session(‘192.168.3.240’)

#Parameters from Originator -> Target
eeipclient.o_t_instance_id = 0x82
eeipclient.o_t_length = 44
eeipclient.o_t_requested_packet_rate = 100000  #Packet rate 100ms (default 500ms)
eeipclient.o_t_realtime_format = RealTimeFormat.HEADER32BIT
eeipclient.o_t_owner_redundant = False
eeipclient.o_t_variable_length = False
eeipclient.o_t_connection_type = ConnectionType.POINT_TO_POINT

#Parameters from Target -> Originator
eeipclient.t_o_instance_id = 0x81
eeipclient.t_o_length = 44
eeipclient.t_o_requested_packet_rate = 100000  #Packet rate 100ms (default 500ms)
eeipclient.t_o_realtime_format = RealTimeFormat.MODELESS
eeipclient.t_o_owner_redundant = False
eeipclient.t_o_variable_length = False
eeipclient.t_o_connection_type = ConnectionType.POINT_TO_POINT

eeipclient.configuration_assembly_instance_id=0x80


eeipclient.forward_open()
item = RDK.Item(‘UR3’)
Joints = bytearray(struct.pack(“f”, value))

try:
    while 1:
    # Program example:
        if item.Valid():
            print(‘Item selected: ‘ + item.Name())
            print(‘Item posistion: ‘ + repr(item.Pose()))

            print(‘Items in the station:’)

            print(‘State of the first Input byte: {0}’.format(eeipclient.t_o_iodata))

            joints=item.Joints().list()
            count=4
            for joint in joints:
                print(count)
                barray=bytearray(struct.pack(“f”, joint))
                eeipclient.o_t_iodata[count]=barray[0]
                eeipclient.o_t_iodata[count+1]=barray[1]
                eeipclient.o_t_iodata[count+2]=barray[2]
                eeipclient.o_t_iodata[count+3]=barray[3]
                count+=4
            print(‘State of the second output byte: {0}’.format(eeipclient.o_t_iodata))
            print(type(eeipclient.o_t_iodata))
            time.sleep(0.1)
       
except KeyboardInterrupt:
    print(“Keyboard interrupt exception caught”)

print(‘forword close..’)
eeipclient.forward_close()
eeipclient.unregister_session()

Explanation

python sys パッケージをインポートして、ライブラリディレクトリの絶対パスを追加します。私の場合はC: \Users\Desktop\ip.py-master\Masterです。

import sys
sys.path.append(r”C:\Users\root\Desktop\eeip.py-master\eeip.py-master”)
from eeip import *

192.168.3.240 は、Ethernet/IP Adapter の IP アドレスです。

eeipclient.register_session(‘192.168.3.240’)

ここでは、OriginatorからTargetへの接続経路を設定するプログラムになります。これらのパラメータをどのように合わせるか、Beckhoff TwinCAT3側が説明しますので心配しないでください。

#Parameters from Originator -> Target
eeipclient.o_t_instance_id = 0x82
eeipclient.o_t_length = 44
eeipclient.o_t_requested_packet_rate = 100000  #Packet rate 100ms (default 500ms)
eeipclient.o_t_realtime_format = RealTimeFormat.HEADER32BIT
eeipclient.o_t_owner_redundant = False
eeipclient.o_t_variable_length = False
eeipclient.o_t_connection_type = ConnectionType.POINT_TO_POINT

ここでは、TargetからOriginatorへの接続経路を設定するプログラムを紹介します。これらのパラメータをどのように合わせるか、Beckhoff TwinCAT3側が説明しますので心配しないでください。

#Parameters from Target -> Originator
eeipclient.t_o_instance_id = 0x81
eeipclient.t_o_length = 44
eeipclient.t_o_requested_packet_rate = 100000  #Packet rate 100ms (default 500ms)
eeipclient.t_o_realtime_format = RealTimeFormat.MODELESS
eeipclient.t_o_owner_redundant = False
eeipclient.t_o_variable_length = False
eeipclient.t_o_connection_type = ConnectionType.POINT_TO_POINT

以下は、コンフィギュレーションインスタンスIDを設定するプログラムです。これらのパラメータをどのように合わせるか、Beckhoff TwinCAT3側が説明しますので心配しないでください。

eeipclient.configuration_assembly_instance_id=0x80

Ethernet/IP Adpater(このチュートリアルではBeckhoff TwinCAT3)にforward_openリクエストを送信し、接続を確立します。

eeipclient.forward_open()

RoboDK は非常に優れた Python API を提供しており、RoboDK のデータに簡単にアクセスすることができます。ここでは、API を介して UR ロボットの 6 つの関節の値を取得するリクエストです。

joints=item.Joints().list()
            count=4
            for joint in joints:
                print(count)
                barray=bytearray(struct.pack(“f”, joint))
                eeipclient.o_t_iodata[count]=barray[0]
                eeipclient.o_t_iodata[count+1]=barray[1]
                eeipclient.o_t_iodata[count+2]=barray[2]
                eeipclient.o_t_iodata[count+3]=barray[3]
                count+=4
            print(‘State of the second output byte: {0}’.format(eeipclient.o_t_iodata))
            print(type(eeipclient.o_t_iodata))
            time.sleep(0.1)

例外が発生している間に、forward_closeリクエストとunregisterリクエストをアダプターに送信するようにする必要があるので、Exceptionを書くことを忘れないでください。

except KeyboardInterrupt:
    print(“Keyboard interrupt exception caught”)

forward_close request()とunregister_session()を送信するスクリプトです。

eeipclient.forward_close()
eeipclient.unregister_session()

TwinCAT Side

次はTwinCAT Sideのコンフィギュレーションを行います。

Add Ethernet/IP Adapter

I/O>Devices>Add New Itemで、新しいDeviceを追加します。

EtherNet/IP>EtherNet/IP Adapter[Slave]>Okを選択します。

プロジェクト内にTC3 EIP Adapterが作成されます。

Configure the Adapter

Ethernet/IP Adapterを開き、AdapterタブでSearchボタンを押すと、IPCで使用可能なネットワークアダプターが表示されます。

IPCで使用できるネットワークアダプターが表示されます。

Configure the Task

Sync Taskタブを開き、Special Sync Taskを選択し、Create new I/O Taskを選択します。

新しいタスクの名前を入力します。

IP Address

Ethernet/IPアダプタのデバイスを展開する>Box1(TC EtherNet/IPスレーブ)を開き、Settingsタブから8000:21、8000:22、8000:23でNetwork Settingを行います。

先程RoboDK Sideで紹介したように、ip addressのパラメータはeeipclinet.register_session(”)のMethodと一致させる必要があります。

IPアドレス=192.168.3.240、ネットワークマスク=255.255.255.0を設定しました

Append IO Assembly

Box1を右クリックし、”Append IO Assembly “を選択します。

Ethernet/IP Adapterに新しい Assemblyが作成されました。

Inputs Data

Inputsを右クリックし、Add New Itemを選択します。

データ型としてBYTEを選択し、”Create Array Type”をクリックし配列型の変数を作成します。

0 “を選択して1D 配列を定義し、データ長を0…23を入力します。RoboDK の API を使って実際のロボット関節位置を取得するため、各関節位置は 32ビット(6×4=24 バイト)の値だからです。

ロボット関節位置用のInput Dataが定義されました.

同じ操作でもう1つのInputs Dataを追加します。

データ型としてByteを選択し、”Create Array Type”ボタンを押します。

0 “を選択して1D 配列を定義し、データ長をを0…15で入力します。このチュートリアルでは、入力データの合計サイズが40バイトなので、前のステップでは24バイトのデータが定義されています。ここでは、40-24=16なので、16バイトの配列を定義します。

Done!

Outputs Data

出力データも同様に、出力フィールドを右クリックし、新しいOutput Dataを追加してください。

データ型としてByteを選択し、”Create Array Type”ボタンを押します。

長さ20のByte配列を定義します。

先程と同じ操作で40Bytesを揃えるようにしてください。

Match the Setting between TwinCAT and RoboDK

PythonスクリプトとTwinCATコンフィギュレーションとの間で、設定を一致させるため、Ethernet/IP Boxをクリックし、Settings Tabに移動します。

Parameters from Originator -> Target

o_t_Instance_id

出力インスタンスが、TwinCAT側のインスタンス番号は130でHex = 0x82です。

o_t_length

リアルタイムフォーマットでは4バイトのヘッダがあるため、t_lengthは44となる(ただし、ユーザデータのサイズは合計で40バイトである)。

o_t_requested_packet_rate

RPIがTwinCATのSync Taskのサイクルタイムより大きいことを確認してください。

Parameters from Target -> Originator

t_o_Instance_id

Inputインスタンスの場合、TwinCAT側のInstance番号は、129でHex = 0x82となります。

t_o_length

Modelessの4バイトのヘッダがあるので、t_lengthは44になります。

t_o_requested_packet_rate

RPIがTwinCATのSync Taskのサイクルタイムより大きいことを確認してください。

Add PLC

最後に、TwinCATプロジェクトに新しいPLCを追加する必要があります。PLCを右クリックし、Add New Itemを選択します。

Standard PLC Projectを選び>Addします。

Done!

GVL

Global Variable Listを作成し、 process input/outputの入出力データを定義する。

{attribute ‘qualified_only’}
VAR_GLOBAL
Inputs AT %I* :ARRAY[0..23]OF BYTE;
Outputs AT %Q*:ARRAY[0..19]OF BYTE;
END_VAR

MAIN Program

MEMMOVE関数を使用しRoboDKから受信したデータの一部(関数データ)を一括で実数の配列に転送します。

PROGRAM MAIN
VAR
i:INT;
r32:ARRAY[0..5] OF real;
END_VAR


FOR i :=0 TO 19 DO
GVL.Outputs[i]:=INT_TO_BYTE(i+10);
END_FOR

MEMMOVE(
destAddr:=ADR(r32[0])
,srcAddr:=ADR(GVL.Inputs[0])
,n:=24)

;

Mapping

User programの変数とProcess IO Mappingは忘れずに。

Inputs

Outputs

Visualization 

簡単な画面を作成し軸の座標を表示します。

Result

DevState=0、Ethernet/IP Adapter自体は問題なし。

State=0、 Ethernet/IP slaveにもエラーなし。

ConnState=0、 Scannerと接続してることを示しています。

192.168.3.42はRoboDKがインストールされたPCのIPアドレスです。WiresharkからForward Openのリクエストが送信され、192.168.3.240(TwinCAT3 Ethernet/IP adpater)がSuccessの返信がReturnしました。

Point to Point Data data exchange packages can be found from wireshark.

WiresharkからPoint to Pointのデータ交換Packagesがみえました。

こちらのLinkから動作確認できます。

Footer_Basic

Please Support some devices for my blog

Amazon Gift List

Find ME

Twitter:@3threes2
Email:soup01threes*gmail.com (* to @)
YoutubeChannel:https://www.youtube.com/channel/UCQ3CHGAIXZAbeOC_9mjQiWQ

シェアする

  • このエントリーをはてなブックマークに追加

フォローする