マイクロマウス製作六十五日目


こんにちは!

なんだかまだ今日ものどが痛い松崎です。
結構周りでも夏の終わりかけのこの時期に風邪を引いている人が多いので、
みなさんもお気をつけください。
マスク暑い…(´□` )

さて、壁切れ補正の実装に取り組んだ結果難しくなってきたマイクロマウス研修です。

今日の目標は、昨日の研修を踏まえて、

  1. うまく実装できていなかった壁切れ補正をちゃんと書き直す
  2. 以下の図のようなコース、両側に壁がない場合も壁の切れ目をきちんと読めるようにする

の2つです。

写真 2013-08-21 11 08 46

ではまずひとつめ。
うまく実装できていなかった壁切れ補正をちゃんと書き直す

昨日、いろいろと試行錯誤しながら書いたプログラムがうまく動いたにも関わらず、
実は肝心の壁切れ補正をしていなかったという事実が判明してショックでしたが、
今日は壁切れ補正をするようにプログラムを書き換えてみました。
※昨日のブログは→こちら

以下の通りに、
if文の中にwhile文を入れて書き直しました。

//最短走行時の超信地旋回前壁切れ補正
	
	if(len > SECTION*2)												//2区画以上走る場合
	{
		while(len - STEP2LEN(step_r + step_l) > SECTION*1);			//停止する1区間前まで走る
		
		if(sen_r.is_wall == true)									//右壁がある場合
		{	
			while(sen_r.is_wall == true)							//右壁が切れるまで走る
			step_r = step_l = 0;									//ステップ数カウントのリセット
			while((step_r + step_l) < LEN2STEP(len_remains));		//あと走るべき距離走る
		}
		
		else if(sen_l.is_wall == true)								//左壁がある場合
		{	
			while(sen_l.is_wall == true)							//左壁が切れるまで走る
			step_r = step_l = 0;									//ステップ数カウントのリセット
			while((step_r + step_l) < LEN2STEP(len_remains));		//あと走るべき距離走る		
		}
		
		else
		{
			while(len - STEP2LEN(step_r + step_l) == SECTION*1);	//一区画走る
			
			MTU2.TSTR.BIT.CST3 = 0;							//モータのカウントをストップ
			MTU2.TSTR.BIT.CST4 = 0;							//モータのカウントをストップ
		}
			
	}
			
	else												//2区画以内しか走らない場合
	{
		while((step_r + step_l) < obj_step);			//目標地点まで走行
	
	}

	
	MTU2.TSTR.BIT.CST3 = 0;							//モータのカウントをストップ
	MTU2.TSTR.BIT.CST4 = 0;							//モータのカウントをストップ
	
}


これで、壁を見て走行を補正するプログラムにはなりました。
プログラム上では本日の目標1は達成のようです♪イエイ!

これで一度走ってみます。

ムム、やはり両側に壁がない場合に変な動きをしてしまっていますね。。
斜めに走っています。
ちなみにこれは何度もやると、うまくちゃんと曲がってくれるときもありますし、斜めに曲がる方向が右だったり左だったりもします。

本日の目標2ですね。

これに対してのり先生に相談して立てた原因の仮説が、
写真 2013-08-21 11 08 46

この図の場合に、AやBの壁を見て姿勢を補正してしまっているのではないか?というもの。

でも、プログラムに問題があるようには思えません。
こういう場合、よく実際にコースにマウスを置いて順にプログラムを確認するとイメージが湧きます。
今回もそのように実際にプログラムを追ってみます。

まず、2区画以上走る場合というif文に入り、停止する地点の一区画前まで走ります。

if(len > SECTION*2)												//2区画以上走る場合
	{
		while(len - STEP2LEN(step_r + step_l) > SECTION*1);			//停止する1区間前まで走る

写真 2013-08-21 11 29 23

停止する地点の一区画前まで来た時点で、左右の壁の状態によってその後の処理を振り分けます。

まず、右壁がある場合→壁がきれるまで走って、壁が切れたと認識した地点からあらかじめ指定したパラメータ分進み、止まります。

	if(sen_r.is_wall == true)									//右壁がある場合
		{	
			while(sen_r.is_wall == true)							//右壁が切れるまで走る
			step_r = step_l = 0;									//ステップ数カウントのリセット
			while((step_r + step_l) < LEN2STEP(len_remains));		//あと走るべき距離走る
		}

写真 2013-08-21 11 28 32

左壁がある場合→壁がきれるまで走って、壁が切れたと認識した地点からあらかじめ指定したパラメータ分進み、止まります。

		else if(sen_l.is_wall == true)								//左壁がある場合
		{	
			while(sen_l.is_wall == true)							//左壁が切れるまで走る
			step_r = step_l = 0;									//ステップ数カウントのリセット
			while((step_r + step_l) &lt; LEN2STEP(len_remains));		//あと走るべき距離走る		
		}

写真 2013-08-21 11 28 44

それ以外の場合→壁の切れ目は一切気にせずとにかくまたもう一区画走り、止まります。

		else
		{
			while(len - STEP2LEN(step_r + step_l) == SECTION*1);	//一区画走る
			
			MTU2.TSTR.BIT.CST3 = 0;							//モータのカウントをストップ
			MTU2.TSTR.BIT.CST4 = 0;							//モータのカウントをストップ
          }

写真 2013-08-21 11 28 55

つまり、どんな状況でも、わたしの思う場所で止まって、次の処理である超信地旋回に移るはず!!!だよ!!!
Genieちゃん!!!

写真 2013-08-21 11 29 32

ちなみに、今回壁切れ補正を実装しようと書き足した部分をコメントアウトして走らせると、同じコースを何度でも問題なく走ります。
つまり、どこか書き足した部分に問題があるということなのです。

ひええ、、まったくアイディアが湧きません…。

このブログを見ているお詳しい方は「ここが違うんだよ~~!」とかピンと来ているものなのでしょうか…
(プログラム一部しか公開してないですが…)

ちょっといろいろ考えて見ます^^

-余談-

物理の知識もちょこちょこと必要になることがわかったので、
履修していない物理を勉強しようかな~と思い買ってみました。
写真 2013-08-21 12 10 35
こちらも難しいですw


Posted in Report on the assembly of Pi:Co Classic