3: 2010-07-07 (水) 12:41:54 sho | 4: 2010-07-07 (水) 17:52:25 sho | ||
---|---|---|---|
Line 1: | Line 1: | ||
*プログラミング [#tb098c25] | *プログラミング [#tb098c25] | ||
- | 前進したり、相手を探したり、土俵際に来たらバックしたりする車輪ロボットのプログラムを作成します。 | + | 前進したり、相手を探したり、土俵際に来たらバックしたりする相撲ロボットのプログラムを作成します。 |
**処理の流れを図にする。 [#q9a32975] | **処理の流れを図にする。 [#q9a32975] | ||
+ | |||
+ | #ref("sumou_block.png") | ||
**準備 [#l8e0d6a8] | **準備 [#l8e0d6a8] | ||
Line 16: | Line 18: | ||
**AX-12+をエンドレスターンモードに切りかえる [#jc4c05f3] | **AX-12+をエンドレスターンモードに切りかえる [#jc4c05f3] | ||
- | これまでAX-1+に、0から300度の間のある位置へ動けという命令を出しました。これを位置決めモードといいます。位置決めモードでは、AX-12+のホーンを車輪のようにクルクル回転させることはできません。 | + | これまでは、AX-1+に対し、0から300度間のある位置へ動けという命令を出してきました。これを位置決めモードといいます。位置決めモードでは、AX-12+のホーンを車輪のようにクルクル回転させることはできません。 |
- | 車輪の様に扱うためにはエンドレスターンモードに設定する必要があります。 | + | 車輪の様に扱うためには、エンドレスターンモードに設定する必要があります。 |
fd_Initの後ろに | fd_Initの後ろに | ||
fd_DXSetEndlessTurn (1, 1); | fd_DXSetEndlessTurn (1, 1); | ||
fd_DXSetEndlessTurn (2, 1); | fd_DXSetEndlessTurn (2, 1); | ||
と入力します。 | と入力します。 | ||
- | fd_DXSetEndlessTurnは、エンドレスターンモードに設定する、又は位置決めモードに戻す関数です。 | + | fd_DXSetEndlessTurnは、エンドレスターンモードに設定、又は位置決めモードに設定する関数です。 |
''第1引数''は、DynamixelのIDです。 | ''第1引数''は、DynamixelのIDです。 | ||
- | ''第2引数''は、エンドレスターンと位置決めモードの切り替えです。1でエンドレスターン、0で位置決めモードに設定します。 | + | ''第2引数''は、エンドレスターンと位置決めモードの切り替え値です。1でエンドレスターン、0で位置決めモードに設定します。 |
- | ID1と2のAX-12+をエンドレスターンモードに設定しています。 | + | ここでは、IDが1と2のAX-12+をエンドレスターンモードに設定しています。 |
**AX-S1の赤外線反射センサの値を取得する [#d3df0f37] | **AX-S1の赤外線反射センサの値を取得する [#d3df0f37] | ||
Line 47: | Line 49: | ||
と入力します。 | と入力します。 | ||
3方向のセンサの値を取得し、それを表示します。 | 3方向のセンサの値を取得し、それを表示します。 | ||
- | whileループで囲ってループさせます。 | + | while文で囲ってループさせます。 |
- | ここでプログラムを実行して、3方向のセンサの値の変化を見てみましょう。 | + | ここで適当に名前を付けて保存し、コンパイルします。 |
+ | FDIII-HCに書き込んでプログラムを実行し、3方向のセンサの値の変化を見てみましょう。 | ||
- | RightDataは地面の方向に向いているので常に255となります。 | + | RightDataは、地面の方向に向いているので常に255となります。 |
もしAX-S1を反対に取り付けていたらLeftDataです。以下LeftDataとRightDataを読み替えて下さい。 | もしAX-S1を反対に取り付けていたらLeftDataです。以下LeftDataとRightDataを読み替えて下さい。 | ||
- | CenterDataとLeftDataは手を近づけると値が変わります。 | + | CenterDataとLeftDataは、手を近づけると値が変わります。 |
**前に進む [#dadc53a1] | **前に進む [#dadc53a1] | ||
Line 62: | Line 65: | ||
| Value | 0 | 回転方向 | 回転速度 | | | Value | 0 | 回転方向 | 回転速度 | | ||
- | 回転速度のデータは2バイト、つまり16ビットです。上表のように、16ビットの中のビット11が1なら右回転、0なら左回転です。ビット1~10は回転速度です。 | + | 回転速度のデータは2バイト、つまり16ビットです。上表のように、16ビットの中のビット11が1なら右回転、0なら左回転になります。ビット1~10は回転速度です。 |
エンドレスターンの設定の後に | エンドレスターンの設定の後に | ||
Line 69: | Line 72: | ||
と入力します。 | と入力します。 | ||
- | ID=1のAX12+のアドレス32に(1 << 10) + 500を書き込みます。 | + | ID=1のAX12+のアドレス32,33に(1 << 10) + 500を書き込みます。 |
- | (1 << 10)は、1を10だけ桁の大きいほうへビットシフトすると言う意味です。 | + | (1 << 10)は、1を10だけ桁の大きいほうへ、ビットシフトすると言う意味です。 |
- | つまり2進数で書くと、00000000001の1を左へ10だけ移動して、10000000000となります。これを回転速度の値、ここでは500に足すことで、回転方向を決めるビット11を1に設定します。 | + | つまり2進数で書くと、00000000001の1を左へ10だけ移動して、10000000000となります。これを回転速度の値(ここでは500)に足すことで、回転方向を決めるビット11を1に設定します。 |
AX-12+は左右対称に設置されているので、回転方向は逆にします。 | AX-12+は左右対称に設置されているので、回転方向は逆にします。 | ||
Line 79: | Line 82: | ||
**土俵際にきたらバックする [#r7679d07] | **土俵際にきたらバックする [#r7679d07] | ||
丸いテーブルを土俵と仮定します。 | 丸いテーブルを土俵と仮定します。 | ||
- | 真っ直ぐ進むといづれテーブルから落ちてしまいます。 | + | 真っ直ぐ進むと、いずれテーブルから落ちてしまいます。 |
そこで地面を向いている赤外線反射センサを使います。 | そこで地面を向いている赤外線反射センサを使います。 | ||
- | センサの値がある値より低くなったらバックします。 | + | センサがテーブルから外れ、センサ値がある閾値より低くなったらバックします。 |
while文中のセンサ値を取得した後ろに | while文中のセンサ値を取得した後ろに | ||
Line 101: | Line 104: | ||
プログラムを実行してみましょう。土俵際で前後に行ったりきたりしてしまいます。 | プログラムを実行してみましょう。土俵際で前後に行ったりきたりしてしまいます。 | ||
- | 土俵際に着たら暫くバックするようにします。 | + | 土俵際に着たら暫くの間、バックし続けるようにします。 |
- | バックの回転速度の設定の後に | + | バックするように回転速度を設定した箇所の後に |
fd_Wait (2000); | fd_Wait (2000); | ||
と入力します。 | と入力します。 | ||
Line 127: | Line 130: | ||
} | } | ||
に書き換えます。 | に書き換えます。 | ||
- | 正面のセンサの値が30より大きければ回転速度を1023、それ以外は500となります。 | + | 正面のセンサの値が30より大きければ回転速度を1023、それ以外は500とします。 |
プログラムを実行してみましょう。 | プログラムを実行してみましょう。 | ||
Line 133: | Line 136: | ||
**相手を探す [#ha0d0d54] | **相手を探す [#ha0d0d54] | ||
- | 暫く直進しても相手が見つからない場合は、旋回して辺りを探します。 | + | 暫く直進しても相手が見つからない場合は、旋回して辺りを探してみましょう。 |
- | 「暫く」を「while文が100周したら」に置き換えて考えます。 | + | 「暫く直進する」を「while文が100周するまで触診する」に置き換えて考えます。 |
while文のループ回数をカウントする変数countを宣言します。 | while文のループ回数をカウントする変数countを宣言します。 | ||
main関数の最初に | main関数の最初に | ||
int count = 0; | int count = 0; | ||
と入力します。 | と入力します。 | ||
- | 更にwhile文の最後に | + | 更にwhile文内の最後に |
count++; | count++; | ||
と入力します。while文が一回処理される毎に変数countが1増加します。 | と入力します。while文が一回処理される毎に変数countが1増加します。 | ||
Line 149: | Line 152: | ||
fd_DXWriteWordData (2, 32, (1 << 10) + 500); | fd_DXWriteWordData (2, 32, (1 << 10) + 500); | ||
} | } | ||
- | と入力します。A&&BはAかつBを表します。countが100より大きいかつCenterDataが31より小さい場合、if文の中を実行します。 | + | と入力します。if文の条件にある''A && B''は''AかつB''を表します。countが100より大きいかつCenterDataが31より小さい場合、if文の中を実行します。 |
CenterData < 31は、相手を見つけて突進している最中に旋回してしまわないようにするためです。 | CenterData < 31は、相手を見つけて突進している最中に旋回してしまわないようにするためです。 | ||
Line 162: | Line 165: | ||
if (CenterData > 30) i = 500; | if (CenterData > 30) i = 500; | ||
} | } | ||
- | と入力します。for文を500回ループさせ、for文内では正面センサ値の取得を繰り返します。もし正面センサの値が30より大きければ、iを500にして即座にfor文を抜けます。 | + | と入力します。for文を500回ループさせ、正面センサ値の取得を繰り返します。もし正面センサの値が30より大きければ、iを500にして即座にfor文を抜けます。 |
**プログラム完成 [#ba482b2d] | **プログラム完成 [#ba482b2d] |