top of page

Serial Servo RTCs (Python)

 手軽に利用できるアクチュエータモジュールである、シリアルサーボを動作させるRTCを作成する方法を解説します。

 

このページでは以下の知識を説明なく使用しますので、各解説ページで使用方法を学んでから読み進めてください。

1. はじめに

 

 今回は、以下のRTCを作成し、シリアルサーボを動作させる方法を学びます。

シリアルサーボには、双葉電子工業製(株)のRSシリーズを用います。

ここでは、1つずつシリアルサーボを動作させるショートパケットに対応します。

 

作成するRTCは以下のようになります。

 

  • RSServoManager

RSシリーズのサーボモータを1つずつ動作させます。

 

  • RSServoMoveConsoleIn

シリアルサーボの角度(位置)と移動時間を指令します。

 

  • RSServoServoConsoleIn

シリアルサーボの保持トルクのON/OFF状態などを指令します。

 

  • RSServoSensorConsoleOut

シリアルサーボのセンサ値をコンソール上に出力します。

 

 

 本解説で想定するシステムは、以下の様になります。

PCからUSB接続の変換器を通して、RSサーボに接続し制御します。

8. おわりに

 

 シリアルサーボを動作させるRTCを作成しました。

専用のデータ型を作成することで、スッキリと通信することが出来ました。

 

複雑なRTCも専用のConsoleIn/Outを作成してその動作を確認できました。

このように、作成したRTCをテストするために、テスト用RTCを用いるのは面倒ですがとても重要です。

複雑なシステムになればなるほど、この手間は最終的には近道となると思います。

 

自分のRTCを作るときには、ぜひ応用してみてください。

 

参考文献

  1. 「RS405CB/RS406CB取扱説明書(ver.1.03)」<http://www.futaba.co.jp/robot/command_type_servos/rs405cb>(2014/02/19アクセス)

3. RSServoManager RTC

 

 RSServoManager RTCを作成します。

 テンプレートを以下に従って設定てください。

 

  • モジュール名 

RSServoManager

  • ベンダ名

あなたの名前

  • モジュールカテゴリ

Hobby

  • 実行周期

1000

  • アクションコールバック

onInitialize
onActivated

onDeactivated
onExecute

  • データポート

・moveポート

ポート名(InPort) move
データ型 RSServo::Move
変数名 move
表示位置 LEFT

・servoポート

ポート名(InPort) servo
データ型 RSServo::Servo
変数名 servo
表示位置 LEFT

・sensorポート

ポート名(OutPort) sensor
データ型 RSServo::Sensor
変数名 sensor
表示位置 RIGHT

  • コンフィギュレーション

・portコンフィギュレーション

名称 port
データ型 string

デフォルト値 COM1
変数名 conf_port

・baudrateコンフィギュレーション

名称 baudrate
データ型 long

デフォルト値 115200

変数名 conf_baudrate

  •   言語 

Python

 

 プロジェクトの設定が終わったら、RSServoManager.pyに以下のコードを記述します。

以下のコードは抜粋となります。生成したテンプレートに当てはめて下さい。

なお、シリアル通信にはPYSERIALが必要です。Windowsを使用している場合はインストールしてください。

Ubuntuではデフォルトで入っていると思います。

 それではソースコードを解説します。

 

  • 1行目

シリアル通信のためにPYSERIALをインポートします。

 

  • 16行目

シリアルオブジェクトをインスタンス化します。

 

  • 20-30行目

シリアルポートをオープンする関数です。

open_port関数は以下のようになります。

 

open_port(ポート名, ボードレート, タイムアウト)

 

  • 21行目

シリアルポートを指定します。

 

  • 22行目

ボーレートを指定します。

 

  • 23行目

タイムアウトを設定します。

タイムアウトの値は以下のようになっています。

None: 読み取れるまで待ちます

0: 非ブロッキングモード(読み取り時にすぐ戻ります)

x: x s待ちます

 

  • 25-30行目

シリアルポートを開きます。

成功した場合は開いたポート番号を、失敗した場合はエラーメッセージを表示します。

 

  • 32-33行目

