« 2010年9月 | トップページ | 2010年11月 »

2010年10月31日 (日)

モータドライバが火を噴いた

ずっと前から気になってはいるけれど解決していない、モータのトルク問題。先日に引き続き、土日を調査に費やしました。土曜日はモータドライバIC(L6203)の出力がどうなっているのか計測してみようと、モータドライバの出力端子をデジタルオシロにつないでみたところ、何が悪かったのかモータドライバICが火を噴きました。ありゃ。

幸い、予備のL6203がストックしてあったのでICを交換して動作確認したところ再び動くようになりました。でも、あぶないですね、いろんな意味で。

まだ回路が悪いんじゃないかという疑いが晴れないので、試しにPWMのチョッピング周波数を10kHz, 20kHz, 100kHz に振って見て、どれくらいトルクが変わるか実験してみました。その結果、10kHzと20kHzはほとんど差が無く、100kHzにするとほとんどトルクが出ないでモータドライバICが発熱することがわかりました。さらに、L6023の2番ピン(Vs)をデジタルオシロで観察すると、PWMのチョッピングと同じ周期で、±5V以上の大きなノイズが発生していることがわかりました。一方、5番ピン(IN1)、7番ピン(IN2)、11番ピン(Enable)にはあまり大きなノイズは乗ってこないことがわかりました。

この問題を解決するのにはもう少し時間がかかりそうなのですが、次の試走会が来週末にやってきます。それまでに自律走行できるようにしないと、トライアル完走が絶望的になります。ですから、このモータのトルク問題はとりあえず棚上げにして、次に進むことにします。

来年度は制御回路を作りなおしたいな。

2010年10月26日 (火)

問題はシリアル通信だけではなかった

昨日の夜中にUpした日記で、UARTの送信処理が遅いので別タスクに切り出したほうがよいと書きました。しかし、問題はそこだけではありませんでした。

結露を先に書くと、問題は自作のタスクスケジューラにありました。細かいことを書くのが面倒になってきたので説明は省略。

シリアル通信が遅いことにいまさら気付いた

台車を制御しているファームウェアの処理周期が微妙に遅いような気がしていたので測って見たところ、100ms周期で動いていると思っていた処理が104ms周期になっていることがわかりました。いろいろ調べてみた結果、SH2用に自作したSCI_print関数の処理が遅いことがわかりました。この関数はSH2でもprintfが使えるように、%d、%s、%c だけをサポートした軽量級のprintfもどきです。試しにこの関数で32文字程度を送信すると、処理時間が8ms程度かかっています。

なぜそうなるのか。結論を先に書くと、それが非同期UART通信の処理速度だということです。計算してみた結果、気付きました。以下、その計算です。

【設問】

ボーレートがB[bps]のとき、n 文字送信するのに必要な時間 t を求めよ。

【解答】

スタートビット 1bit、データビット 8bit、ストップビット 1bit、パリティ無しと仮定すると、1文字送信するために必要なビット数は 1 + 8 + 1 = 10 [bit]である。したがって、

t = 10 * n / B

となる。

この式に B = 38400, n = 32 を代入すると、 t = 10 * 32 / 38400 ≒ 8.33 * 10^-3 [s] ということで、約8.3msかかることがわかります。だから、UARTで文字列を送信しているだけでms単位の時間があっという間に過ぎていくわけです。

さて対策です。こういう時は、送信処理だけ別タスクにしてしまうのが定石です。SCI関数には手をつけたくないので、Host I/F関連で送信タスクを一つ作ってやることにします。この台車制御用のファームはRTOSを使用していませんが、自作の簡易スケジューラがあるので、そちらにタスクを切り出せばマルチタスクもどきを実現できます。

この対策は、今日のこの記事を書きながら思いつきました。

2010年10月25日 (月)

100kmウォークの反省

第15回三河湾チャリティー100km歩け歩け大会に参加してきました。結果は、第2チェックポイント(52km地点)でリタイヤでした。大会事務局発表では、スタート地点から1307名が歩きだし、100km完歩できたのは774名だったそうです。

