2012b/Member/ddnp/Mission2
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
#contents
*コース全体を見渡して問題を確認[#raising_questions]
まずは、課題をクリアするのに何が必要かを検討してみる。
コースは、一つ目の課題で使ったコースを用いて作成するが、...
&ref(2012b/Member/ddnp/Mission2/course.jpg, 100%, ロボコ...
また、詳しいルールはこちらを参照。[[2012年後期ロボコン>20...
とりあえず、ここから見えてくる大きな課題は3つ
-真ん中の木をどうやって乗り越えるか
-紙パックをどうやって掴むか
-どうやって箱を入れ替えるか
まずはこれらの解決に入ることにする。
*紙パックを運ぶ[#the_way_of_carrying_boxes]
**木を乗り越える [#w08268df]
まず、木を乗り越える方法について吟味してみる。
とりあえず思い当たる方法は二つ。
-箱だけ乗り越える
-本体ごと乗り越える
もしかしたら複数の小型ユニットが本体からの命令で紙パック...
よってこの二つに絞ったが、それぞれの特色を吟味すると、以...
-箱だけ乗り越える場合
--箱を受け渡す機構が必要
--受け渡しのため、最低二台は必要になる
--自由自在に動きまわらせるには、ロボットの回転が不可欠。...
--よって、箱を運ぶためのモーターが一台につき1つしか使え...
--ただし、軽量化は可能
--小型化も楽
--箱の受け渡しにおいて確実性をあげるには、通信することも...
--モーター数制限により、箱の積み上げはほぼ不可能だと思わ...
--コースを点対称に組み、それを利用すれば、1つの機体、1...
-本体ごと乗り越える場合
--本体自体が木を乗り越えられる機構が必要
--大型化、重量化が懸念される
--ただし、動力に必要なモーターは最低2つで済む
--モーターが余れば、箱や本体の乗り越え、箱の積み上げ等、...
--モーターが多く使えるため、箱の積み上げが箱だけ乗り越え...
--RCX本体に接続できる接続コードは3つまでなので、4つ以上...
--センサーも同様
--これより、RCX同士が通信で処理の同期を取る必要性がある
箱を積み上げる気が無かった上、機体やプログラムを使いまわ...
個人的には、本体ごと乗り越えさせる機構の構想が浮かばなか...
乗り越えの方針は決まったため、次に問題となるのは箱の掴み...
**紙パックを挟む [#ccf1b82c]
機体を動かすことについては[[課題1>2012b/Member/ddnp/Miss...
では、どうやって掴むといいだろうか。
-横から挟み込む
-上から吊る
-下から持ち上げる
とりあえず、人の手で行える動作を元に考えたので、自分で思...
&ref(2012b/Member/ddnp/Mission2/how_to_raise.jpg, 100%, ...
この3つの中から、消去法で「横から挟み込む」方法を取るこ...
「下から持ち上げる」方法は、箱の下にロボットの部品を潜り...
後々になって、「押す」という動作があることを思いついたが...
事実、他のチームは「挟み」と「押し」を利用していて、上手...
**挟むためのパーツ[#parts_to_hold]
挟むためのパーツということで、クワガタのように挟み込む形...
&ref(2012b/Member/ddnp/Mission2/arm_A.jpg, 100%, アーム);
写真下部に垂直に付いているギアを回すことで、写真中央のウ...
&ref(2012b/Member/ddnp/Mission2/arm_B.jpg, 100%, 開くアー...
これのギアを回してみると、とりあえず紙パックを掴むことは...
単純に見えて掴めるのか怪しいけど、意外と紙パックにフィッ...
紙パックを挟むこと自体は大して難しくなかった。しかしここ...
**紙パックを持ち上げる[#how_to_raise_up]
問題は紙パックの持ち上げである。
木の障害物がある以上、その障害を乗り越えられるだけの高さ...
しかし、紙パックを木の障害物の高さにまで上げる動作は難し...
機体のコピーを作ることを前提としている以上、ひとつのモー...
他の方法を考えようかと思っていたところ、天の一声(CV:担当...
「アームのギアに強い力をかければ歯車は重くなるから、その...
&ref(2012b/Member/ddnp/Mission2/way_of_armup_A.jpg, 100%,...
普通、歯車の回転はアームを閉める働きをする。
&ref(2012b/Member/ddnp/Mission2/way_of_armup_B.jpg, 100%,...
アームを閉めていくと箱やアーム自身の締め付けが強くなり、...
最終的には、歯車自体が動かなくなるが、それを利用する。
&ref(2012b/Member/ddnp/Mission2/way_of_armup_C.jpg, 100%,...
歯車が動かなくなるので、アーム自体にはそれ以上力が加わら...
&ref(2012b/Member/ddnp/Mission2/way_of_armup_D.jpg, 100%,...
そのアーム全体を動かす力を、上方向にかかるようにすると、...
理論は出来上がったので、実際にアームの仕組みを作ることが...
そしてここからがとてつもなく大変であった。
**紙パックが持ち上がるまでに問題になった所[#arm_problems]
***アームとの歯車の組み合わせ [#g3226a72]
いきなり、歯車同士を垂直に交らわせることが問題となった。
交らわせることの出来る歯車の大きさや、噛み合わせがなかな...
普通の形の歯車を垂直に噛み合わせようとしても、回転してい...
モーターの邪魔にならないくらいに大きい歯車を使用し、かつ...
そして、見事に垂直方向に噛み合わせてくださいと言わんばか...
とりあえず、わかりにくいとは思うが、下図のように歯車の歯...
&ref(2012b/Member/ddnp/Mission2/combi_gear.jpg, 100%, ア...
またその中継歯車は、モーターに直接接続していない。
アーム全体が上に持ち上がるといっても、歯車に接続している...
よって、中継歯車を長いシャフトに通して、これを実現した。...
ここでなら分かると思うが、直接動力を与えられているわけで...
&ref(2012b/Member/ddnp/Mission2/alpha_arm_parts.jpg, 100%...
さて、これで持ち上がるかといったらそうでもない。まだまだ...
が、次の日、何故か突如として持ち上がらなくなる…。原因は輪...
***アームまわりの軽量化、補強 [#b262b93b]
まずはアームの根本のギアを強化。
&ref(2012b/Member/ddnp/Mission2/new_arm_1.jpg, 100%, アー...
-歯車を変えてサイズを一回り小さく
-無駄なブロックが無くなり堅固性の向上につながった模様
続いてアーム部本体の軸回りを強化。
&ref(2012b/Member/ddnp/Mission2/new_arm_2.jpg, 100%, アー...
-持ち上げる際にアーム部分との乖離を起こし安かったためこち...
-軸とアーム部を固定する役目を、薄い一枚ブロックで行なって...
-中継歯車付近、アームの回転軸にあった輪ゴムの厚さほどの謎...
ウォームギア(&ref(2012b/Member/ddnp/Mission2/warm_gear.g...
だがしかし、これでもまだ持ち上がる時と持ち上がらない時が...
***モーター歯車の大きさ [#v5024b1e]
ここで、持ち上がらない原因が、歯車全体が動かなくなったと...
アームに動力を伝えるのに、中継歯車を使った。そしてそれは...
その部分は、モーター自体に歯車をはめ、その歯車が直接中継...
ここで、このモーターに接続している歯車を便宜上「モーター...
&ref(2012b/Member/ddnp/Mission2/morter_gear.jpg, 100%, 中...
参考に写真を貼ったが、これはこの問題発生時点の歯車ではな...
&ref(2012b/Member/ddnp/Mission2/gear_torque.jpg, 100%, ギ...
大きさの違う歯車には、てこの原理が働く。そのため同じ動力...
&ref(2012b/Member/ddnp/Mission2/raise_power_A.jpg, 100%, ...
&ref(2012b/Member/ddnp/Mission2/raise_power_B.jpg, 100%, ...
中継歯車自体がまるでシーソーのような役目を果たしているた...
改良前の状態では、LEGOパーツ中で中くらいの大きさの歯車を...
***歯車の空回り [#i769186d]
&ref(2012b/Member/ddnp/Mission2/arm_powerup_B.jpg, 100%, ...
&ref(2012b/Member/ddnp/Mission2/arm_powerup_A.jpg, 100%, ...
先ほど、中継歯車がシーソーのような役割をするといった。そ...
&ref(2012b/Member/ddnp/Mission2/arm_root.jpg, 100%, アー...
図の青矢印部分で、歯車が空回りし始めたのだ。);ウォームギ...
-モーター歯車を大きくする
-アーム部分の歯車を大きくする
-ウォームギアの部分を別のもっと大きい歯車で代用する
のいずれかを行う必要がある。しかし、モーター歯車を大きく...
アーム部分の歯車を大きくする案も、LEGOのパーツに余裕がな...
***全体的な接続の強化 [#s599454b]
ここまで来ていろいろとやってみた挙句実感したが、この構造...
全体的な歯車のかみ合わせがすぐに不安定になり、空回りする...
&ref(2012b/Member/ddnp/Mission2/gear_protect.jpg, 100%, ...
それにしてもこの輪ゴム、本当にどうやって止めてるのか分か...
&ref(2012b/Member/ddnp/Mission2/morter_protect.jpg, 100%,...
この一つ前の段階では、シャフトを使って堅固すぎる固定をし...
恐らく、アーム回りで自分が関わった改良は大体このあたりで...
***アームテスト用プログラム [#jf39cf0b]
ただ単純に、アーム動力のモーターへ2秒間出力するだけであ...
task main ()
{
// アーム出力調整
SetPower(OUT_B, 6);
// 2秒間アームに出力
OnFwd(OUT_B);
Wait(200);
Off(OUT_B);
}
**紙パックを見つける [#t0611b16]
箱を掴んで持ち上げられるなら、後は紙パックを認知できれば...
***タッチセンサーをアームにつける [#d81277b3]
&ref(2012b/Member/ddnp/Mission2/touch_sensor.jpg, 100%, ...
とりあえず、タッチセンサーをアームに付けてみた。そしてロ...
task main
{
SetSensor(SENSOR_2, SONSOR_TOUCH);
// 感知するまで前進
until(SENSOR_2)
{
OnFwd(OUT_AC);
}
// 停止
Off(OUT_AC);
}
だが、ただ単純につけただけでは感知しない模様。紙パックが...
-本体の速度を上げる
-バンパーを用いて、てこの原理を使う
紙パックの軽さから考えて、感知させるには相当な速さが必要...
&ref(2012b/Member/ddnp/Mission2/bumper_module.gif, 100%, ...
バンパーはアームに取り付ける予定であったため、バンパー自...
***タッチセンサーをロボット背面につける [#re2de7fd]
結果論からいくと、下の写真のようになった。
&ref(2012b/Member/ddnp/Mission2/back_bumper.jpg, 100%, ロ...
&ref(2012b/Member/ddnp/Mission2/backbumper_touchsensor.jp...
&ref(2012b/Member/ddnp/Mission2/bumper_and_sensor.jpg, 10...
ロボット全体の高さの中で、最も高い場所から地面スレスレま...
***紙パックを掴むプログラム [#v5f48545]
タッチセンサーが背面に付いているため、タッチセンサーが反...
**箱の入れ替え [#y2ba45e3]
&ref(2012b/Member/ddnp/Mission2/how_to_exchange_2.jpg, 10...
点対称なコースであるため、先にコースの半分を使って全ての...
&ref(2012b/Member/ddnp/Mission2/how_to_exchange_1.jpg, 10...
しかし、最終的に1つずつ箱を交換していく方法を選択。これ...
*タイヤまわり [#ddea24d5]
&ref(2012b/Member/ddnp/Mission2/wheel_gear.jpg, 100%, タ...
車輪の方も、ライントレスをする以上、可能な限り遅くしたい...
&ref(2012b/Member/ddnp/Mission2/gear_speed.jpg, 100%, ギ...
小さい歯車の一回転は、大きい歯車の一回転に相当しない。そ...
*全体の荷重 [#j7b243b3]
ただ、それと同時に別の問題をクリアした。むしろこっちがメ...
最も重いのはRCX本体。なのでこいつを動かせば、大抵の荷重問...
&ref(2012b/Member/ddnp/Mission2/over_wheel.jpg, 100%, タ...
水色の線が、タイヤの中心から垂直に伸ばした線。、改良前で...
*最終的な本体 [#x3d5bfbd]
ロボット全体とその他補足的な改良を説明する。
&ref(2012b/Member/ddnp/Mission2/itamae.jpg, 100%, 完成し...
ロボットの全体像はこんな感じ。紙パックの下の方を掴めると...
&ref(2012b/Member/ddnp/Mission2/arm_gears.jpg, 100%, アー...
苦労したアームの歯車まわりは、こんな感じ。
&ref(2012b/Member/ddnp/Mission2/itamae_under.jpg, 100%, ...
このロボットも2輪のため、支えるためのパーツが下面に付い...
&ref(2012b/Member/ddnp/Mission2/itamae_under2.jpg, 100%, ...
また、タッチセンサー側への進行が主になるので、光センサー...
とりあえずここでハード面は一旦完成として、プログラムに移...
*必要なプログラム [#d870ac88]
機体は出来たので、プログラムを考えることとなった。
1つずつ箱を運ぶプログラムを書くので、断片的な動作のプロ...
-箱を感知し掴む
-箱を持ち上げ、木を超えさせる(この中で箱を離すプログラム...
-箱をゴール内まで運ぶ(3つ分)
-通信を持ちいて箱を置いたことを伝え、また同じ内容を受信す...
こちらのプログラムを、他の三人にお願いした。これらを完成...
-スタート地点から出発し、一つ目に辿り着く
-箱を受け渡すところまで進む
-通信場所まで移動する
-渡された箱のある場所まで移動する
-渡された箱付近からゴール付近まで戻る
全体的な流れはこんなかんじを想定。
+一つ目の箱に辿り着く
+箱を感知し掴む
+箱を受け渡すところまで進む
+通信場所まで移動
+通信
+渡された箱まで移動
+ゴール付近まで移動
+ゴール内に収める
+次の箱に移動
+2〜8を繰り返す
これにて、全体的な見通しが立ったため、各自プログラムを作...
**ライントレスを改良 [#uc700fcd]
箱の配置場所からして、境界線のライントレスが線の右側と左...
/*
############################
定数定義
############################
*/
// トレス判定系
#define DEEPBLACK 42 // 濃い黒のしきい値
#define BLACK 46 // 黒のしきい値
#define WHITE 50 // 白のしきい値
#define DEEPWHITE 52 // 濃い白のしきい値
#define CORNER_WAIT 2500 // コーナー判定を無視する時間
#define CHANGE_LINE1 2000 // 一回目のライントレス方向...
// 境界トレス用
#define CORNER_TIME 60 // 直角判定する時間
// 黒トレス用
#define SEESIGHT 120 // 黒トレス時のライン捜索時間
/*
#############################
# 変数宣言
#############################
*/
int clockwise = 3; // 黒トレス時の回転方向を記憶 奇数...
int rad_increase = 1; // 黒トレス時の反転回数 倍角変...
int corner_times = 0; // コーナーを曲がった回数
int backturn = 0; // シュート時の角度補正用
int corner_wait = -2300; // コーナーを曲がった時の時間
int lineside = 1; // 境界トレスの境界線を切り替え 奇...
/*
#############################
# マクロ
#############################
*/
#define RotateRight OnFwd(OUT_A); OnRev(OUT_C); // 時計...
#define RotateLeft OnFwd(OUT_C); OnRev(OUT_A); // 反時...
/*
#############################
# 境界トレス
# ルーチン
#############################
*/
sub border_trace()
{
// 白側→黒側
if(SENSOR_1 > DEEPWHITE)
{
// 薄くなるまで回転
while(SENSOR_1 > WHITE)
{
if(lineside % 2)
{
// 左小回転
RotateLeft;
}
else
{
// 右小回転
RotateRight;
}
}
}
// 黒側→白側
else if(SENSOR_1 < DEEPBLACK)
{
ClearTimer(2); // 旋回時間を測定
// 薄くなるまで回転
while(SENSOR_1 < BLACK)
{
if(lineside % 2)
{
// 右小回転
RotateRight;
}
else
{
// 左小回転
RotateLeft;
}
}
// コーナーを判定且つ以前コーナーに来てからしばらく経...
if(FastTimer(2) >= CORNER_TIME && FastTimer(0) >= corn...
{
backturn = FastTimer(2)+5; // 曲がるのにかかった時間...
corner_times++; // コーナーの数を数える
PlayTone(440, 30); // コーナーの数を数えたことを知...
corner_wait = FastTimer(0); // コーナーを曲がったとき...
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
/*
#############################
# 黒トレス
# ルーチン
#############################
*/
sub line_trace()
{
// 完全に白い場所を感知した時、方向修正
if(SENSOR_1 >= WHITE)
{
rad_increase = 1; // 倍角変数を初期化
// 黒ラインに入るまで処理。黒ラインが見当たらないとき...
while(SENSOR_1 >= WHITE && rad_increase <= 3)
{
ClearTimer(1); // タイマーリセット
// 黒ラインに入るまで、且つ旋回時間が過ぎるまで旋回
while((SENSOR_1 >= BLACK) && (FastTimer(1) <= SEESIGH...
{
// 時計回り
if(clockwise % 2)
{
RotateRight;
}
// 反時計回り
else if(!(clockwise % 2))
{
RotateLeft;
}
}
// 白い場所から脱出できなかった場合
if(SENSOR_1 >= BLACK)
{
clockwise ++; // 回転方向を変更
rad_increase += 1; // 回転時間を増加
}
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
ロボットの速度に合わせて、感知する黒の領域も、41付近から4...
とりあえずここまで完成させて、後の不具合は組み込みながら...
**このあたりまで来て気づいた重要なこと:ソフト面 [#l9356d...
他の人達がちらほらプログラムを完成させてきたところで、あ...
**このあたりまで来て気づいた重要なこと:ハード面 [#p5dbb2...
ここで、箱を感知してから半回転する動作は、回転時間を定数...
&ref(2012b/Member/ddnp/Mission2/itamae_under.jpg, 100%, ...
この理由は、第三の支えとなっているパーツが原因であると思...
&ref(2012b/Member/ddnp/Mission2/course_register.jpg, 100%...
さらにその上、本体が大きすぎてライントレスをしようとして...
**定数では不確実 [#t1fb9051]
上で述べたように、障害を全てプログラムで乗り越えようとし...
*最終的なプログラム [#y243c171]
結局、一つ目の箱を仕切り棒の向こう側に渡すところまでしか...
//------------------------------------------------//
//
// Title : Box_exchanger
//
// Usage : ライントレスを行いながら
// 真ん中のしきりをクリアして
// 左右別々のコースにある
// 白と黒の箱を交換する
//
//------------------------------------------------//
/*
############################
定数定義
############################
*/
// トレス判定系
#define DEEPBLACK 42 // 濃い黒のしきい値
#define BLACK 46 // 黒のしきい値
#define WHITE 50 // 白のしきい値
#define DEEPWHITE 52 // 濃い白のしきい値
#define CORNER_WAIT 2500 // コーナー判定を無視する時間
#define CHANGE_LINE1 2000 // 一回目のライントレス方向...
// 境界トレス用
#define CORNER_TIME 60 // 直角判定する時間
// 黒トレス用
#define SEESIGHT 120 // 黒トレス時のライン捜索時間
// 箱をつかむ系
#define QUARTER_TURN_TIME 120 // 1/4回転
#define STAY_BACK_TIME 150 // 持ち上げる際に一度退く...
#define APPROACH_TIME 80 // 箱に近づく時間
// 箱を渡す系
#define BOXED_TURN_TIME 270 // 箱をもっての回転時間
#define PUSH_TIME 60 // 箱を押す時間
// アーム処理系
#define OPEN_TIME 320 // アームを完全に開閉する時間
#define KEEP_TIME 80 // 箱を完全につまむまでの時間
#define RAISEUP_TIME 100 // アームを持ち上げる時間
/*
#############################
# 変数宣言
#############################
*/
int clockwise = 3; // 黒トレス時の回転方向を記憶 奇数...
int rad_increase = 1; // 黒トレス時の反転回数 倍角変...
int corner_times = 0; // コーナーを曲がった回数
int backturn = 0; // 角を曲がった度数補正用
int corner_wait = -2300; // コーナーを曲がった時の時間
int lineside = 1; // 境界トレスの側を切り替え 奇数で...
/*
#############################
# マクロ
#############################
*/
#define RotateRight OnFwd(OUT_A); OnRev(OUT_C); // 時計...
#define RotateLeft OnFwd(OUT_C); OnRev(OUT_A); // 反時...
/*
#############################
# 境界トレス
# ルーチン
#############################
*/
sub border_trace()
{
// 白側→黒側
if(SENSOR_1 > DEEPWHITE)
{
// 薄くなるまで回転
while(SENSOR_1 > WHITE)
{
if(lineside % 2)
{
// 左小回転
RotateLeft;
}
else
{
// 右小回転
RotateRight;
}
}
}
// 黒側→白側
else if(SENSOR_1 < DEEPBLACK)
{
ClearTimer(2); // 旋回時間を測定
// 薄くなるまで回転
while(SENSOR_1 < BLACK)
{
if(lineside % 2)
{
// 右小回転
RotateRight;
}
else
{
// 左小回転
RotateLeft;
}
}
// コーナーを判定且つ以前コーナーに来てからしばらく経...
if(FastTimer(2) >= CORNER_TIME && FastTimer(0) >= corn...
{
backturn = FastTimer(2)+5; // 曲がるのにかかった時間...
corner_times++; // コーナーの数を数える
PlayTone(440, 30); // コーナーの数を数えたことを知ら...
corner_wait = FastTimer(0); // コーナーを曲がったとき...
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
/*
#############################
# 黒トレス
# ルーチン
#############################
*/
sub line_trace()
{
// 完全に白い場所を感知した時、方向修正
if(SENSOR_1 >= WHITE)
{
rad_increase = 1; // 倍角変数を初期化
// 黒ラインに入るまで処理。黒ラインが見当たらないとき...
while(SENSOR_1 >= WHITE && rad_increase <= 3)
{
ClearTimer(1); // タイマーリセット
// 黒ラインに入るまで、且つ旋回時間が過ぎるまで旋回
while((SENSOR_1 >= BLACK) && (FastTimer(1) <= SEESIGH...
{
// 時計回り
if(clockwise % 2)
{
RotateRight;
}
// 反時計回り
else if(!(clockwise % 2))
{
RotateLeft;
}
}
// 白い場所から脱出できなかった場合
if(SENSOR_1 >= BLACK)
{
clockwise ++; // 回転方向を変更
rad_increase += 1; // 回転時間を増加
}
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
/*
#############################
# 箱掴みルーチン
#############################
*/
sub box_catch()
{
// 一時後退
OnRev(OUT_AC);
Wait(STAY_BACK_TIME);
// 半周回転
SetPower(OUT_AC, 3); // 回転時のモーター動力確保のため...
OnRev(OUT_A);
OnFwd(OUT_C);
Wait(QUARTER_TURN_TIME*2);
Off(OUT_AC);
SetPower(OUT_AC, 2); // 動力戻す
// アーム開
OnFwd(OUT_B);
Wait(OPEN_TIME);
// 手前引っ張り修正
OnRev(OUT_AC);
Wait(STAY_BACK_TIME);
Off(OUT_AC); // ここまで箱に向かう処理
OnRev(OUT_B);
Wait(OPEN_TIME + KEEP_TIME);
Off(OUT_B); // ここまで箱を軽く掴む
OnFwd(OUT_AC);
Wait(STAY_BACK_TIME);
Off(OUT_AC); // 少し後ろに引っ張る
OnFwd(OUT_B);
Wait(OPEN_TIME);
Off(OUT_B);
// 引っ張る
OnRev(OUT_AC);
Wait(APPROACH_TIME);
Off(OUT_AC);
OnRev(OUT_B);
Wait(OPEN_TIME + KEEP_TIME);
Off(OUT_B);
// 処理終了
Off(OUT_ABC);
SetPower(OUT_AC, 2);
SetPower(OUT_B, 7);
}
/*
#############################
# 箱乗り上げルーチン
#############################
*/
sub box_throw()
{
// 動力UPのため一度全体のモーターを初期化
SetPower(OUT_AC, 3);
SetPower(OUT_B, 7);
// 一時後退
OnRev(OUT_AC);
Wait(STAY_BACK_TIME);
// 半周回転
SetPower(OUT_AC, 4);
OnRev(OUT_C);
OnFwd(OUT_A);
Wait(BOXED_TURN_TIME);
Off(OUT_AC);
SetPower(OUT_AC, 3);
// アーム持ち上げと同時に直進
OnRev(OUT_B);
OnRev(OUT_AC);
Wait(RAISEUP_TIME);
Off(OUT_B);
// さらに押す
Wait(PUSH_TIME);
Off(OUT_AC);
// 箱を離す
OnFwd(OUT_B);
Wait(OPEN_TIME);
// 二回押して確実に向こう側に渡してみる
repeat(2)
{
// 退いて
OnFwd(OUT_AC);
Wait(PUSH_TIME);
Off(OUT_AC);
OnRev(OUT_B);
Wait(OPEN_TIME);
// 押す
OnRev(OUT_AC);
Wait(PUSH_TIME);
Off(OUT_AC);
OnFwd(OUT_B);
Wait(OPEN_TIME);
}
// 処理終了
Off(OUT_ABC);
SetPower(OUT_AC, 2);
SetPower(OUT_B, 7);
}
/*
################################
#
# メイン関数
#
################################
*/
task main()
{
//-------------------------//
// 初期化設定
//-------------------------//
SetSensor(SENSOR_1, SENSOR_LIGHT); // センサー1に光...
SetSensor(SENSOR_2, SENSOR_TOUCH); // センサー2にタ...
SetPower(OUT_AC, 2); // 走行動力を設定
SetPower(OUT_B, 7); // アーム動力を設定
ClearTimer(0); // プログラムを走らせてからの時間を...
//------------------------//
// スタート
// ↓
// 一つ目の箱
//------------------------//
// 箱に向かって直進
until(SENSOR_2)
{
OnFwd(OUT_AC);
}
Off(OUT_AC);
// 箱を取得
box_catch();
//------------------------//
// 一つ目の箱
// ↓
// 板乗り越え
//------------------------//
// 黒いラインまで前進
until(SENSOR_1 < DEEPBLACK)
{
OnFwd(OUT_AC);
}
Off(OUT_AC);
// 仕切り棒を感知するか、ライン右側に移動するまで黒ライ...
until(SENSOR_2 || !(clockwise % 2))
{
line_trace();
}
// 仕切り棒を感知するまでライン右側を境界トレス
until(SENSOR_2)
{
border_trace();
}
// 箱を仕切り棒の向こう側に置く
box_throw();
// 動作を停止
Off(OUT_ABC);
}
自分が作ったプログラムを実際にロボットに組み込んで試した...
-全体が流れるような処理になったため、until文を使用して上...
-箱を掴む動作のプログラムは、ただ単純にアームを閉じるだけ...
-同じく箱を乗り越えさせる処理も、二回ほど押しこむ動作を追加
-ライントレス中に、仕切り棒に当たって動かなくなる現象を逆...
ところで、掲載のために見返しをしてみたらコメント文が酷い...
#define PUSH_TIME 60 // 箱を♂時間
//-------------------------//
// 初期化設定
//-------------------------//
SetSensor(SENSOR_1, SENSOR_LIGHT); // ヒカリセンサー1起動!!!
SetSensor(SENSOR_2, SENSOR_TOUCH); // タッチセンサー2初期化!!!
SetPower(OUT_AC, 2); // モーター動力カクニン!!!
SetPower(OUT_B, 7); // アームモーターエネルギー充填!!
ClearTimer(0); // 3,2,1!ハッシン!!!(ドゥムゥッ...ッ.......(...
*総括 [#dff1dc6d]
**反省点 [#n10d53c3]
反省点としては、というか反省点しか無い気もするのだが、以...
***チームの連携 [#h24e4616]
今回の課題については、特にチームの連携が必要だったと実感...
***時間配分 [#nd404fc5]
先生に再三「ハードでなくソフトに時間をかけてほしい」と言...
**総括 [#y647a26e]
結局ロボコンでは、箱すらも運べなかった。本番当日になって...
&ref(2012b/Member/ddnp/Mission2/itamae.jpg, 100%, ロボッ...
***ちなみに、本番当日になって発生した問題とは [#pb2d4707]
書くところがないため、ここにそれを纏めるが、開ききったア...
&ref(2012b/Member/ddnp/Mission2/arm_close.jpg, 100%, 閉ま...
アームが閉まっている最中に持ち上げる時は問題がないのだが、
&ref(2012b/Member/ddnp/Mission2/arm_open.jpg, 100%, 開い...
図のようにアームが全開になっている時にアームを締めようと...
*おまけ [#d56f0789]
RCX本体からは、1音しか出すことが出来ない。以前、「RCXで...
終了行:
#contents
*コース全体を見渡して問題を確認[#raising_questions]
まずは、課題をクリアするのに何が必要かを検討してみる。
コースは、一つ目の課題で使ったコースを用いて作成するが、...
&ref(2012b/Member/ddnp/Mission2/course.jpg, 100%, ロボコ...
また、詳しいルールはこちらを参照。[[2012年後期ロボコン>20...
とりあえず、ここから見えてくる大きな課題は3つ
-真ん中の木をどうやって乗り越えるか
-紙パックをどうやって掴むか
-どうやって箱を入れ替えるか
まずはこれらの解決に入ることにする。
*紙パックを運ぶ[#the_way_of_carrying_boxes]
**木を乗り越える [#w08268df]
まず、木を乗り越える方法について吟味してみる。
とりあえず思い当たる方法は二つ。
-箱だけ乗り越える
-本体ごと乗り越える
もしかしたら複数の小型ユニットが本体からの命令で紙パック...
よってこの二つに絞ったが、それぞれの特色を吟味すると、以...
-箱だけ乗り越える場合
--箱を受け渡す機構が必要
--受け渡しのため、最低二台は必要になる
--自由自在に動きまわらせるには、ロボットの回転が不可欠。...
--よって、箱を運ぶためのモーターが一台につき1つしか使え...
--ただし、軽量化は可能
--小型化も楽
--箱の受け渡しにおいて確実性をあげるには、通信することも...
--モーター数制限により、箱の積み上げはほぼ不可能だと思わ...
--コースを点対称に組み、それを利用すれば、1つの機体、1...
-本体ごと乗り越える場合
--本体自体が木を乗り越えられる機構が必要
--大型化、重量化が懸念される
--ただし、動力に必要なモーターは最低2つで済む
--モーターが余れば、箱や本体の乗り越え、箱の積み上げ等、...
--モーターが多く使えるため、箱の積み上げが箱だけ乗り越え...
--RCX本体に接続できる接続コードは3つまでなので、4つ以上...
--センサーも同様
--これより、RCX同士が通信で処理の同期を取る必要性がある
箱を積み上げる気が無かった上、機体やプログラムを使いまわ...
個人的には、本体ごと乗り越えさせる機構の構想が浮かばなか...
乗り越えの方針は決まったため、次に問題となるのは箱の掴み...
**紙パックを挟む [#ccf1b82c]
機体を動かすことについては[[課題1>2012b/Member/ddnp/Miss...
では、どうやって掴むといいだろうか。
-横から挟み込む
-上から吊る
-下から持ち上げる
とりあえず、人の手で行える動作を元に考えたので、自分で思...
&ref(2012b/Member/ddnp/Mission2/how_to_raise.jpg, 100%, ...
この3つの中から、消去法で「横から挟み込む」方法を取るこ...
「下から持ち上げる」方法は、箱の下にロボットの部品を潜り...
後々になって、「押す」という動作があることを思いついたが...
事実、他のチームは「挟み」と「押し」を利用していて、上手...
**挟むためのパーツ[#parts_to_hold]
挟むためのパーツということで、クワガタのように挟み込む形...
&ref(2012b/Member/ddnp/Mission2/arm_A.jpg, 100%, アーム);
写真下部に垂直に付いているギアを回すことで、写真中央のウ...
&ref(2012b/Member/ddnp/Mission2/arm_B.jpg, 100%, 開くアー...
これのギアを回してみると、とりあえず紙パックを掴むことは...
単純に見えて掴めるのか怪しいけど、意外と紙パックにフィッ...
紙パックを挟むこと自体は大して難しくなかった。しかしここ...
**紙パックを持ち上げる[#how_to_raise_up]
問題は紙パックの持ち上げである。
木の障害物がある以上、その障害を乗り越えられるだけの高さ...
しかし、紙パックを木の障害物の高さにまで上げる動作は難し...
機体のコピーを作ることを前提としている以上、ひとつのモー...
他の方法を考えようかと思っていたところ、天の一声(CV:担当...
「アームのギアに強い力をかければ歯車は重くなるから、その...
&ref(2012b/Member/ddnp/Mission2/way_of_armup_A.jpg, 100%,...
普通、歯車の回転はアームを閉める働きをする。
&ref(2012b/Member/ddnp/Mission2/way_of_armup_B.jpg, 100%,...
アームを閉めていくと箱やアーム自身の締め付けが強くなり、...
最終的には、歯車自体が動かなくなるが、それを利用する。
&ref(2012b/Member/ddnp/Mission2/way_of_armup_C.jpg, 100%,...
歯車が動かなくなるので、アーム自体にはそれ以上力が加わら...
&ref(2012b/Member/ddnp/Mission2/way_of_armup_D.jpg, 100%,...
そのアーム全体を動かす力を、上方向にかかるようにすると、...
理論は出来上がったので、実際にアームの仕組みを作ることが...
そしてここからがとてつもなく大変であった。
**紙パックが持ち上がるまでに問題になった所[#arm_problems]
***アームとの歯車の組み合わせ [#g3226a72]
いきなり、歯車同士を垂直に交らわせることが問題となった。
交らわせることの出来る歯車の大きさや、噛み合わせがなかな...
普通の形の歯車を垂直に噛み合わせようとしても、回転してい...
モーターの邪魔にならないくらいに大きい歯車を使用し、かつ...
そして、見事に垂直方向に噛み合わせてくださいと言わんばか...
とりあえず、わかりにくいとは思うが、下図のように歯車の歯...
&ref(2012b/Member/ddnp/Mission2/combi_gear.jpg, 100%, ア...
またその中継歯車は、モーターに直接接続していない。
アーム全体が上に持ち上がるといっても、歯車に接続している...
よって、中継歯車を長いシャフトに通して、これを実現した。...
ここでなら分かると思うが、直接動力を与えられているわけで...
&ref(2012b/Member/ddnp/Mission2/alpha_arm_parts.jpg, 100%...
さて、これで持ち上がるかといったらそうでもない。まだまだ...
が、次の日、何故か突如として持ち上がらなくなる…。原因は輪...
***アームまわりの軽量化、補強 [#b262b93b]
まずはアームの根本のギアを強化。
&ref(2012b/Member/ddnp/Mission2/new_arm_1.jpg, 100%, アー...
-歯車を変えてサイズを一回り小さく
-無駄なブロックが無くなり堅固性の向上につながった模様
続いてアーム部本体の軸回りを強化。
&ref(2012b/Member/ddnp/Mission2/new_arm_2.jpg, 100%, アー...
-持ち上げる際にアーム部分との乖離を起こし安かったためこち...
-軸とアーム部を固定する役目を、薄い一枚ブロックで行なって...
-中継歯車付近、アームの回転軸にあった輪ゴムの厚さほどの謎...
ウォームギア(&ref(2012b/Member/ddnp/Mission2/warm_gear.g...
だがしかし、これでもまだ持ち上がる時と持ち上がらない時が...
***モーター歯車の大きさ [#v5024b1e]
ここで、持ち上がらない原因が、歯車全体が動かなくなったと...
アームに動力を伝えるのに、中継歯車を使った。そしてそれは...
その部分は、モーター自体に歯車をはめ、その歯車が直接中継...
ここで、このモーターに接続している歯車を便宜上「モーター...
&ref(2012b/Member/ddnp/Mission2/morter_gear.jpg, 100%, 中...
参考に写真を貼ったが、これはこの問題発生時点の歯車ではな...
&ref(2012b/Member/ddnp/Mission2/gear_torque.jpg, 100%, ギ...
大きさの違う歯車には、てこの原理が働く。そのため同じ動力...
&ref(2012b/Member/ddnp/Mission2/raise_power_A.jpg, 100%, ...
&ref(2012b/Member/ddnp/Mission2/raise_power_B.jpg, 100%, ...
中継歯車自体がまるでシーソーのような役目を果たしているた...
改良前の状態では、LEGOパーツ中で中くらいの大きさの歯車を...
***歯車の空回り [#i769186d]
&ref(2012b/Member/ddnp/Mission2/arm_powerup_B.jpg, 100%, ...
&ref(2012b/Member/ddnp/Mission2/arm_powerup_A.jpg, 100%, ...
先ほど、中継歯車がシーソーのような役割をするといった。そ...
&ref(2012b/Member/ddnp/Mission2/arm_root.jpg, 100%, アー...
図の青矢印部分で、歯車が空回りし始めたのだ。);ウォームギ...
-モーター歯車を大きくする
-アーム部分の歯車を大きくする
-ウォームギアの部分を別のもっと大きい歯車で代用する
のいずれかを行う必要がある。しかし、モーター歯車を大きく...
アーム部分の歯車を大きくする案も、LEGOのパーツに余裕がな...
***全体的な接続の強化 [#s599454b]
ここまで来ていろいろとやってみた挙句実感したが、この構造...
全体的な歯車のかみ合わせがすぐに不安定になり、空回りする...
&ref(2012b/Member/ddnp/Mission2/gear_protect.jpg, 100%, ...
それにしてもこの輪ゴム、本当にどうやって止めてるのか分か...
&ref(2012b/Member/ddnp/Mission2/morter_protect.jpg, 100%,...
この一つ前の段階では、シャフトを使って堅固すぎる固定をし...
恐らく、アーム回りで自分が関わった改良は大体このあたりで...
***アームテスト用プログラム [#jf39cf0b]
ただ単純に、アーム動力のモーターへ2秒間出力するだけであ...
task main ()
{
// アーム出力調整
SetPower(OUT_B, 6);
// 2秒間アームに出力
OnFwd(OUT_B);
Wait(200);
Off(OUT_B);
}
**紙パックを見つける [#t0611b16]
箱を掴んで持ち上げられるなら、後は紙パックを認知できれば...
***タッチセンサーをアームにつける [#d81277b3]
&ref(2012b/Member/ddnp/Mission2/touch_sensor.jpg, 100%, ...
とりあえず、タッチセンサーをアームに付けてみた。そしてロ...
task main
{
SetSensor(SENSOR_2, SONSOR_TOUCH);
// 感知するまで前進
until(SENSOR_2)
{
OnFwd(OUT_AC);
}
// 停止
Off(OUT_AC);
}
だが、ただ単純につけただけでは感知しない模様。紙パックが...
-本体の速度を上げる
-バンパーを用いて、てこの原理を使う
紙パックの軽さから考えて、感知させるには相当な速さが必要...
&ref(2012b/Member/ddnp/Mission2/bumper_module.gif, 100%, ...
バンパーはアームに取り付ける予定であったため、バンパー自...
***タッチセンサーをロボット背面につける [#re2de7fd]
結果論からいくと、下の写真のようになった。
&ref(2012b/Member/ddnp/Mission2/back_bumper.jpg, 100%, ロ...
&ref(2012b/Member/ddnp/Mission2/backbumper_touchsensor.jp...
&ref(2012b/Member/ddnp/Mission2/bumper_and_sensor.jpg, 10...
ロボット全体の高さの中で、最も高い場所から地面スレスレま...
***紙パックを掴むプログラム [#v5f48545]
タッチセンサーが背面に付いているため、タッチセンサーが反...
**箱の入れ替え [#y2ba45e3]
&ref(2012b/Member/ddnp/Mission2/how_to_exchange_2.jpg, 10...
点対称なコースであるため、先にコースの半分を使って全ての...
&ref(2012b/Member/ddnp/Mission2/how_to_exchange_1.jpg, 10...
しかし、最終的に1つずつ箱を交換していく方法を選択。これ...
*タイヤまわり [#ddea24d5]
&ref(2012b/Member/ddnp/Mission2/wheel_gear.jpg, 100%, タ...
車輪の方も、ライントレスをする以上、可能な限り遅くしたい...
&ref(2012b/Member/ddnp/Mission2/gear_speed.jpg, 100%, ギ...
小さい歯車の一回転は、大きい歯車の一回転に相当しない。そ...
*全体の荷重 [#j7b243b3]
ただ、それと同時に別の問題をクリアした。むしろこっちがメ...
最も重いのはRCX本体。なのでこいつを動かせば、大抵の荷重問...
&ref(2012b/Member/ddnp/Mission2/over_wheel.jpg, 100%, タ...
水色の線が、タイヤの中心から垂直に伸ばした線。、改良前で...
*最終的な本体 [#x3d5bfbd]
ロボット全体とその他補足的な改良を説明する。
&ref(2012b/Member/ddnp/Mission2/itamae.jpg, 100%, 完成し...
ロボットの全体像はこんな感じ。紙パックの下の方を掴めると...
&ref(2012b/Member/ddnp/Mission2/arm_gears.jpg, 100%, アー...
苦労したアームの歯車まわりは、こんな感じ。
&ref(2012b/Member/ddnp/Mission2/itamae_under.jpg, 100%, ...
このロボットも2輪のため、支えるためのパーツが下面に付い...
&ref(2012b/Member/ddnp/Mission2/itamae_under2.jpg, 100%, ...
また、タッチセンサー側への進行が主になるので、光センサー...
とりあえずここでハード面は一旦完成として、プログラムに移...
*必要なプログラム [#d870ac88]
機体は出来たので、プログラムを考えることとなった。
1つずつ箱を運ぶプログラムを書くので、断片的な動作のプロ...
-箱を感知し掴む
-箱を持ち上げ、木を超えさせる(この中で箱を離すプログラム...
-箱をゴール内まで運ぶ(3つ分)
-通信を持ちいて箱を置いたことを伝え、また同じ内容を受信す...
こちらのプログラムを、他の三人にお願いした。これらを完成...
-スタート地点から出発し、一つ目に辿り着く
-箱を受け渡すところまで進む
-通信場所まで移動する
-渡された箱のある場所まで移動する
-渡された箱付近からゴール付近まで戻る
全体的な流れはこんなかんじを想定。
+一つ目の箱に辿り着く
+箱を感知し掴む
+箱を受け渡すところまで進む
+通信場所まで移動
+通信
+渡された箱まで移動
+ゴール付近まで移動
+ゴール内に収める
+次の箱に移動
+2〜8を繰り返す
これにて、全体的な見通しが立ったため、各自プログラムを作...
**ライントレスを改良 [#uc700fcd]
箱の配置場所からして、境界線のライントレスが線の右側と左...
/*
############################
定数定義
############################
*/
// トレス判定系
#define DEEPBLACK 42 // 濃い黒のしきい値
#define BLACK 46 // 黒のしきい値
#define WHITE 50 // 白のしきい値
#define DEEPWHITE 52 // 濃い白のしきい値
#define CORNER_WAIT 2500 // コーナー判定を無視する時間
#define CHANGE_LINE1 2000 // 一回目のライントレス方向...
// 境界トレス用
#define CORNER_TIME 60 // 直角判定する時間
// 黒トレス用
#define SEESIGHT 120 // 黒トレス時のライン捜索時間
/*
#############################
# 変数宣言
#############################
*/
int clockwise = 3; // 黒トレス時の回転方向を記憶 奇数...
int rad_increase = 1; // 黒トレス時の反転回数 倍角変...
int corner_times = 0; // コーナーを曲がった回数
int backturn = 0; // シュート時の角度補正用
int corner_wait = -2300; // コーナーを曲がった時の時間
int lineside = 1; // 境界トレスの境界線を切り替え 奇...
/*
#############################
# マクロ
#############################
*/
#define RotateRight OnFwd(OUT_A); OnRev(OUT_C); // 時計...
#define RotateLeft OnFwd(OUT_C); OnRev(OUT_A); // 反時...
/*
#############################
# 境界トレス
# ルーチン
#############################
*/
sub border_trace()
{
// 白側→黒側
if(SENSOR_1 > DEEPWHITE)
{
// 薄くなるまで回転
while(SENSOR_1 > WHITE)
{
if(lineside % 2)
{
// 左小回転
RotateLeft;
}
else
{
// 右小回転
RotateRight;
}
}
}
// 黒側→白側
else if(SENSOR_1 < DEEPBLACK)
{
ClearTimer(2); // 旋回時間を測定
// 薄くなるまで回転
while(SENSOR_1 < BLACK)
{
if(lineside % 2)
{
// 右小回転
RotateRight;
}
else
{
// 左小回転
RotateLeft;
}
}
// コーナーを判定且つ以前コーナーに来てからしばらく経...
if(FastTimer(2) >= CORNER_TIME && FastTimer(0) >= corn...
{
backturn = FastTimer(2)+5; // 曲がるのにかかった時間...
corner_times++; // コーナーの数を数える
PlayTone(440, 30); // コーナーの数を数えたことを知...
corner_wait = FastTimer(0); // コーナーを曲がったとき...
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
/*
#############################
# 黒トレス
# ルーチン
#############################
*/
sub line_trace()
{
// 完全に白い場所を感知した時、方向修正
if(SENSOR_1 >= WHITE)
{
rad_increase = 1; // 倍角変数を初期化
// 黒ラインに入るまで処理。黒ラインが見当たらないとき...
while(SENSOR_1 >= WHITE && rad_increase <= 3)
{
ClearTimer(1); // タイマーリセット
// 黒ラインに入るまで、且つ旋回時間が過ぎるまで旋回
while((SENSOR_1 >= BLACK) && (FastTimer(1) <= SEESIGH...
{
// 時計回り
if(clockwise % 2)
{
RotateRight;
}
// 反時計回り
else if(!(clockwise % 2))
{
RotateLeft;
}
}
// 白い場所から脱出できなかった場合
if(SENSOR_1 >= BLACK)
{
clockwise ++; // 回転方向を変更
rad_increase += 1; // 回転時間を増加
}
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
ロボットの速度に合わせて、感知する黒の領域も、41付近から4...
とりあえずここまで完成させて、後の不具合は組み込みながら...
**このあたりまで来て気づいた重要なこと:ソフト面 [#l9356d...
他の人達がちらほらプログラムを完成させてきたところで、あ...
**このあたりまで来て気づいた重要なこと:ハード面 [#p5dbb2...
ここで、箱を感知してから半回転する動作は、回転時間を定数...
&ref(2012b/Member/ddnp/Mission2/itamae_under.jpg, 100%, ...
この理由は、第三の支えとなっているパーツが原因であると思...
&ref(2012b/Member/ddnp/Mission2/course_register.jpg, 100%...
さらにその上、本体が大きすぎてライントレスをしようとして...
**定数では不確実 [#t1fb9051]
上で述べたように、障害を全てプログラムで乗り越えようとし...
*最終的なプログラム [#y243c171]
結局、一つ目の箱を仕切り棒の向こう側に渡すところまでしか...
//------------------------------------------------//
//
// Title : Box_exchanger
//
// Usage : ライントレスを行いながら
// 真ん中のしきりをクリアして
// 左右別々のコースにある
// 白と黒の箱を交換する
//
//------------------------------------------------//
/*
############################
定数定義
############################
*/
// トレス判定系
#define DEEPBLACK 42 // 濃い黒のしきい値
#define BLACK 46 // 黒のしきい値
#define WHITE 50 // 白のしきい値
#define DEEPWHITE 52 // 濃い白のしきい値
#define CORNER_WAIT 2500 // コーナー判定を無視する時間
#define CHANGE_LINE1 2000 // 一回目のライントレス方向...
// 境界トレス用
#define CORNER_TIME 60 // 直角判定する時間
// 黒トレス用
#define SEESIGHT 120 // 黒トレス時のライン捜索時間
// 箱をつかむ系
#define QUARTER_TURN_TIME 120 // 1/4回転
#define STAY_BACK_TIME 150 // 持ち上げる際に一度退く...
#define APPROACH_TIME 80 // 箱に近づく時間
// 箱を渡す系
#define BOXED_TURN_TIME 270 // 箱をもっての回転時間
#define PUSH_TIME 60 // 箱を押す時間
// アーム処理系
#define OPEN_TIME 320 // アームを完全に開閉する時間
#define KEEP_TIME 80 // 箱を完全につまむまでの時間
#define RAISEUP_TIME 100 // アームを持ち上げる時間
/*
#############################
# 変数宣言
#############################
*/
int clockwise = 3; // 黒トレス時の回転方向を記憶 奇数...
int rad_increase = 1; // 黒トレス時の反転回数 倍角変...
int corner_times = 0; // コーナーを曲がった回数
int backturn = 0; // 角を曲がった度数補正用
int corner_wait = -2300; // コーナーを曲がった時の時間
int lineside = 1; // 境界トレスの側を切り替え 奇数で...
/*
#############################
# マクロ
#############################
*/
#define RotateRight OnFwd(OUT_A); OnRev(OUT_C); // 時計...
#define RotateLeft OnFwd(OUT_C); OnRev(OUT_A); // 反時...
/*
#############################
# 境界トレス
# ルーチン
#############################
*/
sub border_trace()
{
// 白側→黒側
if(SENSOR_1 > DEEPWHITE)
{
// 薄くなるまで回転
while(SENSOR_1 > WHITE)
{
if(lineside % 2)
{
// 左小回転
RotateLeft;
}
else
{
// 右小回転
RotateRight;
}
}
}
// 黒側→白側
else if(SENSOR_1 < DEEPBLACK)
{
ClearTimer(2); // 旋回時間を測定
// 薄くなるまで回転
while(SENSOR_1 < BLACK)
{
if(lineside % 2)
{
// 右小回転
RotateRight;
}
else
{
// 左小回転
RotateLeft;
}
}
// コーナーを判定且つ以前コーナーに来てからしばらく経...
if(FastTimer(2) >= CORNER_TIME && FastTimer(0) >= corn...
{
backturn = FastTimer(2)+5; // 曲がるのにかかった時間...
corner_times++; // コーナーの数を数える
PlayTone(440, 30); // コーナーの数を数えたことを知ら...
corner_wait = FastTimer(0); // コーナーを曲がったとき...
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
/*
#############################
# 黒トレス
# ルーチン
#############################
*/
sub line_trace()
{
// 完全に白い場所を感知した時、方向修正
if(SENSOR_1 >= WHITE)
{
rad_increase = 1; // 倍角変数を初期化
// 黒ラインに入るまで処理。黒ラインが見当たらないとき...
while(SENSOR_1 >= WHITE && rad_increase <= 3)
{
ClearTimer(1); // タイマーリセット
// 黒ラインに入るまで、且つ旋回時間が過ぎるまで旋回
while((SENSOR_1 >= BLACK) && (FastTimer(1) <= SEESIGH...
{
// 時計回り
if(clockwise % 2)
{
RotateRight;
}
// 反時計回り
else if(!(clockwise % 2))
{
RotateLeft;
}
}
// 白い場所から脱出できなかった場合
if(SENSOR_1 >= BLACK)
{
clockwise ++; // 回転方向を変更
rad_increase += 1; // 回転時間を増加
}
}
}
else
{
OnFwd(OUT_AC); // 常に前進
}
}
/*
#############################
# 箱掴みルーチン
#############################
*/
sub box_catch()
{
// 一時後退
OnRev(OUT_AC);
Wait(STAY_BACK_TIME);
// 半周回転
SetPower(OUT_AC, 3); // 回転時のモーター動力確保のため...
OnRev(OUT_A);
OnFwd(OUT_C);
Wait(QUARTER_TURN_TIME*2);
Off(OUT_AC);
SetPower(OUT_AC, 2); // 動力戻す
// アーム開
OnFwd(OUT_B);
Wait(OPEN_TIME);
// 手前引っ張り修正
OnRev(OUT_AC);
Wait(STAY_BACK_TIME);
Off(OUT_AC); // ここまで箱に向かう処理
OnRev(OUT_B);
Wait(OPEN_TIME + KEEP_TIME);
Off(OUT_B); // ここまで箱を軽く掴む
OnFwd(OUT_AC);
Wait(STAY_BACK_TIME);
Off(OUT_AC); // 少し後ろに引っ張る
OnFwd(OUT_B);
Wait(OPEN_TIME);
Off(OUT_B);
// 引っ張る
OnRev(OUT_AC);
Wait(APPROACH_TIME);
Off(OUT_AC);
OnRev(OUT_B);
Wait(OPEN_TIME + KEEP_TIME);
Off(OUT_B);
// 処理終了
Off(OUT_ABC);
SetPower(OUT_AC, 2);
SetPower(OUT_B, 7);
}
/*
#############################
# 箱乗り上げルーチン
#############################
*/
sub box_throw()
{
// 動力UPのため一度全体のモーターを初期化
SetPower(OUT_AC, 3);
SetPower(OUT_B, 7);
// 一時後退
OnRev(OUT_AC);
Wait(STAY_BACK_TIME);
// 半周回転
SetPower(OUT_AC, 4);
OnRev(OUT_C);
OnFwd(OUT_A);
Wait(BOXED_TURN_TIME);
Off(OUT_AC);
SetPower(OUT_AC, 3);
// アーム持ち上げと同時に直進
OnRev(OUT_B);
OnRev(OUT_AC);
Wait(RAISEUP_TIME);
Off(OUT_B);
// さらに押す
Wait(PUSH_TIME);
Off(OUT_AC);
// 箱を離す
OnFwd(OUT_B);
Wait(OPEN_TIME);
// 二回押して確実に向こう側に渡してみる
repeat(2)
{
// 退いて
OnFwd(OUT_AC);
Wait(PUSH_TIME);
Off(OUT_AC);
OnRev(OUT_B);
Wait(OPEN_TIME);
// 押す
OnRev(OUT_AC);
Wait(PUSH_TIME);
Off(OUT_AC);
OnFwd(OUT_B);
Wait(OPEN_TIME);
}
// 処理終了
Off(OUT_ABC);
SetPower(OUT_AC, 2);
SetPower(OUT_B, 7);
}
/*
################################
#
# メイン関数
#
################################
*/
task main()
{
//-------------------------//
// 初期化設定
//-------------------------//
SetSensor(SENSOR_1, SENSOR_LIGHT); // センサー1に光...
SetSensor(SENSOR_2, SENSOR_TOUCH); // センサー2にタ...
SetPower(OUT_AC, 2); // 走行動力を設定
SetPower(OUT_B, 7); // アーム動力を設定
ClearTimer(0); // プログラムを走らせてからの時間を...
//------------------------//
// スタート
// ↓
// 一つ目の箱
//------------------------//
// 箱に向かって直進
until(SENSOR_2)
{
OnFwd(OUT_AC);
}
Off(OUT_AC);
// 箱を取得
box_catch();
//------------------------//
// 一つ目の箱
// ↓
// 板乗り越え
//------------------------//
// 黒いラインまで前進
until(SENSOR_1 < DEEPBLACK)
{
OnFwd(OUT_AC);
}
Off(OUT_AC);
// 仕切り棒を感知するか、ライン右側に移動するまで黒ライ...
until(SENSOR_2 || !(clockwise % 2))
{
line_trace();
}
// 仕切り棒を感知するまでライン右側を境界トレス
until(SENSOR_2)
{
border_trace();
}
// 箱を仕切り棒の向こう側に置く
box_throw();
// 動作を停止
Off(OUT_ABC);
}
自分が作ったプログラムを実際にロボットに組み込んで試した...
-全体が流れるような処理になったため、until文を使用して上...
-箱を掴む動作のプログラムは、ただ単純にアームを閉じるだけ...
-同じく箱を乗り越えさせる処理も、二回ほど押しこむ動作を追加
-ライントレス中に、仕切り棒に当たって動かなくなる現象を逆...
ところで、掲載のために見返しをしてみたらコメント文が酷い...
#define PUSH_TIME 60 // 箱を♂時間
//-------------------------//
// 初期化設定
//-------------------------//
SetSensor(SENSOR_1, SENSOR_LIGHT); // ヒカリセンサー1起動!!!
SetSensor(SENSOR_2, SENSOR_TOUCH); // タッチセンサー2初期化!!!
SetPower(OUT_AC, 2); // モーター動力カクニン!!!
SetPower(OUT_B, 7); // アームモーターエネルギー充填!!
ClearTimer(0); // 3,2,1!ハッシン!!!(ドゥムゥッ...ッ.......(...
*総括 [#dff1dc6d]
**反省点 [#n10d53c3]
反省点としては、というか反省点しか無い気もするのだが、以...
***チームの連携 [#h24e4616]
今回の課題については、特にチームの連携が必要だったと実感...
***時間配分 [#nd404fc5]
先生に再三「ハードでなくソフトに時間をかけてほしい」と言...
**総括 [#y647a26e]
結局ロボコンでは、箱すらも運べなかった。本番当日になって...
&ref(2012b/Member/ddnp/Mission2/itamae.jpg, 100%, ロボッ...
***ちなみに、本番当日になって発生した問題とは [#pb2d4707]
書くところがないため、ここにそれを纏めるが、開ききったア...
&ref(2012b/Member/ddnp/Mission2/arm_close.jpg, 100%, 閉ま...
アームが閉まっている最中に持ち上げる時は問題がないのだが、
&ref(2012b/Member/ddnp/Mission2/arm_open.jpg, 100%, 開い...
図のようにアームが全開になっている時にアームを締めようと...
*おまけ [#d56f0789]
RCX本体からは、1音しか出すことが出来ない。以前、「RCXで...
ページ名: