目次
1. 本ドキュメントについて2. 統合プログラムで使われる外部変数について
3. 統合プログラム内のスレッドについて
4. 統合プログラム内の関数について
5. 統合プログラムのソース
1. 本ドキュメントについて
-
統合プログラムの説明書をつくる。
このドキュメントでは、統合プログラムと統合プログラム内の外部変数、スレッド、関数についてまとめる。
2. 統合プログラム内の外部変数について
統合プログラム内で定義されている外部変数には、flag, ang, *tsright, usflag, uss1, uss2, uss3 がある。
変数名 | 型 | 初期値 | 説明 | 関連関数 | |
---|---|---|---|---|---|
flag | int | 0 | モーターの動作許可のようなもの。flagが0以外の値であればモーターは目標値の前でも停止される。 | motor_flag.c | |
ang | double | 0 | MIRSの姿勢角を表す。競技開始時のMIRSの姿勢角を0度とする。 | motor_flag.c , adjust() | |
*tsright | char | タッチ、白線、赤外線のセンサの値を参照するためのポインタ。sensor_check.c内でtsright=irs_datとしてアドレスを与えている。 | sensor_check.c | ||
usflag | int | 0 | 超音波センサを使うスレッドに条件を与えたり、逆に超音波センサの状態をmainに伝えるための変数。 | ||
uss1 | int | 9999 | 超音波センサ(1〜3)の情報を伝えるための変数 | ||
uss2 | 9999 | ||||
uss3 | 0 |
3. 統合プログラム内のスレッドについて
統合プログラム内には、uss_dis_thread, uss_side_thread, uss_all_thread, motoflag_thread, sensor_thread,の5つのスレッド用の関数がある。これらの関数をプログラム内でスレッドをつくり呼び出している。
また、usflagという外部変数の値を操作することで、超音波センサを用いたスレッド(uss_dis_thread,uss_side_thread,uss_all_thread)を終了させたり、条件を変えている。
uss_dis_thread
前方の壁まで近づくときに使う。usflag==8では起動しない。usflagが10かつ超音波センサが40以下の値を4回返したときに、uss2の値を4649にすることで、mainのスレッドに前方の壁に近づいたことを伝える。
uss_side_thread
右側が壁か出口かを判断する。rotaryクリアに使う。usflag==9では起動しない。usflagが10かつ超音波センサが3回50以上の値を返し、さらにタッチセンサが触れていない場合に、uss3の値を4649にし、mainのスレッドに右側が出口であることを伝える。
uss_all_thread
前、右、左の超音波センサの値から、前、左、右それぞれが壁なのか移動可なのかを判断する。cosmoクリアに使う。usflag==7では起動しない。usflag==0がループの条件である。渡された引数が100だった場合には前左右3方向の状態に応じてusflagの値を変化させ、小部屋の状況を判断する。左が壁でなければusflagに+2し、右が壁でなければusflagに+1する。これでusflagが1なら左のみ壁ありの状態、2なら右のみ壁ありの状態、3なら左右ともに壁がない状態と判断できる。渡す引数を100にしなければただuss1,uss2,uss3にそれぞれの超音波センサの値を代入するだけのスレッドになるため、mainのスレッド上で条件判断をして小部屋を脱出する。
超音波センサを使うスレッドについて
超音波センサを使うスレッドは、usflagの値によって終了させたり起動しないようにしている。これは、タッチセンサが触れて補正動作をしているときに、超音波センサを使うスレッドに出口があったなどと判断させないためである。タッチセンサがふれて補正をしているということは、MIRS自体が通路に対してズレが大きいということである。そのときは超音波センサの値に意味がなくなるためこのような処理を行った。
motoflag_thread
モーターを動かすスレッドである。motor_flagという関数が終了するまでスレッドは終了しない。motor_flagは目標値に到達するまでモーターを動かす関数だが、flagという外部変数が0以外のときは動作を終了する。これにより、タッチセンサが触れたときなどはmain上でflagの値を操作することで、モーターの回転を止め、補正動作にモーターを動かすことができる。
sensor_thread
タッチセンサ、白線センサ、赤外線センサの値をチェックする関数sensor_check.cを呼び出すスレッド。mainプログラム開始時に起動し、その後基本的に終了することはない。
3. 統合プログラム内の関数について
統合プログラム内には、前述のスレッド用関数の他に、main, rotary, cosmo, key, adjust といった関数がある。
rotary 型宣言:void rotary(void)
目的 :ロータリーをクリアする。
概要 : おおまかなフローチャートは後述する。rotary()の動作は、数字認識後にロータリー方向を向いた状態から始まる。ロータリー中央の柱まで近づき、反時計まわりに周回し、右側に出口があれば脱出する。なお、入り口を出口だと判断させないために、姿勢角が周回開始の角度から±45度以内だった場合は右側に壁がなくても脱出しないようにしている。
フローチャート
cosmo 型宣言:void cosmo(void)
目的 :小部屋をクリアする。
概要 : おおまかなフローチャートは後述する。cosmo()の動作は、数字認識後に小部屋方向を向いた状態から始まる。uss_all_threadにより、通路という左右に壁がある状態(usflag==0)から、左または右に壁がない状態になるまで前進する。その後は左が壁、右が壁、壁なしという小部屋に入ったときの3つの状況に応じて動き、出口を発見しだい脱出する。壁としている方向に壁がなくなった場合はそこを出口とする。壁としていない方向に壁が現れたときは、すでに直進して通路に入ったものとする。
フローチャート
key 型宣言:void key(void)
目的 :鍵をクリアする。
概要 : おおまかなフローチャートは後述する。key()の動作は、数字認識後に鍵方向を向いた状態から始まる。もともとは赤外線センサの値を取得して鍵を押したか判断するつもりであった。しかし赤外線センサが不調であったため、単純にタッチセンサのみでクリアする。前方のタッチセンサが押されるまで直進し、押されしだい180度反転する。
フローチャート
adjust 型宣言:int adjust(int rel)
目的 :現在の姿勢角と目的の角度の差をとり、モーターの関数に渡す目標角を算出する。
概要 : おおまかなフローチャートは後述する。動作を実例を挙げて説明する。曲がり角で右に90度曲がりたいとする。しかし実際のMIRSは通路に対し直角でなく、傾いていることの方が多い。このとき姿勢角が3度になっていたとする。adjust(-90)とすると、返り値は-93となる。このadjustの返り値をその場回転する関数の目標値とすれば、直角に曲がった状態にすることができ、ズレの積み重ねを防ぐことができる。
始めのwhileループで姿勢角を表す変数angの値を-180から180までに調整する。ang自体を計算するのはモーター駆動関数内で行われており、ang の値の範囲は決まっていない。しかし200度と-160度で状況は変わらないため、目標値を算出する際には角度は一意に定められた方が都合が良い。
adjustの引数には、ズレがないとしたとき相対的(relative)に曲がりたい角度を指定する。adjust内で、現在の姿勢角から、本来そうであって欲しかった理想的(ideal)な角度を求める。理想の姿勢角と実際の姿勢角の差を、曲がりたい角度と足すことで真に回転しなければならない目標角を算出する。
フローチャート
main 型宣言:int main(void)
目的 :競技時実際に実行される関数であり、競技クリアを目的とする。
概要 : main中の部分ごとのフローチャートは後述する。main中では、通路動作、数字認識などを行う。なお、数字認識をする関数はMIRS0901の作成したもの(input_DB等)を使っている。
フローチャート
main 数字認識部 補正補正動作
2. 統合プログラムのソース
統合プログラムのソースを貼り付けておく。 road.c
関連文書
プログラムで発生した問題