私をこのイベントに誘ってくれた友人Sくん(経験者)のアドバイスがあったおかげで、装備は過不足なく、二重靴下作戦により足に肉刺ができずに済みました。

参加者数が多かったため、スタートは3回に分けて行われました。私たちの出発は最後の9:00スタートでした。体力的には問題無かったのですが、第1チェックポイント(33km地点)についたときにはすでに足の裏のアーチや太もも裏のハムストリングがかなり痛くなっていました。しかし、痛みには慣れるもので、どこか痛くなる→痛みになれる→また別の場所が痛くなる、の繰り返しでした。

42km地点まで行けばマッサージが受けられると思って、それを心の支えにして42km地点までたどり着くと時刻は20:55になっていました。「(42kmポイントの運営時間終了まで)あと5分しかないから、マッサージは受けられない。(それにマッサージを受けていると第2チェックポイントの終了時間に間に合わなくなるから)もう行くしかない。」と係員に言われて、休むことなくそこからさらに10km先の第2チェックポイントを目指しました。

チェックポイント終了時刻までにチェックポイントにたどり着かないと、自動的にリタイヤ扱いになります。10km先の第2チェックポイントの終了時刻は 23:30。ということは、残り時間は1時間半。間に合うためには 6.7 km/h で歩く必要があります。普通の歩行速度を4km/hとれば、早歩きから軽いジョギングに近いスピードです。でも、前に進むだけで精いっぱいの私にはもうスピードを上げる余力が残っていません。このあたりで私の心が折れました。「100km歩き切りたい」と強く思うSくんには先に行ってもらい、とにかく第2チェックポイントにたどり着くことに専念しました。

私が第2チェックポイント(52km地点)にたどり着いたのは23:58でした。チェックポイントの50m手前くらいから「あと3分です、いそいで~~~!」という声が聞こえました。もうチェックポイントの終了時刻を30分近く過ぎているので、何のことかよくわかりませんでしたが、とりあえずいそいでみました。チェックポイントについてみると、すでにテントが畳まれており、リタイヤ確定者を大会本部に電話連絡している最中でした。計測チップも回収されてないし、あと3分とか言っていたからもしかすると私はまだリタイヤ扱いになっていないのかなと思いつつも、心が既に折れてしまっていたので、ここでリタイヤを申し出て私のチャレンジが終了しました。

私と別れたのち、Sくんは20分くらいの余裕を持ったまま第2チェックポイントを通過したそうです。そして、最終的に100km完歩を成し遂げたそうです。脱帽です。尊敬します。誘ってくれてありがとう。そして、ゴールを見届けることなく先に帰ってしまってごめんなさい。

さて今回の反省です。

【よかった点】

  • 装備は過不足なく、必要十分であった。
  • 特に、ポータブルナビは持ってこなくてよかったと思う。元々バッテリは4時間しかもたないし、バッテリをたくさん持ってくると重くなるので。
  • 前泊したおかげで朝余裕を持って起きられた。
  • 天候に恵まれた。暑すぎず寒すぎず、雨も降らなかった。
  • 沢山の人に応援してもらえた。
  • 自分では肉体的に限界だと思った後も、その1.5倍くらいの距離は気力だけで行けることが分かった。
  • なにより、大きなけがや故障が無くて済んだ。
  • リタイヤ後に温泉と食事が待っていた。寝るところもあった。死んだあと天国に行くとこんな感じなんじゃないかと思った。
  • 1日たって足裏アーチ以外痛いところがない。筋肉痛がない。

【悪かった点】

  • 「絶対にやり遂げる」という強い意志を持たずに臨んでしまった。
  • 甘く見ていた。そのため、事前の練習を怠った。その結果、肉体的限界が早く来てしまい、制限時間に追われてもペースを上げることができなかった。
  • 食事に時間をかけすぎたかもしれない。その結果、歩くために使える時間が減ってしまい、制限時間に追われる羽目になった。
  • 私のペースが上がらないせいで、Sくんの足を引っ張ることになってしまった。
  • 第2チェックポイントでまだリタイヤが確定していない(かもしれない)状況で、自らリタイアを宣言してしまった。

