れごぼく@メガネボーイズ2008 RSSフィード

2008-11-20

[]ETロボコンモデリングワークショップに参加してきた 22:53 ETロボコンのモデリングワークショップに参加してきた - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - ETロボコンのモデリングワークショップに参加してきた - れごぼく@メガネボーイズ2008 ETロボコンのモデリングワークショップに参加してきた - れごぼく@メガネボーイズ2008 のブックマークコメント

他のメンバーが参加できていなかったので、ここにまとめておきます。

審査方法について

モデル審査方法
  • 1次審査(定量評価)
    • モデル評価+性能面評価
    • 減点方式、審査基準に従って、悪い点をどんどん減点していく
    • この段階では、特徴あるモデルよりバランスよく、間違いのないモデルの方審査をとおりやすい
  • 2次査審査(定性評価)
    • モデル評価
    • 審査員ごとに持点があり、良いモデルに対して点数を投票していく形式。
    • 審査員の心をつかむ、特徴のあるモデルの方が審査に残りやすい。
  • 3次審査(定性評価)
    • 2次審査を通った10チームくらいのモデルに対し、定性評価を実施する
    • これも2次審査と同じで、バランスが良いことよりも、特徴があるチームの方が残りやすい
  • 総合結果の決定方法について
    • 競技結果とモデル審査結果の調和平均で順位を決める
    • 両方とも良い結果が出ていないと1位にはなれない

近年のモデルの傾向

2007年の傾向
  • モデリング領域の拡大
    • 単純なモデルだけでなく、トレーサビリティ、図解、見易さを意識したチームが増加してきた
  • 性能重視
    • 戦略の妥当性の証明のため、豊富な実験データを書いているチームが多数
    • しかし、構造モデルの質が悪い傾向にある
2008年の傾向
  • コード生成ツール活用チームの増加
    • 東海からはMATLAB/Simulink、関東からはSoftware Factoriesを実践しているチームが出場
    • 個人チームでも部分的にコード生成するツールを作っているチームあり
  • 戦略の要素技術の定着
    • 過去の大会で発掘された手法が全チームに広がり、底上げがなされている

審査員が気になること

全体的に基礎的なモデリング技術が低い
  • モデルの内容よりモデルの書き方、資料の作り方に重点が置かれている
  • 資料としては良いが、モデルがいまひとつのチームが多い
モデルの肥大化
  • シートにモデルを書きすぎるチームが多い
    • モデルが活用できていない
  • 清書としてモデルを使っているチームが多い
  • 思考の道具としてのモデル、思考の過程がモデルに反映されていない

審査委員からのコメント1「基本的なモデリング技術を見直そう」

  • 人間にとっての読みやすさ(human-readability)を重視しすぎて正しいモデルが描けていない
  • 読みやすさを意図していたとしても、誤解を与えるような書き方は良くない
  • 注意する点3つ
    • 何を表現したいのか?
    • どのモデルで表現するのが適切か?
    • どのように表現するのが正しいか?
  • 各チームは「何を表現したいのか?」は分かっていても、以下ができていない場合が多い
    • どのモデル図で表現するか?
    • 選んだモデル図で正しく表現するにはどうしたらよいか?
  • 人間にとって読みやすさ、意図の伝わりやすさを損なわずに、正しいモデルを書くことは可能なはず
  • (余談)human-readableなモデル VS machine-readableなモデル
    • 最近のモデル駆動型開発の技術では、以下の2つを同時に実現しようという流れがある
      • 機械が読める、動くモデル
      • 人間が読める、意図が分かるモデル

審査委員からのコメント2「知見をモデルへフィードバックしよう」

  • 個々の走行戦略を詳しく説明しているが、モデルに表現できていない場合が多い
  • おそらくはコード上では表現できているが、モデルには表現でき
  • 検証の結果をモデルへフィードバックすることに注意を払うべき
    • 現実の開発では、検証で得られた知見がコードにしか表現されていないことが多いため、開発の中で意図や理屈が消えてしまうことが良くある
    • しかし、モデルとして残すことで意図や理屈を残しやすくなる

審査委員からのコメント3「リッチなモデル or シンプルなモデル」

近年のモデルの傾向 = モデルの肥大化
  • 企業の常連チームのモデルが肥大化する傾向にある
    • 情報量、内容が多く、読むのが大変なもの
    • 補足説明が多く、図と文章で重複しているもの
  • 読み手を絞れていない
    • 審査員にアピールしたいこと、他の参加者へアピールしたいこと、いろいろ書きすぎている
    • 総じてよくできているけど、どこが重要な箇所なので、どこがウリなのか分かりづらい
