目次
1. 概要
「DynamixelforUnity(D4U)」は、Unity3D内で簡単にDynamixelサーボモーター制御を実装するためのアセットです。D4Uは、様々なDynamixelサーボモーターと効率的かつ容易に接続し、制御し、データを読み取るための多くのメソッドを提供します。
具体的には、D4Uは以下の機能セットに焦点を当てています:
- サーボモーターの制御テーブルを自動的に読み込む
- 複数のサーボモーターモデルを同時に制御できる
- シンプルな宣言型のコードでDynamixelサーボモーターを制御できる
- 低レベルのサーボモーターを抽象化し、サーボモーター制御を簡素化するための多くのクラスを提供する
- 複数のモデルの一括制御や単位変換などの高度な機能を有効にする
- Unity3D内での低レベルの通信とサーボモーター制御を提供する(必要な場合)
が可能になります。
そのほかにも複数モデルの一括制御、単位換算など便利な関数が含まれて、ユーザーはUnity3D内から完全にロボット制御コードの記述に集中でき、C#で簡単に統合できるシンプルなコードを使用して、さまざまなアプリケーション、ゲーム、シミュレーション、または他の経験やユースケースに統合できます。これらはUnity3Dを活用します。
対応OS
対応プロトコル
対応Dynamixelモデル
DYNAMIXEL Protocol 2.0に対応するモデル。
- MX-28
- MX-64
- MX-106
- X Series (2X Series included)
- PRO Series
- P Series
2. インストール
利用したいUnityプロジェクトが開かれている状態で、DynamixelForUnity.unitypackageをダブルクリック、もしくは利用したいUnityプロジェクトのProjectウィンドウにドラッグアンドドロップします。
すべて選択された状態でImportしてください。
3. ライセンス購入とアクティベーション
完全な体験を得るためには、HatsuMuv からライセンスを購入する必要があります。ライセンスなしでは、Unityの実行ごとに10回の操作しか行えません。
購入後、以下のフォームへのリンクが提供されます。フォームでは、デバイスIDなどの登録情報を提供する必要があります。デバイスIDは、ライセンスを使用するマシンにD4Uを関連付けるために使用される固有のID番号です。

デバイスIDを生成し、上記のフォームに挿入するには、ツールバーでGet DeviceID for Registrationをクリックします。これにより、デバイスIDが自動的にクリップボードにコピーされ、コンソールウィンドウに表示されます。以下のスクリーンショットに示されている指示に従ってください:

D4Uを購入した後、SN(シリアルナンバー)がメールで送られてきます。D4U内でSNを使用するには、次のようにD4Uの検証メソッドにメールとSNを挿入するか、Unity3DのUI内の「Dynamixel For Unity Component」に挿入してください:

アクティベーションを確認するには、シーンを実行し、コンソールでアクティベーションが正しく行われたかどうかを確認できます。
4. クイックスタート
ここでは、2つのDynamixelサーボモーターの位置の取得および設定をするデモを紹介します。
新規シーンの作成
- 新しいシーンを作成し、HatsuMuv/DynamixelForUnity/Prefabs/DynamixelForUnityをヒエラルキーウィンドウにドラッグアンドドロップします。

- ヒエラルキーメニューでDynamixelForUnityゲームオブジェクトを選択します。