【改善提案】

  • 肉体的限界のラインを引き上げる。
  • そのために、足裏のアーチとハムストリングを重点的に鍛える。
  • さらに、速いペースで移動し続けられるようになるために、ハーフマラソン、フルマラソンに挑戦する。
  • 精神力を鍛えるために、メンタルトレーニングを学び、実践してみる。

2010年10月21日 (木)

100kmウォークの準備

今日は単なる日記です。今週末の10/23, 24 は、三河湾チャリティ100km歩け歩け大会に参加してきます。当日朝に三島を出たのでは 8:30までに愛知県の碧南市臨海体育館にたどり着けないので、前泊して朝に余裕を持たせる計画です。

天気予報では雨が降らなそうなので、レインコートはいらないかもしれません。できる限り荷物を減らしたいですからね。

今日中に荷物を準備して、明日は会社から帰ったら即愛知県に向けて出発する予定です。

2010年10月17日 (日)

条件付き確率

今期は放送大学の確率統計の講義を受けています。今日は条件付き確率の話だったのですが、ネット上で探し物をしていてよく理解できなかった問題がありました。それは、「隣人兄弟・他方の性別」という問題です。

問題文は、こうなっています。

隣の家に2人の子供がいる事が解っています、ある日、隣の子供のうち1人が女の子である事が解りました。

このとき、もう1人の子供も女の子である確率はいくつでしょうか?

※なお、男女比は1:1とする。

直感では、

  • 二人目の子供の性別は一人目の性別と独立しているのだから、確率は 1/2 だ。

なのですが、一方、1/3 だという意見もあって、その根拠は

  • (男、男)、(男、女)、(女、男)、(女、女)の組み合わせがあるうち、一人目が男とわかった時点で(女、女)の組み合わせが消えた。だから、(男、男)、(男、女)、(女、男)のどれかなのだから、1/3 だ。一人目が女とわかった時点で(男、男)の組み合わせが消えた。だから、(女、女)、(男、女)、(女、男)のどれかなのだから、1/3 だ。(10/18 訂正しました)

というわけです。

この混乱は、この問題が独立事象の問題としてとらえるか、条件付き確率の問題としてとらえるかの違いによるものだと思います。で、この問題はどちらなのでしょうか。

私は、このサイトに書かれている説明を読んで、ようやく理解できました。つまり、こういうことです。

(独立事象の問題になる場合)

隣の家に2人の子供がいる事が解っています、ある日、隣の子供のうち1人が女の子である事が解りました。

このとき、もう1人の子供女の子である確率はいくつでしょうか?

※なお、男女比は1:1とする。

(条件付き確率の問題になる場合)

隣の家に2人の子供がいる事が解っています、ある日、隣の子供のうち1人が女の子である事が解りました。

このとき、もう1人の子供女の子である確率はいくつでしょうか?

※なお、男女比は1:1とする。

この理解が間違っているというご指摘がありましたが、コメントください。

--------------------------------------------------------------

(10/18追記) なんか、「が」も「も」も関係ない気がしてきました。条件付き確率の問題として扱っても、やっぱり 1/2 なんじゃないかと。

条件付き確率の定義を考えると、

事象Bが起こるという条件のもとで別の事象Aが起こる確率を条件付き確率といい、P(A|B)で表す。

P(A|B) = P(A∩B) / P(B)

ですね。

ここで、B:一人が女の子、A:一人が女の子とすると、二人とも女の子であるという事象はA∩Bです。したがって、「一人目が女の子で合った場合、二人目も女の子である確率」すなわちP(A|B)は上式より、

P(A|B) = P(A∩B) / P(B) = (1/4) / (1/2) = 1/2

です。だから、条件付き確率でやっても 1/2 が正しい。

2010年10月16日 (土)

回路が悪いのかも

昨日のつくばチャレンジの公開走行実験で、何人かの先生方からロボットの足回りについてアドバイスを頂きました。そこで今日は、そもそも今使っているモータとバッテリで、十分なトルクがでるのか実験してみることにしました。

