これ以上早くするのは厳しいような気がする
この画処理ロボットは
酷いアンダーステアの補正と
内輪の荷重が殆ど抜けるため
旋回中は外輪だけを駆動して内輪は転がしているだけ。
そこまでやってもアンダーは出ているし、
負担が掛かっている後輪も滑り出している。
後輪のグリップアップのためにリアトーイン1度と2度を試すも、
タイヤを引きずる音が大きくなるだけでグリップ向上にはつながらず。
今回のグリップ不足はスリップ角では解決できないようだ。
これ以上早くするのは厳しいような気がする
この画処理ロボットは
酷いアンダーステアの補正と
内輪の荷重が殆ど抜けるため
旋回中は外輪だけを駆動して内輪は転がしているだけ。
そこまでやってもアンダーは出ているし、
負担が掛かっている後輪も滑り出している。
後輪のグリップアップのためにリアトーイン1度と2度を試すも、
タイヤを引きずる音が大きくなるだけでグリップ向上にはつながらず。
今回のグリップ不足はスリップ角では解決できないようだ。
各ICやセンサやらモータ、バッテリ等も入手済みで、基板も発注しているが、
完走できる状態まで作り上げれる気がしない。
RWD構成のボトルネックはブレーキングで、兎に角止まらない。
クロスラインを検出後の急減速では、その減速による荷重移動で後輪の摩擦円が小さくなる。
密着型センサのロボットでは低重心のお陰で、モーターパワーが摩擦円を超えることは稀だったのだが、
画像処理ロボットでは前輪よりも前の高い所に重量物が配置されているため、
減速時の荷重移動が大きく簡単に後輪のグリップが破綻してしまう。
で、タイヤが滑ったまま減速が出来ないことが頻発するし、片輪のグリップが先に破綻した場合スピンする。
タイヤの滑りを検知したらブレーキを弱めてグリップを回復してやればスピンは抑制できるけど、
制動距離が長くなってしまう(50cmで止まれなきゃ意味が無い)。
あと、コーナへの進入時に、弱い減速しか出来ないと、速度が高いままコーナの奥まで入ってしまう。
すると横方向に必要なグリップが急激に増えて後輪が破綻してスピンする。
対策としては、重心を上げている原因のカメラユニットの軽量化が一番だが、
SSMレバー比や外乱への強度や機械的強度といった制約が多いので、
後輪に付近に重り(約17g)を積んで、制動時の荷重移動の影響を小さくしてみた。
結果はとしては、
・クランク区間での減速が間に合うようになり直線での速度を向上できた。
・コーナ進入時のブレーキも強くできて、スピンし難くなった。
その他RMCRには時間が足りなくて盛り込めなかった制御を追加したところ、
やっと一つ壁を超えた。
ダンボールを短冊状に切って
12mm厚になるように重ねて
白色のテープを巻いて
床に並べる
参考:http://monoist.atmarkit.co.jp/mn/articles/1208/08/news002_4.html
強度UPを狙う新しいカメラユニットの支柱ができた。4g位重くなってしまった。
操舵の影響でカメラが揺れるのを防ぐためには、思ってた以上に捩れ剛性が必要なようだ。
走行速度が向上すると共に
初期の構成だとカメラが揺れるのが目で見て分かるようになってきた。
その後、支持棒の間隔を22mmから42mmに広げることで目視では振動は無くなったが、
ログを見ると偶にコーナ旋回中にライントレースが振動的になることがあった。
BOSSの助言で支持棒をダンボールで補強してやるとログ上でも振動が収まり、コーナ旋回中の暴れも減ったため、その仕様でRMCRには参加した。
しかし、構造的に弱いようなので今回の作成にいたる。
結果、手で触っても剛性があがったようなので暫くは安心してよいかな
あと5cm先を見るために、カメラの取り付け角度を変更する
これまで0.9程度だったSSMレバー比が1.2位になる。
で、
確認用のコースでライン検出を確認するとクロスラインを検出できない。
照明用LEDの取り付け角度や距離が変わり反射が小さくなったせいか。
RMCR参加時の照明の組み合わせは
秋月の1WパワーLEDにレンズホルダをつけた物だった。
最初はLEDだけで使用し、明るさを補うため反射板を自作して試したりしたが、結局レンズが一番結果が良かった。
このレンズホルダに標準で入っているレンズは、おそらくOSOLRA2045Mでデータシートでの照射角度は45度。
なのでさらに集光するために照射角度30度のOSOLRB2030Mに変更する。
結果としてクロスラインが見えるようになった。ただ照射範囲が狭くなり明るさにムラが出るので、LEDをあと1つ追加したほうが良いかも。
ちなみに15度品のOSOLRA2015Mも試したが、これは30度品と集光の変化が無いように見える。
目的は路面を明るく照らすことであって、LED照明を作ることではないので、
これ以上の明るさを求めるなら、下手に試行錯誤するよりも
市販の光学的に調整されたフラッシュライトを分解して使うべきだろうな。
モノクロカメラ素子の感度のピークが赤外近くにあるなら、
赤色のフラッシュを焚いて、カメラにローパスフィルタつければ、
外乱光の影響を抑えることができるのでは?
ということを大雑把に試してみた。
波長580nm以下の光をカットしてくれるシャープカットフィルタSC58(見た目はカラーセロハン)と
波長660nmの超高輝度LEDのH-3000L(3000mcd)を組み合わせてみた。
カメラで撮影すると、フィルタ有り無しでの明るさの変化はほぼなく、外乱光の影響も小さくなりそう。
しかし、全体的に暗い。
4灯で0.15W位しかないため、光量がまるで足りていない。
というか660nm付近のLEDはあまり発光効率が良くないみたい。
現在の照明と同じ光量にするためには沢山のLEDが必要となり、重くなるので照明には使えなさそう。
照明を焚く理由は、ハレーション対策や坂の下等の一部暗い所で画が暗くなることの対策もあるけれど、
露光時間を短くしてブレた画を作らないようにすること。
常にロボットは動いているので露光時間が長いと、
トレースラインやクロスラインがボヤケて白色がどんどん暗くなり、コントラストが悪くなる。
露光時間が長すぎると
クロスラインを見落とすだけでなく、S時コーナの切り替えしやクランクや
車線変更の復帰時のようなところでもコースを見失ってしまう。
①中古のポケットカメラを買ってくる(amazonで1円~)
②特殊ねじの頭をドリルで壊す
③M64282FPとレンズのついたモジュールが出てくる
④各信号線を確認して
⑤Arduinoにつなぐ
⑥プログラムを書く
#define voutPin 0
#define readPin 2
#define xckPin 3
#define resetPin 4
#define loadPin 5
#define sinPin 6
#define startPin 7
#define reg0 0x00
#define reg1 0x0F //ゲイン
#define reg2 0x05 //C1 露光時間
#define reg3 0x00 //C0 露光時間
#define reg4 0x01
#define reg5 0x00
#define reg6 0x01
#define reg7 0x07
#define Xck_H digitalWrite(xckPin,HIGH)
#define Xck_L digitalWrite(xckPin,LOW)
unsigned char data[256];
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(readPin, INPUT);
pinMode(xckPin, OUTPUT);
pinMode(resetPin, OUTPUT);
pinMode(loadPin, OUTPUT);
pinMode(sinPin, OUTPUT);
pinMode(startPin, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
char buf;
int adcnt;
int datacnt;
int i;
digitalWrite(resetPin,LOW);//RESET -> L
Xck_H;
Xck_L;
Xck_H;
Xck_L;
digitalWrite(resetPin,HIGH);//RESET -> H リセット解除
Xck_H;
Xck_L;
//レジスタ設定
setReg(2,reg2);
setReg(3,reg3);
setReg(1,reg1);
setReg(0,reg0);
setReg(4,reg4);
setReg(5,reg5);
setReg(6,reg6);
setReg(7,reg7);
Xck_H;
Xck_L;
digitalWrite(startPin,HIGH);//スタートH カメラスタート
Xck_H;
digitalWrite(startPin,LOW);//スタートL
Xck_L;
Xck_H;
while(digitalRead(readPin)==LOW){//READシグナル待
Xck_L;
Xck_H;
}
adcnt=0;
datacnt=0;
//今回は8列8行毎に32×32画素を取得する
while(datacnt<255){
if((adcnt&0x0070)==0x0000){//8列中1列データ取得
data[datacnt]=(analogRead(voutPin)/4); //ADの最大値1024を8bitに圧縮
datacnt=datacnt+1;
}
adcnt=adcnt+1;
Xck_L; Xck_H;
Xck_L; Xck_H;
Xck_L; Xck_H;
Xck_L; Xck_H;
Xck_L; Xck_H;
Xck_L; Xck_H;
Xck_L; Xck_H;
Xck_L; Xck_H;
}
//シリアルモニタに画像データを表示する
for(i=0;i<256;i++){
if(i%16==0){Serial.println(" ");}
if(data[i]<100){Serial.print(" ");}
if(data[i]<10){Serial.print(" ");}
Serial.print(data[i], DEC);
Serial.print(" ");
}
Serial.println(" ");
while(1){}
}
void setReg( unsigned char adr, unsigned char data )
{
//アドレス転送(3bit)
if((adr&0x04)==0x04){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((adr&0x02)==0x02){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((adr&0x01)==0x01){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
//データ転送(8bit)
if((data&0x80)==0x80){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((data&0x40)==0x40){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((data&0x20)==0x20){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((data&0x10)==0x10){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((data&0x08)==0x08){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((data&0x04)==0x04){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((data&0x02)==0x02){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H; Xck_L;
if((data&0x01)==0x01){digitalWrite(sinPin,HIGH);}else{digitalWrite(sinPin,LOW);}
Xck_H;
digitalWrite(loadPin,HIGH); //LOADピン→H
digitalWrite(sinPin,LOW);
Xck_L;
digitalWrite(loadPin,LOW); //LOADピン→L
}
カメラの感度調整は殆ど露光時間で行う。
ゲインで弄ると2値化処理しているような画になる。
フレームレートは露光時間とデータ転送時間できまる
照明を明るくして露光時間を減らした上で、
Xckのクロックを上げて、AD変換速度も上げる。(がじぇるねを使う)
さらに、
128×128画素も不要ならばデータを読み飛ばしてAD変換の時間を削る。
画の後半が不要ならば、データの始めの方(写真の上の方)だけを取得して
リセットをかける。捨てた後半のデータ転送時間が節約できる
これで、H8-3048で37fps位にはなる。
参考
http://www.seattlerobotics.org/encoder/200205/gbcam.html
http://www2.plala.or.jp/k_y_yoshino/w6/vision.html
http://mieng.net/miu/index.php?main_page=product_info&products_id=18
http://embedded754.blog6.fc2.com/
画処理ロボットは
Takumiさんが見つけたモジュールを
大湯さんの手法で動かして、
滝田研究室の制御法でライントレースしている。
JMCR2004で既にtakumiさんや滝田教授がやってたことである。
○カメラ制御
カメラへ供給するクロックや信号の幅は無視して、
汎用IOをパコパコ動かして制御している。
このやり方はカメラの種類は違うけれど、大湯さんのゲームボーイカメラ(M64282)用コードを元にしている。
Takumiさん曰く、アセンブラで書くともっとサンプリング周波数を上げることは可能なのだけど、
スキルが無いので、H8→SHにしてサンプリング周波数を向上させている
○画データからのラインの検出
カメラデータ中のあるラインを左から右方向に差分して行き、
その差分値の最大値と最小値の間にラインがあると判断する。
これは、滝田研究室の論文
超小型1kHzスマートカメラを用いたSSM軌道誘導車両の制御 : 動吸振器による安定化
を参考に作成
○ライントレース制御
2重ループのカスケード制御で
外のループで
ライン中心点の位置と現在の操舵角度から目標操舵角度を求める
このループの速度はカメラのサンプリング周波数に影響される
内のループで
目標操舵角度と操舵角度が一致するように制御している
これは、滝田研究室の論文
1kHzスマートカメラ搭載SSM軌道誘導車両の高速化 : 操舵比とレバー比可変によるドリフト抑制
を参考にしたのだけど、間違って解釈していたようで形が違うことがわかった。
○駆動系
いつものメカにいつもの制御。
というわけで、画処理ロボットは
先人のネタを再構築して、CPUパワーと駆動系性能によるゴリ押しで走っています。