今年の優勝者のモデルはシンプルモデル
  • 上記のような「胸焼けのするモデル」をよく見たせいか、今年の優勝チームのモデルは驚くほど簡素
  • 見る人を意識して、情報をデザインできてている
    • インフォメーションデザイン

チャンピオンシップ大会に参加してきた 23:02 チャンピオンシップ大会に参加してきた - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - チャンピオンシップ大会に参加してきた - れごぼく@メガネボーイズ2008 チャンピオンシップ大会に参加してきた - れごぼく@メガネボーイズ2008 のブックマークコメント

orz

以上。

2008-11-18

試走用プログラムを作ります 00:00 試走用プログラムを作ります - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - 試走用プログラムを作ります - れごぼく@メガネボーイズ2008 試走用プログラムを作ります - れごぼく@メガネボーイズ2008 のブックマークコメント

  • ゴール後停止までの時間調整用兼マーカー検知検証用試走プログラム(lgbk)

前回の関東予選で、これを一緒にできるやつをつくってたから、これをベースに現状のソースコードとマージしていきます。

本番に向けての作業 23:30 本番に向けての作業 - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - 本番に向けての作業 - れごぼく@メガネボーイズ2008 本番に向けての作業 - れごぼく@メガネボーイズ2008 のブックマークコメント

  1. タイミング調整のExcel(mn)
  2. タイミング調整用試走プログラム(mn)
  3. シナリオの動作確認(インコースは終了)(fj)
  4. 点線走行の新品電池調整(fj)
  5. ゴール後停止までの時間調整用兼マーカー検知検証用試走プログラム(lgbk)
  6. 本番走行プログラム一式(空いた誰か)

2008-11-16

ステアリングの慣性の違いをどう検出するか 15:04 ステアリングの慣性の違いをどう検出するか - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - ステアリングの慣性の違いをどう検出するか - れごぼく@メガネボーイズ2008 ステアリングの慣性の違いをどう検出するか - れごぼく@メガネボーイズ2008 のブックマークコメント

ステアリング補正をするには現在のステアリングの慣性の向きを把握しないといけない

fj氏、曰く。

http://meganeboy.g.hatena.ne.jp/fuji_ttt/20081019

黒の1個前と連続検出回数を記録しておけばいいんじゃない?

fj氏、曰く。

ふむふむ。

 平均的な黒の期間を計算しておいて、直近の黒の期間が、その半分よりも長かったら「↑」で、短かったら「↓」かなぁ。
「負けないもん。」: 平均的な黒の期間はもうオンコードでもいいかと思う。

つまりは、平均で黒の連続回数が5回の場合

  • 「○●●●●●●●●●●●●○」となってれば黒が過多、つまり右に慣性がかかっている状態と考える。
  • 「○●●○」となっていれば、白が過多?と考えて、左側に慣性がかかっている状態と考える。

OK。その路線で攻めてみよう。

まず変数を用意してみた

	// 現在の黒の連続回数
	unsigned short m_blackCtCur;

	// 1つ前の黒の連続回数
	unsigned short m_blackCtPrev;

マーカー検知前走行のときに、黒の検出連続回数を記録しておく

マーカー検知前の走行のときに記録しておきます。

ノイズまじってたらどうすんだ?という話もありますけど、Application側ではノイズが除去されたきれいな世界を想定してやります。

ノイズの除去的なのは、Mechanismで対処すべきでしょう。

// マーカー検知前の走行
void ActiveMarkerDetectionLogic::runBeforeMarkerDetect(SRunningSituationData *pData) {
	// 駆動ユニットと操舵ユニットを制御する
	// ステアリング補正の際に、マーカー検知前走行最後のステアリング操作と色判定結果が
	// 必要になるため、記録しておく。
	if (pData->ColorDistinctionResult == WHITE) {
		this->m_pSteeringUnit->turn(LEFT_TURN, MARKER_DETECTION_NORMAL_STEERING_SPEED);
		this->m_lastSteering = LEFT_TURN;
		this->m_lastColor = WHITE;
		
		// 黒の検出回数を記録しておく
		this->m_blackCtPrev = this->m_blackCtCur;
		this->m_blackCtCur = 0;
	} else if (pData->ColorDistinctionResult == BLACK) {
		this->m_pSteeringUnit->turn(RIGHT_TURN, MARKER_DETECTION_NORMAL_STEERING_SPEED);
		this->m_lastSteering = RIGHT_TURN;
		this->m_lastColor = BLACK;
		this->m_blackCtCur++;
	} else {
		this->m_pSteeringUnit->turn(LEFT_TURN, MARKER_DETECTION_ON_MARKER_STEERING_SPEED);
		this->m_lastSteering = LEFT_TURN;
		this->m_lastColor = MARKER;
	}
	this->m_pDriveUnit->forward(MARKER_DETECTION_NORMAL_DRIVE_SPEED);
}