シリアルポートをクローズじます。

close_port関数は以下のようになります。

 

close_port()

 

  • 35-40行目

シリアルサーボに保持トルクのON/BRAKE/OFF指令を与える関数です。

保持/非保持/ブレーキモードから選択して動作させます。

 

on関数は以下のようになります。

 

void on(シリアルサーボのID, 保持モードのモード)

 

各コマンドやデータの意味は簡単に説明します。

詳しくは、RS405CB/RS406CB取り扱い説明書[1]をご覧ください。

RSシリーズのシリアルサーボには以下のような形式でコマンドを送信します。

 

[Header] [ID] [Flags] [Address] [Length] [Count] [Data] [Sum]

 

Header :パケットの先頭を表します。ここでは0xFA、0xAFとなります。

ID :シリアルサーボのIDです。

Flags : リターンパケットの設定やデータ書き込み時の設定を行います。

Address :メモリーマップ上のアドレスを表します。Lengthに指定した長さのデータをメモリーマップに書き込みます。

Length :データの長さ(byte数)を指定します。

Count :サーボの数を表します。今回は1に設定します。

Sum :チェックサムです。IDからDataまでの各バイトの排他的論理和(XOR)を計算した値を設定します。

 

on関数では、以下のようなバイト列で動作指令を与えます。

 

|0xFA|0xAF|ID|0x01|0x24|0x01|0x01|保持トルクのモード|Sum|

 

 

保持トルクのモードは、0x00で非保持、0x01で保持, 0x02でブレーキとなります。

 

  • 37行目

リストに先ほど説明したコマンドを格納します。

 

  • 38行目

チェックサムを計算し、リストに追加します。

 

  • 40行目

コマンドを出力します。この関数は後ほど説明します。

 

 

  • 42-50行目

シリアルサーボに動作指令を与える関数です。

シリアルサーボの角度(位置)と移動時間を与えて、動作させます。

 

move関数は以下のようになります。

 

move(シリアルサーボのID, 角度, 移動時間)

 

move関数では、以下のようなバイト列で動作指令を与えます。

目標位置と時間は1 byteを超えるため、上位(H)と下位(L)に分けて設定します。

各| |は1 byte単位となります。

 

|0xFA|0xAF|ID|0x01|0x1E|0x04|0x01|目標位置L|目標位置H|時間L|時間H|Sum|

 

  • 44-48行目

リストに先ほど説明したコマンドを格納し、出力します。

位置と時間を上位バイトと下位バイトに分けるには、AND演算とビットシフトを用います。

下位バイトは0x00FFと論理的ANDを取ることで、上位ビットは全て0となり、下位ビットは元の値を残せます。

上位バイトは0xFF00と論理的ANDを取り、上位ビットを残した後に1 byteのサイズに収まるよう8 bitシフトしています。

 

  • 50行目

シリアルサーボが動作している間スリープします。

スリープには以下の関数を使用します。

 

time.sleep(中断の時間 s)

 

  • 53-75行目

シリアルサーボのセンサ値を取得する関数です。

これまでの関数と異なり、シリアルサーボからの返信を受け取ります。

 

get_sensor関数は以下のようになります。

センサ情報構造体とは、IDLで定義したRSServo::Sensorのことです。

 

get_sensor(シリアルサーボのID)

 

  • 55-58行目

コマンドの出力まではこれまでと同様です。

 

  • 60行目

センサ値を読み込みます。

読み込みには以下のメソッドを使用します。

 

read(読み込みバイト数)

 

  • 60-70行目

先ほどまで2 byte以上のデータをエンコードしてコマンドを作成していました。

今度はこれと逆のことをして、センサ値をデコードします。

id以外は2 byteのデータなので、2 byteのデータを復元します。

上位バイトと下位バイトを合わせるには、ビットシフトとOR演算を用います。

上位ビットを8 bitずらし、下位ビットと論理的ORを取ります。

なお、読み込んだセンサ値は8bit文字列になっているので、ord関数を使ってバイトの値に変換しています。

 