-
インスペクターウィンドウで、DynamixelForUnityコンポーネントに、メールアドレスとSNコードを、デバイス名フィールドには、Dynamixelサーボモーターに接続されたUSBシリアルポートを入力します(ポート名はデバイスマネージャーから取得できます 例:「COM3」)。
-
(オプション)操作するサーボモーターのボーレートを知っている場合は、事前にDynamixelForUnityのインスペクターでボーレートを設定します。分からない場合は空白のままにします。(後に記述するC#スクリプトのDynamixelForUnityのSetUpメソッドにてスキャンされますが、これには時間がかかることがあります)。
-
「コンポーネントの追加」ボタンをクリックし、スクリプト名を任意のもの(今回は「Demo」)と入力します。それから「新しいスクリプト」をクリックします。

- グレーの「Demo」スクリプトをダブルクリックします。しばらくするとVisualStudioが起動されます。

C#スクリプトのコーディング
Visual Studioが起動しtら、以下のように書きます。このコードは、2つのサーボモーターの現在位置をDebug.Logに出力し、その後、それぞれのGoalPositionを1024に設定します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HatsuMuv.DynamixelForUnity.x64;
public class Demo : MonoBehaviour
{
DynamixelForUnity d4u;
void Start()
{
d4u = GetComponent<DynamixelForUnity>();
d4u.ConnectDynamixel();
d4u.SetUp();
d4u.SyncSetDataGroupMultiModels("OperatingMode", new uint[] { 3, 3 });
d4u.SyncSetDataGroupMultiModels("TorqueEnable", new uint[] { 1, 1 });
int[] presentPosition = d4u.SyncGetSignedDataGroupMultiModels("PresentPosition");
Debug.Log("PresentPosition: " + string.Join(", ", presentPosition));
d4u.SyncSetDataGroupMultiModels("GoalPosition", new uint[] { 1024, 1024 });
}
void OnApplicationQuit()
{
uint[] torqueEnableCommand = new uint[] { 0, 0 };
d4u.SyncSetDataGroupMultiModels("TorqueEnable", torqueEnableCommand);
}
}
実行
Unity画面に戻り、再生ボタンをクリックしてください。
サーボモーターの位置はコンソールに表示されます。

5. Script Reference
名前空間は
// 対応するシステム(OS)から以下の名前空間の中から一つを選択してください
HatsuMuv.DynamixelForUnity.x64
HatsuMuv.DynamixelForUnity.x86
から、お客様ののシステムに対応環境から選んでください。
DynamixelForUnity
DynamixelForUnityは宣言的なコードでDynamixelモーターを制御できるよう提供されるクラスです。一つのポートにつき一つのコンポーネントで管理します。IControlTableUserを実装します。
使用の流れ
- ConnectDynamixelでポートを開く。
- (オプション)SetUpもしくはSetIDsForUseで使用するモーターIDとモデル番号を保持する。この手順を踏むことで、データフィールド名だけで命令を送信することや、すべてのモーターへの命令を送信する際に簡潔に書くことができます。
- SetDataなどのメソッドでモーターを制御。OperatingModeなどのEEPROM領域のデータはトルクがOFF状態でないと書き込めないことに注意してください。
- 終了時はOnApplicationQuitもしくはOnDisable内でトルク無効化などの終了処理を行って下さい。DynamixelForUnityはOnDestroyが呼ばれたタイミングで接続されていればDisconnectDynamixelします。
定数
定数 |
値 |
説明 |
PROTOCOL_VERSION |
2 |
DynamixelForUnityはプロトコルバージョン2.0にのみ対応。 |
変数
変数名 |
説明 |
showMessage |
これをtrueにするとDynamixelForUnityのすべての実行ログが Debug.Logに出力される。エラーや警告は影響されない。 |
プロパティ
プロパティ名 |
説明 |
ControlTables |
複数のモデルのcontrolTableを格納したオブジェクト。データフィールド名から命令を送信する関数はこれを参照する。 |
BaudRate |
現在のボーレートを返す。読み取り専用。 |
IDsForUse |
DynamixelForUnityに保持されているID配列。SetUpメソッドで設定される。読み取り専用。 |
ModelNumbers |
Dictionary<byte, int>型。保持されているIDのモーターのモデル番号を表す。SetIDsForUseメソッド、SetUpメソッドで設定される。読み取り専用。 |
ConnectStatus |
モーターとの接続の有無を表す真偽値。読み取り専用。 |
Varification |
ライセンスが認証されているかを表す真偽値。読み取り専用。 |
Verificate
使用前にこのメソッドを実行し、ライセンスを検証してください。
ConnectDynamixel
-
宣言
public bool ConnectDynamixel()
public bool ConnectDynamixel(string deviceName)
public bool ConnectDynamixel(BaudRate baudRate)
public bool ConnectDynamixel(string deviceName, BaudRate baudRate)
-
引数
- string deviceName
- 接続するポート名。ex.)"COM3"
- BaudRate baudRate
- 接続するボーレート。
-
返り値
接続に成功すればtrueを、そうでなければfalseを返す。
-
説明
指定されたボーレートでポートを開き、Dynamixelモーターと接続する。ポートまたはボーレートの指定がなければ、インスペクタで指定された値を用いる。
ScanInBaudRate
-
宣言
public byte[] ScanInBaudRate(BaudRate baudRate, byte[] idsForScan = null)
-
引数
- BaudRate baudRate
- スキャンに用いるボーレート。
- byte[] idsForScan
- スキャンを行う対象のID。特定のIDのモーターだけ探す際に利用する。nullが指定されるとすべてのIDをスキャンする。
-
返り値
利用可能なモーターIDのbyte配列。
-
説明
指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。
-
宣言
public byte[] ScanInBaudRate(BaudRate baudRate, byte minIDsForScan, byte maxIDsForScan)
-
引数
- byte minIDsForScan
- スキャンを行う対象のIDを範囲の下限。(範囲に含む)
- byte maxIDsForScan
- スキャンを行う対象のIDを範囲の上限。(範囲に含む)
-
返り値
利用可能なモーターIDのbyte配列。
-
説明
指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。スキャン対象を範囲で指定することができる。
ScanInBaudRateAsync
-
宣言
public async Task<byte[]> ScanInBaudRateAsync(BaudRate baudRate, byte[] idsForScan = null, CancellationToken cancellationToken = default(CancellationToken))
-
引数
- BaudRate baudRate
- スキャンに用いるボーレート。
- byte[] idsForScan
- スキャンを行う対象のID。特定のIDのモーターだけ探す際に利用する。nullが指定されるとすべてのIDをスキャンする。
- CancellationToken cancellationToken
- 処理をキャンセルするために使用。
-
返り値
利用可能なモーターIDのbyte配列。
-
説明
非同期的に指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。
-
宣言
public async Task<byte[]> ScanInBaudRateAsync(BaudRate baudRate, byte minIDsForScan, byte maxIDsForScan, CancellationToken cancellationToken = default(CancellationToken))
-
引数
- byte minIDsForScan
- スキャンを行う対象のIDを範囲の下限。(範囲に含む)
- byte maxIDsForScan
- スキャンを行う対象のIDを範囲の上限。(範囲に含む)
- CancellationToken cancellationToken
- 処理をキャンセルするために使用。
-
返り値
利用可能なモーターIDのbyte配列。
-
説明
非同期的に指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。スキャン対象を範囲で指定することができる。
Ping
PingGetModelNumber
GetAllModelNumber
-
宣言
public int[] GetAllModelNumber(byte[] ids = null)
-
引数
- byte[] ids
- モデル番号を得る対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
返り値
モデル番号の配列。通信失敗した項目には-1が入れられる。
-
説明
指定された複数のIDにPingを打ち、モデル番号の配列を返す。
SetControlTable
SetUp
-
宣言
public byte[] SetUp(BaudRate? baudRate = null, byte[] idsForScan = null, bool scanAllBaudRateIfNotFound = true)
-
引数
- BaudRate? baudRate
- 最初にスキャンするボーレート。nullが指定されるとInspectorなどであらかじめ設定されたBaudRateが使用される。
- byte[] idsForScan
- セットアップ対象のID。nullが指定されるとすべてのIDを対象にスキャンを実行する。
- bool scanAllBaudRateIfNotFound
- 最初にスキャンしたボーレートでDynamixelモーターが見つからなければすべてのボーレートでスキャンする。
-
返り値
利用可能なモーターIDのbyte配列。
-
説明
ScanInBaudRateメソッドでdynamixelモーターをスキャンし、SetIDsForUseメソッドでスキャンしたIDを使用するモーターとして保持する。
SetUpAsync
-
宣言
public async Task<byte[]> SetUpAsync(BaudRate? baudRate = null, byte[] idsForScan = null, bool scanAllBaudRateIfNotFound = true, CancellationToken cancellationToken = default(CancellationToken))
-
引数
- BaudRate? baudRate
- 最初にスキャンするボーレート。nullが指定されるとInspectorなどであらかじめ設定されたBaudRateが使用される。
- byte[] idsForScan
- セットアップ対象のID。nullが指定されるとすべてのIDを対象にスキャンを実行する。
- bool scanAllBaudRateIfNotFound
- 最初にスキャンしたボーレートでDynamixelモーターが見つからなければすべてのボーレートでスキャンする。
- CancellationToken cancellationToken
- 処理をキャンセルするために使用。
-
返り値
利用可能なモーターIDのbyte配列。
-
説明
非同期的にScanInBaudRateAsyncメソッドでdynamixelモーターをスキャンし、SetIDsForUseメソッドでスキャンしたIDを使用するモーターとして保持する。
SetIDsForUse
モーターIDとモデル番号をDynamixelForUnityに保持させることで、データフィールド名だけで命令を送信することや、すべてのモーターへの命令を送信する際に簡潔に書くことができます。
DisconnectDynamixel
CloseAndReopenPort
RebootDynamixel
FactoryResetDynamixel
-
宣言
public void FactoryResetDynamixel(DynamixelFactoryResetMode mode, byte[] ids = null)
-
引数
- DynamixelFactoryResetMode mode
- すべての値をリセットするか、ID 以外のすべての値をリセットするか、ID とボーレート以外のすべての値をリセットするかを選択する。
- byte[] idsForScan
- 対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
説明
Dynamixelモーターを工場出荷時の状態にリセットする。
SetBaudRate
SetData
-
宣言
public bool SetData(ushort ADDR, ushort LEN, uint data, byte id)
-
引数
- ushort ADDR
- 書き込むデータフィールドのアドレス。モデルのControl Tableを参照。
- ushort LEN
- 書き込むデータフィールドのサイズ。モデルのControl Tableを参照。
- uint data
- 書き込むデータ。
- byte id
- 対象のID。
-
返り値
成功すればtrueを、そうでなければfalseを返す。
-
説明
指定されたIDのDynamixelモーターにデータを書き込む。
データフィールドのアドレスと長さはの各Dynamitelモーターのe-ManualからContorol Tableを確認してください。
-
宣言
public bool SetData(ControlTableAddressInfo addressInfo, uint data, byte id)
-
引数
- ControlTableAddressInfo addressInfo
- Control Tableの各データフィールドのアドレス、長さ、アクセスを持つ構造体。
- uint data
- 書き込むデータ。
- byte id
- 対象のID。
-
返り値
成功すればtrueを、そうでなければfalseを返す。
-
説明
SetData(ushort ADDR, ushort LEN, uint data, byte id)を使用して、指定されたIDのDynamixelモーターにデータを書き込む。データフィールドが読み取り専用であれば実行されない。
-
宣言
public bool SetData(string dataName, uint data, byte id)
-
引数
- string dataName
- Control Tableのデータフィールド名
- uint data
- 書き込むデータ。
- byte id
- 対象のID。
-
返り値
成功すればtrueを、そうでなければfalseを返す。
-
説明
SetData(ushort ADDR, ushort LEN, uint data, byte id)を使用して、指定されたIDのDynamixelモーターにデータを書き込む。データフィールドが読み取り専用であれば実行されない。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SetSignedData
-
宣言
public bool SetSignedData(ushort ADDR, ushort LEN, uint data, byte id)
public bool SetSignedData(ControlTableAddressInfo addressInfo, int data, byte id)
public bool SetSignedData(string dataName, int data, byte id)
-
説明
指定されたIDのDynamixelモーターに符号付きデータを書き込む。SetDataの説明を参照してください。
GetData
-
宣言
public uint GetData(ushort ADDR, ushort LEN, byte id)
-
引数
- ushort ADDR
- 書き換えるデータフィールドのアドレス。モデルのControl Tableを参照。
- ushort LEN
- 書き換えるデータフィールドのサイズ。モデルのControl Tableを参照。
- byte id
- 対象のID。
-
返り値
読み取ったデータ。エラーが発生した場合0を返す。
-
説明
指定されたIDのDynamixelモーターのデータを読み取る。
データフィールドのアドレスと長さはの各Dynamitelモーターのe-ManualからContorol Tableを確認してください。
-
宣言
public uint GetData(ControlTableAddressInfo addressInfo, byte id)
-
引数
- ControlTableAddressInfo addressInfo
- Control Tableの各データフィールドのアドレス、長さ、アクセスを含む構造体。
- byte id
- 対象のID。
-
返り値
読み取ったデータ。エラーが発生した場合0を返す。
-
説明
GetData(ushort ADDR, ushort LEN, byte id)を使用して、指定されたIDのDynamixelモーターのデータを読み取る。
-
宣言
public uint GetData(string dataName, byte id)
-
引数
- string dataName
- Control Tableのデータフィールド名
- byte id
- 対象のID。
-
返り値
読み取ったデータ。エラーが発生した場合0を返す。
-
説明
GetData(ushort ADDR, ushort LEN, byte id)を使用して、指定されたIDのDynamixelモーターのデータを読み取る。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
GetSignedData
-
宣言
public int GetSignedData(ushort ADDR, ushort LEN, byte id)
public int GetSignedData(ControlTableAddressInfo addressInfo, byte id)
public int GetSignedData(string dataName, byte id)
-
説明
指定されたIDのDynamixelモーターの符号付きデータを読み取る。GetDataの説明を参照してください。
SyncSetDataGroup
-
宣言
public bool SyncSetDataGroup(ushort ADDR, ushort LEN, uint[] data, byte[] ids = null)
public bool SyncSetDataGroup(ControlTableAddressInfo addressInfo, uint[] data, byte[] ids = null)
-
引数
- ushort ADDR
- 書き換えるデータフィールドのアドレス。モデルのControl Tableを参照。
- ushort LEN
- 書き換えるデータフィールドのサイズ。モデルのControl Tableを参照。
- ControlTableAddressInfo addressInfo
- Control Tableの各データフィールドのアドレス、長さ、アクセスを含む構造体。
- uint[] data
- 書き込むデータ配列。
- byte[] ids = null
- 対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
返り値
成功すればtrueを、そうでなければfalseを返す。
-
説明
GroupSyncWrite用いて複数モーターに同時にデータを書き込む。
SyncSetDataGroupMultiModels
-
宣言
public bool SyncSetDataGroupMultiModels(string dataName, uint[] data, byte[] ids = null)
-
説明
GroupSyncWrite用いて複数モーターに同時にデータを書き込む。データフィールド名が同一であれば、異なるアドレスでも送信する。その場合、ユニークなアドレス毎にSyncSetDataGroupを呼び出す。SyncSetDataGroupの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SyncSetSignedDataGroup
-
宣言
public bool SyncSetSignedDataGroup(ushort ADDR, ushort LEN, int[] data, byte[] ids = null)
public bool SyncSetSignedDataGroup(ControlTableAddressInfo addressInfo, int[] data, byte[] ids = null)
-
説明
GroupSyncWrite用いて複数モーターに同時に符号付きデータを書き込む。SyncSetDataGroupの説明を参照してください。
SyncSetSignedDataGroupMultiModels
-
宣言
public bool SyncSetSignedDataGroupMultiModels(string dataName, int[] data, byte[] ids = null)
-
説明
GroupSyncWrite用いて複数モーターに同時に符号付きデータを書き込む。SyncSetDataGroupMultiModelsの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SyncGetDataGroup
-
宣言
public uint[] SyncGetDataGroup(ushort ADDR, ushort LEN, byte[] ids = null)
public uint[] SyncGetDataGroup(ControlTableAddressInfo addressInfo, byte[] ids = null)
-
引数
- ushort ADDR
- 読み取るデータフィールドのアドレス。モデルのControl Tableを参照。
- ushort LEN
- 読み取るデータフィールドのサイズ。モデルのControl Tableを参照。
- ControlTableAddressInfo addressInfo
- Control Tableの各データフィールドのアドレス、長さ、アクセスを含む構造体。
- byte[] ids = null
- 対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
返り値
読み取ったデータ配列。
-
説明
GroupSyncRead用いて複数モーターから同時にデータを読み取る。
SyncGetDataGroupMultiModels
-
宣言
public uint[] SyncGetDataGroupMultiModels(string dataName, byte[] ids = null)
-
説明
GroupSyncReadを用いて複数モーターに同時にデータを読み取る。データフィールド名が同一であれば、異なるアドレスでも送信する。その場合、ユニークなアドレス毎にSyncSetDataGroupを呼び出す。SyncGetDataGroupの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SyncGetSignedDataGroup
-
宣言
public int[] SyncGetSignedDataGroup(ushort ADDR, ushort LEN, byte[] ids = null)
public int[] SyncGetSignedDataGroup(ControlTableAddressInfo addressInfo, byte[] ids = null)
-
説明
GroupSyncReadを用いて複数モーターに同時に符号付きデータを読み取る。SyncGetDataGroupの説明を参照してください。
SyncGetSignedDataGroupMultiModels
-
宣言
public int[] SyncGetSignedDataGroupMultiModels(string dataName, byte[] ids = null)
-
説明
GroupSyncReadを用いて複数モーターに同時に符号付きデータを読み取る。SyncGetDataGroupMultiModelsの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
BulkSetDataGroup
-
宣言
public BulkWritePacket BulkSetDataGroup()
-
返り値
BulkWritePacketオブジェクト。
-
説明
GroupBulkWriteを用いて複数モーターに一括でデータを書き込むためのBulkWritePacketオブジェクトを返す。
GroupBulkWriteを行うにはBulkWritePacketを媒介するメソッドチェーンで記述します。
BulkGetDataGroup
-
宣言
public BulkReadPacket BulkGetDataGroup()
-
返り値
BulkReadPacketオブジェクト。
-
説明
GroupBulkReadを用いて複数モーターに一括でデータを読み取るためのBulkReadPacketオブジェクトを返す。
GroupBulkReadを行うにはBulkReadPacketを媒介するメソッドチェーンで記述します。
コントロールテーブルの使用方法
各Dynamixelサーボモーターのコントロールテーブルを表すテキストファイルを作成しました。コントロールテーブルは、各プロパティ名を対応するサーボモーターモデル内のレジスタ番号にマッピングしています。
これらのコントロールテーブルは、ROBOTIS e-Manualにあるサーボモーターのコントロールテーブルに対応しています。
以下の場所でコントロールテーブルのデータを確認できます: HatsuMuv/DynamixelForUnity/Resources/ControlTables/。
スクリーンショットのように、対応するサーボモーターを見つけてください:

