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


こんにちは!

昨日までの四日間、お休みを頂いて実家に帰省しました。
1歳の姪にジェニちゃんを見せると(手を触れないように注意しながら)、動くわ光るわ音が出るわで、
他のどんなおもちゃより興味深そうに観察していましたw
アンパンマンそっちのけですw
写真 2013-07-28 20 02 34
父が私のはんだづけを吟味している様子。
ちょっとほめられましたw
写真 2013-07-28 20 17 48

精密機器なので用心しながら持ち歩かなければならないのですが、
がんばって持って帰った甲斐がありました♪

さて、今日のマイクロマウス研修です。
先日はPMWについてレクチャーを受けるもその深遠な世界を前に挫折しました。
PMWは、様々なものに通ずる(がしかし通り一遍の仕組みだけで動くわけではない…にくい…)事柄ということで非常に重要なのですが、
追々勉強していきましょうということになり、
今日は、run.cに入っているstraight関数の中身をじっくり見てみました。

straight関数は、ズバリ「直線走行」をするプログラムです。
音を鳴らされたり、LEDをぴかぴかさせられたりしているジェニちゃんも、本業は「走行」!
その肝がこの関数というわけです。

前提として今日いまさら「そうなのか!」と思ったことは、
先日のジェニちゃんにおける時間の感覚のなぞと同じく、距離の感覚はどうなってるんだろう、ということ。
のり先生によると、ジェニちゃんはモータのステップ数を距離に換算して把握しているそうです。
macro.hにそれが書いてあります。


#define LEN2STEP(l) (2*400*(l)/TIRE_CIRCUIT) //走行距離(mm)からステッピングモータのステップ数(左右あわせた数)を算出
#define STEP2LEN(s) (TIRE_CIRCUIT*(s)/(2*400)) //ステッピングモータのステップ数(左右合わせた数)から走行距離を算出

ジェニちゃんのモータは0.9度刻みで1ステップとなります。
ですから、0.9/360=400、つまり400ステップでタイヤが一回転するということです。
また、ジェニちゃんのタイヤが一回転したときの走行距離はもちろんタイヤの円周に等しく、
円周を求める式は「直径×円周率」なので、
1ステップごとに「直径×π/400 mmsec」進んでいるということになりますね!(ふう、義務教育をなんとかかんとか思い出しながらのり先生の説明を理解しました…)

さてさてその前提を踏まえて
以下がstraight関数の全貌です。


void straight(int len, int tar_speed) //直線走行
{
 //走行距離len[mm] と 目標速度tar_speed[mm/s] を指定する。
 //最高速度は変数max_speedに予め代入すること

 int obj_step; //目標ステップ数

r_accel = accel; //加速度(後で指定方法を変更すること)
 step_r = step_l = 0; //ステップ数カウントのリセット

con_wall.enable = true; //壁による姿勢制御を有効にする

 obj_step = LEN2STEP(len); //目標ステップ数を算出

MOT_CWCCW_R = MOT_CWCCW_L = MOT_FORWARD; //もしカウントが入ってきたら前方に進む

MTU2.TSTR.BIT.CST3 = MTU2.TSTR.BIT.CST4 = 1; //カウントスタート

 //目標速度が最低速度を下回らないようにする
 if(tar_speed < MIN_SPEED)  {  tar_speed = MIN_SPEED;  }  //減速を開始し始めるところまで待つ(あと走るべき距離が減速するべき距離より短くなったら・・・)  while( (len - STEP2LEN(step_r + step_l) ) > ( ((speed*speed) - (tar_speed*tar_speed)) / (2.0*1000.0*accel) ));

r_accel = -accel; //減速する

 while((step_r + step_l) < obj_step) ; //目標地点まで走行   MTU2.TSTR.BIT.CST3 = 0; //モータのカウントをストップ   MTU2.TSTR.BIT.CST4 = 0; //モータのカウントをストップ }   

見ての通り、とてもわかりやすーいプログラム!(ではないですか?) 基本はwhile文のループで、条件がなりたたなくなったらヒョイヒョイと次へと移っていくシンプルな構造です。 これならわたしにもわかります。(細かい計算はのり先生の解説が必要です…。) 特にこの部分が「なるほど!」という感じでした。

  while( (len - STEP2LEN(step_r + step_l) ) > ( ((speed*speed) - (tar_speed*tar_speed)) / (2.0*1000.0*accel) ));

r_accel = -accel; //減速する

((len※走るべき距離 – STEP2LEN(step_r + step_l) ※カウントされゆく走っている距離) がどんどん減っていき、
( ((speed*speed) – (tar_speed*tar_speed)) / (2.0*1000.0*accel) ))※減速するべき距離 と「>」の不等号が成り立たなくなり、
while文のループを抜け出して、r_accel = -accel;※減速する 減速を開始する。
なんてシンプルなんだ…!

図にするとこんな感じでしょうか。
水色のところに至ると、減速を始めます。

genie2013

壁切れ補正を実装したくていろんなプログラムをじっくり見ていると、
あらゆる動きが(もちろん)計算とプログラムで成り立っているのですが、すべて解剖してみるととてもシンプルな原理だということに気付きます。

もちろんもちろん、数学が苦手な松崎にはにわかには理解できないことばかりなのですが、
のり先生や佐倉さん、yukiさんから説明してもらって、その仕組みを少しでも理解したと感じた瞬間の喜びはひとしおです!

早く壁切れ実装したーい♪

※お知らせ
アールティでは、アートワークができるアルバイトさんを募集しています。
夏休みの間だけでも結構です。
興味がある方は、ご連絡ください♪


Posted in Pi:Co Classic製作記