もし、値が読み込めていなければ例外をスローします。

 

  • 72-73行目

このサーボモータは-1500から1500の角度をとります。

1500よりも大きい値は二の歩数で表現された負の値でので、変換しています。

実際には1500より大きい値が返されることがあるので、マージンをとって1800より大きい値を変換しています。

 

  • 77-81行目

この関数は他の関数の処理を助けるヘルパー関数です。

 

_calc_checksum(チェックサムを除いたコマンド)

 

チェックサムの計算を行い、値を返します。

 

  • 83-86行目

この関数は他の関数の処理を助けるヘルパー関数です。

 

_write_serial(コマンド)

 

コマンドの出力を行います。

 

  • 84行目

出力バッファをクリアします。

 

  • 85行目

入力バッファをクリアします。

 

  • 86行目

コマンドを出力します。

 

ここからは、上記の関数を使用してRTC本体の挙動をプログラムします。

 

  • 89行目

ポートをオープンします。

引数のポート名とボーレートにはコンフィグレーションを与えます。

このようにすることで、ユーザーの環境に合わせてRTCを外部から操作できます。

このように環境により異なるものにはコンフィグレーションを使用します。

 

  • 94行目

ポートをクローズします。

ポートのクローズには以下の関数を使用します。

 

  • 99-104行目

サーボ指令がある場合は、シリアルサーボに保持トルクのON/BRAKE/OFF指令を与えます。

 

  • 108-128行目

動作指令がある場合は、シリアルサーボに動作指令を与えます。

その後、センサ値を取得しセンサ値ポートから出力します。

 

 以上で、RSServoManagerのコーディングは終了です。

 

今回はコードが長く、大変でしょうが頑張って最後までコーディングしてみて下さい。

RSシリーズ以外のシリアルサーボでも、同様の構造でRTC化できると思います。

ぜひ、お手元のシリアルサーボでお試し下さい。

7. 動作確認

 

 作成したRTCを実行して下さい。

RSServoManagerのポート名とボーレートのコンフィグレーションは必ず変更し、各環境に合うよう設定してください。

その後、各RTCを接続し、Activateします。

 

 まずは、RSServoServoConsoleInにシリアルサーボの保持トルクをOnにします。

ここでは、id: 1、on:1 と入力します。IDはご使用のサーボに合わせて下さい。

ロボコンマガジン
4. RSServoMoveConsoleIn RTC

 

 RSServoMoveConsoleIn RTCを作成します。

 テンプレートを以下に従って設定てください。

 

  • モジュール名 

RSServoMoveConsoleIn

  • ベンダ名

あなたの名前

  • モジュールカテゴリ

Hobby

  • 実行周期

1000

  • アクションコールバック

onInitialize

onExecute

  • データポート

・moveポート

ポート名(OutPort) move
データ型 RSServo::Move
変数名 move
表示位置 RIGHT

  •   言語 

Python

 

 プロジェクトの設定が終わったら、RSServoMoveConsoleIn.pyに以下のコードを記述します。

以下のコードは抜粋となります。生成したテンプレートに当てはめて下さい。

 コードの解説をします。

 

  • 2-10行目

RSServo::Move構造体のメンバを、順にユーザに入力させます。

 

  • 12行目

動作指令ポートから出力します。

 

 以上で、RSServoMoveConsoleInのコーディングは終了です。

 シリアルサーボの保持トルクがOnになったのを確認したら、RSServoMoveConsoleInでシリアルサーボを動かします。

ここでは、id: 1、angle: -450、duration: 200と入力します。IDはご使用のサーボに合わせて下さい。

2. Serial Servo RTCの構成

 

 シリアルサーボを1つずつRTC化するのではなく、シリアルラインをRTC化します。

前述したUSB接続の変換器をRTC化するイメージです。

シリアルサーボをRTC化する方が、一見わかりやすい気もします。

しかし、シリアルラインは1つしかないため、システムから見た場合は、シリアルラインをRTC化するほうが素直です。

 

