TITLE:ロボットハンドを動かす *ロボットハンドを動かす [#u69e0124] **Dynamixel Configuratorで動かす [#i7e648cf] まずは確認のため、[[Dynamixel Configurator>BTE068]]でAX-12+を作動させてみましょう。トルク設定をしていませんので、ポジション移動の際は十二分に注意して下さい。~ ID1からID6まで以下の手順を繰り返します。 +「Read All」で状態を読み込む。 +ダイヤルでポジションを移動する。 **物を掴む [#a91d93dc] ID1~ID3でハンド部分の位置が決まり、ID5、6でハンド部分が開閉します。~ 空のペットボトル等を掴んで持ち上げてみましょう。 #ref(Clip.png) 如何でしょうか。持ち上げることができたでしょうか。~ Dynamixel Configuratorでは、個々のアクチュエータにそれぞれ手動で指令を行わなければならず、随分と手間がかかるのではないでしょうか。~ ID1のゴールポジションを変更することで右へ旋回します。旋回後、腕を下して掴み上げたものを下してください。~ では、Dynamixel Configuratorでの操作をプログラムで再現してみましょう。 **プログラムする [#bc44f46d] ロボットハンドの左につかむ物を設置して下さい。腕の先へ掴めるものが来るように配置しましょう。 #html{{ <pre class="brush:c"> #include <fd.h> // メイン関数 void main (void) { fd_SetBeepCondition (FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP); fd_SetUVThreshold (7.4); DX_ChangeBaudrate (1000000); fd_Wait (2000); // 基本姿勢の作成 fd_DXSetPosition (1, 512); fd_DXSetPosition (2, 512); fd_DXSetPosition (3, 512); fd_DXSetPosition (4, 512); fd_DXSetPosition (5, 512); fd_Wait (1000); // 左へターン fd_DXSetPosition (1, 605); fd_Wait (500); // 開く fd_DXSetPosition (5, 362); fd_DXSetPosition (6, 662); fd_Wait (1000); // 腕を下げる fd_DXSetPosition (2, 818); fd_Wait (1000); // 挟む fd_DXSetPosition (5, 542); fd_DXSetPosition (6, 482); fd_Wait (1000); // 持ち上げる fd_DXSetPosition (2, 512); fd_Wait (1000); // 右へ移動 fd_DXSetPosition (1, 419); fd_Wait (1000); // 腕を下げる fd_DXSetPosition (2, 818); fd_Wait (1000); // 離す fd_DXSetPosition (5, 362); fd_DXSetPosition (6, 662); fd_Wait (1000); // 基本姿勢へ戻る fd_DXSetPosition (1, 512); fd_DXSetPosition (2, 512); fd_DXSetPosition (3, 512); fd_DXSetPosition (4, 512); fd_DXSetPosition (5, 512); fd_Wait (1000); } </pre> }} 今回はDynamixel Configuratorでの操作をそのままプログラムしました。指定位置は掴むものに合った値に変更して下さい。~ まだ動きが随分とぎこちないですね。もう少し滑らかに動くように修正します。 **モーションを使用する [#q1da695a] [[FREEDOM Ⅲライブラリ>FDIIILIB]]には、モーションに関するAPIが用意されていますので、動作をモーションに置き換えてみます。 #html{{ <pre class="brush:c"> #include <fd.h> #define fd_SetSpec(a,b,c) fd_SetSpec((PHomePosition)a,(PSpec)b,c) #define fd_SetHomePosition(a) fd_SetHomePosition((PHomePosition)a) #define fd_PlayMotion(a,b,c,d,e) fd_PlayMotion((PPose)a,b,c,d,e) const THomePosition HomePos = { 512, 512, 512, 512, 512 , 512 }; const TSpec Spec[] = { { 1, DEV_AX12, fd_AxisOfs(0), +341, { 257, 768}, 0, 1023, { 1, 1, 32, 32} }, { 2, DEV_AX12, fd_AxisOfs(1), +341, { 390, 818}, 0, 1023, { 1, 1, 32, 32} }, { 3, DEV_AX12, fd_AxisOfs(2), +331, { 64, 512}, 0, 1023, { 1, 1, 32, 32} }, { 4, DEV_AX12, fd_AxisOfs(3), +331, { 0, 1023}, 0, 1023, { 1, 1, 32, 32} }, { 5, DEV_AX12, fd_AxisOfs(4), +331, { 0, 592}, 0, 1023, { 1, 1, 32, 32} }, { 6, DEV_AX12, fd_AxisOfs(5), +331, { 432, 1023}, 0, 1023, { 1, 1, 32, 32} }, }; TApplyPart HandParts = { // 全軸ロボットハンド Priority: 1, PartNum: 6, Part: { fd_AxisOfs(0), fd_AxisOfs(1), fd_AxisOfs(2), fd_AxisOfs(3), fd_AxisOfs(4), fd_AxisOfs(5) } }; TPose pose [FD_MAX_POSE_NUM]; /*======================================================================*/ // * モーションデータ const TPose WorkMotion [] = { { Structure:{ 0, 0, 0, 0, 0, 0 }, Adj:ADJ_SACC_SDECEL, Div:2000, }, // ホームポジション { Structure:{ 450, 0, 0, 0, 0, 0 }, Adj:ADJ_SACC_SDECEL, Div:1000, }, // 左旋回 { Structure:{ 450, 0, 0, 0, -900, 900 }, Adj:ADJ_SACC_SDECEL, Div:1000, }, // 指を開く { Structure:{ 450, 300, -300, 0, -900, 900 }, Adj:ADJ_SACC_SDECEL, Div:500, }, // 腕を下げる { Structure:{ 450, 450, -450, 0, -900, 900 }, Adj:ADJ_SACC_SDECEL, Div:500, }, { Structure:{ 450, 600, -300, 0, -900, 900 }, Adj:ADJ_SACC_SDECEL, Div:500, }, { Structure:{ 450, 900, 0, 0, -900, 900 }, Adj:ADJ_SACC_SDECEL, Div:500, }, { Structure:{ 450, 900, 0, 0, 300, -300 }, Adj:ADJ_SACC_SDECEL, Div:1000, }, // 指を閉じる { Structure:{ 450, 600, 0, 0, 300, -300 }, Adj:ADJ_SACC_SDECEL, Div:500, }, // 腕を上げる { Structure:{ 450, 450, -450, 0, 300, -300 }, Adj:ADJ_SACC_SDECEL, Div:500, }, { Structure:{ -900, 450, -450, 0, 300, -300 }, Adj:ADJ_SACC_SDECEL, Div:1000, }, // 右旋回 { Structure:{ -900, 600, 0, 0, 300, -300 }, Adj:ADJ_SACC_SDECEL, Div:500, }, // 腕を下げる { Structure:{ -900, 900, 0, 0, 300, -300 }, Adj:ADJ_SACC_SDECEL, Div:500, }, { Structure:{ -900, 900, 0, 0, -900, 900 }, Adj:ADJ_SACC_SDECEL, Div:1000, }, // 指を開く { Structure:{ -900, 0, 0, 0, -900, 900 }, Adj:ADJ_SACC_SDECEL, Div:1000, }, // 腕を上げる { Structure:{ 0, 0, 0, 0, 0, 0 }, Adj:ADJ_SACC_SDECEL, Div:1000, }, // ホームポジション }; /*======================================================================*/ /* メイン関数 */ /*======================================================================*/ void main (void) { // 初期化 fd_SetBeepCondition (FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP); fd_SetUVThreshold (7.4); DX_ChangeBaudrate (1000000); fd_Wait (2000); // モーション初期設定 fd_SetSpec (&HomePos, Spec, fd_SpecSize (Spec)); // ホームポジションを設定 fd_SetHomePosition (HomePos); // モーション実行 fd_PlayMotion (WorkMotion, 1, sizeof(WorkMotion)/sizeof(TPose), 100, &HandParts); // モーション終了待機 while (fd_GetMotionStat (&HandParts)) fd_Wait (10); // トルクOFF fd_SetDXEnableControl (false, &HandParts); } </pre> }} ***解説 [#j28efc99] 少しは滑らかに動いたのではないでしょうか。では、モーションの使用について説明します。 ****ホームポジション [#i4a94692] 基本となる位置を指定します。モーションはホームポジションを基準に指定された角度で動きます。 #html{{ <pre class="brush:c;first-line:6"> const THomePosition HomePos = { 512, 512, 512, 512, 512 , 512 }; </pre> }} 今回は全てのAX-12+に対し、512を指定しています。これはAX-12+の出力軸に対し150°の位置指定を行うことになります。
(This host) = http://www.besttechnology.co.jp