これらのコントロールテーブルは、D4Uのさまざまなメソッドのパラメータとして使用できます。パラメータ名を文字列として渡すことで、さまざまなサーボモーターの制御やフィードバックを行うことができます。
例:
// 以下のメソッドでコントロールテーブルのパラメータを読み取るためにコントロールテーブルのパラメータを渡すことができます。ここで、コントロールテーブルのパラメータは設定/読み取りする必要のあるレジスタの文字列表現に対応します。
// この例では、SyncGetDataGroupMultiModelsメソッドを使用してデータを一括で設定しています。
SyncGetDataGroupMultiModels("GoalPosition");
BulkWritePacketの使用方法
Bulk Writeコマンドの実行には、次の手順が含まれます:
- Bulk Writeパラメータを保持するための構造体を初期化する。
- 構造体にパラメータを追加する。
- Bulk Writeコマンドを送信する。
- (オプション)コマンドの実行結果を読み取る。
上記の4つのステップを実行するために、BulkWritePacketオブジェクトが使用されます。以下で説明されているように、そのプロパティを設定し、メソッドを呼び出すことでこれらの手順を実行できます。
ステップ1. 構造体の初期化
書き込みパケットのパラメータを保持するための構造体を初期化するために、まず関連するBulkWritePacketオブジェクトを宣言して初期化する必要があります。以下のように行います:
BulkWritePacket writePacket = dynamixelForUnity.BulkSetDataGroup();
ステップ2. パラメータの追加
BulkWritePacketオブジェクトを作成すると、書き込むデータはパラメータとして作成したオブジェクトに追加する必要があります。以下のように行います:
writePacket.AddParam(addressInfo1, idArray1, data1);
writePacket.AddParam(addressInfo2, idArray2, data2);
writePacket.AddParam(addressInfo3, idArray3, data3);
ステップ3. バルクライトコマンドの送信
パラメータを追加したら、BulkWritePacketオブジェクトのSend()メソッドを呼び出すことでコマンドを実行できます。以下のように行います:
writePacket.Send();
ステップ4. (オプション)BulkWriteコマンドの実行結果の確認
コマンドのステータスを確認することもできます。コマンドが正常に実行されたかどうかを確認するために、プロパティ「AllSuccess」をチェックできます。これはコマンドが成功した場合にtrueに設定されます。
Csharp!
if(writePacket.AllSuccess)
Debug.Log("成功");
また、コマンドが成功したかどうかを確認するために、BulkPacketオブジェクト自体を’if’条件文内に直接配置することもできます。
if(writePacket)
Debug.Log("成功");
全体的に、以下のようにして効率的に4つのステップを1行で実行できます:
if(dynamixelForUnity
.BulkSetDataGroup()
.AddParam(addressInfo1, idArray1, data1)
.AddParam(addressInfo2, idArray2, data2)
.AddParam(addressInfo3, idArray3, data3)
.Send())
Debug.Log("成功");
GroupBulkWriteを用いて複数モーターに一括でデータを書き込むためのオブジェクト。BulkWritePacketを媒介するメソッドチェーンで記述する。
例
dynamixelForUnity.BulkSetDataGroup()
.AddParam(addressInfo1, idArray1, data1)
.AddParam(addressInfo2, idArray2, data2)
.Send();
プロパティ
プロパティ名 |
説明 |
IDParamPair |
Dictionary<byte, ParamInfo>型。各IDと書き込むデータフィールドの情報を保持。ParamInfoはアドレス、長さ、成功したか、送信するデータを保持する。読み取り専用。 |
AllSuccess |
全てのパラメータの通信が成功したかを表す真偽値。読み取り専用。 |
HasSent |
コマンドが送信されたかを表す真偽値。読み取り専用。 |
AddParam
-
宣言
public BulkWritePacket AddParam(ushort ADDR, ushort LEN, uint[] data, byte[] ids = null)
-
引数
- ushort ADDR
- 書き込むデータフィールドのアドレス。モデルのControl Tableを参照。
- ushort LEN
- 書き込むデータフィールドのサイズ。モデルのControl Tableを参照。
- uint[] data
- 書き込むデータ。
- byte[] id
- 対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
返り値
自身。
-
説明
書き込むデータフィールドの情報とデータをIDParamPairに格納する。
-
宣言
public BulkWritePacket AddParam(ControlTableAddressInfo addressInfo, uint[] data, byte[] ids = null)
-
引数
- ControlTableAddressInfo addressInfo
- Control Tableの各データフィールドのアドレス、長さ、アクセスを含む構造体。
- uint[] data
- 書き込むデータ。
- byte[] id
- 対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
返り値
自身。
-
説明
AddParam(ushort ADDR, ushort LEN, uint[] data, byte[] ids = null)を使用して書き込むデータフィールドの情報とデータをIDParamPairに格納する。データフィールドが読み取り専用であれば実行されない。
AddParamSigned
-
宣言
public BulkWritePacket AddParamSigned(ushort ADDR, ushort LEN, int[] data, byte[] ids = null)
public BulkWritePacket AddParamSigned(ControlTableAddressInfo addressInfo, int[] data, byte[] ids = null)
-
説明
書き込むデータフィールドの情報と符号付きデータをIDParamPairに格納する。AddParamの説明を参照してください。
Send
ResetStatus
BulkReadPacketの使用方法
bulk readの実行には以下のステップが含まれます:
- bulk readのパラメータを保持するための構造体を初期化します。
- 構造体にパラメータを追加します。
- bulk readコマンドを送信します。
- (オプション)コマンドの実行結果を読み取ります。
- サーボモーターからの返された値を読み取ります。
上記の4つのステップを実行するためには、BulkReadPacketオブジェクトを使用してそのプロパティを設定し、下記で説明するようにメソッドを呼び出す必要があります。
ステップ1. 構造体の初期化
読み取りパケットのパラメータを保持するための構造体を初期化するには、まず関連するBulkReadPacketオブジェクトを次のように宣言して初期化します:
BulkReadPacket readPacket = dynamixelForUnity.BulkGetDataGroup();
ステップ2. パラメータの追加
BulkReadPacketオブジェクトを作成したら、読み取るデータをオブジェクトにパラメータとして追加する必要があります。以下のように行えます:
readPacket.AddParam(addressInfo1, idArray1);
readPacket.AddParam(addressInfo2, idArray2);
readPacket.AddParam(addressInfo3, idArray3);
ステップ3. バルクリードコマンドの送信
パラメータを追加したら、BulkReadPacketオブジェクトのSend()メソッドを呼び出すことでコマンドを実行できます:
readPacket.Send();
ステップ4. (オプション)バルクリードコマンド実行の結果の確認
コマンドのステータス、つまり正常に実行されたかどうかをオプションで確認できます。プロパティ"AllSuccess"をチェックすることで、コマンドが正常に実行された場合にtrueに設定されます。
if(readPacket.AllSuccess)
Debug.Log("成功");
代わりに、直接BulkPacketオブジェクトを「if」条件式に配置して、コマンドが成功したかどうかを確認することもできます。
if(readPacket)
Debug.Log("成功");
ステップ5. サーボモーターからの返された値の読み取り
バルクリードコマンドを実行した後にサーボモーターから読み取ったデータを読むには、BulkReadPacketのGetData()メソッドを以下のように使用します:
uint[] data = readPacket.GetData();
全体的に、以下のようにしてステップを実行し、結果を表示できます:
例:
if(var readPacket = dynamixelForUnity
.BulkGetDataGroup()
.AddParam(addressInfo1, idArray1)
.AddParam(addressInfo2, idArray2)
.AddParam(addressInfo3, idArray3)
.Send())
{
Debug.Log("成功");
uint[] data = readPacket.GetData();
Debug.Log("データ:" + string.Join(", ", data));
}
プロパティ
プロパティ名 |
説明 |
IDParamPair |
Dictionary<byte, ParamInfo>型。各IDと読み取るデータフィールドの情報を持つ。ParamInfoはアドレス、長さ、成功したか、読み取ったデータを持つ。読み取り専用。 |
AllSuccess |
全てのパラメータの通信が成功したかを表す真偽値。読み取り専用。 |
HasSent |
コマンドが送信されたかを表す真偽値。読み取り専用。 |
AddParam
-
宣言
public BulkReadPacket AddParam(ushort ADDR, ushort LEN, byte[] ids = null)
-
引数
- ushort ADDR
- 読み取るデータフィールドのアドレス。モデルのControl Tableを参照。
- ushort LEN
- 読み取るデータフィールドのサイズ。モデルのControl Tableを参照。
- byte[] id
- 対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
返り値
自身。
-
説明
読み取るデータフィールドの情報とデータをIDParamPairに格納する。
-
宣言
public BulkReadPacket AddParam(ControlTableAddressInfo addressInfo, byte[] ids = null)
-
引数
- ControlTableAddressInfo addressInfo
- Control Tableの各データフィールドのアドレス、長さ、アクセスを含む構造体。
- byte[] id
- 対象のID。nullが指定されるとDynamixelForUnityに保持されているIDが対象になる。
-
返り値
自身。
-
説明
AddParam(ushort ADDR, ushort LEN, byte[] ids = null)を使用して読み取るデータフィールドの情報をIDParamPairに格納する。
Send
GetData
GetSignedData
ResetStatus
ParamInfo
BulkWritePacket、BulkReadPacketでデータフィールドを表すクラス。
変数
変数名 |
説明 |
address |
データのアドレス。 |
length |
データの長さ。 |
isSuccess |
通信に成功したかどうか |
data |
BulkWritePacketでは書き込むデータ。BulkReadPacketでは読み取ったデータ。 |
ControlTables
各モーターのControl Tableを格納するクラス。Control Tableは指定された形式で書かれたテキストをコンストラクタの引数に入れることで初期化します。コンストラクタはstring[]かTextAsset[]のどちらかを引数に取ります。
DynamxielForUnity対応モデルのControl TableのテキストファイルがAssets/HatsuMuv/DynamixelForUnity/Resources/ControlTablesに配置されています。
使用例はControlTableInjectorFromResourcesを参照してください。
ControlTablesは初期化時に利用するモーターのControlTableを。
1行目はモデル名とモデル番号を":“を挟んで記述します。
そのほかの行はデータ名、アドレス、長さ、アクセスを記述します。アクセスは読み取り専用ならば"R”、書き込みも可能であるなら"RW"を指定します。
"#“や”//"で開始される行はコメントとして無視されます。
<モデル名>:<モデル番号>
<データ名>, <アドレス>, <長さ>, <アクセス>
<データ名>, <アドレス>, <長さ>, <アクセス>
...
プロパティ
プロパティ名 |
説明 |
ModelNames |
モデル番号に対応するモデル名を表すDictionary<int, string> 型。 |
-
宣言
public ControlTableAddressInfo GetAddrssInfo(int modelNumber, string dataName)
public ControlTableAddressInfo this[int modelNumber, string dataName]
-
引数
- int modelNumber
- モデル番号。
- string dataName
- データ名。
-
返り値
データフィールドの情報を表すControlTableAddressInfo型。
-
説明
指定したモデル番号とデータ名からデータフィールドの情報を表すControlTableAddressInfo型を返す。
インデクサー[int modelNubmer, string dataName]でも同様の結果を得られる。
GetControlTable
-
宣言
public Dictionary<string, ControlTableAddressInfo> GetControlTable(int modelNumber)
public Dictionary<string, ControlTableAddressInfo> this[int modelNumber]
-
引数
- int modelNumber
- 対象のモデル番号。
-
返り値
コントロールテーブルを表すDictionary<string, ControlTableAddressInfo>型。
-
説明
指定されたモデル番号からコントロールテーブルを表すDictionary<string, ControlTableAddressInfo>型を返す。
インデクサー[int modelNubmer]でも同様の結果を得られる。
Contains
-
宣言
public bool Contains(int modelNumber)
-
引数
- int modelNubmer
- 調べるモデル番号。
-
返り値
指定されたモデル番号のControl Tableが存在すればtrue、そうでなければfalseを返す。
-
説明
指定したモデル番号のControl Tableが存在するかを返す。
-
宣言
public bool Contains(int modelNumber, string dataName)
-
引数
- int modelNubmer
- 調べるモデル番号。
- string dataName
- 調べるデータ名。
-
返り値
指定されたモデル番号のControl Tableが存在し、かつ指定されたデータ名のデータフィールドが存在すればtrueを、そうでなければfalseを返す。
-
説明
指定したモデル番号のデータ名のデータフィールドが存在するかを返す。
GetModelsContains
-
宣言
public int[] GetModelsContains(string dataName)
-
引数
- string dataName
- 調べるデータ名。
-
返り値
指定されたデータ名のデータフィールドをControl Tableに持つモデル番号の配列。
-
説明
指定されたデータ名のデータフィールドをControl Tableに持つモデル番号の配列を返す。
ControlTableAddressInfo
Control Tableにおけるデータフィールドの情報を表す構造体。
変数
変数名 |
説明 |
address |
データのアドレス。 |
length |
データの長さ。 |
readWrite |
書き込み可能ならtrue、読み取り専用ならばfalse。 |
IControlTableUser
コントロールテーブルを注入するインターフェース。DynamixelForUnityが実装します。
SetControlTables
- 宣言
public void SetControlTables(ControlTables controlTables)
Core
Dynamixel SDK互換のクラス。コンストラクタにHatsuVerifオブジェクトを入れインスタンスを生成してください。
6.Example Sceneの解説
HatsuMuv/DynamixelForUnity/Example/ExampleScene_x64.unity はDynamixelForUnityを用いたGUIアプリケーションのサンプルです。
このシーンには、DynamixelForUnityを使用してDynamixelサーボモーターと接続、サーボモーターのスキャン、サーボモーターの制御、サーボモーターから読み取ったさまざまな情報のGUIへの表示を行う、サンプルのグラフィカルユーザーインターフェース(GUI)アプリケーションが含まれています。
画面の解説

