使用するDynamixelの情報を予めライブラリ内に保持させておき、位置や角速度等の指令およびフィードバック値は物理値を扱い、各々の区別はIDのみで行うAPIです。~ これAPIによりDynamixelのモデルごとに異なるコントロールテーブルや煩雑な運転方法の違いを意識する事なく、少ないコードで目的の挙動を実現できます。~ なお、従来通りコントロールテーブルへの直接アクセスを制限するものではありませんが、その場合は本機能が想定する状況と一致しなくなる事があります。~ ※以下の使用例は[[DX2LIB]]を前提としています。 ***初期設定関連 [#t35acc12] Dynamixelが持つ固有の情報を予め記憶させておくことで、それ以後の操作はIDのみを指定し、どのモデルであっても使用頻度が高いアイテムはコントロールテーブルを意識する事無く同じAPIで同様の動作ができます。 ****DXL_ScanDevices [#j98a660f] ID0~252のデバイスを順次検索し、サポートするDynamixelであればライブラリ内のリストに登録する。~ リストに登録されていないデバイスのIDに対しては存在しないものとして通信を行わないため、DXL_ScanDevicesかDXL_GetModelInfoを用いて予めリストに登録しておく必要がある。 int DXL_ScanDevices (TDeviceID dvid, uint8_t *ids); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~見つかったデバイスのID一覧を必要に応じて取得する配列の保存先。最小でも253バイトを確保すること。 -戻り値 --int~ ~見つかったデバイスの数。 -使用例 #html{{ <pre class="brush: c;"> #include <stdio.h> #include <dx2lib.h> void main (void) { // COM10を57600bpsでオープン TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); if (dev != 0) { // ID=0~252の情報を取得し成功したもののみライブラリ内のリストに追加 printf("detect num=%d\n", DXL_ScanDevices (dev, NULL)); DX2_Close (dev); } } </pre> }} ****DXL_GetModelInfo [#pfc0b4fd] 指定IDのモデル情報の取得し、サポートするDynamixelであればライブラリ内のリストに登録する。~ リストに登録されていないデバイスのIDに対しては存在しないものとして通信を行わないため、DXL_ScanDevicesかDXL_GetModelInfoを用いて予めリストに登録しておく必要がある。 PDXL_ModelInfo DXL_GetModelInfo (TDeviceID dvid, uint8_t id); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 -戻り値 --[[PDXL_ModelInfo>#PDXL_ModelInfo]] ~登録されたIDと一致する[[TDXL_ModelInfo>#TDXL_ModelInfo]]のアドレス。 -使用例 #html{{ <pre class="brush: c;"> #include <stdio.h> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("/dev/ttyUSB0", 57600); for (uint8_t id = 0; id <= 252; id++) { // idの情報を取得し成功したらライブラリ内のリストに追加 PDXL_ModelInfo p = DXL_GetModelInfo (dev, id); if (p->modelno != 0) printf ("[%3d] %s ($%04X) %d\n", id, p->name, p->modelno, p->devtype); } } DX2_ClosePort (dev); } </pre> }} ****DXL_PrintDevicesList [#pcf4b964] ライブラリ内のリストに登録された全てのデバイスの情報をコンソールに出力する。~ ID・モデル名・モデル番号の順に出力される。 bool DXL_PrintDevicesList (int (*pf) (const char *, ...)); -パラメータ --int (*'''pf''')(const char *, ...) ~printf等の書式化文字列出力ルーチンのポインタ。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <stdio.h> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("/dev/ttyUSB0", 57600); DXL_ScanDevices (dev, NULL); DXL_PrintDevicesList ((void *)&printf); DX2_ClosePort (dev); } </pre> }} ****DXL_InitDevicesList [#y8cba5d4] ライブラリ内に保持されたデバイスのリストをクリアする。 void DXL_InitDevicesList (void); ***エラー [#yebd75c5] ****DXL_GetErrorCode [#p3a25282] 追加APIの処理の中で最後に取得したエラーを返す。本API自体は通信を行わない。 TErrorCode DXL_GetErrorCode (TDeviceID dvid, uint8_t id); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 -戻り値 --[[TErrorCode>#TErrorCode]] ~エラーコード。~ ****DXL_GetHWErrorCode [#d81bfd4b] 対象IDのコントロールテーブルにハードウェアエラーが備わっている場合にのみ取得する。~ bool DXL_GetHWErrorCode (TDeviceID dvid, uint8_t id, uint8_t *hwerr); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --uint8_t '''*hwerr''' ~取得されたハードウェアエラーの保存先。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。 ***運転・動作モード [#o7180cd5] 運転モードはDynamixelのDrive Mode、動作モードはOperating Modeを意味します。~ 運転モードはデフォルトの回転方向やプロファイルの選択、マスタースレーブの設定を行います。~ 動作モードについてはDynamixel X・Pシリーズの動作モードを基準とし、他のモデルにおいてもこの動作モードの番号を踏襲することとします。 ****DXL_SetDriveMode [#v277bea5] 対象IDの運転モードを変更する。~ 指定されたモードと現在のモードが異なる場合にのみトルクをOFFにし運転モードを更新する。~ 対称IDがライブラリ内のリストに登録されている必要がある。 bool DXL_SetDriveMode (TDeviceID dvid, uint8_t id, uint8_t mode); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --uint8_t '''mode''' ~機種依存あり -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); // ID:1を検索し見つかれば登録 DXL_GetModelInfo (dev, 1); // ID:1のXシリーズをTime-Base Profileに設定 DXL_SetDriveMode (dev, 1, 4); DX2_ClosePort (dev); } </pre> }} ****DXL_SetDriveModesEquival [#d70d54e6] 複数IDの運転モードを一括変更する。~ 指定されたモードと現在のモードが異なる場合にのみトルクをOFFにし運転モードを更新する。~ ライブラリ内のリストに登録されていないIDは無視される。 bool DXL_SetDriveModesEquival (TDeviceID dvid, const uint8_t *ids, int num, uint8_t mode); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --int '''num''' ~対象とするID数 --uint8_t '''mode''' ~機種依存あり -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); uint8_t ids[3] = {1, 2, 3}; // ID:1~3を検索し見つかれば登録 for (int i = 0; i < sizeof (ids); i++) DXL_GetModelInfo (dev, ids[i]); // ID:1~3のDrive Modeを出荷時デフォルト値に設定 DXL_SetDriveModesEquival (dev, ids, sizeof (ids), 0); DX2_ClosePort (dev); } </pre> }} ****DXL_SetOperatingMode [#k245dc90] 対象IDの動作モードを変更する。~ 指定されたモードと現在のモードが異なる場合にのみトルクをOFFにし動作モードを更新する。~ 対称IDがライブラリ内のリストに登録されている必要がある。 bool DXL_SetOperatingMode (TDeviceID dvid, uint8_t id, uint8_t mode); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --uint8_t '''mode''' ~[[Dynamixel Xシリーズの動作モード>X Series Control table#j5c7292f]]を想定し、それに完全対応しないデバイスに対しては近似値もしくは失敗を返す。~ 0: Current Control (電流制御)~ 1: Velocity Control (速度制御)~ 3: Position Control (位置制御)~ 4: Expand Position Control (多回転位置制御)~ 5: Current-Base Position Control~ 16: PWM Control~ -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); // ID:1を検索し見つかれば登録 DXL_GetModelInfo (dev, 1); // ID:1をCurrent-Base Position Controlに設定 DXL_SetOperatingMode (dev, 1, 5); DX2_ClosePort (dev); } </pre> }} ****DXL_SetOperatingModesEquival [#a14c1876] 複数IDの動作モードを一括変更する。~ 指定されたモードと現在のモードが異なる場合にのみトルクをOFFにし動作モードを更新する。~ ライブラリ内のリストに登録されていないIDは無視される。 bool DXL_SetOperatingModesEquival (TDeviceID dvid, const uint8_t *ids, int num, uint8_t mode); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --int '''num''' ~対象とするID数 --uint8_t '''mode''' ~[[Dynamixel Xシリーズの動作モード>X Series Control table#j5c7292f]]を想定し、それに完全対応しないデバイスに対しては近似値もしくは失敗を返す。~ 0: Current Control~ 1: Velocity Control~ 3: Position Control~ 4: Expand Position Control~ 5: Current-Base Position Control~ 16: PWM Control -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); uint8_t ids[3] = {1, 2, 3}; // ID:1~3を検索し見つかれば登録 for (int i = 0; i < sizeof (ids); i++) DXL_GetModelInfo (dev, ids[i]); // ID:1~3をVelocity Controlに設定 DXL_SetOperatingModesEquival (dev, ids, sizeof (ids), 1); DX2_ClosePort (dev); } </pre> }} ****DXL_GetOperatingMode [#r99e31c3] 対象IDの動作モードを取得する。なお内部ではDrive Modeも一緒に取得し保持している。 bool DXL_GetOperatingMode (TDeviceID dvid, uint8_t id, uint8_t *mode); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --uint8_t '''*mode''' ~取得した動作モードの保存先。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***LED[#xf29b16b] Dynamixelに備わっているLEDは全てのモデルにおいてコントロールテーブル上の同じアドレスに割り当てがなされている訳では無いため、デバッグに有用なLEDを一つのAPIで使用できます。 ****DXL_SetLED [#z55d09d0] 対象IDのLEDを明滅させる。 bool DXL_SetLED (TDeviceID dvid, uint8_t id, bool en); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --bool '''en''' ~trueで点灯、falseで消灯。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。 ***制御ON/OFF [#i3fd9a94] コントロールテーブル上でトルクイネーブルと称しているアイテムは、LED同様にモデルによってアドレスが異なります。制御の開始と停止を司るため、こちらも同じAPIで運用できます。 ****DXL_SetTorqueEnable [#j4f978f0] 対象IDの制御を開始ないし停止させる。~ なお、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetTorqueEnable (TDeviceID dvid, uint8_t id, bool en); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --bool '''en''' ~trueで開始、falseで停止。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); DXL_GetModelInfo (dev, 1); DXL_SetOperatingMode (dev, 1, 3); // ID:1の制御をON DXL_SetTorqueEnable (dev, 1, true); // ID:1へ角度指令 180deg DXL_SetGoalAngle (dev, 1, 180.0); // 1000ms待機 Sleep (1000); // ID:1の制御をOFF DXL_SetTorqueEnable (dev, 1, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetTorqueEnables [#x43cf46c] 複数IDの制御を個別に開始ないし停止させる。~ ライブラリ内のリストに登録されていないIDは無視される。~ なお、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetTorqueEnables (TDeviceID dvid, const uint8_t *ids, const bool *ens, int num); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const bool '''*ens''' ~idsで指定されたID順にtrueで開始、falseで停止を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_SetTorqueEnablesEquival [#je2874de] 複数IDの制御を一括で開始ないし停止させる。~ ライブラリ内のリストに登録されていないIDは無視される。~ なお、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetTorqueEnablesEquival (TDeviceID dvid, const uint8_t *ids, int num, bool en); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --int '''num''' ~対象とするID数 --bool '''en''' ~trueで開始、falseで停止。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); DXL_GetModelInfo (dev, 1); DXL_GetModelInfo (dev, 2); DXL_GetModelInfo (dev, 3); uint8_t ids[3] = {1, 2, 3}; // ID:1~3の制御をON DXL_SetTorqueEnablesEquival (dev, ids, sizeof (ids), true); DX2_ClosePort (dev); } </pre> }} ****DXL_GetTorqueEnable [#q530f74d] 対象IDのトルクイネーブル状態を取得する。 bool DXL_GetTorqueEnable (TDeviceID dvid, uint8_t id, bool *en); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --bool *'''en''' ~取得したトルクイネーブルの保存先。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_GetTorqueEnables [#uaf219a6] 複数IDのトルクイネーブル状態を取得する。~ ライブラリ内のリストに登録されていないIDは無視される。 bool DXL_GetTorqueEnables (TDeviceID dvid, const uint8_t *ids, bool *en, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --bool *'''en''' ~idsで指定されたID順に取得したトルクイネーブルを保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***角度 [#n65074dc] DynamixelのコントロールテーブルではPositionと称しているユニークな単位系を持つアイテムは、モデルによって動作角度や分解能が大きく異なります。異なるモデルを混在して運用する場合は非常に不便なため、物理値の角度[deg]を用いてアクセスします。 ****DXL_SetGoalAngle [#e1977b03] 指定IDへ目標角度を指令する。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAngle (TDeviceID dvid, uint8_t id, double angle); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''angle''' ~目標角度[deg]。中立位置を0[deg]とする。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); DXL_GetModelInfo (dev, 1); DXL_SetOperatingMode (dev, 1, 3); DXL_SetTorqueEnable (dev, 1, true); // ID:1へ角度指令 180deg DXL_SetGoalAngle (dev, 1, 180.0); Sleep (1000); // ID:1へ角度指令 -180deg DXL_SetGoalAngle (dev, 1, -180.0); Sleep (1000); // ID:1へ角度指令 0deg DXL_SetGoalAngle (dev, 1, 0.0); Sleep (1000); DXL_SetTorqueEnable (dev, 1, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetGoalAngles [#s1f41399] 複数IDへ個別の目標角度を指令する。~ ライブラリ内のリストに登録されていないIDは無視される。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAngles (TDeviceID dvid, const uint8_t *ids, const double *angles, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const double '''*angles''' ~idsで指定されたID順に目標角度[deg]を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); DXL_GetModelInfo (dev, 1); DXL_GetModelInfo (dev, 2); DXL_GetModelInfo (dev, 3); uint8_t ids[3] = {1, 2, 3}; DXL_SetOperatingModesEquival (dev, ids, sizeof (ids), 3); DXL_SetTorqueEnablesEquival (dev, ids, sizeof (ids), true); // 3軸分の角度を保存したの配列 double angles[3] = { 0.0, 150.0, 300.0 }; // 3軸分の角度指令 DXL_SetGoalAngles (dev, ids, angles, sizeof (ids)); Sleep (2000); DXL_SetTorqueEnablesEquival (dev, ids, sizeof (ids), false); DX2_ClosePort (dev); } </pre> }} ****DXL_GetPresentAngle [#fb59c621] 対象IDの現在角度を取得する。 bool DXL_GetPresentAngle (TDeviceID dvid, uint8_t id, double *angle); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''*angle''' ~取得した現在角度[deg]の保存先。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <stdio.h> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); uint8_t id = 1; DXL_GetModelInfo (dev, id); DXL_SetOperatingMode (dev, id, 3); DXL_SetTorqueEnable (dev, id, true); DXL_SetGoalAngle (dev, id, -180.0); Sleep (1000); DXL_SetGoalAngle (dev, id, 180.0); for (int i = 0; i < 1000; i++) { double pang; // 現在角度取得 if (DXL_GetPresentAngle (dev, id, &pang)) printf ("%5.1\r", pang); Sleep (10); } DXL_SetTorqueEnable (dev, id, false); DX2_ClosePort (dev); } </pre> }} ****DXL_GetPresentAngles [#i142d062] 複数IDの現在角度を取得する。~ ライブラリ内のリストに登録されていないIDは無視される。 bool DXL_GetPresentAngles (TDeviceID dvid, const uint8_t *ids, double *angles, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --bool *'''angles''' ~idsで指定されたID順に取得した現在角度[deg]を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***停止 [#jf8a4f51] 制御をOFFにする事で制御が停止するのと合わせて脱力状態になります。それでは現在の角度を保持しつつ止めることができないため、指令されたタイミングの角度を取得してその値をそのまま角度指令し直す機能を設けています。 ****DXL_StandStillAngle [#l0d88042] 指定IDを現在角度で停止させる。~ 動作モードがPosition Controlである事。 bool DXL_StandStillAngle (TDeviceID dvid, uint8_t id); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_StandStillAngles [#ycb32de3] 複数IDを現在角度で停止させる。~ ライブラリ内のリストに登録されていないIDは無視される。~ 動作モードがPosition Controlである事。 bool DXL_StandStillAngles (TDeviceID dvid, const uint8_t *ids, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***角速度 [#k0c728ab] DynamixelのコントロールテーブルではVelocityと称しているユニークな単位系を持つアイテムは、モデルによってレンジや分解能が異なります。異なるモデルを混在して運用する場合は非常に不便なため、物理値の角速度[deg/sec]を用いてアクセスします。 ****DXL_SetGoalVelocity [#h69c7a42] 指定IDへ目標角速度を指令する。~ 動作モードがVelocity Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalVelocity (TDeviceID dvid, uint8_t id, double velocity); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''velocity''' ~目標角速度[deg/s]。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); DXL_GetModelInfo (dev, 1); DXL_SetOperatingMode (dev, 1, 1); DXL_SetTorqueEnable (dev, 1, true); // 角速度指令 30deg/s DXL_SetGoalVelocity (dev, 1, 30.0); Sleep (1000); // 角速度指令 40deg/s DXL_SetGoalVelocity (dev, 1, 40.0); Sleep (1000); DXL_SetTorqueEnable (dev, 1, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetGoalVelocities [#f05ae68b] 複数IDへ個別の目標角速度を指令する。~ ライブラリ内のリストに登録されていないIDは無視される。~ 動作モードがVelocity Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalVelocities (TDeviceID dvid, const uint8_t *ids, const double *velocities, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const double '''*velocities''' ~idsで指定されたID順に目標角速度[deg/s]を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_GetPresentVelocity [#d72c96dd] 対象IDの現在角速度を取得する。 bool DXL_GetPresentVelocity (TDeviceID dvid, uint8_t id, double *velocity); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''*velocity''' ~取得した現在角速度[deg/s]の保存先。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_GetPresentVelocities [#o2ae7240] 複数IDの現在角速度を取得する。~ ライブラリ内のリストに登録されていないIDは無視される。 bool DXL_GetPresentVelocities (TDeviceID dvid, const uint8_t *ids, double *velocities, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --bool *'''velocities''' ~idsで指定されたID順に取得した現在角速度[deg/s]を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***角度と角速度 [#w97ee5a9] 角度と合わせて角速度を同時に指令することで、指定角度へゆっくり動かすと行った動作を行わせる事ができます。~ なお、Dynamixelの角速度制御の分解能はさほど大きくないため、角速度が低い場合は誤差が大きくなります。 ****DXL_SetGoalAngleAndVelocity [#e7da1de8] 指定IDへ目標角度と目標角速度を指令する。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAngleAndVelocity (TDeviceID dvid, uint8_t id, double angle, double velocity); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''angle''' ~目標角度[deg]。 --double '''velocity''' ~目標角速度[deg/s]。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); uint8_t id = 3; DXL_GetModelInfo (dev, id); DXL_SetOperatingMode (dev, id, 3); DXL_SetTorqueEnable (dev, id, true); // 現在角度から-170degの角度へ30deg/sの角速度で DXL_SetGoalAngleAndVelocity (dev, id, -170.0, 30.0); Sleep (10000); // 現在角度から160degの角度へ40deg/sの角速度で DXL_SetGoalAngleAndVelocity (dev, id, 160.0, 40.0); Sleep (10000); DXL_SetTorqueEnable (dev, id, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetGoalAnglesAndVelocities [#xf5a9edf] 複数IDへ個別の目標角度と目標角速度を指令する。~ ライブラリ内のリストに登録されていないIDは無視される。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAnglesAndVelocities (TDeviceID dvid, const uint8_t *ids, const PAngleVelocity anglevelocity, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const [[PAngleVelocity>#PAngleVelocity]] '''anglevelocity''' ~idsで指定されたID順に目標角度[deg]と目標角速度[deg/s]を保持する構造体の配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***角度と時間 [#fc6d5a92] 角度と合わせて時間を同時に指令します。ライブラリ内では時間を角速度(=(目標角度-現在角度)/移動時間)に変換して指令します。~ なお、Dynamixelの角速度制御の分解能はさほど大きくないため、移動速度が長い場合は誤差が大きくなります。~ また事前にDXL_SetDriveModeもしくはDXL_SetDriveModesEquivalでVelocity-Base Profile(出荷時デフォルト)を指定しておく必要があります。~ 最新のファームウェアを備えたDynamixelの場合は[[角度と時間2>#h3998856]]のAPIを利用することを推奨します。 ****DXL_SetGoalAngleAndTime [#m7b677e1] 指定IDへ目標角度と現在角度から目標角度までの移動時間を指令する。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAngleAndTime (TDeviceID dvid, uint8_t id, double angle, double sec); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''angle''' ~目標角度[deg]。 --double '''sec''' ~移動時間[sec]。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); uint8_t id = 3; DXL_GetModelInfo (dev, id); DXL_SetOperatingMode (dev, id, 3); DXL_SetTorqueEnable (dev, id, true); // 現在角度から-150degの角度へ3秒で移動 DXL_SetGoalAngleAndTime (dev, id, -150.0, 3.0); Sleep (4000); // 現在角度から180degの角度へ5秒で移動 DXL_SetGoalAngleAndTime (dev, id, 180.0, 5.0); Sleep (6000); DXL_SetTorqueEnable (dev, id, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetGoalAnglesAndTime [#e7666eb0] 複数IDへ個別の目標角度と現在角度から目標角度までの移動時間を指令する。~ ライブラリ内のリストに登録されていないIDは無視される。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAnglesAndTime (TDeviceID dvid, const uint8_t *ids, const double *angles, int num, double sec); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const double '''*angles''' ~idsで指定されたID順に目標角度[deg]を保持する配列の保存先。 --int '''num''' ~対象とするID数 --double '''sec''' ~目標移動時間[sec]。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***角度と時間2 [#h3998856] 角度と合わせて時間を同時に指令します。目的は[[先のAPI>#fc6d5a92]]と同様ですが、Dynamixelの新しいファームウェアに備わっているTime-Base Profileを用いて指令するため、指定時間通りに目標角度に到達します。~ 事前に[[DXL_SetDriveMode>#v277bea5]]もしくは[[DXL_SetDriveModesEquival>#d70d54e6]]でTime-Base Profileを設定しておく必要があります。 ****DXL_SetGoalAngleAndTime2 [#z4d26a27] 指定IDへ目標角度と現在角度から目標角度までの移動時間を指令する。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAngleAndTime2 (TDeviceID dvid, uint8_t id, double angle, double sec); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''angle''' ~目標角度[deg]。 --double '''sec''' ~移動時間[sec] (0.0~32.767)。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); uint8_t id = 3; DXL_GetModelInfo (dev, id); // Time-Base profileを設定 DXL_SetDriveMode (dev, id, 0x04); DXL_SetOperatingMode (dev, id, 3); DXL_SetTorqueEnable (dev, id, true); // 現在角度から-150degの角度へ3秒で移動 DXL_SetGoalAngleAndTime2 (dev, id, -150.0, 3.0); Sleep (4000); // 現在角度から180degの角度へ5秒で移動 DXL_SetGoalAngleAndTime2 (dev, id, 180.0, 5.0); Sleep (6000); DXL_SetTorqueEnable (dev, id, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetGoalAnglesAndTime2 [#d7df7383] 複数IDへ個別の目標角度と現在角度から目標角度までの移動時間を指令する。~ ライブラリ内のリストに登録されていないIDは無視される。~ 動作モードがPosition Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalAnglesAndTime2 (TDeviceID dvid, const uint8_t *ids, const double *angles, int num, double sec); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const double '''*angles''' ~idsで指定されたID順に目標角度[deg]を保持する配列の保存先。 --int '''num''' ~対象とするID数 --double '''sec''' ~移動時間[sec] (0.0~32.767)。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***電流 [#s6aa8f95] 電流センサを搭載したモデルのみで使用できます。 ****DXL_SetGoalCurrent [#wa3ee92b] 指定IDへ目標電流を指令する。~ プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalCurrent (TDeviceID dvid, uint8_t id, double current); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''current''' ~目標電流[mA]。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); DXL_GetModelInfo (dev, 1); DXL_SetOperatingMode (dev, 1, 0); DXL_SetTorqueEnable (dev, 1, true); // 電流指令 200mA DXL_SetGoalCurrent (dev, 1, 200.0); Sleep (1000); // 電流指令 -200mA DXL_SetGoalAngle (dev, 1, -200.0); Sleep (1000); DXL_SetTorqueEnable (dev, 1, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetGoalCurrents [#z0c18d06] 複数IDへ個別の目標電流を指令する。~ ライブラリ内のリストに登録されていないIDは無視される。~ プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalCurrents (TDeviceID dvid, const uint8_t *ids, const double *currents, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const double '''*currents''' ~idsで指定されたID順に目標電流[mA]を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_GetPresentCurrent [#sacbfb55] 指定IDの現在電流を取得する。 bool DXL_GetPresentCurrent (TDeviceID dvid, uint8_t id, double *current); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''*current''' ~取得した現在電流[mA]の保存先。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_GetPresentCurrents [#d8f1e099] 複数IDの現在電流を取得する。~ ライブラリ内のリストに登録されていないIDは無視される。 bool DXL_GetPresentCurrents (TDeviceID dvid, const uint8_t *ids, double *currents, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --bool *'''currents''' ~idsで指定されたID順に取得した現在電流[mA]を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ***PWM [#v2e45701] 現時点でXシリーズのみで使用でき、モデルが異なっていてもできる限り同じ運用ができるよう物理値のデューティー比[%]を用いてアクセスします。 ****DXL_SetGoalPWM [#h83a6441] 指定IDへ目標PWMを指令する。~ 動作モードがPWM Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalPWM (TDeviceID dvid, uint8_t id, double pwm); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''pwm''' ~目標PWM[%]。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ -使用例 #html{{ <pre class="brush: c;"> #include <dx2lib.h> void main (void) { TDeviceID dev = DX2_OpenPort ("\\\\.\\COM10", 57600); DXL_GetModelInfo (dev, 1); DXL_SetOperatingMode (dev, 1, 16); DXL_SetTorqueEnable (dev, 1, true); // PWM指令 50% DXL_SetGoalPWM (dev, 1, 50.0); Sleep (1000); // PWM指令 -40% DXL_SetGoalPWM (dev, 1, -40.0); Sleep (1000); DXL_SetTorqueEnable (dev, 1, false); DX2_ClosePort (dev); } </pre> }} ****DXL_SetGoalPWMs [#ba8464e4] 複数IDへ個別の目標PWMを指令する。~ ライブラリ内のリストに登録されていないIDは無視される。~ 動作モードがPWM Controlである事と、プロトコルV2のDynamixelは明示的に制御を開始しない限りモータの制御を行わない。 bool DXL_SetGoalPWMs (TDeviceID dvid, const uint8_t *ids, const double *pwms, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --const double '''*pwms''' ~idsで指定されたID順に目標PWM[%]を保持する配列の保存先。 --int '''num''' ~対象とするID数 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_GetPresentPWM [#n50d706e] 指定IDの現在PWMを取得する。 bool DXL_GetPresentPWM (TDeviceID dvid, uint8_t id, double *pwm); -パラメータ --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''id''' ~対象とするID (0~252)。 --double '''*pwm''' ~取得した現在PWM[%]の保存先。 -戻り値 --bool ~処理が正常終了したらtrue、それ以外はfalseを返す。~ ****DXL_GetPresentPWMs [#n82d7982] 複数IDの現在PWMを取得する。~ ライブラリ内のリストに登録されていないIDは無視される。 bool DXL_GetPresentPWMs (TDeviceID dvid, const uint8_t *ids, double *pwms, int num); --[[TDeviceID>#TDeviceID]] '''dvid''' ~DX?_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 --uint8_t '''*ids''' ~対象とするID一覧を保持する配列の保存先。 --bool *'''pwms''' ~idsで指定されたID順に取得した現在PWM[%]を保持する配列の保存先。 --int '''num''' ~対象とするID数 ***オリジナルな定義 [#b0574c7a] &aname(TDXL_DevType); :TDXL_DevType | enum {&br; devtNONE, devtDX, devtAX, devtRX, devtEX, devtMX, devtXL320, devtPRO, devtPROP, devtX&br; }~ デバイスのグループ分け。Dynamixelは概ねのこのグループで機能が大別される。 &aname(TDXL_ModelInfo); &aname(PDXL_ModelInfo); :TDXL_ModelInfo, *PDXL_ModelInfo | struct {&br; uint16_t modelno; // デバイス固有のモデル番号&br; char name[16]; // デバイス名&br; [[TDXL_DevType>#TDXL_DevType]] devtype; // デバイスのグループ&br; struct { // 位置の範囲&br; int32_t max;&br; int32_t min;&br; } positionlimit;&br; struct { // 角度の範囲&br; double max;&br; double min;&br; } anglelimit;&br; struct { // 速度の範囲&br; int32_t max;&br; int32_t min;&br; } velocitylimit;&br; struct { // PWMの範囲&br; int32_t max;&br; int32_t min;&br; } pwmlimit;&br; double velocityratio; // 角速度変換係数 [deg/sec]&br; double currentratio; // 電流変換係数 [mA]&br; double pwmratio; // PWM変換係数 [%]&br; }~ Dynamixel固有の情報(モデル名や本APIで使用する各制御値の物理値変換係数等)をまとめた構造体でアライメントは1バイト。
(This host) = http://www.besttechnology.co.jp