【実験方法】 

  • 7.2Vのニッケル水素電池パックとDCモータ(Maxon RE35)を直接配線して、水平な床上でロボットがばねを引っ張る力を計測する。

【準備】 

  • ばねばかりがないので、適当な固めのつるまきばねで代用することにしました。
  • 1kgのおもりを使ってあらかじめバネ定数を計測しておきます。錘が無い状態のばねの長さは5.4cm、1kgのおもりをつけるとばねの長さが 12.8cmになりました。
  • したがって、バネ定数Kは、K=1.0 /(12.8 - 5.4) = 0.14 [kgf/cm] です。

【実験結果】

  • バッテリ容量が 2200mAh のバッテリパック1本を直接配線した場合、ロボットが引っ張ったときのばねの長さL1は 28 cm でした。
  • しがたって、引っ張る力F1は、F1= K * L1 = 0.14 * 28 = 3.92 [kgf] です。
  • 同様に、バッテリ容量 5000mAh のバッテリパック1本を直接配線した場合、ばねの長さL2 は31cmでした。
  • したがって、引っ張る力F2は、F2 = K * L2 = 0.14 * 31 = 4.48 [kgf] です。

【考察】

  • ロボットの全備重量を 8.0kg 、坂の角度を15°と仮定したとき、タイヤの変形や転がり抵抗を無視すると、ロボットが坂を登るのに必要な力は、8.0 * sin(15°) = 2.07 [kgf] です。
  • 転がり抵抗は、ロボットに取り付けたつるまきばねを水平に引っ張って、ロボットが動き出すときのばねの長さで代用できます。ばねの長さがL3 = 12.5[cm]でロボットが動き始めたので、転がり抵抗 F3 は F3 = K * L3 = 0.14 * 12.5 = 1.75 [kgf] です。
  • したがって、転がり抵抗を含めた登坂に必要な力は、F = 2.07 + 1.75 = 3.82 [kgf]です。
  • ということは、容量 2200mAhのバッテリで15°の坂を登るのはなんとかギリギリセーフになるかどうかの瀬戸際くらいだと思います。
  • 5000mAhの電池を使った場合はマージンが 4.48 - 3.82 = 0.66 [kgf] 分だけ大きくなるので、多少余裕を持って坂を登れそうです。
  • 転がり抵抗が意外と大きいことがわかりました。もう少し幅が狭く、直径が大きく、ソリッドなタイヤに交換すれば、転がり抵抗を低減できて、もっとスムーズに走れるでしょう。

【結論】

  • 現在のモータとバッテリで、理論的には15°の坂を登れる。
  • タイヤを交換して転がり抵抗を減らすと、もっと楽に坂を登れるようになる。

今回は、坂を登るのに必要となるトルクを今のモータとバッテリが賄えるのかどうか知ることを主眼に置いたため、走行速度に関しては完全に無視しています。とりあえず、今回の実験結果から考えると、バッテリとモータはシロで、制御回路が悪いか、制御方法が悪いかのどちらかに原因がありそうです。

公開走行実験(第4回)の反省

昨日は平日でしたが、年休をとって公開走行実験(第4回)に参加してきました。自宅を出るときは小雨がぱらついていましたが、つくばでは雨が降る気配もなく走行実験できました。