- ヒエラルキーメニューでDynamixelForUnityゲームオブジェクトを選択します。

-
インスペクターウィンドウで、DynamixelForUnityコンポーネントに、メールアドレスとSNコードを、デバイス名フィールドには、Dynamixelサーボモーターに接続されたUSBシリアルポートを入力します(ポート名はデバイスマネージャーから取得できます 例:「COM3」)。
-
(オプション)操作するサーボモーターのボーレートを知っている場合は、事前にDynamixelForUnityのインスペクターでボーレートを設定します。分からない場合は空白のままにします。(後に記述するC#スクリプトのDynamixelForUnityのSetUpメソッドにてスキャンされますが、これには時間がかかることがあります)。
DynamixelForUnityのコンポーネントの設定が完了したら、再生ボタンをクリックしてください。DynamixelForUnityは自動的に指定されたポートを開き、利用可能なサーボモーターに接続します。

画面には接続されたDynamixelサーボモーターの一覧が表示されます。接続されたボーレートは画面の上部に表示されます。
画面下部の読み取り専用のデータ項目は常に更新されています(現在位置など)。
その他の項目は、接続時とデータが入力された場合に更新されます(例えば、サーボモーターの新しい位置を設定する場合など)。
ヒント: 実際の値と異なる場合は、データを再取得するためにリフレッシュボタンを押してください。
実装の解説
D4UExampleController
Start()
private async void Start()
{
NeedWait = true;
if (d4u == null)
{
Debug.LogError("[DynamixelForUnitySample] DynamixelForUnity is not assigned!");
return;
}
d4u.Varificate(new DevTest.HatsuVarif(licenceFilePath: "some", userID: "some", email: "example@sample.com", phonenumber: "123456789"));
cancellationTokenSource = new CancellationTokenSource();
var connectResult = await Task.Run(() => InitializeDynamixel(cancellationTokenSource.Token));
if (connectResult) StartMotorMetrics();
NeedWait = false;
}
NeedWaitプロパティは画面ロードアニメーションを再生するために外部から参照されています。
DynamixelForUnity d4uはInspectorから代入されることを期待しています。
d4u.Varificateメソッドを用いてライセンスの認証を行ってください。
cancellationTokenSourceは非同期タスクを中断するために作成します。
モーターに接続し初期化をするメソッドInitializeDynamixelを非同期で実行しこれを待ち受けます。
InitializeDynamixelによってDynamixelモーターを接続できたならばStartMotorMetricsmメソッドによってモーターの状態を連続して計測し続けるループが開始されます。
InitializeDynamixel(CancellationToken ct)
private async Task<bool> InitializeDynamixel(CancellationToken ct)
{
if (d4u == null)
{
Debug.LogError("[DynamixelForUnitySample] DynamixelForUnity is not assigned!");
return false;
}
if (!d4u.ConnectStatus)
{
var connectResult = d4u.ConnectDynamixel();
if (!connectResult)
{
Debug.LogError("[DynamixelForUnitySample] Dynamixel is not connected. Connect it first.");
return false;
}
await d4u.SetUpAsync(cancellationToken:ct);
}
motors = new List<DynamixelMotor>();
ids = d4u.IDsForUse;
if (ids.Length == 0) return false;
await GetAllMotorProperty(ct);
return true;
}
d4u.ConnectDynamixelメソッドでモーターと接続します。引数にポート名、ボーレートを指定することもできます。その場合Inspectorで入力された値は無視されます。
SetUpAsyncメソッドは二つのメソッドを呼んで、モーターのスキャンと見つかったIDの保持を一括で行います。
- ScanInBaudRateAsyncメソッドを呼んで指定されたポート名、ボーレートでDynamixelモーターをスキャンします。モーターが見つからなかった場合、すべてのボーレートでスキャンを再実行し、最初にモーターが見つかったボーレートにポートを設定します。
- SetIDsForUseメソッドを呼んで見つかったモーターのIDとモデル番号を保持します。
モーターIDとモデル番号をDynamixelForUnityに保持させることで、データフィールド名だけで命令を送信できる、一部の関数ですべてのモーターへの命令を送信する際に簡潔に書くことができる、などの恩恵があります。
ExampleSceneを作る上で、モーターの情報を扱う際にDynamixelMotorクラスを実装しています。あなたの作成するアプリケーションに応じてプロパティを追加してください。
GetAllMotorPropertyメソッドによってすべてのモーターのプロパティを取得し、DynamixelMotorインスタンスを作成します。
GetAllMotorProperty(CancellationToken ct)
private async Task GetAllMotorProperty(CancellationToken ct)
{
OperatingMode[] operatingModes =
await Task.Run(() =>
d4u.SyncGetDataGroupMultiModels("OperatingMode")
.Select(d => (OperatingMode)d)
.ToArray(),
ct);
float[] homingOffsets = await Task.Run(() => d4u.SyncGetSignedDataGroupMultiModels("HomingOffset").ToActualNumber(UNIT.POSITION).ToFloatArray(), ct);
...
for (int i = 0; i < ids.Length; i++)
{
DynamixelMotor m;
if (motors.Count < i + 1)
{
m = new DynamixelMotor(ids[i]);
motors.Add(m);
}
else
{
m = motors[i];
}
m.OperatingMode = operatingModes[i];
m.HomingOffset = homingOffsets[i];
...
}
}
DynamixelMotorクラスの一つ一つのプロパティについてSyncGetSignedDataGroupMultiModelsメソッドで取得しています。一つのプロパティを例に挙げて説明します。
float[] homingOffsets =
await Task.Run(
() => d4u.SyncGetSignedDataGroupMultiModels("HomingOffset")
.ToActualNumber(UNIT.POSITION)
.ToFloatArray(),
ct
);
homingOffsetsを初期化する行にわかりやすく改行を入れたものです。
2行目のTask.Runメソッドは第一引数の関数を別スレッドで非同期に実行するものです。
3行目からは別スレッドで実行したい関数です。
d4u.SyncGetSignedDataGroupMultiModels(“HomingOffset”)はDynamixelForUnityに保持されているすべてのモーターに対して"HomingOffset"というデータフィールドの値を取得します。
.ToActualNumber(UNIT.POSITION)はSyncGetSignedDataGroupMultiModelsから得られた生のデータに単位を適用します。UNIT.POSITIONは定数です。
.ToFloatArray()はdouble[]をfloat[]に変換します。
MotorMetricsはGetAllMotorPropertyからいくつかのデータをそぎ落とした同様のメソッドです。
StartMotorMetrics()
MotorMetricsLoop(CancellationToken ct)
StopMotorMetrics()
private void StartMotorMetrics()
{
if (!d4u.ConnectStatus)
return;
cancellationTokenSource = cancellationTokenSource ?? new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
metricsLoop = MotorMetricsLoop(cancellationToken);
}
private async Task MotorMetricsLoop(CancellationToken ct)
{
while (true)
{
if (ct.IsCancellationRequested)
return;
Debug.Log("[SampleController] Metrics");
try
{
await MotorMetrics(ct);
}
catch (OperationCanceledException)
{
Debug.Log("[SampleController] Metrics canceled");
return;
}
catch (Exception e)
{
Debug.LogError(e);
return;
}
}
}
private async Task StopMotorMetrics()
{
if (cancellationTokenSource != null && !cancellationTokenSource.IsCancellationRequested)
{
cancellationTokenSource.Cancel();
cancellationTokenSource.Dispose();
cancellationTokenSource = null;
if(metricsLoop != null)
await metricsLoop;
}
}
連続的にモーターのデータを計測し続けるループを実行するメソッド群です。MotorMetricsLoopはCancellationTokenによってキャンセルされるまでMotorMetricsを呼び出し続けます。
StopMotorMetricsはMotorMetricsをキャンセルし、処理が終了するまで待ち受けます。
D4UExampleUI
UI要素の生成を行います。
D4UExampleControllerからモーター毎のパネルを生成し、それらのデータを更新させます。
D4UExampleUIElement
各パネルのフィールドを直接コントロールしている。UI要素から入力を受けるとD4UExampleContorllerに値を渡す。
目次
1. 概要
「DynamixelforUnity(D4U)」は、Unity3D内で簡単にDynamixelサーボモーター制御を実装するためのアセットです。D4Uは、様々なDynamixelサーボモーターと効率的かつ容易に接続し、制御し、データを読み取るための多くのメソッドを提供します。
具体的には、D4Uは以下の機能セットに焦点を当てています:
が可能になります。
そのほかにも複数モデルの一括制御、単位換算など便利な関数が含まれて、ユーザーはUnity3D内から完全にロボット制御コードの記述に集中でき、C#で簡単に統合できるシンプルなコードを使用して、さまざまなアプリケーション、ゲーム、シミュレーション、または他の経験やユースケースに統合できます。これらはUnity3Dを活用します。
対応OS
対応プロトコル
対応Dynamixelモデル
DYNAMIXEL Protocol 2.0に対応するモデル。
2. インストール
利用したいUnityプロジェクトが開かれている状態で、DynamixelForUnity.unitypackageをダブルクリック、もしくは利用したいUnityプロジェクトのProjectウィンドウにドラッグアンドドロップします。
すべて選択された状態でImportしてください。
3. ライセンス購入とアクティベーション
完全な体験を得るためには、HatsuMuv からライセンスを購入する必要があります。ライセンスなしでは、Unityの実行ごとに10回の操作しか行えません。
購入後、以下のフォームへのリンクが提供されます。フォームでは、デバイスIDなどの登録情報を提供する必要があります。デバイスIDは、ライセンスを使用するマシンにD4Uを関連付けるために使用される固有のID番号です。

デバイスIDを生成し、上記のフォームに挿入するには、ツールバーでGet DeviceID for Registrationをクリックします。これにより、デバイスIDが自動的にクリップボードにコピーされ、コンソールウィンドウに表示されます。以下のスクリーンショットに示されている指示に従ってください:
D4Uを購入した後、SN(シリアルナンバー)がメールで送られてきます。D4U内でSNを使用するには、次のようにD4Uの検証メソッドにメールとSNを挿入するか、Unity3DのUI内の「Dynamixel For Unity Component」に挿入してください:
アクティベーションを確認するには、シーンを実行し、コンソールでアクティベーションが正しく行われたかどうかを確認できます。
4. クイックスタート
ここでは、2つのDynamixelサーボモーターの位置の取得および設定をするデモを紹介します。
新規シーンの作成
インスペクターウィンドウで、DynamixelForUnityコンポーネントに、メールアドレスとSNコードを、デバイス名フィールドには、Dynamixelサーボモーターに接続されたUSBシリアルポートを入力します(ポート名はデバイスマネージャーから取得できます 例:「COM3」)。
(オプション)操作するサーボモーターのボーレートを知っている場合は、事前にDynamixelForUnityのインスペクターでボーレートを設定します。分からない場合は空白のままにします。(後に記述するC#スクリプトのDynamixelForUnityのSetUpメソッドにてスキャンされますが、これには時間がかかることがあります)。
「コンポーネントの追加」ボタンをクリックし、スクリプト名を任意のもの(今回は「Demo」)と入力します。それから「新しいスクリプト」をクリックします。
C#スクリプトのコーディング
Visual Studioが起動しtら、以下のように書きます。このコードは、2つのサーボモーターの現在位置をDebug.Logに出力し、その後、それぞれのGoalPositionを1024に設定します。
実行
Unity画面に戻り、再生ボタンをクリックしてください。
サーボモーターの位置はコンソールに表示されます。

5. Script Reference
名前空間は
から、お客様ののシステムに対応環境から選んでください。
DynamixelForUnity
DynamixelForUnityは宣言的なコードでDynamixelモーターを制御できるよう提供されるクラスです。一つのポートにつき一つのコンポーネントで管理します。IControlTableUserを実装します。
使用の流れ
定数
変数
Debug.Logに出力される。エラーや警告は影響されない。
プロパティ
Verificate
宣言
public bool Verificate(HatsuVerif verif)
引数
返り値
ライセンスの有効性。
説明
使用前にこのメソッドを実行し、ライセンスを検証してください。
ConnectDynamixel
宣言
public bool ConnectDynamixel()
public bool ConnectDynamixel(string deviceName)
public bool ConnectDynamixel(BaudRate baudRate)
public bool ConnectDynamixel(string deviceName, BaudRate baudRate)
引数
返り値
接続に成功すればtrueを、そうでなければfalseを返す。
説明
指定されたボーレートでポートを開き、Dynamixelモーターと接続する。ポートまたはボーレートの指定がなければ、インスペクタで指定された値を用いる。
ScanInBaudRate
宣言
public byte[] ScanInBaudRate(BaudRate baudRate, byte[] idsForScan = null)
引数
返り値
利用可能なモーターIDのbyte配列。
説明
指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。
宣言
public byte[] ScanInBaudRate(BaudRate baudRate, byte minIDsForScan, byte maxIDsForScan)
引数
返り値
利用可能なモーターIDのbyte配列。
説明
指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。スキャン対象を範囲で指定することができる。
ScanInBaudRateAsync
宣言
public async Task<byte[]> ScanInBaudRateAsync(BaudRate baudRate, byte[] idsForScan = null, CancellationToken cancellationToken = default(CancellationToken))
引数
返り値
利用可能なモーターIDのbyte配列。
説明
非同期的に指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。
宣言
public async Task<byte[]> ScanInBaudRateAsync(BaudRate baudRate, byte minIDsForScan, byte maxIDsForScan, CancellationToken cancellationToken = default(CancellationToken))
引数
返り値
利用可能なモーターIDのbyte配列。
説明
非同期的に指定されたボーレートでPingを打ち、Dynamixelモーターをスキャンする。SetBaudRateメソッドを用いて指定されたボーレートに変更する。スキャン対象を範囲で指定することができる。
Ping
宣言
public bool Ping(byte ID, bool hideErrorMsg = true)
引数
返り値
接続されているか。
説明
指定されたIDにPingを打ち、接続されているか確認する。
PingGetModelNumber
宣言
public int PingGetModelNumber(byte ID)
引数
返り値
モデル番号。通信失敗時には-1を返す。
説明
指定されたIDにPingを打ち、モデル番号を取得する。
GetAllModelNumber
宣言
public int[] GetAllModelNumber(byte[] ids = null)
引数
返り値
モデル番号の配列。通信失敗した項目には-1が入れられる。
説明
指定された複数のIDにPingを打ち、モデル番号の配列を返す。
SetControlTable
宣言
public void SetControlTable(ControlTables controlTables)
引数
説明
IControlTableUserの実装。コントロールテーブルをセットする。
SetUp
宣言
public byte[] SetUp(BaudRate? baudRate = null, byte[] idsForScan = null, bool scanAllBaudRateIfNotFound = true)
引数
返り値
利用可能なモーターIDのbyte配列。
説明
ScanInBaudRateメソッドでdynamixelモーターをスキャンし、SetIDsForUseメソッドでスキャンしたIDを使用するモーターとして保持する。
SetUpAsync
宣言
public async Task<byte[]> SetUpAsync(BaudRate? baudRate = null, byte[] idsForScan = null, bool scanAllBaudRateIfNotFound = true, CancellationToken cancellationToken = default(CancellationToken))
引数
返り値
利用可能なモーターIDのbyte配列。
説明
非同期的にScanInBaudRateAsyncメソッドでdynamixelモーターをスキャンし、SetIDsForUseメソッドでスキャンしたIDを使用するモーターとして保持する。
SetIDsForUse
宣言
public void SetIDsForUse(byte[] idsForUse)
引数
説明
IDを利用対象として保持し、モデル番号と関連付ける。
モーターIDとモデル番号をDynamixelForUnityに保持させることで、データフィールド名だけで命令を送信することや、すべてのモーターへの命令を送信する際に簡潔に書くことができます。
DisconnectDynamixel
宣言
public void DisconnectDynamixel()
説明
ポートを閉じる。
CloseAndReopenPort
宣言
public void CloseAndReopenPort(bool withSetBaudRate = true)
引数
説明
ポートを閉じ、開き直す。
RebootDynamixel
宣言
public void RebootDynamixel(byte[] ids = null)
引数
説明
DynamixelモーターをRebootする。
FactoryResetDynamixel
宣言
public void FactoryResetDynamixel(DynamixelFactoryResetMode mode, byte[] ids = null)
引数
説明
Dynamixelモーターを工場出荷時の状態にリセットする。
SetBaudRate
宣言
public bool SetBaudRate(BaudRate baudRate)
引数
返り値
成功すればtrueを、そうでなければfalseを返す。
説明
ポートのボーレートを設定する。
SetData
宣言
public bool SetData(ushort ADDR, ushort LEN, uint data, byte id)
引数
返り値
成功すればtrueを、そうでなければfalseを返す。
説明
指定されたIDのDynamixelモーターにデータを書き込む。
データフィールドのアドレスと長さはの各Dynamitelモーターのe-ManualからContorol Tableを確認してください。
宣言
public bool SetData(ControlTableAddressInfo addressInfo, uint data, byte id)
引数
返り値
成功すればtrueを、そうでなければfalseを返す。
説明
SetData(ushort ADDR, ushort LEN, uint data, byte id)を使用して、指定されたIDのDynamixelモーターにデータを書き込む。データフィールドが読み取り専用であれば実行されない。
宣言
public bool SetData(string dataName, uint data, byte id)
引数
返り値
成功すればtrueを、そうでなければfalseを返す。
説明
SetData(ushort ADDR, ushort LEN, uint data, byte id)を使用して、指定されたIDのDynamixelモーターにデータを書き込む。データフィールドが読み取り専用であれば実行されない。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SetSignedData
宣言
public bool SetSignedData(ushort ADDR, ushort LEN, uint data, byte id)
public bool SetSignedData(ControlTableAddressInfo addressInfo, int data, byte id)
public bool SetSignedData(string dataName, int data, byte id)
説明
指定されたIDのDynamixelモーターに符号付きデータを書き込む。SetDataの説明を参照してください。
GetData
宣言
public uint GetData(ushort ADDR, ushort LEN, byte id)
引数
返り値
読み取ったデータ。エラーが発生した場合0を返す。
説明
指定されたIDのDynamixelモーターのデータを読み取る。
データフィールドのアドレスと長さはの各Dynamitelモーターのe-ManualからContorol Tableを確認してください。
宣言
public uint GetData(ControlTableAddressInfo addressInfo, byte id)
引数
返り値
読み取ったデータ。エラーが発生した場合0を返す。
説明
GetData(ushort ADDR, ushort LEN, byte id)を使用して、指定されたIDのDynamixelモーターのデータを読み取る。
宣言
public uint GetData(string dataName, byte id)
引数
返り値
読み取ったデータ。エラーが発生した場合0を返す。
説明
GetData(ushort ADDR, ushort LEN, byte id)を使用して、指定されたIDのDynamixelモーターのデータを読み取る。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
GetSignedData
宣言
public int GetSignedData(ushort ADDR, ushort LEN, byte id)
public int GetSignedData(ControlTableAddressInfo addressInfo, byte id)
public int GetSignedData(string dataName, byte id)
説明
指定されたIDのDynamixelモーターの符号付きデータを読み取る。GetDataの説明を参照してください。
SyncSetDataGroup
宣言
public bool SyncSetDataGroup(ushort ADDR, ushort LEN, uint[] data, byte[] ids = null)
public bool SyncSetDataGroup(ControlTableAddressInfo addressInfo, uint[] data, byte[] ids = null)
引数
返り値
成功すればtrueを、そうでなければfalseを返す。
説明
GroupSyncWrite用いて複数モーターに同時にデータを書き込む。
SyncSetDataGroupMultiModels
宣言
public bool SyncSetDataGroupMultiModels(string dataName, uint[] data, byte[] ids = null)
説明
GroupSyncWrite用いて複数モーターに同時にデータを書き込む。データフィールド名が同一であれば、異なるアドレスでも送信する。その場合、ユニークなアドレス毎にSyncSetDataGroupを呼び出す。SyncSetDataGroupの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SyncSetSignedDataGroup
宣言
public bool SyncSetSignedDataGroup(ushort ADDR, ushort LEN, int[] data, byte[] ids = null)
public bool SyncSetSignedDataGroup(ControlTableAddressInfo addressInfo, int[] data, byte[] ids = null)
説明
GroupSyncWrite用いて複数モーターに同時に符号付きデータを書き込む。SyncSetDataGroupの説明を参照してください。
SyncSetSignedDataGroupMultiModels
宣言
public bool SyncSetSignedDataGroupMultiModels(string dataName, int[] data, byte[] ids = null)
説明
GroupSyncWrite用いて複数モーターに同時に符号付きデータを書き込む。SyncSetDataGroupMultiModelsの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SyncGetDataGroup
宣言
public uint[] SyncGetDataGroup(ushort ADDR, ushort LEN, byte[] ids = null)
public uint[] SyncGetDataGroup(ControlTableAddressInfo addressInfo, byte[] ids = null)
引数
返り値
読み取ったデータ配列。
説明
GroupSyncRead用いて複数モーターから同時にデータを読み取る。
SyncGetDataGroupMultiModels
宣言
public uint[] SyncGetDataGroupMultiModels(string dataName, byte[] ids = null)
説明
GroupSyncReadを用いて複数モーターに同時にデータを読み取る。データフィールド名が同一であれば、異なるアドレスでも送信する。その場合、ユニークなアドレス毎にSyncSetDataGroupを呼び出す。SyncGetDataGroupの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
SyncGetSignedDataGroup
宣言
public int[] SyncGetSignedDataGroup(ushort ADDR, ushort LEN, byte[] ids = null)
public int[] SyncGetSignedDataGroup(ControlTableAddressInfo addressInfo, byte[] ids = null)
説明
GroupSyncReadを用いて複数モーターに同時に符号付きデータを読み取る。SyncGetDataGroupの説明を参照してください。
SyncGetSignedDataGroupMultiModels
宣言
public int[] SyncGetSignedDataGroupMultiModels(string dataName, byte[] ids = null)
説明
GroupSyncReadを用いて複数モーターに同時に符号付きデータを読み取る。SyncGetDataGroupMultiModelsの説明を参照してください。
SetUpメソッドもしくはSetIDsForUseメソッドによってIDとモデル番号が保持されていなければ使用できません。
BulkSetDataGroup
宣言
public BulkWritePacket BulkSetDataGroup()
返り値
BulkWritePacketオブジェクト。
説明
GroupBulkWriteを用いて複数モーターに一括でデータを書き込むためのBulkWritePacketオブジェクトを返す。
GroupBulkWriteを行うにはBulkWritePacketを媒介するメソッドチェーンで記述します。
BulkGetDataGroup
宣言
public BulkReadPacket BulkGetDataGroup()
返り値
BulkReadPacketオブジェクト。
説明
GroupBulkReadを用いて複数モーターに一括でデータを読み取るためのBulkReadPacketオブジェクトを返す。
GroupBulkReadを行うにはBulkReadPacketを媒介するメソッドチェーンで記述します。
コントロールテーブルの使用方法
各Dynamixelサーボモーターのコントロールテーブルを表すテキストファイルを作成しました。コントロールテーブルは、各プロパティ名を対応するサーボモーターモデル内のレジスタ番号にマッピングしています。
これらのコントロールテーブルは、ROBOTIS e-Manualにあるサーボモーターのコントロールテーブルに対応しています。
以下の場所でコントロールテーブルのデータを確認できます: HatsuMuv/DynamixelForUnity/Resources/ControlTables/。
スクリーンショットのように、対応するサーボモーターを見つけてください:

これらのコントロールテーブルは、D4Uのさまざまなメソッドのパラメータとして使用できます。パラメータ名を文字列として渡すことで、さまざまなサーボモーターの制御やフィードバックを行うことができます。
例:
// 以下のメソッドでコントロールテーブルのパラメータを読み取るためにコントロールテーブルのパラメータを渡すことができます。ここで、コントロールテーブルのパラメータは設定/読み取りする必要のあるレジスタの文字列表現に対応します。 // この例では、SyncGetDataGroupMultiModelsメソッドを使用してデータを一括で設定しています。 SyncGetDataGroupMultiModels("GoalPosition");
BulkWritePacketの使用方法
Bulk Writeコマンドの実行には、次の手順が含まれます:
上記の4つのステップを実行するために、BulkWritePacketオブジェクトが使用されます。以下で説明されているように、そのプロパティを設定し、メソッドを呼び出すことでこれらの手順を実行できます。
ステップ1. 構造体の初期化
書き込みパケットのパラメータを保持するための構造体を初期化するために、まず関連するBulkWritePacketオブジェクトを宣言して初期化する必要があります。以下のように行います:
// bulk write packet BulkWritePacket writePacket = dynamixelForUnity.BulkSetDataGroup();
ステップ2. パラメータの追加
BulkWritePacketオブジェクトを作成すると、書き込むデータはパラメータとして作成したオブジェクトに追加する必要があります。以下のように行います:
writePacket.AddParam(addressInfo1, idArray1, data1); // 必要なだけパラメータを追加できます writePacket.AddParam(addressInfo2, idArray2, data2); writePacket.AddParam(addressInfo3, idArray3, data3);
ステップ3. バルクライトコマンドの送信
パラメータを追加したら、BulkWritePacketオブジェクトのSend()メソッドを呼び出すことでコマンドを実行できます。以下のように行います:
ステップ4. (オプション)BulkWriteコマンドの実行結果の確認
コマンドのステータスを確認することもできます。コマンドが正常に実行されたかどうかを確認するために、プロパティ「AllSuccess」をチェックできます。これはコマンドが成功した場合にtrueに設定されます。
また、コマンドが成功したかどうかを確認するために、BulkPacketオブジェクト自体を’if’条件文内に直接配置することもできます。
if(writePacket) Debug.Log("成功");
全体的に、以下のようにして効率的に4つのステップを1行で実行できます:
if(dynamixelForUnity .BulkSetDataGroup() .AddParam(addressInfo1, idArray1, data1) .AddParam(addressInfo2, idArray2, data2) .AddParam(addressInfo3, idArray3, data3) .Send()) Debug.Log("成功");
GroupBulkWriteを用いて複数モーターに一括でデータを書き込むためのオブジェクト。BulkWritePacketを媒介するメソッドチェーンで記述する。
例
dynamixelForUnity.BulkSetDataGroup() .AddParam(addressInfo1, idArray1, data1) .AddParam(addressInfo2, idArray2, data2) .Send();
プロパティ
AddParam
宣言
public BulkWritePacket AddParam(ushort ADDR, ushort LEN, uint[] data, byte[] ids = null)
引数
返り値
自身。
説明
書き込むデータフィールドの情報とデータをIDParamPairに格納する。
宣言
public BulkWritePacket AddParam(ControlTableAddressInfo addressInfo, uint[] data, byte[] ids = null)
引数
返り値
自身。
説明
AddParam(ushort ADDR, ushort LEN, uint[] data, byte[] ids = null)を使用して書き込むデータフィールドの情報とデータをIDParamPairに格納する。データフィールドが読み取り専用であれば実行されない。
AddParamSigned
宣言
public BulkWritePacket AddParamSigned(ushort ADDR, ushort LEN, int[] data, byte[] ids = null)
public BulkWritePacket AddParamSigned(ControlTableAddressInfo addressInfo, int[] data, byte[] ids = null)
説明
書き込むデータフィールドの情報と符号付きデータをIDParamPairに格納する。AddParamの説明を参照してください。
Send
宣言
public BulkWritePacket Send(bool discardAllWhenErrorHappen = false)
引数
返り値
自身。
説明
IDParamPairに基づいてGroupBulkWriteコマンドをDynamxielモーターに送信する。
ResetStatus
宣言
public void ResetStatus()
説明
通信結果と送信フラグをリセットする。書き込むデータは削除されない。
BulkReadPacketの使用方法
bulk readの実行には以下のステップが含まれます:
上記の4つのステップを実行するためには、BulkReadPacketオブジェクトを使用してそのプロパティを設定し、下記で説明するようにメソッドを呼び出す必要があります。
ステップ1. 構造体の初期化
読み取りパケットのパラメータを保持するための構造体を初期化するには、まず関連するBulkReadPacketオブジェクトを次のように宣言して初期化します:
// bulk read packet BulkReadPacket readPacket = dynamixelForUnity.BulkGetDataGroup();
ステップ2. パラメータの追加
BulkReadPacketオブジェクトを作成したら、読み取るデータをオブジェクトにパラメータとして追加する必要があります。以下のように行えます:
readPacket.AddParam(addressInfo1, idArray1); // 必要なだけパラメータを追加できます readPacket.AddParam(addressInfo2, idArray2); readPacket.AddParam(addressInfo3, idArray3);
ステップ3. バルクリードコマンドの送信
パラメータを追加したら、BulkReadPacketオブジェクトのSend()メソッドを呼び出すことでコマンドを実行できます:
ステップ4. (オプション)バルクリードコマンド実行の結果の確認
コマンドのステータス、つまり正常に実行されたかどうかをオプションで確認できます。プロパティ"AllSuccess"をチェックすることで、コマンドが正常に実行された場合にtrueに設定されます。
if(readPacket.AllSuccess) Debug.Log("成功");
代わりに、直接BulkPacketオブジェクトを「if」条件式に配置して、コマンドが成功したかどうかを確認することもできます。
if(readPacket) Debug.Log("成功");
ステップ5. サーボモーターからの返された値の読み取り
バルクリードコマンドを実行した後にサーボモーターから読み取ったデータを読むには、BulkReadPacketのGetData()メソッドを以下のように使用します:
全体的に、以下のようにしてステップを実行し、結果を表示できます:
例:
if(var readPacket = dynamixelForUnity .BulkGetDataGroup() .AddParam(addressInfo1, idArray1) .AddParam(addressInfo2, idArray2) .AddParam(addressInfo3, idArray3) .Send()) { Debug.Log("成功"); uint[] data = readPacket.GetData(); Debug.Log("データ:" + string.Join(", ", data)); }
プロパティ
AddParam
宣言
public BulkReadPacket AddParam(ushort ADDR, ushort LEN, byte[] ids = null)
引数
返り値
自身。
説明
読み取るデータフィールドの情報とデータをIDParamPairに格納する。
宣言
public BulkReadPacket AddParam(ControlTableAddressInfo addressInfo, byte[] ids = null)
引数
返り値
自身。
説明
AddParam(ushort ADDR, ushort LEN, byte[] ids = null)を使用して読み取るデータフィールドの情報をIDParamPairに格納する。
Send
宣言
public BulkReadPacket Send(bool discardAllWhenErrorHappen = false)
引数
返り値
自身。
説明
IDParamPairに基づいてGroupBulkReadコマンドをDynamxielモーターに送信する。
GetData
宣言
public uint[] GetData(bool resetStatus = false)
引数
返り値
読み取ったデータ配列。
説明
読み取ったデータ配列を取得する。
GetSignedData
宣言
public int[] GetSignedData(bool resetStatus = false)
引数
返り値
読み取ったデータ配列。
説明
読み取った符号付きデータ配列を取得する。
ResetStatus
宣言
public void ResetStatus()
説明
通信結果と送信フラグをリセットする。読み取ったデータも削除する。
ParamInfo
BulkWritePacket、BulkReadPacketでデータフィールドを表すクラス。
変数
ControlTables
各モーターのControl Tableを格納するクラス。Control Tableは指定された形式で書かれたテキストをコンストラクタの引数に入れることで初期化します。コンストラクタはstring[]かTextAsset[]のどちらかを引数に取ります。
DynamxielForUnity対応モデルのControl TableのテキストファイルがAssets/HatsuMuv/DynamixelForUnity/Resources/ControlTablesに配置されています。
使用例はControlTableInjectorFromResourcesを参照してください。
ControlTablesは初期化時に利用するモーターのControlTableを。
1行目はモデル名とモデル番号を":“を挟んで記述します。
そのほかの行はデータ名、アドレス、長さ、アクセスを記述します。アクセスは読み取り専用ならば"R”、書き込みも可能であるなら"RW"を指定します。
"#“や”//"で開始される行はコメントとして無視されます。
プロパティ
GetAddrssInfo
宣言
public ControlTableAddressInfo GetAddrssInfo(int modelNumber, string dataName)
public ControlTableAddressInfo this[int modelNumber, string dataName]
引数
返り値
データフィールドの情報を表すControlTableAddressInfo型。
説明
指定したモデル番号とデータ名からデータフィールドの情報を表すControlTableAddressInfo型を返す。
インデクサー[int modelNubmer, string dataName]でも同様の結果を得られる。
GetControlTable
宣言
public Dictionary<string, ControlTableAddressInfo> GetControlTable(int modelNumber)
public Dictionary<string, ControlTableAddressInfo> this[int modelNumber]
引数
返り値
コントロールテーブルを表すDictionary<string, ControlTableAddressInfo>型。
説明
指定されたモデル番号からコントロールテーブルを表すDictionary<string, ControlTableAddressInfo>型を返す。
インデクサー[int modelNubmer]でも同様の結果を得られる。
Contains
宣言
public bool Contains(int modelNumber)
引数
返り値
指定されたモデル番号のControl Tableが存在すればtrue、そうでなければfalseを返す。
説明
指定したモデル番号のControl Tableが存在するかを返す。
宣言
public bool Contains(int modelNumber, string dataName)
引数
返り値
指定されたモデル番号のControl Tableが存在し、かつ指定されたデータ名のデータフィールドが存在すればtrueを、そうでなければfalseを返す。
説明
指定したモデル番号のデータ名のデータフィールドが存在するかを返す。
GetModelsContains
宣言
public int[] GetModelsContains(string dataName)
引数
返り値
指定されたデータ名のデータフィールドをControl Tableに持つモデル番号の配列。
説明
指定されたデータ名のデータフィールドをControl Tableに持つモデル番号の配列を返す。
ControlTableAddressInfo
Control Tableにおけるデータフィールドの情報を表す構造体。
変数
IControlTableUser
コントロールテーブルを注入するインターフェース。DynamixelForUnityが実装します。
SetControlTables
public void SetControlTables(ControlTables controlTables)
Core
Dynamixel SDK互換のクラス。コンストラクタにHatsuVerifオブジェクトを入れインスタンスを生成してください。
6.Example Sceneの解説
HatsuMuv/DynamixelForUnity/Example/ExampleScene_x64.unity はDynamixelForUnityを用いたGUIアプリケーションのサンプルです。
このシーンには、DynamixelForUnityを使用してDynamixelサーボモーターと接続、サーボモーターのスキャン、サーボモーターの制御、サーボモーターから読み取ったさまざまな情報のGUIへの表示を行う、サンプルのグラフィカルユーザーインターフェース(GUI)アプリケーションが含まれています。
画面の解説
インスペクターウィンドウで、DynamixelForUnityコンポーネントに、メールアドレスとSNコードを、デバイス名フィールドには、Dynamixelサーボモーターに接続されたUSBシリアルポートを入力します(ポート名はデバイスマネージャーから取得できます 例:「COM3」)。
(オプション)操作するサーボモーターのボーレートを知っている場合は、事前にDynamixelForUnityのインスペクターでボーレートを設定します。分からない場合は空白のままにします。(後に記述するC#スクリプトのDynamixelForUnityのSetUpメソッドにてスキャンされますが、これには時間がかかることがあります)。
DynamixelForUnityのコンポーネントの設定が完了したら、再生ボタンをクリックしてください。DynamixelForUnityは自動的に指定されたポートを開き、利用可能なサーボモーターに接続します。
画面には接続されたDynamixelサーボモーターの一覧が表示されます。接続されたボーレートは画面の上部に表示されます。
画面下部の読み取り専用のデータ項目は常に更新されています(現在位置など)。
その他の項目は、接続時とデータが入力された場合に更新されます(例えば、サーボモーターの新しい位置を設定する場合など)。
ヒント: 実際の値と異なる場合は、データを再取得するためにリフレッシュボタンを押してください。
実装の解説
D4UExampleController
Start()
private async void Start() { NeedWait = true; if (d4u == null) { Debug.LogError("[DynamixelForUnitySample] DynamixelForUnity is not assigned!"); return; } // Varificate your licence here d4u.Varificate(new DevTest.HatsuVarif(licenceFilePath: "some", userID: "some", email: "example@sample.com", phonenumber: "123456789")); cancellationTokenSource = new CancellationTokenSource(); var connectResult = await Task.Run(() => InitializeDynamixel(cancellationTokenSource.Token)); if (connectResult) StartMotorMetrics(); NeedWait = false; }
NeedWaitプロパティは画面ロードアニメーションを再生するために外部から参照されています。
DynamixelForUnity d4uはInspectorから代入されることを期待しています。
d4u.Varificateメソッドを用いてライセンスの認証を行ってください。
cancellationTokenSourceは非同期タスクを中断するために作成します。
モーターに接続し初期化をするメソッドInitializeDynamixelを非同期で実行しこれを待ち受けます。
InitializeDynamixelによってDynamixelモーターを接続できたならばStartMotorMetricsmメソッドによってモーターの状態を連続して計測し続けるループが開始されます。
InitializeDynamixel(CancellationToken ct)
private async Task<bool> InitializeDynamixel(CancellationToken ct) { if (d4u == null) { Debug.LogError("[DynamixelForUnitySample] DynamixelForUnity is not assigned!"); return false; } if (!d4u.ConnectStatus) { var connectResult = d4u.ConnectDynamixel(); if (!connectResult) { Debug.LogError("[DynamixelForUnitySample] Dynamixel is not connected. Connect it first."); return false; } await d4u.SetUpAsync(cancellationToken:ct); } motors = new List<DynamixelMotor>(); ids = d4u.IDsForUse; if (ids.Length == 0) return false; await GetAllMotorProperty(ct); return true; }
d4u.ConnectDynamixelメソッドでモーターと接続します。引数にポート名、ボーレートを指定することもできます。その場合Inspectorで入力された値は無視されます。
SetUpAsyncメソッドは二つのメソッドを呼んで、モーターのスキャンと見つかったIDの保持を一括で行います。
モーターIDとモデル番号をDynamixelForUnityに保持させることで、データフィールド名だけで命令を送信できる、一部の関数ですべてのモーターへの命令を送信する際に簡潔に書くことができる、などの恩恵があります。
ExampleSceneを作る上で、モーターの情報を扱う際にDynamixelMotorクラスを実装しています。あなたの作成するアプリケーションに応じてプロパティを追加してください。
GetAllMotorPropertyメソッドによってすべてのモーターのプロパティを取得し、DynamixelMotorインスタンスを作成します。
GetAllMotorProperty(CancellationToken ct)
private async Task GetAllMotorProperty(CancellationToken ct) { OperatingMode[] operatingModes = await Task.Run(() => d4u.SyncGetDataGroupMultiModels("OperatingMode") .Select(d => (OperatingMode)d) .ToArray(), ct); float[] homingOffsets = await Task.Run(() => d4u.SyncGetSignedDataGroupMultiModels("HomingOffset").ToActualNumber(UNIT.POSITION).ToFloatArray(), ct); ... for (int i = 0; i < ids.Length; i++) { DynamixelMotor m; if (motors.Count < i + 1) { m = new DynamixelMotor(ids[i]); motors.Add(m); } else { m = motors[i]; } m.OperatingMode = operatingModes[i]; m.HomingOffset = homingOffsets[i]; ... } }
DynamixelMotorクラスの一つ一つのプロパティについてSyncGetSignedDataGroupMultiModelsメソッドで取得しています。一つのプロパティを例に挙げて説明します。
float[] homingOffsets = await Task.Run( () => d4u.SyncGetSignedDataGroupMultiModels("HomingOffset") .ToActualNumber(UNIT.POSITION) .ToFloatArray(), ct );
homingOffsetsを初期化する行にわかりやすく改行を入れたものです。
2行目のTask.Runメソッドは第一引数の関数を別スレッドで非同期に実行するものです。
3行目からは別スレッドで実行したい関数です。
d4u.SyncGetSignedDataGroupMultiModels(“HomingOffset”)はDynamixelForUnityに保持されているすべてのモーターに対して"HomingOffset"というデータフィールドの値を取得します。
.ToActualNumber(UNIT.POSITION)はSyncGetSignedDataGroupMultiModelsから得られた生のデータに単位を適用します。UNIT.POSITIONは定数です。
.ToFloatArray()はdouble[]をfloat[]に変換します。
MotorMetricsはGetAllMotorPropertyからいくつかのデータをそぎ落とした同様のメソッドです。
StartMotorMetrics()
MotorMetricsLoop(CancellationToken ct)
StopMotorMetrics()
private void StartMotorMetrics() { if (!d4u.ConnectStatus) return; cancellationTokenSource = cancellationTokenSource ?? new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; metricsLoop = MotorMetricsLoop(cancellationToken); } private async Task MotorMetricsLoop(CancellationToken ct) { while (true) { if (ct.IsCancellationRequested) return; Debug.Log("[SampleController] Metrics"); try { await MotorMetrics(ct); } catch (OperationCanceledException) { Debug.Log("[SampleController] Metrics canceled"); return; } catch (Exception e) { Debug.LogError(e); return; } } } private async Task StopMotorMetrics() { if (cancellationTokenSource != null && !cancellationTokenSource.IsCancellationRequested) { cancellationTokenSource.Cancel(); cancellationTokenSource.Dispose(); cancellationTokenSource = null; if(metricsLoop != null) await metricsLoop; } }
連続的にモーターのデータを計測し続けるループを実行するメソッド群です。MotorMetricsLoopはCancellationTokenによってキャンセルされるまでMotorMetricsを呼び出し続けます。
StopMotorMetricsはMotorMetricsをキャンセルし、処理が終了するまで待ち受けます。
D4UExampleUI
UI要素の生成を行います。
D4UExampleControllerからモーター毎のパネルを生成し、それらのデータを更新させます。
D4UExampleUIElement
各パネルのフィールドを直接コントロールしている。UI要素から入力を受けるとD4UExampleContorllerに値を渡す。