マーカー検知前走行のイベント遷移処理

慣性の方向を気にするのは、補正走行に入る直前。

このときに決めた方向に補正を行うことになる。


void ActiveMarkerDetectionLogic::stateTransBeforeMarkerDetect(SRunningSituationData *pData) {
	// 灰色を検知したら、ステアリング補正走行に移行する
	if ( MARKER == pData->ColorDistinctionResult ) {
		m_steeringDirForAdjust = NO_TURN;
		this->m_state = STATE_STERRING_ADJUST;
		this->m_prevStateEndTime = pData->RunningLapsedTime;
		

		// 黒の検出回数を記録しておく
		this->m_blackCtPrev = this->m_blackCtCur;
		this->m_blackCtCur = 0;

		// 遷移する前にステアリング補正の向きを決めておく
		
		// 直前の色が白なら右に
		if ( WHITE == this->m_lastColor ) {
			m_steeringDirForAdjust = RIGHT_TURN;
		}
		
		// 直前が黒で、黒検出過多な場合は、左に
		if ( ( BLACK == this->m_lastColor ) && ( AVG_BLACK_DETECT_COUNT <= this->m_blackCtPrev )) {
			m_steeringDirForAdjust = LEFT_TURN;
		}
	}
}

マーカー検知後のステアリング補正走行

void ActiveMarkerDetectionLogic::runSteeringAdjust(SRunningSituationData *pData) {
	
	// ステアリング補正がもう不要な場合はブレーキをかける
	if ( ( STEERING_ADJUST_COUNT <= this->m_steeringAdjustCount ) ||
		 ( NO_TURN == m_steeringDirForAdjust ) ) {
		 	this->m_pSteeringUnit->fix ( 5 );
	} else {
		this->m_steeringAdjustCount++;
		this->m_pSteeringUnit->turn(m_steeringDirForAdjust, MARKER_DETECTION_ON_MARKER_STEERING_SPEED);
	}

}

2008-11-15

どうやってステアリング操作を保持しておくか? 21:16 どうやってステアリング操作を保持しておくか? - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - どうやってステアリング操作を保持しておくか? - れごぼく@メガネボーイズ2008 どうやってステアリング操作を保持しておくか? - れごぼく@メガネボーイズ2008 のブックマークコメント

char変数でも用意しておくか

マーカー検知走行をやってたときの最後のステアリング操作、色判定結果を記録しておけばいいので、char変数に記録しておく。

	// マーカー検知走行での最後のステアリング操作
	unsigned char m_lastSteering;

	// マーカー検知走行での最後の色識別結果
	unsigned char  m_lastColor;

マーカー検知前走行でステアリング操作と色判定結果を記録しておく

void ActiveMarkerDetectionLogic::runBeforeMarkerDetect(SRunningSituationData *pData) {
	// 駆動ユニットと操舵ユニットを制御する
	// ステアリング補正の際に、マーカー検知前走行最後のステアリング操作と色判定結果が
	// 必要になるため、記録しておく。
	if (pData->ColorDistinctionResult == WHITE) {
		this->m_pSteeringUnit->turn(LEFT_TURN, MARKER_DETECTION_NORMAL_STEERING_SPEED);
		this->m_lastSteering = LEFT_TURN;
		this->m_lastColor = WHITE;
	} else if (pData->ColorDistinctionResult == BLACK) {
		this->m_pSteeringUnit->turn(RIGHT_TURN, MARKER_DETECTION_NORMAL_STEERING_SPEED);
		this->m_lastSteering = RIGHT_TURN;
		this->m_lastColor = BLACK;
	} else {
		this->m_pSteeringUnit->turn(LEFT_TURN, MARKER_DETECTION_ON_MARKER_STEERING_SPEED);
		this->m_lastSteering = LEFT_TURN;
		this->m_lastColor = MARKER;
	}
	this->m_pDriveUnit->forward(MARKER_DETECTION_NORMAL_DRIVE_SPEED);
}

しかし、問題なのはステアリングの慣性の違いをどう把握するかだ

http://meganeboy.g.hatena.ne.jp/fuji_ttt/20081019

の②と③の違い。

ショートカットでも、苦戦中らしい。

なんちゃってステートマシンの実装をしてみた 18:59 なんちゃってステートマシンの実装をしてみた - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - なんちゃってステートマシンの実装をしてみた - れごぼく@メガネボーイズ2008 なんちゃってステートマシンの実装をしてみた - れごぼく@メガネボーイズ2008 のブックマークコメント

