課題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と同じ動作をする関数である.