2.1 Serial Servo RTCのポート構成

 

 Serial Servo RTCは、以下の様なポート構成で作成します。

 

  • 動作指令ポート

シリアルサーボの角度(位置)と移動時間を指令します。

 

  • サーボ指令ポート

シリアルサーボの保持トルクのON/OFF状態などを指令します。

 

  • センサ値ポート

シリアルサーボのセンサ値を出力します。

2.2 ポートのデータ型

 

 シリアルサーボ用のデータ型はRTミドルウェアに標準で定義されていないため、独自データ型を定義します。

RSシリーズのシリアルサーボ用に、以下の3つのデータ型を定義します。

 

  • RSServo::Move型

・tm

タイムスタンプ

・id

シリアルサーボのID

・angle

角度

・duration

移動時間

 

動作指令ポートに使用します。

 

  • RSServo::Servo型

・tm

タイムスタンプ

・id

シリアルサーボのID

・on

トルク保持のON/BRAKE/OFF

 

サーボ指令ポートに使用します。

 

  • RSServo::Sensor型

・tm

タイムスタンプ

・id

シリアルサーボのID

・angle

現在角度

・time

現在時間

・speed

現在スピード

・load

現在負荷

・temperature

現在温度

・voltage

現在電圧

 

センサ値ポートに使用します。

 

 上記の定義を以下のようなIDLファイルに記述します。

適当なテキストエディタで以下のコードを入力し、HobbyRobotDataType.idlファイルに保存してください。

*一部の変数の型が雑誌掲載時と異なりますのでご注意下さい。

 ここで説明するRTCは以下の様な構成で動作を確認しています。

 

  • USB-RS485変換器

Futaba製 RSC-U485

 

  • シリアルサーボ

Futaba製 RS405CB

 

  • 電源スイッチ付きハブ

Futaba製 TB-RV71EH-7.4V/4W

5. RSServoServoConsoleIn RTC

 

 RSServoServoConsoleIn RTCを作成します。

 テンプレートを以下に従って設定てください。

 

  • モジュール名 

RSServoServoConsoleIn

  • ベンダ名

あなたの名前

  • モジュールカテゴリ

Hobby

  • 実行周期

1000

  • アクションコールバック

onInitialize

onExecute

  • データポート

・moveポート

ポート名(OutPort) servo
データ型 RSServo::Servo
変数名 servo
表示位置 RIGHT

  •   言語 

Python

 

 プロジェクトの設定が終わったら、RSServoServoConsoleIn.pyに以下のコードを記述します。

以下のコードは抜粋となります。生成したテンプレートに当てはめて下さい。

 コードの解説をします。

 

  • 2-7行目

RSServo::Servo構造体のメンバを、順にユーザに入力させます。

 

  • 9行目

サーボ指令ポートから出力します。

 

 以上で、RSServoServoConsoleInのコーディングは終了です。

6. RSServoSensorConsoleOut RTC

 

 RSServoSensorConsoleOut RTCを作成します。

 テンプレートを以下に従って設定てください。

 

  • モジュール名 

RSServoSensorConsoleOut

  • ベンダ名

あなたの名前

  • モジュールカテゴリ

Hobby

  • 実行周期

1000

  • アクションコールバック

onInitialize

onExecute

  • データポート

・sensorポート

ポート名(OutPort) sensor
データ型 RSServo::Sensor
変数名 sensor
表示位置 LEFT

  •   言語 

Python

 

 プロジェクトの設定が終わったら、RSServoServoConsoleOut.pyに以下のコードを記述します。

以下のコードは抜粋となります。生成したテンプレートに当てはめて下さい。

 コードの解説をします。

 

  • 3-11行目

センサ値ポートに値を取得した場合、コンソールにRSServo::Sensor構造体のメンバを出力します。

 

 以上で、RSServoSensorConsoleOutのコーディングは終了です。

 最後に、シリアルサーボが動作したのを確認したら、RSServoSensorConsoleOutでセンサ値を確認します。

ここでは、以下のようになりました。

これで、RTCの動作を確認することができました。

bottom of page