さてその反省です。まずは良かった点から。

  • 高速道路で渋滞にはまってミーティングに間に合わないかと思ったが、なんとか10:30までに会場について、ミーティングに参加できた。(ちなみに自宅を出たのは朝の6:00でした)
  • カルマンフィルタのチューニングに必要な、最低限度のセンサログを2回分収集できた。
  • データ取りをして戻ってきた後、本部テントでロボットの足まわりについて何人かの先生方からアドバイスをいただけたこと。
  • 受付テントにいた事務局のお姉さんがかわいかったこと (*´Д`*)

続いて悪かった点。

  • 他チームの方とほとんど会話しなかったこと。
  • 1回目の試走では、2個目の一時停止地点付近でバッテリが空になってしまったこと。新品のバッテリパックを使ったので、一度放電させてからでないと十分充電できなかったのかもしれない。
  • レーザーレンジスキャナのログがうまく取れていない。これは事前の準備不足による。

最後に改善提案。

  • 非常停止スイッチの周りにトラテープ(黄色と黒のテープ)を貼る。(車検時の推奨事項)
  • クーリングファンにメッシュ等を入れる。(車検時の指摘事項)
  • ロボットの足回について見直す。モータに流れる電流について詳しく調査する。(Maxonの90W級モータを使っていて坂を登れないなどということは考えられないとのアドバイスをいただいたので。)
  • 台車のファームウェア側で、AIモジュールからコマンドを受信しなくなったら自動的に止まるような仕組みを盛り込む。

2010年10月14日 (木)

SI2010の予行原稿

を書いています。締め切りが10/8だったのが、1週間延長されて10/15になりました。でも、まだ完成していません。現在、のステータスはというと・・・

  1. ストーリー立てをする。
  2. 全体をざっくり書いてみる。
  3. ざっくり書いた本文を予行原稿のフォーマットに直す。
  4. 一発目の英文Abstractを書く。
  5. 文章をちゃんと繋げていく。
  6. 図面や表を入れる。
  7. 句読点やレイアウトを修正する。 (← いまここ!)
  8. セルフレビューする。(紙に印刷する。声を出して読んでみる。)
  9. 悪いところを直す。
  10. PDFにして提出する。

もう2~3時間かかりそうです。

明日は年休をとって、平日の試走会に行ってきます。

2010年10月13日 (水)

fit-PC2ではAtom Z530のクロック制御ができていない

昨日の日記で、制御用PCとして使っている fit-PC2が熱くなりすぎてOSごとシャットダウンしているのではないかと書きました。今日は、実際にどれくらいCPUが熱くなっているのか計測してみることにしました。

方法。Core Tempというフリーソフトで、CPU温度のログをファイルに落とす。でもこれは失敗でした。というのは、Core Temp が Atomの温度を正しく計測できていないからです。fit-PC2の外装を赤外線温度計で測ると50℃くらいになっているのに、CPUの温度が24℃とか表示しているのはどう考えてもおかしい。一方、HWMonitorというソフトはCPUの温度をそれなりに妥当な値で表示してくれましたが、こちらにはロギング機能がありません。とりあえず、ロボット制御用のプロうグラムが動作している時は、CPUの負荷が40%くらいで、温度は50℃くらいにまでなることは確認しました。

その後、開発用PCに入れたCore Tempの画面を見ていて、CPUの負荷に応じてクロック周波数がダイナミックに変動していることに気付きました。IntelのSpeedstepという技術ですね。この技術はfit-PC2で使用しているAtom Z530にも入っているはずなのですが、fit-PC2上で走らせたCore Tempの画面を見る限りではCPUのクロック周波数が1.6GHzに固定されたまま動いていません。全然省エネしていません。そりゃ熱くなるわけだ。

たしかBIOSの設定でCPUの省電力機能を使うかどうか設定があったはず、と思い、fit-PC2のマニュアルを引っ張りし立てBIOS設定を確認しましたが、デフォルトで省電力機能が有効になる設定になっていました。

ということで、fit-PC2のBIOSがおかしいので、Atom Z530のクロック制御ができておらず、やたらと発熱するのは無いかと推測しています。

がしかし、ここに投稿されている内容と私の理解が食い違っているので、今度はReal Tempというソフトを使って測り直してみます。

2010年10月12日 (火)

PCが熱暴走した?

今日の反省。気分転換は10分以内にしましょう。

今月と来月はプライベートでかなり忙しいのに、ゲームばかりやっていてなかなか大切なことが進んでいません。なぜゲームをやってしまうのか。おそらく、例えばプログラミングや発表資料作成で行き詰った時に、ちょっとした気分転換が欲しいのだと思います。しかし、この気分転換が一度始まると30分、1時間、2時間・・・と時間を食いつぶしていくから大問題です。ゲームが行き詰った時に一度気分転換するという機能をになっている限り、ゲームを封印しても解決にはならないと思います。だから、ゲームをやるなというのではなく、時間を区切るのが効果的でしょう。手元にキッチンタイマーを置いておこうかな。

閑話休題。今日はロボットを屋外で走らせて、センサデータのログ収集をしてきました。そこでまたいくつかトラブルが発生しました。

まず、制御用PCが動作しなくなると、非常停止スイッチで駆動系の電源を切る以外にロボットを止める手立てがないことです。これは、バッテリ電圧が低下して制御用PCの電源が落ちた場合、制御用PCが熱くなりすぎて挙動がおかしくなった場合、制御用PC上で動作しているAIモジュールプログラム(ナビゲーションプログラム)が落ちてしまった場合などが考えられます。対策としては、ファーム側で例えば3秒間コマンドを受信しない場合はモータを止めるという処理を加えることで、万が一の場合でも安全にロボットを止めることができるようになります。(と、偉そうなことを書いていますが実装していません。)

今日は屋外で走行している間に、制御用PCがOS毎暴走したケースが2回ありました。その時、制御用PC(fit-PC2)は長い時間澤っていられないくらいの温度になっていました。なので、おそらく熱で動作がおかしくなってしまったのではないかと考えています。でも、去年はそういうこと無かったので、本当の理由はまだわかりません。

2010年10月11日 (月)

センサデータログにはまだ未解決の部分が残っている

先日の日記で、センサデータのログ問題に関して「ほぼ」解決した、と書きました。ほぼ、と書いたのは一抹の不安があったからです。そして、動くことは動くけれど、まだ未解決の問題が残っていることがわかりました。

先日の反省を踏まえて、タイマイベントにより呼び出されるイベントハンドラ処理が(タイマのインターバルとして設定した)100msを超えてしまった場合に備えて、イベントハンドラの先頭と末尾にInterlocked.Exchangeを仕掛けました。これを仕掛けることでイベントハンドラの再入を検出して、再入しているようなら何もしないで処理を抜けさせます。この時、再入を検出した時点でシステムログに再入検出を記録することにしました。

ここからが問題です。まず、開発用PCのHDDでプログラムを実行すると、システムログにイベントハンドラの再入記録が残っていないので問題無いのですが、同じ開発用PCでもSDカード上でプログラムを実行する(すなわち、SDカード上にセンサログが記録される)と、システムログにイベントハンドラの再入検出が記録されてしまいます。ということは、SDカードに対するファイルの書き込みに100ms以上かかっているということなのでしょうか。

ということで、SDカードに書かれるデータのサイズと書き込み速度を見積もってみます。

  • (LRSのデータログ1行当たりのデータサイズ)
  • =((データ1点あたりのバイト数)+(カンマのバイト数))×(データ点数)
  • =((5 × 2) + 2)×1081
  • = 12972 [Byte] = 13 [KB]

これが1秒間に10回書き込まれるとすると、必要な書き込み速度は 130KB/sです。一方、私が使っているSDカードはClass4と書かれているので、書き込み速度は4MB/s。書き込まれるデータが小刻みなのか大きなブロックなのかでFlash ROMの書き込み速度は大きく変わりますが、それにしても桁が違うので書き込み速度には余裕がありそうです。

そこで、実際に書き込み時間がどれくらいかかっているのか測ってみました。その結果、HDDにセンサログデータを書き込んだ場合は1回あたり0~17ms(最頻値は 1ms)で、SDカードの場合は16~776ms(最頻値不明)でした。SDカードの場合、100ms以下の回数が少なく、120~200ms以上かかるケースが大多数でした。この結果からみて、SDカードへの頻繁な書き込みがボトルネックであることは間違いありません。

対策をいくつか考えてみます。

  • A案: RAM上にセンサログデータを貯めて、ログ収集を終了した時点でファイルに落とす。
  • B案: SDカード上でのプログラム実行を止めて、制御用PCのSSD上でプログラムを実行し、センサデータログもそこに落とす。
  • C案: log4netやsqliteなどの既存のコンポーネントにセンサログ収集を任せる。

A案は、処理速度的には速そうですが、仮に1時間分データを貯めるとすると475MBになるのでできれば避けたい。制御用PCのRAMは1GBしかないので、スワップが沢山発生するのもいやですから。

B案は、一番手っ取り早い方法です。元々、プログラムの書き換えやセンサログデータの移動を簡単にするためにSDカード上でプログラムを走らせて、データもそこに落としていました。でも、その手間はクリティカルな問題ではないので、処理速度的にNGなら手間をとったほうがいいかもしれません。なにより、一番確実ですから。

C案は、log4netやsqliteならそこら辺をうまくやってくれるんじゃないかなぁという期待だけで、根拠はありません。なので、やってみても解決しないかもしれません。

ということで、時間が無いので安全確実なB案がよさそうですね。

2010年10月 9日 (土)

スレッドプールに溜まっていたことが判明

先日の日記で書いたセンサデータのログがおかしい件、ほぼ解決しました。

本来ならば一つのスレッドからしかセンサデータのログを書き込んでいないはずなのに、システムログのエラーの出始めるところをみると、複数のスレッドが同じタイミングでエラーを吐いていますね。ここがポイントでした。

理由は、ログ収集開始時にプログラムの処理が遅くなるところがあったからでした。今、マニュアル走行モードのタイマには、System.Timers.Timerを使用して、Elapsedイベントを使って 100ms 毎にセンサデータをログファイルに書き込んでいます。ここで、Elapsedイベントのイベントハンドラの処理が100msを超えてしまうと、別のThreadPoolスレッドで同じイベントが再発生することがあるそうです。

ここでプログラム中でレーザーレンジスキャナのセンサデータをログファイルに保存する部分を見てみると、約1000点のデータを保存するために毎回 scannedData = new int[lrsMaxData]; のようにメモリ領域を確保する処理が入っていることに気付きました。C言語でいうところの malloc / calloc のようにメモリ領域確保は処理時間を要する部類なので、C#でもおそらくそうなのだと思います。これのメモリ領域確保が1回で済むように書き直したところ、平均 20~40msかかっていたセンサログ書き込みが平均 5~6msにまで短くなり、先日の日記で出ていたようなエラーも発生しなくなりました。

2010年10月 7日 (木)

Urg invalid response.

ロボットをマニュアル走行させながらセンサデータを収集するために必要なものを一通りそろえているのですが、センサのログをみるとレーザーレンジセンサ(Top-URG)がおかしなことになっています。そこでシステムのログを見てみたところ、URGライブラリの urg_receiveData関数が "Urg invalid response."というエラーを返していることがわかりました。ちなみに、システムログの収集には、log4net を使用しています。

そのシステムログをみて不可解な点に気付きました。エラーが出始める部分のログはこのようになっています。

INFO  2010/10/07_01:07:21,796 [1] AIModule.Controller.ManualControlForm [(null)] - Start data logging
INFO  2010/10/07_01:07:21,812 [1] AIModule.Utility.DataLogger [(null)] - Data log file opened. Start data logging.
ERROR 2010/10/07_01:07:22,078 [12] AIModule.Device.LaserRangeScanner [(null)] - urg_receiveData failed : Urg invalid response.
ERROR 2010/10/07_01:07:22,078 [14] AIModule.Device.LaserRangeScanner [(null)] - urg_receiveData failed : Urg invalid response.
ERROR 2010/10/07_01:07:22,078 [14] AIModule.Controller.ManualControlForm [(null)] - Failed to get data from LRS.
ERROR 2010/10/07_01:07:22,078 [12] AIModule.Controller.ManualControlForm [(null)] - Failed to get data from LRS.

ログの見方は、左からログのレベル、日付と時刻、ミリ秒、スレッド番号、コンポーネント名、メッセージです。ログレベルがINFO からERRORに変わったところで、まったく同じ時刻で異なるスレッド番号で、 "Urg invalid response."というメッセージが2回出ていますね。なぜ2回出てくるのか謎です。それ以前に、なぜ "Urg invalid response."になっているのかも謎です。

2010年10月 4日 (月)

ファームウェアがおかしかった。(解決)

昨日の日記で書いた件。解決しました。

昨日は、ファームが制御用PCのプログラムが送ったコマンドをちゃんと受信してくれない問題についていろいろ試行錯誤しました。その結果、ファームがおかしいんじゃないか、昨年のつくばチャレンジ本番以降に、ファームを変更したんじゃないかという疑いが出てきました。

そこで、今日はWinMergeを使って、昨年の11/29付でバックアップしてあったファームのソースコードと、日付が無くておそらく一番新しいであろうソースコードを比較してみました。あれ、いろいろいじってますね。結果的には、ファーム側のシリアル通信の受信処理に追加したコードが悪さをしていることが判明しました。

その過程で、制御用PC側のプログラムにもまだ拙いところがあることも判明しました。例えば、ファーム側は受信データがおかしいと、チェックサムが無い、そんなコマンドは無いなどのエラーコードを返し、受信データが正しければACKを返すのですが、制御用PC側のはその返ってくるレスポンスを完全に無視していました。

ファームも制御用PC側のプログラムも、エラー処理等がかなり甘い状態です。トラブル発生時に原因を探しやすくするためにも、この際エラー処理をきっちり入れてあげたいところです。が、先週立てたスケジュールが既にスリップし始めているので、後回しにしちゃいそうな雰囲気です。

2010年10月 3日 (日)

ファームウェアがおかしいのか?

私のロボット開発における自己管理術の一つに、「問題が発生したらその時点で blogに書いてしまう」というのがあります。これには次のようなメリットがあります。

  • 問題点を文章に起こすことで、漠然としていたものが明確になる。
  • 他人に説明しようとすることで、自分が見落としていた事柄に気付く。
  • blogに書かれた問題点を読んだ人が、何かアドバイスやヒントをくれるかもしれない。
  • 解決したら解決方法も書いておくと、あとでプロジェクトを振り返った時に記録を収集しやすい。

このやり方は、会社で先輩が週報を使ってやっていたものを、個人のblogに応用しただけの話です。

そして今日の話題は、今抱えている未解決の問題について。

今週末はロボットに搭載したセンサを使って走行ログをとる予定でした。しかし、いくつか問題があってロボットを動かせませんでした。

もっとも大きい問題は、ロボット台車のファームウェアは去年のものをそのまま使っているのに、制御用PCからのコマンドをうまく受け付けてくれないことです。今年度は回路を入れているケースを交換したので、最初は配線関連のトラブルか、電源のトラブルだと思っていました。しかし、制御用PCからロボット台車のCPUに送ったコマンドのレスポンスを見ると、エラーコードが「そんなコマンド無いよ」というエラーコードになっている場合が多いことがわかりました。しかし厄介なのは、ちゃんとコマンドを受け取れたことを示すレスポンスもたまにあることです。

試しに、制御用PC側のプログラムを去年のものにしてみましたが、やはりファームはコマンドをきちんと受理してくれていないようです。う~ん、ファームをどこかいじったっけ?

ちなみに、ロボット台車の制御回路上のDIPスイッチを切り替えてファームをテストモードで起動すると、Tera Termからキーボード操作でハードウェアの動作確認ができるようにしてあります。そのテストモードでは、ファームがちゃんと動いているようです。

おそらく昨年のつくばチャレンジ本番以降に、ファームに何らかの変更を加えているのではないかとおもうので、昨年バックアップしたファームのソースと一番新しいソースを比較してみます。

レベルの違い

つくばチャレンジの兄貴分ともいえるDARPA Ground Challengeで見事完走を果たしたスタンフォード大ですが、この記事の動画を見てレベルが違いすぎると感じました。進化してます。すごい、すごすぎる! 二つ目の動画を見てください。

【PC Watch CTC 2010レポート基調演説編】

http://pc.watch.impress.co.jp/docs/news/event/20100927_396103.html

このレベルをもってすれば、10年以内に無人走行車が街中を走るのは夢ではないでしょう。

« 2010年9月 | トップページ | 2010年11月 »

最近の写真