−−−>
左の画像が元の画像で、右が処理後の画像です。灰色の部分が「ボールの影」として認識 した部分です。(小さい黒丸は図形の重心です。) 影と大体同じ大きさの、丸くて黒い紙もフレームに入っていますが、これも 「ボールの影」判定が出ています。大きさと形が近ければ、この様に立体物も、床の模様にも 同じ判定が出ます。
でも、ここまで来ると、物の大きさと、ロボットとの位置関係が分かっているので、距離センサでスキャンして 立体かどうか確認できます。
試しに「線の上に乗る」部分のプログラムまで実行してみました。上の検出結果によって 計算どおりにロボットが動けば、ボールを少し押してから止まるはずですが、頭の方向 、画像からのボールの位置の取り出し、指定位置への走行など、それぞれの段階の誤差が 重なってか、少し押したり、手前で止まったりといろいろでした。
そのまま、以前作った正面にあるボールを腕で拾う動作を実行してみると、うまく拾えるときも ありました。ボールをロボットの正面に導くようなガイドをつけてしまえば終わりのような 気もしましたが、これだけのセンサーと、自由度の多いボディーがある意味がなくなってしまうので、 ここはやはり、ハードを生かすソフトを書きたいと思います。
少し前に、360度スキャンのプログラムを書きましたが、同じ要領で、ロボット前の床面の、 ロボット前面からの距離にして5cmから10cm程度の辺りをスキャンします。 そして、取得したデータからボールがどの辺りにあるかを判断します。
360度サーチの時は、取得したデータはレーダーチャートになりますが、こちらは下に示す 図のようなグラフになるので、山の位置からボールの中心位置を判断し、ロボット位置値の 微調整のためのデータや、手を伸ばす目標位置を計算します。
今回は、これをローラーを3個に減らすことによって改善しました。ロボットの重量の割りに ボディーの剛性が低いため、やはりグラグラしますが、前よりだいぶ良くなりました。
4.画像を処理し、ボールを見つける。
<処理後の画像>
5.ボールとロボットの相対位置および、移動距離と方向を画像から計算する。
6.計画のとおりに移動する。
7.ロボットの足元を赤外線距離センサ(PSDセンサ)でスキャンする。
8.ボールの場所をレーダーチャートから特定する。
<レーダーチャート>
9.ボールが正面に来るように旋回する。
10.腕を広げる。(予め作ってメモリに入れてあるアクションデータ使用)
11.ボールを挟むまで腕を閉じてゆく(手先のタッチセンサで挟んだかどうか判断)
12.持ち上げる。
ソフトウェアの機能要素を統合してゆく形の製作は、ひと段落した気がするので、今後しばらく は、機能要素の開発やハードの機能拡張、使ったことが無い部品のトライなどをしようかと 思いました。
そこで、PSDセンサの電源系統にリレーを入れて、ON/OFF出来る様にしました。 使ったリレーはOKITAのDIP-1M-05Dという、14PのDIPパッケージサイズのリレーで、H8の ポートから直接駆動できるものです。W1〜W4の余りの部品です。 購入してからずいぶん時間がたちますが、使えました。また、データシートのダウンロード も出来たので、まだ売っている様です。
W6v3は何もしない状態で約7.2V・0.6A使っていますが、PSDを切り離すと7.2V・0.4Aに 下がるので、電池の持ちが良くなると期待してます。
あと、ついでに、PSDセンサの作動状態が分かるように、移動ユニット前面に、PSDセンサ と一緒にONになる、点滅回路入りの緑色LEDを付けました。
今向いている方向に移動する
去年のプログラムと違うのは、移動を始める前に、磁気コンパスが付いている頭を、 出力がちょうど方位データの変わり目になるように回しておく点です。 こうすると、その変わり目をまたぐように蛇行すれば、今向いている方向に進みます。
次は地磁気に対する絶対方位を入力して、そちらに移動するプログラムを作ろうかと 思っています。これが使えると、部屋の中でのナビゲーションがW4の時と比べて 格段に楽になると思います。
制御の精度は、方位を角度で言って、ざっと数度程度といった感じです。問題は、 今試している、自室以外の場所でも同程度の性能を発揮するのかですが、それは おいおい試してみようと思っています。
カメラの軸あわせ
今まで、左のカメラで撮影した画像が数度ほど傾いていましたが、これで調整が つきました。ずっと気になっていたのでスッキリしました。
先ずこのボードが出来上がったら、ラジコンのセグウェイみたいなものを作ってみようかと 思っています。(カットアンドトライだけでやってみようと思っているので、うまく行かない 可能性大です。)
私の場合、新しく同タイプのものを作る時は、前の作品をバラして (保管場所、材料費、製作時間の節約のため)材料として使ってしまうのが常ですが 、W6の後継機は、W6を使わないで、独立したもの として作ろうかと考えています。
ムービーのダウンロード(120kByte)
「倒立振子の制御ってこんなだったよなー」と、おぼろげな記憶をたよりに、いいかげんな 制御プログラムを書いて動かしてみました。なんか、それっぽく動きはしますが、すぐに たおれました。モーター、ギアボックス、電池、モータードライバICなど、秒単位の短い時間で動かすぶんには 、加熱などの異常はないようなので、ハードとしては遊べるものが出来たみたいです。
マイコンと電池を内蔵し、搭載マイコンのみで制御しています。また、RC受信機も積んでい ますので、PCから切り離して、プロポからスタートをかけたりも出来ますが、ムービーでは プログラムのロード用の通信ケーブルの抜き差しが面倒なので、ケーブルを引っ張りながら 動いています。
電池の構成は2L1/2L2と同じで、制御系等がハンディーカム用の7.2V Li-Ion電池で、動力系が 6VのNi-MH電池です。
センサーはPG03(RCジャイロ)とADXL202を1個づつ積んでいます。 今日のところはPG03だけ使っています。
任意の傾斜状態で自由落下している状態と、 センサーを地面に対して水平にし、静止している状態の出力が一緒であるのと同じ理由で、 動力を切った状態で、自然に倒れている時等は、加速度センサーから傾斜を求めることが出来ません。 といった理由で、 ジャイロからの角速度情報が一定以下の時だけ、加速度センサーを有効にしました。
先週よりも安定が良くなったので、RCで動かせる錘を載せるなどすれば、操縦できそうだと 思いました。
はじめは、どこを見て操縦すればいいか分からず、すぐに倒れてしまいましたが、 何回か試してコツがつかめてくると、「バランスゲーム」といった感じで、なんとなく 操縦できるようになって来ました。テレビでなどで見た車輪型の倒立振子は、もっと ずっと安定良く動いていたので、もっと安定が 良くなるはずなんだろうと思いましたが、これはこれで面白いと思いました。
操縦といえば、ずっとラジコンで遊んでいた経験から言って、かなり「慣れ」というか「練習」 の要素が絡んで来ると思います。なので、どの辺りで「これは操縦不能だ!」と判断するか 微妙だと思いました。
また、どの程度不安定にしておくのが、操縦して面白いおもちゃになるのか、 さじ加減が難しいところだと思いました。
ムービーのダウンロード(343kByte)
相撲ロボットの競技に、車輪型倒立振子クラスを作ったら、面白そうだと思いました。
DC/DCコンバータの取り説に指定があるので、今回初めて 「OSコン(有機半導体アルミ電解コンデンサ)」を使いました。いやーずいぶん単価の高い コンデンサです。
ちなみに、今W6に積んである電源ユニットは、組み立てた時にOSコンの入手先が分からな かったので、OSコンの数倍の容量の「高周波低インピーダンス型アルミ電解コンデンサ」 を付けています。(このOSコンはRSコンポーネンツで買いました。)
緑の線は赤外線センサのチャート、青の線は超音波センサのチャートです。 青い丸のマークは、壁と思われる場所。赤いマークは測定結果が怪しい場所です。 この測定では、超音波センサの方から、4箇所の「壁」データが取れました。
赤外線センサのレンジ内ならば、超音波センサのチャートと突合せて、超音波センサ の方で「壁」と認識した部分の性質がより明確になります。例えば、超音波センサは、赤外線センサ とくらべて分解能が低いので、家具の隙間の入り口等では戻ってきます。一方赤外線センサ の方はそのまま奥まで届きます。こんな感じの差が「赤マーク」の所に出ています。
「壁」が認識結果の境界の先まで続いている時は、超音波が一定以下の角度で壁に入射した時 にエコーが返らない性質から、レンジオーバーになります。それが画面の下に、青い線が 飛び出している部分です。
といった要領で情報を取り出して行きます。W2〜W4で遊んでいた数年間は、 この辺を主にやっていました。そんなわけで、幾何計算の関数は、書いてから10年くらい たつものを使いました。(我ながら、飽きないものだと思います)壁と思われる「点」を、まとめて「線」に する部分は、画像処理の方で、2値化された後のデータから、エリアをまとめる時に 使ったアルゴリズムを使いました。
太いピンクが「壁」として取り出された」データで、始点・終点やIDなどが、関数から 返ってきます。
あと、一歩進めて、腰と首の RCサーボはSX-101からERG-WRX等、手元にストックがあるデジタルサーボに交換して 精度を高めようかなどとも思っています。
「壁に沿って走る」時の参考に、360度スキャンの結果を使おうとするような時は、 今のままでも、まあ何とかなるのですが、画像認識で何か拾おうとする時など、 目標の距離と方向の測定が甘いと、腕が 空振りするので、そちらの方からもデジタルサーボ化を考えています。
距離センサーを回転させながら測定すると、まっすぐな壁は、壁に対して浅い角度で入射した 超音波が、ロボットの方に返ってこないことから、ごく一部しか取り出せません。 そこで、壁は認識できた始点・終点の先にずっと続いているものとして処理しています。
この例では、図の中で右上に突き出している部分は実際は壁なので、正しく走行不可能エリア として除外されています。
主な用途は、W6がどう判断して動いているかを、ターミナルソフトにテキストで表示して、 プログラムのデバグに役立てようとするものです。
載せた無線モジュールは、IPIの通販で、1年?くらい前に買ったFM-RTF-Q1-433とFM-RRF-Q1-433という 433.92MHzでFM方式のモジュールで、イギリスのメーカーによるものの様です。W6側ではメインCPUのSCI2に接続しています。 ROBO-ONEでかづひさんにWeird-7を見せてもらった後「似たような無線モジュールないかなー」と探して買ったものです。
取説によると、最高40Kbit/Sで室内75m、屋外300m通信可能とあります。W6には 十分な性能に感じます。
エンコーダの読み取りはTCLK-BとTCLK-Cから入力してITU0とITU1で行おうと試したのですが、 信号の立ち上がり/下がりが遅いところに、モーターのノイズがのってくるため、スレッショルド 近辺でたくさんカウントされてしまう様で「手で車輪を動かしている時は正常にカウントされるのに、 モーターで走るとダメ」という結果でした。(入力のLOWレベル電圧が、約0.8Vと、高いのも、原因 かもしれません。)
W2、W3そしてW4では、ローパスフィルタ とシュミットトリガ入力のゲートICを通してからバイナリカウンタへ入れていましたが、同じ部品の ストックが無かったので、PAポートから、約2m秒間隔で読み取ることによって、ローパス フィルタの代わりにしました。これで動いたので、支障が出るまでこのまま使おうと思います。 CPUの無駄使いですが、どのみち、今のところは遊んでいる時間 が多いので良しとしました。
複雑な形を作っても、なかなかうまく成型出来ないだろうと思い、簡単な形ということで 車輪のカバーを作ってみることにしました。型製作の時間節約のため、左用、右用で共用できる型を 作っています。型の材質は「ラドール」という、フィギュア製作で使い慣れている、石粉粘土 を使っています。
これができたら、腕のアルミがむき出しになっている部分のカバーを作ろうかと思っています。 そして、要領が分かってきたら、「顔」なんか作ってみたらどうかとも考えているところです。
エンコーダの1カウントの移動距離が約7.6mm、車輪の間隔が約153mmなので、 信地旋回をした場合の、制御精度は最高で3度以内程度ということになります。 あんまり良くないです。
カウント値を同期させることによる直進性能のアップは、6畳くらいの部屋で動かしている 分には「十分に直進に見える」感じでした。ただ、左右のエンコーダの位置関係、 起動電流の違い、キャスターの向き、ギアボックスのバックラッシュの状態の違い など幾つか原因は考えられますが、 走行開始の瞬間に進路がそれることが時々ありました。
ボールへのアプローチの精度は以前とそれほど変わらず期待はずれでした。でもまあ、走行速度 そのものを「2004.06.06」のところで倍にした点と、腕等RCサーボの動作スピード変更で、以前 約30秒かかっていたものが20秒程度まで短くなりました。ボールに手が届くところまで移動した 後、拾うために、狙いをつける動作に時間を取られているので、次の改善ポイントはココです。
いつも使っているデジカメは15秒までしか動画を撮影できないので、14秒以内で動作完了 するように、もう少し工夫したいと思います。
先ず試しに、蛍光灯を撮影した後、画像をネガポジ反転すれば、天井に描かれた線として、 ライントレース用のプログラムで認識できないか試してみました。
--> --> |
あっけなくラインとして認識できました。あとは、画像に写っているものと、ロボットとの 位置関係を計算する関数の中で、ロボットとラインが書かれている平面 との位置関係を、変更するだけです。まだあまりいろいろな条件で試していませんが、 蛍光灯の真下に移動するプログラムを動かしてみたところ、それらしい位置に行くので、 位置関係の割り出し計算は、だいたい良いみたいです。
お手軽でいいですね。
具体的には、例えばRCサーボを動かすコマンドは、作ったときは、メインCPU もしくはPCからキャラクタの"A"を始めに送り、No.2の受け取り準備が整った頃 を見計らって(約40m sec待って)関節番号と角度データを送る様にしていましたが、 No.2サブCPUから明確に「受け取り準備完了」のサイン(実際にはコマンドキャラクタの エコーバック)を受けて、データ送信にかかるような方式に変更しました。
最近作った、上位のCPUから見て出力系のコマンドは、大体エコーバックがありますが 、古いコマンドには無かったりしたので、この辺りを整理しています。 その他、画像の取得のように、一定のバイト数のデータが送られてくれば、コマンドに 対する動作が終了したとみなせる入力系のコマンドにも、エコーバックがあったりしたので これも「コマンドキャラクターのエコーバック無し」に統一する方向で直しています。
以前、動物の番組(アッテンボローの何とかいうやつ?)を見ていて、めまぐるしく木から木へ 飛び移るザルを指し、「このサルは大変目が良いので早く動ける」といったようなことを 言っていましたが、目が良くないせいで動作が大変のろいW6を作りながら、まったくもって 良い目(視覚の処理能力まで含めて)が、すばやい動きへの一つのキーだと思いました。
サーミスタというものを初めて使いましたが、精度のことをあまり気にしなければ、 接続は簡単だったので、モーターとかバッテリーとかの温度も計測しようかと思いました。 インターネット経由など、ロボットを身近に置かないで動かそうとした時には、こういった 情報も、ロボットの状態を知る手がかりとして役立ちそうだと思いました。
このプログラムによって、いつもW6を動かしている部屋 (蛍光灯の下にW6が移動できる床面積が3畳くらいある) では、±50mm位の精度で、蛍光灯の真ん中を床に投影した位置を座標原点、 南側の端をX軸の正の向きとして、部屋に対する絶対位置が求められるようになり、 走り回った後でも、部屋の中の決まった位置に帰ってこられるようになりました。
次は、部屋の中でスポンジボールを捜すプログラム、ボールを拾うプログラムと組み合わせて 、床に散乱しているボールを拾い集めて、部屋の特定の位置(座標を予めロボットに与えておく) に置いた箱に集められるようにしようかと、機能の統合テストを始めましたが、とんでもない 自己位置データが出てくるときがあり、まだバグつぶしに時間がかかりそうです。
一定の誤差はあるとしても、ロボットの絶対座標が取れるようになったので、地図情報 を持たせるべく、データ構造の検討を始めました。ひとまずはW4で使っていた地図 データベースのデータ構造をスタート地点として始めようと思っています。
部屋の絶対座標、ロボットから見た座標、移動の時の方向の与え方、首と腰の0方向、 ラジアンと度の変数があることなどなど、 座標系に関する計算で”はまる”ケースが多くなってきたので、プログラム全体を通して なるべく間違えにくくなるように変数や引数を整理しようと思い始めました。
ところで、いつものスポンジボールの場合、昼間は外からの光で下に濃い影が出来ないので、 今使っている画像認識ルーチンでは見つけられません。そこで今回は、黒いスポンジのブロックを 拾い集める対象として動かしました。
じっと動かない時間が長いですが、動かない時は、PCに画像を送っています。
今は、仕組みを作ることに注力しているので気にしないことにしていますが、改善したいです。
上を向いている時は、天井の蛍光灯を見て、自分の位置を計算しています。床にビニールテープで
X,Y軸が書いてあるのが写っていますが、ここが、蛍光灯の中央の真下で、「部屋」の
座標原点(0,0)にしている場所です。部屋を見回すための位置(300,300)や
集積ポイント(900、50)はここからの距離としてプログラム中に記述されています。
こういうマークを床に描くなら、こっちを見ても良いのですが、まあ、今回は「蛍光灯を ランドマークに使う」ということをテーマにしていますので、見ていません。プログラムの デバグの時に、ロボットの場所をメジャーで測るために使っているだけです。
やはり、ムービーの時間の内、画像をPCに転送する時間が半分近くを占めています。これを 改善するにはどうしたら良いか考えると、単純に、転送しなくて済むように、すべてW6内臓の メインCPUでローカルに行う方法と、LAN接続やUSB接続に変えて通信スピードを上げる方法 が思いつきました。(撮影回数が減るようにアルゴリズムを工夫というのもありますが、気持ちと しては、もっと撮影回数を増やしたいので・・・)
ローカルに行う方法を考えたところ、以前、動くもののトラッキングをメインCPUでやった 時の事を思い出し、今PCで動かしているプログラムをメインCPUに移植することは、 RAMの容量や、C言語の移植性を考えると可能ではあるけれども、結局6秒以内(転送の 所要時間)に画像認識が完了せず、今のメインCPUでは結局スピードダウンになる可能性が あると思いました。そんなわけで、死蔵状態のアルファプロジェクト製 SH3ボードの復活に思いが向かいました。
また、通信方式を変えるとしても、メインCPU基板の変更になるので、どっちにしても 時間短縮にはメインCPUのハードをさわるしか無さそうだと思いました。
今日のところは、取り付け作業中で、結果の確認はまだです。ただ、ちょっと動かしたところでは、 手でストッパーまで動かすと180度以上動くので、SX−101Zみたいに180度使えるの かと思っていたら、両機種とも180度まで動きませんでした。誤算でした。でも、360度 スキャンはあまり使わないので、視覚からの測距性能を重視して、このまま行くことにしました。
2L2でERG−WRを使っていた時は気が付きませんでしたが、 ちょっと見たところ、可動範囲はだいたい120度 くらいで、範囲を超えたパルスを入れたときは脱力でした。
次にボールを拾い集めるプログラムで動かしてみました。蛍光灯を見上げた時、その角度が 足りず、部屋の床の上で、蛍光灯を視野に納められる範囲がすごく減ってしまいました。 測距の正確さと 蛍光灯を使った自己位置測定機能のどっちを取るか秤にかけて、自己位置測定機能を 取ることにしました。そこで、首のピッチ軸の動作角を確保するため、ここもERG-VRに 換えました。
第1のステップとして、右カメラで捕らえたある物が、左カメラの画像のどこに映っているかを 探すために、特徴点抽出をやっています。特徴点は、とりあえず、水平方向のみに画像を スキャンして取り出した、エッジ抽出画像を使ってみることにしました。
次は首の周りに、何かカバーを付けたいです。
上段の画像が、それぞれ左右のカメラからの画像です。 赤い点は、距離を計測することが出来た場所を示しています。下段の図は、同心円の中心を ロボットの位置として、計測できた対象の位置をプロットしたもので、レーダー画像 のようなものです。
「目の錯覚」といえば、この「錯覚」を生ずる仕組みが、人と同じようにモノを見るキーに なっているという実感が強まってきたので、今後、より積極的に、認識プログラムの評価関数に 取り入れてゆこうと思いました。
プログラミングにおいては、学生の頃に製作に燃えたオセロゲームプログラムの評価関数 を作った経験や、難しくてイマイチよく分からなかった「ゲーム理論」や古典的な「人工知能」 の本で読んだ事柄などが役に立っているような気がしました。
キットが組みあがったので、キットに付いてきたシングルタスクのH8/OSをROMにインストールし、 H8/OSのシステムコールとキット付属のgccの環境が 動いていることを確認するため、タクトスイッチを押したらLEDが点灯するプログラムを 作ってみました。LAN関係のハードは、付属のhttpのプログラムで確認しました。
PC側は、一番ハードルが低そうな、VB6のWinsockについてマニュアル (MSDNライブラリ)を読みながら、プログラミングの練習をしています。UDPで、VBの プログラムからLAN経由で受け取った文字列を、シリアルポートから吐き出して、ハイパー ターミナルに表示するのをやってみたら動いたので、誤解無くマニュアルを読めたみたいです。 とりあえず使えそうなことが確認できて良かったです。
ふと、PCの回路図を見ながら、ビット操作をするアセンブラのプログラムを書くようなことを していた頃と比べると、ずいぶん変わったと感じました。
このキットについて、いろいろとネットで情報収集をしてみると、発売当初は回路に 不具合のあるキットだったらしいということが分かりました。が、今売っているキットは 改修済の様です。(追加のコンデンサ等、部品や説明書が入っていました。)
キット付属のH8/OS Var.2.5で、ボードに載っているDRAMを使えないか調べていたのですが、 DRAMエリアにプログラムを転送するとまともに動かないので、リセット直後はリフレッシュが されていない?様だと思いました。練習としてCMOSカメラのTrevaを接続して、1秒間に何 フレームくらいPCに取り 込めるか試してみようと思っていますが、プログラムは内蔵RAMエリアで実行し、アプリケーション でDRAMを使える様にした後、画像データだけDRAMに入れるようにしようかと考えました。
ちなみに、プログラムはこんな感じです。いまのW6のシステムを踏襲し、 文字列のコマンドで、マイコン側に何をするか指示しています。通信開始の権限は PC側が持っています。
Cの方は、プログラミングの環境整備として、使い慣れたヘッダファイル(3067f.h)を gccのインクルードファイルのディレクトリにセット し、いつものようにVC++6の環境でコンパイルのチェックが出来るように、H8/OSのシステム コールのダミー関数を作りました。(使う関数だけ)
Private Sub Check1_Click() If Check1.Value = 1 Then 'LED点灯 Winsock1.SendData "a1" Else 'LED消灯 Winsock1.SendData "a0" End If End Sub Private Sub Command1_Click() End End Sub Private Sub Command2_Click() 'タクトスイッチ状態レポート Winsock1.SendData "b0" End Sub Private Sub Form_Load() With Winsock1 .RemoteHost = "192.168.0.145" .RemotePort = 6000 .Bind 1002 End With End Sub Private Sub Text1_Change() Winsock1.SendData Text1.Text End Sub Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim strData As String Winsock1.GetData strData Text2.Text = strData End Sub |
VB6のソース |
#include < h8/3067f.h > #include < h8/syscall.h > /*LAN初期化*/ int init() { char *mac; PBDDR = 0xef; write_mode(SIO); ether_init(0x200000); if(get_ether_status() == 0) { write_string("NIC is not found!\n"); return -1; } mac = get_mac_address(); write_string("MAC:"); write_mode(BINARY);sys_write(mac, 6); write_mode(ASCII);write_string("\n"); return(0); } /*割り込み処理*/ int udp(unsigned short port, struct sockaddr_in *addr) { char buffer[64]; int i, n; if(port != 6000) return -1; n = udp_read(buffer, 63); udp_write(" ", 3); sys_write(buffer, n); if(n == 2) { if(buffer[0] == 'a' && buffer[1] == '1') P4DR.BIT.B0 = 1; if(buffer[0] == 'a' && buffer[1] == '0') P4DR.BIT.B0 = 0; if(buffer[0] == 'b' && buffer[1] == '0') { if(P5DR.BIT.B1 != 0) udp_write("The switch is not pressed down.", 31); else udp_write("The switch is pressed down.", 27); } } return(0); } /*メイン*/ int main() { int i, j; char work[64]; struct sockaddr_in addr; write_mode(SIO); write_string("\n"); P5DDR = 0x00; P5PCR.BYTE = 0x0f; P4DDR = 0xff; if(init() == -1) return -1; ip_setup(IPADDR(192,168,0,145), IPADDR(255,255,255,0)); udp_regport(udp); while(1); } |
Cのソース |
この地図データベースは、スポンジキューブを拾い集めるときに、「スポンジキューブ」として 画像認識された対象が、アプローチ可能な場所にあるかのチェックや、アプローチのルートの 計画等に使用します。
ちなみに、今あるキューブ拾いのプログラムは、いつも部屋の中心に行って、そこから見える キューブまでまっすぐに行くという、出発地点を限定することによって、 途中で家具類に引っかかる可能性を考慮しなくても 成功する可能性が高いというアルゴリズムを使っています。
//地図データベースの構造体 struct MAP_DB { int id; //オブジェクトID double end_point[2][2]; //エリアの始点と終点 double area_width; //エリアの幅 int num_neighbour; int neighbour_id[16]; //隣接オブジェクトのID int num_node; double node_point[16][2]; //隣接オブジェクトとの接続座標 int num_wall; double wall_end_point[4][2][2];//壁の始点と終点 }; |
Cの構造体 部屋が長方形で、家具類も長方形のものが多いので、エリアのエレメントも 長方形としました。 構造体の配列にして、データベースとして使います。 |
ROM化すると、メモリへのアクセスが早くなることから、プログラムがだいぶ速く動くよう になるので、同じ露出テーブルでは露出不足気味になりました。そこで、露出テーブルの数字を 調整しました。
ステレオカメラ、地図DB、部屋の中での絶対座標を知る手段、ランドマークの 形や大きさを登録してあるDB等があれば、この様な見る方向によって見え方が 変わるようなランドマークでも使えそうだと思いました。
別の条件についても思いをめぐらせてみました。現行のノーマルAIBOの様に、地図DB無し? でカラーカメラ1つの場合は、AIBOの充電ステーションの様に、どっちから見ても 見え方が同じになるランドマークが理にかなっていると納得しました。
これだと汎用性が無いので、一般的な文字認識などの「パターンマッチング」の関数を 実装した方が良さそうな気がしてきました。問題は、カメラで撮影した画像から図形を 取り出した場合は、ゆがんでいたり、大きさが不確定だったりするので、どうやって 登録してあるパターンと比較できるところまで持ち込むかが難しいと思いました。
でも、一般的な問題だと思うので、この問題を扱っている論文を探して参考に出来るのでは ないかと思いました。
腕をたたんでいる時は、PWMパルスが止まっても、もともと電源を切ってもRCサーボ自体の
機械的な抵抗の範囲でそのままの姿勢を保つようなポーズを各関節のホームポジションとして
いるため問題無いのですが、腕を伸ばしている時に、腕がガクッと下がってしまいます。
ボール拾いのプログラムを動かしていて、ボールを集積場所で放すときにガクッと来るのが
気になってきたので、予めモーションデータを作るのを止めて、リアルタイムで各関節の
目標位置までを補間するだけにしました。
コレによって、目に付くほどの長時間にわたってPWMパルスが途切れることが無くなりました。
また、計算の負荷を軽くするため、各関節の加速・減速のプロファイルに三角関数の形を 使うことを止めて、ただの三角形(注:台形ではありません)に変えました。
CRのローパスフィルタとシュミットトリガのインバータが付いたので、晴れてH8の ITUでパルスをカウントできるようになりました。
ギアの交換とグリスアップを終えて、走行中の音がだいぶ静かになりました。 ちなみにグリスは、田宮模型から出ている「シリコングリス」を使っています。
|
メンテ風景 メンテナンスのため、車輪、移動ユニット下部のカバー等を外して、ギアボックスを取り出したと ころです。 |
|
ギアの亀裂 写真の中、矢印の先の辺りで、ギアに筋が入っている場所が破損個所です。 |
実際に試してみると、60cm程前にあるキューブの位置が、20cm以上ずれて記録 されました。
原因を追究してゆくと、蛍光灯を見上げて、自機位置を取得する時の、首 サーボの位置決め誤差が大きく効いている様だと分かりました。 (要は、地図に記した自機位置からずれてました。)
先日、首のRCサーボを交換した時、例えば「ピッチ方向に65度 上を向く」と指定した時に、67度位になっているのをほおってありましたが、これでは ダメなようなので、指定角度をRCサーボのPWMパルスの長さに変換する方法を、1本 の直線で行わず、PC側で、回帰計算を行い、複数の点から補間多項式で求める方式に変える ことにしました。
その後、結果の確認方法として、分度器をあてて計るようなやり方よりも、より精度が出る
簡単な方法は無いものかと少し考えました。ロータリーエンコーダをRCサーボの軸に
付けて計測する方法が紹介されていたのを思い出しました。
しかし、ある程度のロータリーエンコーダーは高価である事と、W6の首にロータリーエンコーダ
を足すのは面倒なことから、ここは一つ、
学校で習う物理実験のベーシックな方法を
思い出し、レーザーポインタと壁に付けた印を使う方法を試してみることにしました。
そんなわけで、W6の頭の上にレーザーポインタを取り付けるべく、以前「粗品」として
もらったキーホルダー型のレーザーポインタを分解し、発光モジュールに
電源とスイッチを外に付けました。
|
レーザーポインタ ケースからレーザーのモジュールを取り出して、動作確認しているところです。 似たようなものが、今でも秋月電子から「赤色レーザー発光モジュール」として 入手可能なようです。 |