右センサを5ミリ秒程度に読み,5cmよりも壁に少し近づいたようならば左モータの速度を少し下げて,微妙に左へカーブをかけ,逆に10cm程度よりも壁から離れたようなら左モータの速度を微妙に上げて右へカーブをかけるようにし,右手の壁から5cmから10cm程度の距離を保つように調整して走らせるような関数followRight()を作成せよ.
int followRight(int msec10, int sensor_thold); //引数は走行時間の指定(10ミリ秒単位)と,センサの基準値
ただし,forward()と同様に,もしも指定時間が0ならば無限に動作しつづけるものとする.
followRight()の内部では,壁からの距離を調整するのにsencor.cで用意されているcheckRightWall()が利用できる.
int checkRightWall( unsigned int r_near, unsigned int r_far );
checkRightWall()は,直前にcheckSensorを呼び出しておくことが条件になっているので注意.センサは,近い→大きい・遠い→小さい値となる
int sensor, range; sensor = checkSensor(sensor_thold); //壁からの距離を示す基準値 range = checkRightWall(sensor_thold+20, sensor_thold-50); //必ずcheckSensorの次に呼び出す ※ 大小関係に注意 (壁に近づきすぎ)220 > 200(基準値) > 150(壁からはなれすぎ)
この例のように,checkSensorの基準値は,checkRightWallの範囲設定の内側,つまり近い距離・遠い距離を示す値の間になるような値になるように指定.
前センサ ● ●範囲内であれば点灯 左センサ● ●右センサ
センサ値の反応が220と150の間の範囲にあれば,ロボットに搭載したLED4個のうち,checkRightWall関数は緑のLEDが点灯させるようになっている.またcheckSensorの基準値を越えれば,課題7の時に説明したように,checkSensor関数は右センサに反応ありとして黄色のLEDを点灯させる.
checkRightWall()の返値(range)は,次のような値になっている。
値 | 意味 |
---|---|
0 | 範囲内 |
1 | 壁に近づきすぎ |
2 | 壁から離れすぎ |
-1 | エラー(r_nearとr_farの大小関係が逆になっている) |
これから,switch文を使っておおよそ次のようなプログラムになるはずである.
int followRight(int msec, int sensor_thold) { int sensor, range; forward(1); //まず全速前進 for(;;){ 指定時間が経過した→return 0; sensor = checkSensor(sensor_thold); //壁からの距離を示す基準値 range = checkRightWall(sensor_thold+?, sensor_thold-?); //必ずcheckSensorの次に呼び出す switch(range) { case 0: 全速前進 break; case 1: やや壁から離れるように調整 break; case 2: 壁に近づくように調整 break; default: stop(); //ありえない事態なので、停止 return -1; //失敗の報告 } } }
壁から離れる、近づくためには、followRight()の中でdriveMotor()を呼び出して,右モータと左モータの速度を調整すること.現在のモータ速度は大域変数のdutydata_Rとdutydata_Lに格納されている.(dutydataに関しては課題4で再確認.)
driveMotor(現在の右モータの速度-n, 現在の左モータの速度+n ); //nの値は適切に設定
driveMotorで速度調整中(加速中)の間は,センサをチェックしていないことになるため,その間に壁に接触してしまうことがある.加速の度合(現在速度と目標速度の差)を大きくすると,その分加速に時間がかかる.加速の度合を大きすぎないようにすれば,センサをチェックしない時間を短くでき,壁に接触しないようにできる