課題8で作成したfollowRight()の中で,前方に反応があった場合に終了して-1を返すようにせよ.それ以外,無事に指定時間走行できた場合には0を返すこと.
また,driveMotorの内部でもセンサをチェックするようにする.前左右どれかのセンサが反応したら,即刻緊急停止してから-1を返すようにせよ.無事に加速終了したときには0を返して終了する.
forward()やfollowRight()や,turnRight()など内部でdriveMotorを呼び出している各関数では,もしもdriveMotorが-1を返してきたときには(加速に失敗したときには),即刻動作をうちきり,-1を返すようにせよ.動作が成功すれば0を返すこと.
緊急停止は,次の関数を用意して呼び出せばよい.
int emergencyStop() { p1=ブレーキ p3=ブレーキ ta2 = モータ速度をいきなり0に ta3 = モータ速度をいきなり0に SetCpuBoardLED( ON );// CPUボードLED点灯 wait()でしばらく待機(※これがないと,LEDがすぐ消灯して気づかない) SetCpuBoardLED( OFF );// CPUボードLEDオフ }
SetCpuBoardLED()は,sensor.cの中に最初から用意されていた関数で,CPUボード上のLEDを制御する機能を提供している.
各モータ系の関数(foward()など)が-1を返してきたときには,一度ロボットを停止し,全センサをチェックして,その結果次第で次の動作を決定するような判断ルーチンを作成せよ.
これは,右手法と呼ばれる迷路をとくための判断ルーチンである.右手伝いに壁に右手を付けたまま進めば,いずれ迷路のゴールにたどり着くことを利用している.
課題7で使用したchechSensor()の返値を使用して,次のようにmain関数に判断ルーチンを作成すればよい.(switch文の説明)
void main(void) { 初期化部分 for(;;) { センサ結果=checkSensor(基準値); switch(センサ結果) { case 右センサに反応なしの場合: turnRight(); break; case 前センサに反応なしの場合: followRight(); break; case ほかの状況: その状況に適した行動; break; case ほかの状況: その状況に適した行動; break; case 以下略 ← 考えられるすべての状況に対処しないといけない } } }
壁に接触しないように、より細かい制御のためには、次のように各case内部で、動作結果をちゃんと調べて、失敗したときの対処を行う必要がある。例えば次のような単純な対応ができる。
case 右センサに反応なしの場合: 返値=turnRight(); if(返値==失敗を意味する値) { //turnRight()に失敗したときの対処、例えば次のようにバックさせる back3cm(); } break;
さらに、そこまでする必要はないかもしれないが、もっと細かく制御するためには、距離値を直接確認することも考えられる.
case 行き止まりの場合: 右センサ値 = readSensor(0); //右センサの読み込み 左センサ値 = readSensor(2); //左センサの読み込み if(右の方が壁から遠い) { 右回りで180度回転 } else { 左回りで180度回転 } } break;
readSensor()は,sensor.cの中に用意されている関数で,課題6で使用したreadSensorと同じ動作をする関数である.