ページへ戻る

− Links

 印刷 

DXLIB_Arduino のバックアップソース(No.9) :: Besttechnology

knowledge:DXLIB_Arduino のバックアップソース(No.9)

« Prev[4]  Next »[5]
TITLE:DXLIB for Arduino
Dynamixelを制御するためのプログラムを作成する際のライブラリを提供します。Arduino IDEにインストールするだけで自身のスケッチからDynamixelを制御できます。~
PC版DYNAMIXEL Protocol [[1.0>Dynamixel Library]]/[[2.0>Dynamixel Protocol 2 Library]] Libraryと同様にプロトコルやシリアル通信を意識せずともコントロールテーブルへの読み書きが行えます。なおAVRではメモリの都合からV1.5から追加されたライブラリは使用できません。また当該バージョンからクラスのインスタンス化の際の引数が変更されていますので注意が必要です。

-ライブラリのダウンロード~
--
#ref(dxlib1.5beta_for_arduino.zip)~
---現時点で想定の全てを検証したものではないのでβ版扱い
---Arduino UNO以外も対象とするためにソースからシリアルライブラリに関する記述を削除し、シリアル通信にかかる7つのハンドラを新たに設置
---Arduino UNOに限って初期化を始め送受信にかかるハンドラをソフトウェアシリアルとハードウェアシリアル用に提供
---AVRを除くターゲットに適用した場合、PCないしARM系マイコンボード用に提供しているDXLIBに[[追加されたAPI>DXL_intuitive]]が使用可能~
詳細は追って公開
---仕様変更によるサンプルプログラム修正

--
#ref(dxlib1.4_for_arduino.zip)
---チェックサムの検証を厳密化
---新たにReadBlockDataとWriteBlockData関数を追加し、コントロールテーブルの読み出し及び書き込みはこの関数を介するように変更
---プロトコルV2の例外時(0xFF 0xFF 0xFDの並びでデータが現れた場合に末尾に0xFDを付与)の処理を全ての関数へ適用(一部制約あり)
---コンパイル時のwarningを抑止
---多少サンプルプログラムの構成を変更
---Win版dxlibからアイテムのアドレスをマクロ定義したヘッダをコピー

--
#ref(dxlib1.3_for_arduino.zip)
---dxlib.cppのハードウェアシリアルポートの初期化不足修正

--
#ref(dxlib1.2_for_arduino.zip)
---任意のハードウェアシリアルポートへの割り当て対応

--
#ref(dxlib1.1_for_arduino.zip)
---Dynamixel Protocol V.2に対応
---低位の送受信関数追加
---32bitデータの送受信関数追加
---アドレスとサイズに関する引数は全て16bitに統一

--
#ref(dxlib1.0_for_arduino.zip)
---初期リリース

DXLIBのインストールは、ArduinoのIDEの「スケッチ→ライブラリのインクルード→.ZIP形式のライブラリをインストール...」メニューを使用してダウンロードしたZIPファイルを選択するだけです。~
インストールが完了すると、ユーザーフォルダ配下に「Arduino/libraries/dxlib」が作られ、ライブラリのソースといくつかのサンプルプログラムがその中に展開されます。詳しくはサンプルプログラムとライブラリのソースを参照して下さい。~

DXLIB v1.5以降で使用できるヘッダファイルとAPIは以下の通りです。
-&color(#0099ff){''dxlib.h''};~
[[DYNAMIXEL Communiation Protocol 1.0]]対応デバイスを対象とする場合、'''dxlib.h'''をスケッチにインクルードする事で'''DXLIB'''クラスが利用できるようになります。'''dx2lib.h'''との共存は想定していません。
#html{{
<pre class="brush: c;">
#include &lt;dxlib.h&gt;
#include "avr_uno_softserial.h"
const DXLIB::TDXHost_ConfParam param {
  us_init, us_deinit, us_setbaudrate, us_rxpurge, us_putc, us_puts, us_gets, us_flush
};

DXLIB dxif (& param);

void setup() {
  dxif.begin (57600);
}</pre>
}}
-&color(#0099ff){''dx2lib.h''};~
[[DYNAMIXEL Communiation Protocol 2.0]]対応デバイスを対象とする場合、'''dx2lib.h'''をスケッチにインクルードする事で'''DX2LIB'''クラスが利用できるようになります。'''dxlib.h'''との共存は想定していません。
#html{{
<pre class="brush: c;">
#include &lt;dx2lib.h&gt;
#include "avr_uno_softserial.h"
const DX2LIB::TDXHost_ConfParam param {
  us_init, us_deinit, us_setbaudrate, us_rxpurge, us_putc, us_puts, us_gets, us_flush
};

DX2LIB dxif (& param);

void setup() {
  dxif.begin (57600);
}</pre>
}}

