ラズパイ5 +Python+CANopenでモータを回す ③ PythonでSDOの読み出し(仮)caninfo.py
ここでは、CANopenの規格の話題に入る前に、Pythonでモータに関する情報をちょこっと読みます。
CANopenは、
- アプリケーション層のベーシックな規格がCiA 301/302で規定
されています。その上には、用途によって、たくさんの規格が用意されています。この連載ではモータを回すので、
- CiA 401(汎用I/Oモジュール)とCiA 402(モーション・コントロール;サーボ・コントローラ、ステッピング・モータ、周波数インバータ)
これらの規格を利用してアプリケーションを作ります。
これらの規格は、具体的なオブジェクト、例えば、速度、加速度といった項目が用意されていて、オブジェクト・ディクショナリという名称で提供されます。とても詳細なパラメタが用意されているうえ、メーカ独自のパラメタもたくさんあるので、眺めるだけで、気がめいってしまいます。
メーカの用意したコントローラのWebページに、xxx.eds(エレクトロニック・データ・シート。XMLではない)というファイルがダウンロードできるようになっています。このテキスト・ファイルの内容が、オブジェクト・ディクショナリそのものです。メーカの用意したツールにオブジェクト・ディクショナリ・ビューワが提供されていて、位置や速度といったものは最新データを見ることができます。
コントローラBLVD-KRD用のドキュメントは英語版のみで、HP-5143E.pdfです。
Brushless Motor BLV series R type Driver CANopen communication profile
●ID(Identifier:識別子)
プログラミングやツールの利用時に、複数の「ID」が出てきます。物理的に機材を認識するためにNode-ID(ノードID)が使われます。モータに一つのユニークなIDをふって区別します。モータといっても実際は、コントローラBLVDです。購入時、多くの機器では'1'がふられているので、何らかのツールで変更して使います(1~127)。ここで使っているモータはサポート・ソフトのMEXE02で変更できます。モータによっては、コントローラ上のDIPスイッチで変更します。
この連載では、1台目はNode-ID=「12(10進数)」に設定しています。
下の図は、MEXE02の(m13) CANopen通信フレームモニタの画面の一部です。
CAN-IDという欄があります。CAN メッセージの先頭に位置します。SDO(RX)では0x60C、SDO(TX)では0x58Cが記録されています。これは、Node-IDとは違うものです。IXXATのUSB-to_CAN V2 Compactには、canAnalyser3 Miniというユーティリティでは単にIDという表記です。
もし、Node-IDが12でないなら、0x60Cや0x58Cは異なったCAN-IDが使われます。具体的に見ていきましょう。
CAN-IDは11ビットで構成されています。LSBの7ビットはNode-IDです。7ビットあるので、1~127が記入できます。'12'=0xCを書き入れます(メーカの資料で16進数はXXhという表記ですが、pythonのプログラミンをする際は0xXXという16進数表記を使うので、混在している)。
MSBの4ビットはfunctionです。
0 | 0 | 0 | 1 | 1 | 0 | 0 |
functionです。
Communication object (COB) |
詳細 | Code (バイナリ表記) |
---|---|---|
NMT | Network Management (broadcast) |
0000 |
EMCY | Emergency messages | 0001 |
TIME | 0010 | |
PDO1 (tx) (TPDO1) | 0011 | |
PDO1 (rx) (RPDO1) | 0100 | |
PDO2 (tx) (TPDO2) | 0101 | |
PDO2 (rx) (RPDO2) | 0110 | |
PDO3 (tx) (TPDO3) | 0111 | |
PDO3 (rx) (RPDO3) | 1000 | |
PDO4 (tx) (TPDO4) | 1001 | |
PDO4 (rx) (RPDO4) | 1010 | |
SDO (tx) | Parameter | 1011 |
SDO (rx) | Parameter | 1100 |
Guarding | HERTBEAT | 1110 |
SYNC | Synchronization message (broadcast) |
0001 |
NMTの000とSYNCの080は、それ自身がCAN-IDで、Node-IDは使われません |
◆60Cは、 COB-ID (dec) 1548 Function Code (bin) 1100 Node ID (bin) 0001100 Communication Object Receive SDO |
◆58Cは、 COB-ID (dec) 1420 Function Code (bin) 1011 Node ID (bin) 0001100 Communication Object Transmit SDO |
Analog Devices TCML-IDEで表示した具体例です。
●環境
- ハードウェア Raspberry Pi 5(4GBモデル)
- OS Raspberry Pi OS (64ビット)、リリース日December 5th 2023
- ラズパイ環境 Python 3.11.2
- Windows10 22H2にて、ssh(OpenSSH_9.2p1 Debian-2+deb12u2, OpenSSL 3.0.11 19 Sep 2023)および、VNC Viewerを動作させている
- Windows環境 Python 3.10.5
●pythonのライブラリを利用する
ここでは、pythonのcanopenライブラリを使って、オブジェクト・ディクショナリのデータのいくつかを読み取ります。
CANopenでは、各種設定/読み出しを行うために、
- コントローラからの要求によって送受信されるSDO(Service Data Object)を使って通信
- センサ側が自発的、同期的に配信するPDO(Process Data Object)を用いて通信
の2系統があります。SDOでは、設定項目がすべて読み出せます。書き込める項目もあります。PDOでは、登録してある送信と受信のパラメタ、例えば、現在位置、現在のスピードなどが読み出せ、リアルタイムな動作に利用されます。
なぜ2種類あるかというのは、オブジェクト・ディクショナリのオブジェクト数が膨大で、アクセスがポーリングで行うと、とても時間がかかります。MEXE02では、USB経由でポーリングしているので、瞬間に全部のデータを読み出せます。Maxonのツールでは、CANバス経由でポーリングするので、全部読み出すのに分単位かかります。
そこで、常に最新データを見たいものを登録しておくのがPDOという仕組みにした?と思われます。
CANopenは同期通信です。例えば、syncのパラメタに100msを設定しておくと、PDOのパラメタは確実に100msごとに読み出せます。
ここでは、SDOのいくつかの項目を、pythonで読み出します。まだモータを回転するようなレベルのプログラムではありません。
●canopenのインストールと実行<Windows>
赤色の経路でアクセスします。
Windowsのコマンドプロンプトを起動します。canopenライブラリをインストールします。
>pip install canopen
>python -m pip freeze | findstr canopen
canopen==2.2.0
次のプログラムをcaninfo.pyで保存します。
モータのNode-IDは12にサポート・ソフトのMEXE02(後述)で設定しました。デフォルトは1だと思うので、変更しないときは、Node-IDを1でアクセスしてください。複数のモータが同じCANバスにつながるとき、Node-IDは、全部異なる必要があります。
BLVD-KRD_CANopen_V200.edsは、https://www.orientalmotor.co.jp/ja/products/detail?hinmei=BLVD-KRDからダウンロードし、プログラムと同じディレクトリに保存します.
次の記述では、CANのインターフェースにIXXATのUSB-to_CAN V2 Compactを利用したときの記述です。kvaser社であれば、bustype='kvaser'になります。この後のラズパイの場合、このconnectの記述1行だけが異なります。
# Connect to the CAN bus
network.connect(bustype='ixxat', channel=0, bitrate=250000)
以降、edsファイル=オブジェクト・ディクショナリに登録されている値をSDOで読み出しています。indexが0x1018で、subが1にvendor idが登録されています。この1018はCiA 301/302で規定されていて、各社必須なオブジェクトなので、必ず読み出せます。
vendor_id = node.sdo[0x1018][1].raw
この温度はこのコントローラ特有のオブジェクトなので、他社は、別のindexになっていると思われます。
Motor_temp = node.sdo[0x407d].raw
このオブジェクトは、モーションでは必要なので、各社共同じindexになっています。
Target_position = node.sdo[0x607a].raw
import canopen # Start with creating a network representing one CAN bus # Add some nodes with corresponding Object Dictionaries network.check() # Connect to the CAN bus print("\n===start ID=12 OrientalMotor\n") # Disconnect from CAN bus |
実行した様子です。
●canopenのインストールと実行<ラズパイ>
赤色の経路でアクセスします。
アマゾンで購入したCAN HATで使われているmcp2515のデバイス・ドライバを組み込みます。/boot/firmware/config.txtの最後に、root権限で次の1行を追加してrebootします。
dtoverlay=mcp2515-can0,oscillator=12000000,interrupt=25
2023年10月に更新されたラズパイOS bookwormでは、pythonは仮想環境を利用してプログラムを作ります。
python仮想環境 備忘録 仮想環境の作成 python -m venv envtest 有効化 source envtest/bin/activate 無効化 deactivate 初期状態に(いったん deactivate してから) python -m venv --clear envtest
|
envcanという仮想環境を作ります。
yoshi@ras05:~ $ python -m venv envcan
yoshi@ras05:~ $ source envcan/bin/activate
(envcan) yoshi@ras05:~ $ pip install canopen
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting canopen
Using cached https://www.piwheels.org/simple/canopen/canopen-2.2.0-py3-none-any.whl (61 kB)
Collecting python-can>=3.0.0
Using cached https://www.piwheels.org/simple/python-can/python_can-4.3.1-py3-none-any.whl (262 kB)
Collecting wrapt~=1.10
Using cached wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (80 kB)
Collecting packaging>=23.1
Using cached https://www.piwheels.org/simple/packaging/packaging-24.0-py3-none-any.whl (53 kB)
Collecting typing-extensions>=3.10.0.0
Downloading https://www.piwheels.org/simple/typing-extensions/typing_extensions-4.11.0-py3-none-any.whl (34 kB)
Collecting msgpack~=1.0.0
Using cached msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (400 kB)
Installing collected packages: wrapt, typing-extensions, packaging, msgpack, python-can, canopen
Successfully installed canopen-2.2.0 msgpack-1.0.8 packaging-24.0 python-can-4.3.1 typing-extensions-4.11.0 wrapt-1.16.0
(envcan) yoshi@ras05:~ $ pip list
Package Version
----------------- -------
canopen 2.2.0
msgpack 1.0.8
packaging 24.0
pip 23.0.1
python-can 4.3.1
setuptools 66.1.1
typing_extensions 4.11.0
wrapt 1.16.0
次のプログラムをcaninfo.pyの名称で保存しました。
import canopen # Start with creating a network representing one CAN bus # Add some nodes with corresponding Object Dictionaries network.check() # Connect to the CAN bus print("\n=== start ID=12 OrientalMotor ===\n") print("\n #6000 \n") # Disconnect from CAN bus |
実行します。最初に、ip link setコマンドでデバイスcan0の状態をUPに設定します。
(envcan) yoshi@ras05:~ $ sudo ip link set can0 up type can bitrate 1000000
(envcan) yoshi@ras05:~ $ python caninfo.py
=== start ID=12 OrientalMotor ===
vendor_id 702
Manufacturer device name BLVD-KRD
Motor_temp 33.5
#6000
Max torqe 10000
Target position 0
◆デバイス・ドライバの組み込みが正常に行われたかを確認。reboot後。 (envcan) yoshi@ras05:~ $ dmesg | grep mcp251x ◆can0がネットワークデバイスに登録され、起動状態になったかを確認 (envcan) yoshi@ras05:~ $ ip link |
このプログラムは、何らかのエラーが起こったとに実行しても動かない可能性があります。コントローラBLVD-KRDの電源を入れた直後、PWR/SYS LEDが白色で点滅している状態で動かしてください。上記のプログラムの実行後は青色点滅(インフォメーションが発生)です。この状態でも、再度プログラムは正常に動作します。
隣にあるCOMM LEDは、白色の点灯、点滅であればエラーは起こっていません。
SDOの読み出しなどでは、timeoutやそのほかのエラーになる場合がありますが、それらの対応は全くしていません。
本連載は、pythonを利用します。C++でも、同様にプログラムを記述できるようなライブラリは、コントローラBLVD-KRDには用意されていません。けれど、ステータスを読み、コントロール・ワードを設定する関数を作っていけば、実装可能だと思います。
たとえば、MaxonのコントローラEPOS4やKvaser の製品には、そのようなライブラリやAPIが用意されています。
MEXE02は、CANopenのプログラミングに必要なモニタ類、リモート運転、I/Oの入出力信号をテスト画面などが用意されていますが、プログラム自体は記述できないようです。
プロトコルはModbusを利用し、「BLV シリーズ R タイプ 取扱説明書 機能編」に、細かな入出力の設定をして、ダイレクト・データ運転、ストアード・データ運転など、細かな制御方法が解説されています。Modbus自体はデータのフォーマットや通信手順だけの規格なので、CANopenのCiA 402のようなものはないと思われます。したがって、メーカが独自に実装したのかもしれません。
●オブジェクト・ディクショナリ
無料でダウンロードできるサポート・ソフトMEXE02には、オブジェクト・ディクショナリを表示する機能があります。
開くと、index数値の低い項目が見れます。今回読み出したVendor IDが見れますね。
読み出しだけができるもの、読み書きのできるものがあります。
値は、UINT8、UINT16、INT32などの型と取りうる桁数が決まっています。
それぞれの項目には単位がありますが、ここでは表示されていません。
1000番台はCommunication Objectsと呼ばれていて、低めの数値の項目はメーカや機種の情報が書かれています。1400~1a03hがPDOのマッピング・パラメタで各社が使っている共通な領域です。
2000番台、3000番台、もしくはこの機種のように4000番台が、Manufacturer Specific Objectsで、メーカが独自に割り当てている機能のパラメタです。
スクロールしていくと、6000番台、6041hのStatuswordは、今後頻繁に利用します。6064hのPosition actual valueはリアルタイムに更新されるロータリ・エンコーダから得られる現在位置です。モータは動いてはいませんが、分解能が高いので、数字がちらちら変化します。
この6000番台は、モータの運転パラメタが用意されていて、各社ほぼ同じになっています。
次回詳しく説明します。
●資料
<モータ> https://www.orientalmotor.co.jp/ja/products/detail?hinmei=BLVD-KRD
下記の四つのファイルをダウンロードします。
<MEXE02> https://www.orientalmotor.co.jp/ja/products/detail?hinmei=MEXE02
<canopenライブラリ> https://github.com/christiansandberg/canopen