沼津高専 電子制御工学科 |
MIRS0403 ソフトウェア取扱説明書 |
MIRS0403-SOFT-0003 |
|
改訂記録 |
版数 |
作成日 |
作成者 |
承認 |
改訂内容 |
A01 |
2005.2.14 |
柴田 龍治 |
上園隆文 |
初版 |
目次
- はじめに
- インストール手順
- 関数一覧
- 行動制御系関数
1.はじめに
本ドキュメントはMIRS0403を制御するソフトウェアの取扱説明書である。
2.インストール手順
本モジュールをカーネルに組み込む方法を以下に示す。
- 必要なファイル(mirs0403_soft.tar.gz)をダウンロードする。
- ファイルを解凍する。
>tar xzvf mirs0403_soft.tar.gz
- コンパイルする。
>make all
- モジュールを組み込む。
>insmod xxx
- uss_moduleが組み込まれていることを確認する。
>lsmod
モジュールを削除する場合は以下のコマンドを使う。
>rmmod xxx
3. 関数一覧
以下に、MIRS0403 で取り扱う関数の一覧を示す。
ソースファイル名 | 関数名 | 書式 | 戻り値 | 動作概要 |
first_try.c | main
| int main(void)
| なし
| 一回目の競技のメイン
|
second_try.c | main
| int main(void)
| なし
| ニ回目の競技のメイン
|
initialize.c | initialize
| int initialize(void)
| なし
| 初期化
|
start_move.c | start_move
| int start_move(void)
| なし
| スタート直後のポスト回避
|
step_search.c | step_search
| int step_seach(void)
| なし
| ポスト探索モード第一段階
|
correct_post_data.c | correct_post_data
| int correct_post_data(void)
| なし
| ポスト探索モード第二段階
|
post_data_check.c | post_data_check
| int post_data_check(int)
| なし
| ポストデータ確認モード
|
post_approach.c | post_approach
| int post_approach(int)
| なし
| ポスト接近モード
|
post_get.c | post_get
| int post_get(int)
| なし
| ポスト獲得モード
|
post_to_post2.c | post_to_post2
| int post_to_post2(int, int)
| なし
| ポスト間移動モード
|
post_crash.c | post_crash
| int post_crash(int, int)
| あり
| ポスト間ポスト検索モード
|
go_back_center.c | go_back_center
| int go_back_center(int)
| なし
| 中心帰還1
|
go_back_center2.c | go_back_center2
| int go_back_center2(int)
| なし
| 中心帰還2
|
go_back_center3.c | go_back_center3
| int go_back_center3(int)
| なし
| 中心帰還3
|
correct_center.c | correct_center
| int correct_center(void)
| なし
| 中心位置補正
|
4.行動制御系関数
int main(void)
MIRS0403 の競技一回目、二回目のメイン関数。
int initialize(void)
プログラムで使用する変数の初期化とFIFOやスレッドの生成を行っている。これはmain()を実行したときに一番初めに実行される関数である。
int start_move(void)
スタート直後に前方を確認して、ポストがあれば回避動作を行って中心へ向かう。
int step_seach(void)
これは、プロペラを回してポストの探索を行う関数である。ステッピングモータを200回転させてプロペラを360度回し、その後初期位置に戻す。その際に、1ステップごとに超音波センサの値を読み取り、そのときのステップ角も同時に配列に保存する。
int correct_post_data(void)
ポスト探索モードで得られたデータから各ポストの座標(極座標系)を決定する関数である。まず、step_search()で得られた200個のデータをポスト別にそれぞれ用意された二次元配列に分けて保存する。この時、各ポストのデータが5個以下であった場合は、それをポストと見なさずにそのデータを無視する。その後、分けられたポストごとのデータから、最も最適なデータを選ぶ。
int post_data_check(int correct_center_flag)
ポスト探索モードで得られた各ポストの座標が正しいか確認する関数。まず、各ポストの座標が現実的にありえる値かどうか確認する。具体的には、ポストの距離がUSS_MIN〜USS_MAXの範囲外であればそのポストのデータを消去する。さらに、correct_post_data()で計算された各ポストのデータ(距離と角度)をもとにプロペラを回し、その角度における超音波センサの値を読み取る。読み取った値と座標との差がポストの直径以上あれば、そのデータを消去する。
correct_center_flag は、ポスト探索モードか中心位置補正モードかを区別するための引数で、1のとき中心位置補正モードである。
int post_approach(int target_post)
指定されたポストに向かって接近する関数。target_post でポスト番号を与え、そのポストの座標を元に中心位置からそのポストに対して正対した後接近。さらにポスト手前30cmで再度正対し、ポスト周回開始点(ポストの手前8cm)まで移動する。
ポストに対する正対は、correct_direction2(),correct_direction1()で行う。
int post_get(int target_code)
ポストの獲得動作を行う関数。target_code で次に獲得すべきポストのコードを与える。この関数はポストに対して正対した状態から始まる。まず90度回転し、その後ポスト周回を始める。周回中に赤外線を検出したらコード判別を行い、target_codeと同じなら獲得動作に移る。獲得後は、周回開始位置まで残りを周回する。もとの位置にもどってきたところでこの関数を抜ける。
int post_to_post2(int target_post, int next_post_no)
二つのポスト間を直接移動する関数。引数 target_post と next_post_no で、現在のポスト番号(ポスト1とする)と次に接近するポスト番号(ポスト2とする)を与える。
この関数は post_get() 終了後のポスト1周回開始点から始まる。アルゴリズムとして、フィールド中心点と二つのポストの中心点を結ぶ三角形を考える。
まずポスト1とポスト2の座標から、ポスト1の中心点とポスト2の中心点を結ぶ直線aの長さを余弦定理により求める。求めた直線aの長さと、フィールド中心点から見たポスト1とポスト2の間の角度A、およびフィールド中心点からポスト2の中心点までの距離bから、正弦定理を応用して、ポスト1の中心点とフィールド中心点を結ぶ直線cと直線aのなす角度Bを求める。
求めた角度Bだけポスト1の周回を移動することにより、ポスト1とポスト2を結ぶ直線a上まで移動することができる。その後、直線aの長さとプロペラ右側の超音波センサの値を比較し、誤差が大きければポスト周回軌道上を前後に移動して補正を行う。補正終了後、90度回転しさらに前方の超音波センサで補正を行う。この時超音波で読み取った値を、ポスト1とポスト2間の距離として改めて保存する。
保存されたポスト間の距離をもとに、ポスト2の手前30cmまで移動し正対補正を行い、その上でポスト2の周回開始点まで移動する。
int post_crash(int target_post, int next_post_no)
今MIRSがいる場所から次に行きたい場所のあいだに他のポストがどのような順番で存在しているのかを調べる関数。他のポストが3個までならそのポストを今いる場所から近い順に並べる。4個以上は対応していない。上図において、中心点からPOST1に行くとき、POST1からPOST2に行くとき、POST2から中心点に行くときの3回使用する。
引数target_postは今いるPOST番号(中心点なら0)を与え、next_post_noは次に行きたいPOST番号(中心点なら0)を与える。
戻り値は、今MIRSがいる場所から次に行きたい場所の間にあるほかのポストの個数。ほかのポストの個数によって0から4までの値を返す。他のポストが3個までしか対応していないので、戻り値が4ならERRORということになる。競技2周目のプログラムでは戻り値が0と1の場合にのみ対応している。
int go_back_center(int post_no)
ポストからフィールド中心点まで戻る関数。post_to_post2()を行って、ポスト2の獲得が終了したところから開始する。上図における角度Cをポスト1とポスト2の座標から求め、角度Cを使って直線b上まで移動した後、フィールド中心まで戻る。その後、ポスト2の座標の角度から計算し初期位置の方向を向く。
引数 post_no でポスト2の番号を与える。
int go_back_center2(int post_no)
ポストからフィールド中心点まで戻る関数。POST1でpost_getを使用したあとに使う。post_crashにより、上図においてPOST1からPOST2にいく途中に他のポストがあるということがわかったときに、POST1からPOST2へいくことをやめて中心点に戻る。
引数post_noはPOST1の番号を与える。
int go_back_center3(int target_post, int next_post_no)
ポストからフィールド中心点まで戻る関数。POST2でpost_getを使用したあとに使う。post_crashにより、上図においてPOST2からフィールド中心点にいく途中に他のポストがあるということがわかったときに、POST2から一度POST1によってからフィールド中心点まで戻る。
引数target_postはPOST2の、next_post_noはPOST1の番号を与える。
int correct_center(void)
現地点からフィールド中心点までのズレを計算し、中心位置補正を行う。初めにstep_search(),correct_post_data()を行い、得られた各ポストのデータを post_tmp.dis[][],post_tmp.ang[][] に保存しなければならない。さらに、correct_center_flag を1としてpost_data_check() を行った上でこの関数を呼び出す。