http://meganeboy.g.hatena.ne.jp/skelton_boy/20081109/1226221537

に書いたように、簡単なswitch文で実装します。

本来はステートマシンってこんな実装しないんだけど、マー言いかという感じで。

各状態ごとに走行ロジックと状態遷移を行う関数を用意する

アウトエッジ移行走行ってのが、外側へ行く走行のことね。

外部から参照されないものなのでprivate。

private:

	/***** マーカー検知前走行 *****/
	// 走行ロジック
	void runBeforeMarkerDetect(SRunningSituationData *pData);
	// 状態遷移の確認
	void stateTransBeforeMarkerDetect(SRunningSituationData *pData);

	/***** ステアリング補正走行 *****/
	// 走行ロジック
	void runSteeringAdjust(SRunningSituationData *pData);
	// 状態遷移
	void stateTransSteeringAdjust(SRunningSituationData *pData);

	/***** アウトエッジ移行走行 *****/
	// 走行ロジック
	void runrunHeadingOutEdge(SRunningSituationData *pData);
	// イベント遷移処理
	void eventTransrunHeadingOutEdge(SRunningSituationData *pData);

	/***** ステアリング安定化走行 *****/
	// 走行ロジック
	void runSteeringStabilizing(SRunningSituationData *pData);
	// 状態遷移処理
	void eventTransSteeringStabilizing (SRunningSituationData *pData);

走行状態を表すenumを用意した

こういうのは列挙型ですよね。

// 走行状態
enum StateActiveMarkerDetection {
	/* なし */
	STATE_NON,
	/* マーカー検知前走行 */
	STATE_BEFORE_MARKER_DETECT,
	/* ステアリング補正走行 */
	STATE_STERRING_ADJUST,
	/* アウトエッジ移行走行 */
	STATE_HEADING_OUT_EDGE,
	/* ステアリング安定化走行 */
	STATE_STERRING_STABILIZING,
};

こんな感じで状態ごとの処理をさせてみる

	// 状態ごとの処理
	switch ( m_state ) {
	case STATE_BEFORE_MARKER_DETECT:
	//[状態]マーカー検知前 () ----------------
		// マーカー検知前の走行
		runBeforeMarkerDetect( pData );
		// 状態遷移を確認する
		stateTransBeforeMarkerDetect ( pData );
		break;

	case STATE_STERRING_ADJUST:
	//[状態]マーカー検知直後(外側にステアリングを切る)----------------
		// ステアリングを補正する
		runSteeringAdjust ( pData );
		// 次の状態に遷移するか確認する
		stateTransSteeringAdjust ( pData );
		break;

	case STATE_HEADING_OUT_EDGE:
	//[状態]アウトエッジ移行)------------------------
		// 走行ロジック
		runrunHeadingOutEdge( *pData );
		// イベント遷移処理
		eventTransrunHeadingOutEdge( *pData );

	case STATE_STERRING_STABILIZING:
	//[状態]マーカー検知後しばらく(安定化走行)------------------------
		// ステアリング走行を安定化する
		runSteeringStabilizing(pData);
		// 次の状態に遷移するか確認する
		stateTransSteeringStabilizing(pData);
		break;
	default:
	//[状態]終了------------------------------------------------------
		m_state = STATE_BEFORE_MARKER_DETECT;
		runningLogicEndFlag = true;
	}

マーカー検知前走行の状態遷移

// マーカー検知前走行のイベント遷移処理
void ActiveMarkerDetectionLogic::stateTransBeforeMarkerDetect(SRunningSituationData *pData) {
	// 灰色を検知したら、ステアリング補正走行に移行する
	if ( MARKER == Data->ColorDistinctionResult ) {
		this->m_state = STATE_STERRING_ADJUST;
		this->m_prevStateEndTime = pData->RunningLapsedTime;
	}
}

ステアリング補正時のイベント遷移処理

void ActiveMarkerDetectionLogic::stateTransSteeringAdjust(SRunningSituationData *pData) {
	// 白か黒を読んだら、マーカー検知前走行に戻る
	if ( ( WHITE == pData->ColorDistinctionResult )  ||
		 ( BLACK == pData->ColorDistinctionResult ) ) {
		 	m_state = STATE_BEFORE_MARKER_DETECT;
		 	return;
	}
	
	// マーカーを見つけた場合は、アウトエッジ移行走行に移行する
	if ( true == pData->ponMarker ) {
		m_state = STATE_HEADING_OUT_EDGE;
	}
}

アウトエッジ移行走行 状態遷移処理