-&color(#0099ff){DXLIB/DX2LIB::''TDXHost_ConfParam''};~
ライブラリv1.5より導入された通信を担う8つの関数のポインタを保持する構造体で、クラスをインスタンス化する際に引数として渡します。~
各メンバーの関数のプロトタイプに合わせた通信処理関数を予め作成しておく必要があります。
#html{{
<pre class="brush: c;">
// Assuming HardwareSerial of Arduino UNO
#include &lt;dx2lib.h&gt;

// UART initialization
uint32_t us_init (uint32_t baud) {
  Serial.begin (baud);
  Serial.setTimeout (20);
  return baud;
}

// Terminate use of UART
void us_deinit (void) {
  Serial.end();
}

// Changing the baud rate
uint32_t us_setbaudrate (uint32_t baud) {
  us_deinit();
  return us_init (baud);
}

// Purge receive buffer
void us_rxpurge (void) {
  while (Serial.available()) Serial.read();
}

// Send one byte
void us_putc (uint8_t c) {
  Serial.write (c);
}

// Send specified number of bytes
void us_puts (const uint8_t *buf, int len) {
  Serial.write (buf, len);
}

// Receive specified number of bytes (Timeout must be set in advance)
int us_gets (uint8_t *buf, int len) {
  return Serial.readBytes (buf, len);
}

// Waiting for transmission completion
void us_flush (void) {
  Serial.flush();
}

// Enclose each communication function in a structure
const DX2LIB::TDXHost_ConfParam param {
  us_init, us_deinit, us_setbaudrate, us_rxpurge, us_putc, us_puts, us_gets, us_flush
};

DX2LIB dx2 (& param);
</pre>
}}
なおライブラリに同梱されるサンプルスケッチではこれらの通信処理関数は使い回しが効くように avr_uno_hardserial.h と avr_uno_softserial.h のヘッダファイルにまとめて記述してあります。
-&color(#0099ff){''DXLIB/DX2LIB'' (const PDXHost_ConfParam param)};~
ヘッダファイルに応じて'''DXLIB'''ないし'''DX2LIB'''いずれかのクラスが使用できます。外部で定義したシリアル通信処理部分をまとめた構造体'''TDXHost_ConfParam'''を指定した上でオブジェクトを生成できます。
#html{{
<pre class="brush: c;">
#include &lt;dx2lib.h&gt;
// ソフトウェアシリアルを選択
//#include "avr_uno_hardserial.h"
#include "avr_uno_softserial.h"

// dxifの名前でDynamixel Protocol V.2 Libraryをインスタンス化
const DX2LIB::TDXHost_ConfParam param {
  us_init, us_deinit, us_setbaudrate, us_rxpurge, us_putc, us_puts, us_gets, us_flush
};

DX2LIB dxif(& param);
</pre>
}}
-&color(#0099ff){void DXLIB/DX2LIB::''begin'' (long baud)};~
ライブラリを使用可能にします。引数('''baud''')にはDynamixelに設定されたボーレートを指定します。~
ボーレートの精度や範囲は使用するシリアルポートに依存します。
#html{{
<pre class="brush: c;">
// 生成されたdxifを57143bpsで初期化
void setup() {
  dxif.begin (57143);
}</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''TxPacket'' (uint8_t id, uint8_t inst, uint8_t *param, uint16_t len)};~
指定されたID('''id''')・インストラクション('''inst''')・パラメータ('''param''')・パラメータ長('''len''')のインストラクションパケットを送信します。
#html{{
<pre class="brush: c;">
// ID=1へPingインストラクションパケットを送信
dxif.TxPacket (1, 0x01, NULL, 0);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''RxPacket'' (uint8_t *rdata, uint16_t rdatasize, uint8_t *rid, uint16_t *rlen, uint8_t *err)};~
ステータスパケットを受信します。成功するとパケット内のパラメータが'''rdata'''へコピーされ、そのパラメータのサイズが'''rlen'''に返されます。なお、ステータスパケットを受信するのに十分なサイズを確保し、そのポインタを'''rdata'''へ、サイズを'''rdatasize'''に指定します。'''rid'''にはID、'''err'''にはDynamixelのエラーが返ります。
#html{{
<pre class="brush: c;">
uint8_t buf[10], id, err;
uint16_t len;
// ID=1へPingインストラクションパケットを送信
dxif.TxPacket (1, 0x01, NULL, 0);
// ステータスパケットを受信
dxif.RxPacket (buf, sizeof (buf), &id, &len, &err)</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''ReadBlockData'' (uint8_t id, uint16_t addr, uint8_t *data, uint16_t len, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')から8ビットのデータを'''data'''へ'''len'''の長さ分読み出します。'''err'''にはDynamixelのエラーが返ります。&br;
なおDX2LIBで4バイト以上を読み出す場合、まずサフィックスが付与された状態でdataへ読み出し、その後に必要に応じてサフィックス削除が行われます。そのため実際に必要なサイズよりも大きめにdataを確保しておく必要があります(最大で1.34倍)。
#html{{
<pre class="brush: c;">
// ID=1のAX-12のComplianceを取得
uint8_t compliance[4];
dxif.ReadBlockData (1, 26, &compliance, 4, NULL);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''ReadByteData'' (uint8_t id, uint16_t addr, uint8_t *data, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')から8ビットのデータを'''data'''へ読み出します。'''err'''にはDynamixelのエラーが返ります。
#html{{
<pre class="brush: c;">
// ID=1のAX-12のLEDを取得
uint8_t led;
dxif.ReadByteData (1, 25, &led, NULL);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''ReadWordData'' (uint8_t id, uint16_t addr, uint16_t *data, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')から16ビットのデータを'''data'''へ読み出します。'''err'''にはDynamixelのエラーが返ります。
#html{{
<pre class="brush: c;">
// ID=1のAX-12からPresentPositionを取得
uint16_t ppos;
dxif.ReadWordData (id, 36, &ppos, NULL);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''ReadLongData'' (uint8_t id, uint16_t addr, uint32_t *data, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')から32ビットのデータを'''data'''へ読み出します。'''err'''にはDynamixelのエラーが返ります。

-&color(#0099ff){bool DXLIB/DX2LIB::''WriteBlockData'' (uint8_t id, uint16_t addr, const uint8_t *data, uint16_t len, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')・8ビットのデータ('''data''')・指定バイト数('''len''')をDynamixelに書き込みます。'''err'''にはDynamixelのエラーが返ります。
#html{{
<pre class="brush: c;">
// ID=1のAX-12のComplianceを設定
uint8_t err;
uint8_t compliance[4] = {1,1,32,32};
dxif.WriteBlockData (1, 26, &compliance, 4, &err);</pre>
}}

-&color(#0099ff){bool DXLIB/DX2LIB::''WriteByteData'' (uint8_t id, uint16_t addr, uint8_t data, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')・8ビットのデータ('''data''')をDynamixelに書き込みます。'''err'''にはDynamixelのエラーが返ります。
#html{{
<pre class="brush: c;">
// ID=1のAX-12のLEDを点灯
uint8_t err;
dxif.WriteByteData (id, 25, 1, &err);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''WriteWordData'' (uint8_t id, uint16_t addr, uint16_t data, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')・16ビットのデータ('''data''')をDynamixelに書き込みます。'''err'''にはDynamixelのエラーが返ります。
#html{{
<pre class="brush: c;">
// ID=1のAX-12のGoalPositionを511に変更
dxif.WriteWordData (id, 30, 511, NULL);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''WriteLongData'' (uint8_t id, uint16_t addr, uint32_t data, uint8_t *err)};~
指定されたID('''id''')・アドレス('''addr''')・32ビットのデータ('''data''')をDynamixelに書き込みます。'''err'''にはDynamixelのエラーが返ります。
-&color(#0099ff){bool DXLIB/DX2LIB::''WriteSyncByteData'' (const uint8_t *pid, uint16_t addr, const uint8_t *pdata, int num)};~
指定されたid数('''num''')分のIDの配列('''pid''')・アドレス('''addr''')・8ビットのデータ配列('''pdata''')をDynamixelに書き込みます。
#html{{
<pre class="brush: c;">
// ID=1~5の5個のAX-12のLEDへ点滅を指令
uint8_t ids={1,2,3,4,5};
uint16_t leds={1,1,1,1,1};
dxif.WriteSyncByteData (ids, 30, leds, 5);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''WriteSyncWordData'' (const uint8_t *pid, uint16_t addr, const uint16_t *pdata, int num)};~
指定されたid数('''num''')分のIDの配列('''pid''')・アドレス('''addr''')・16ビットのデータ配列('''pdata''')をDynamixelに書き込みます。
#html{{
<pre class="brush: c;">
// ID=1~5の5個のAX-12に個別のGoalPositionを指令
uint8_t ids={1,2,3,4,5};
uint16_t poss={100,200,300,400,500};
dxif.WriteSyncWordData (ids, 30, ppos, 5);</pre>
}}
-&color(#0099ff){bool DXLIB/DX2LIB::''WriteSyncLongData'' (const uint8_t *pid, uint16_t addr, const uint32_t *pdata, int num)};~
指定されたid数('''num''')分のIDの配列('''pid''')・アドレス('''addr''')・32ビットのデータ配列('''pdata''')をDynamixelに書き込みます。
-&color(#0099ff){bool DXLIB/DX2LIB::''Ping'' (uint8_t id, uint16_t *err)};~
指定されたID('''id''')のDynamixelを検索します。'''err'''にはDynamixelのエラーが返ります。
-&color(#0099ff){bool DXLIB/DX2LIB::''Reset'' (uint8_t id, uint16_t *err)};~
指定されたID('''id''')のDynamixelを出荷時状態に戻します。'''err'''にはDynamixelのエラーが返ります。

以下はライブラリv1.5から新設されたAPIで、AVRシリーズを除いたターゲットで使用できます。
-&color(#0099ff){bool DXLIB/DX2LIB::''SetLED'' (uint8_t id, bool en)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetTorqueEnable'' (uint8_t id, bool en)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetTorqueEnables'' (const uint8_t *ids, const bool *ens, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetTorqueEnablesEquival'' (const uint8_t *ids, int num, bool en)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetTorqueEnable'' (uint8_t id, bool *en)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetTorqueEnables'' (const uint8_t *ids, bool *en, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAngle'' (uint8_t id, double angle)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAngles'' (const uint8_t *ids, const double *angles, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentAngle'' (uint8_t id, double *angle)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentAngles'' (const uint8_t *ids, double *angles, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''StandStillAngle'' (uint8_t id)};
-&color(#0099ff){bool DXLIB/DX2LIB::''StandStillAngles'' (const uint8_t *ids, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalVelocity'' (uint8_t id, double velocity)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalVelocities'' (const uint8_t *ids, const double *velocities, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentVelocity'' (uint8_t id, double *velocity)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentVelocities'' (const uint8_t *ids, double *velocities, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAngleAndVelocity'' (uint8_t id, double angle, double velocity)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAnglesAndVelocities'' (const uint8_t *ids, PAngleVelocity anglevelocity, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAngleAndTime'' (uint8_t id, double angle, double sec)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAnglesAndTime'' (const uint8_t *ids, const double *angles, int num, double sec)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAngleAndTime2'' (uint8_t id, double angle, double sec)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalAnglesAndTime2'' (const uint8_t *ids, const double *angles, int num, double sec)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalCurrent'' (uint8_t id, double current)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalCurrents'' (const uint8_t *ids, const double *currents, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentCurrent'' (uint8_t id, double *current)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentCurrents'' (const uint8_t *ids, double *currents, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalPWM'' (uint8_t id, double pwm)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetGoalPWMs'' (const uint8_t *ids, const double *pwms, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentPWM'' (uint8_t id, double *pwm)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetPresentPWMs'' (const uint8_t *ids, double *pwms, int num)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetDriveMode'' (uint8_t id, uint8_t mode)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetDriveModesEquival'' (const uint8_t *ids, int num, uint8_t mode)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetOperatingMode'' (uint8_t id, uint8_t mode)};
-&color(#0099ff){bool DXLIB/DX2LIB::''SetOperatingModesEquival'' (const uint8_t *ids, int num, uint8_t mode)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetOperatingMode'' (uint8_t id, uint8_t *mode)};
-&color(#0099ff){bool DXLIB/DX2LIB::''GetHWErrorCode'' (uint8_t id, uint8_t *hwerr)};
-&color(#0099ff){TErrorCode DXLIB/DX2LIB::''GetErrorCode'' (uint8_t id)};
-&color(#0099ff){PDXL_ModelInfo DXLIB/DX2LIB::''GetModelInfo'' (uint8_t id)};
-&color(#0099ff){int DXLIB/DX2LIB::''ScanDevices'' (uint8_t *ids)};
-&color(#0099ff){bool DXLIB/DX2LIB::''PrintDevicesList'' (int (*pf) (const char *, ...))};
-&color(#0099ff){void DXLIB/DX2LIB::''InitDevicesList'' (void)};

« Prev[4]  Next »[5]