void ActiveMarkerDetectionLogic::eventTransHeadingOutEdge(SRunningSituationData *pData) {
	// アウトエッジ移行の時間が過ぎたら、次の状態に移る
	if ( ( pData->RunningLapsedTime - this->m_prevStateEndTime ) >= MARKER_DETECTION_HEAD_OUTEDGE_TIME ) {
		this->m_state++;
		this->m_prevStateEndTime = pData->RunningLapsedTime;
	}
}

積極的マーカー検知走行のステートマシン図をのっけてみた 20:08 積極的マーカー検知走行のステートマシン図をのっけてみた - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - 積極的マーカー検知走行のステートマシン図をのっけてみた - れごぼく@メガネボーイズ2008 積極的マーカー検知走行のステートマシン図をのっけてみた - れごぼく@メガネボーイズ2008 のブックマークコメント

ステートマシン図もどき

f:id:skelton_boy:20081115173411p:image

(1) 検知前走行

  • これは、まだマーカーを見つける前の走行。普通のライントレース。

(2) ステアリング補正走行

  • 走行状況を参照して、灰色を見つけたら、ステアリングタイヤがまっすぐになるように補正する
    • この段階は、マーカーを検知しやすいようにステアリングを補正しているので、マーカーを検知した段階ではない。
  • 図中の表のような場合分けをしているのは、直近の色判定結果が何か?ステアリング操作が何かで、マーカーに入った時のステアリング操作の慣性が違うため。

(3)ひとまず外に切るぜ走行

  • マーカーを見つけたら、アウトエッジに戻す
    • たぶん、普通のライントレースに戻ろうとしている

(4)ステアリング安定化走行

  • ここまでくると、普通のラインとレースと同じ?

2008-11-09

今日の議事録 20:15 今日の議事録 - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - 今日の議事録 - れごぼく@メガネボーイズ2008 今日の議事録 - れごぼく@メガネボーイズ2008 のブックマークコメント

週末までにやること

週末にやること

  • ソースのマージ[ふじ]
  • メモリ不足対応[ごりら]
  • 積極的~と点線走行ロジックの検証[ふじ]
  • 積極的マーカー検知走行ロジック精度向上[ごりら]
  • 点線走行ロジック精度向上[ふじ]
  • 試走用Excelブック[めがね]
  • 走行シナリオ実装[めがね]

積極的マーカー検知走行について 15:54 積極的マーカー検知走行について - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - 積極的マーカー検知走行について - れごぼく@メガネボーイズ2008 積極的マーカー検知走行について - れごぼく@メガネボーイズ2008 のブックマークコメント

f:id:skelton_boy:20081109155013p:image

こんな感じなんだよね。

マーカー検知前にステアリングはどっちになっていたか?と、直前にどの色を読んでいたか?によって、ステアリング補正の仕方が変わるという感じか?

マーカー積極的検知走行を実装するために修正をほどこしました 18:05 マーカー積極的検知走行を実装するために修正をほどこしました - れごぼく@メガネボーイズ2008 を含むブックマーク はてなブックマーク - マーカー積極的検知走行を実装するために修正をほどこしました - れごぼく@メガネボーイズ2008 マーカー積極的検知走行を実装するために修正をほどこしました - れごぼく@メガネボーイズ2008 のブックマークコメント

とりあえず、ある状態の時の走行処理と、状態遷移を関数化しました。

// 走行する
bool ActiveMarkerDetectionLogic::run(SRunningSituationData *pData)
{
	bool runningLogicEndFlag = false;
	
	// 状態ごとの処理
	switch ( m_state ) {
	case STATE_BEFORE_MARKER_DETECT:
	//[状態]マーカー検知前----------------
		// マーカー検知前の走行
		runBeforeMarkerDetect( pData );
		// 状態遷移を確認する
		eventTransBeforeMarkerDetect ( pData );
		break;

	case STATE_STERRING_ADJUST:
	//[状態]マーカー検知直後(外側にステアリングを切る)----------------
		// ステアリングを補正する
		runSteeringAdjust ( pData );
		// 次の状態に遷移するか確認する
		eventTransSteeringAdjust ( pData );
		break;

	case STATE_STERRING_STABILIZING:
	//[状態]マーカー検知後しばらく(安定化走行)------------------------
		// ステアリング走行を安定化する
		runSteeringStabilizing(pData);
		// 次の状態に遷移するか確認する
		eventTransSteeringStabilizing(pData);
		break;
	default:
	//[状態]終了------------------------------------------------------
		m_state = STATE_BEFORE_MARKER_DETECT;
		runningLogicEndFlag = true;
	}
	
	return runningLogicEndFlag;
}