マイクロマウスを順次設計 + 実践KiCad ②

佐倉です。
今回はまだKiCadは出てきません。タイトルに入れるのが早すぎたようです。

今回は、マイクロマウスを順次設計していくにあたってのコンセプトと、その実現方法についてを書いてみました。

コンセプト

まずは今回設計するマイクロマウスのコンセプトを発表します。
自由なライン取りをして、勝てるマイクロマウス。
というのが、今回の私が作りたいマイクロマウスのコンセプトです。

マイクロマウス競技で上位に食い込むためには斜め走行が必須になりつつあります。
今の斜め走行は、斜めに通れる部分の中央と、区画の中央を、ターンでつなぐ事で成り立っています。
しかし、直線はあくまで直線として認識され、愚直にどまんなかを走るので、
実車のレースで行われている、out-in-outのような動きはできません。

従来との違い
青とオレンジの線ではなく、緑の線のように計画して走らせたい

そこで斜め走行の進化系として、自由なライン取りをして速く走りたいというのが今回のコンセプトになります。

実現の方法

自由なライン取りをするためには何が必要なのでしょうか?
自由なライン取り=自分で決めたラインに追従するためには、
①ラインを引ける事
②自分の位置を知る事
③ラインに追従できる駆動系がある事
以上の3つが必要になります。

①ラインを引く

様々な手法があります。
マイコン内でも無理なく実行できるアルゴリズムがあるので心配いりません。
(無理なく実行できるマイコンを選択します。)

②自分の位置を知る

いろいろなやり方があります。
大きなロボットで一般的なのは、レーザレンジファインダや、Kinectなど、距離を直接計測できる機器を使用して、パターンマッチングなどで自己位置を推定する方法です。
しかし、LRFやKinectを使ったマウスは重く、速く走る事ができません。
そこで今回は、様々なセンサを組み合わせて状態を推定する手法の、パーティクルフィルタを使用する予定です。
パーティクルフィルタはかなり処理を食いますが、センサの性能を理由に少し計算数を減らそうという企みがあり、マイコンでなんとか計算させらるだろうという算段です。
(計算が間に合いそうなマイコンを選択します)

また、フュージョンするためのセンサの選定が必要です。
今回は色々考えた結果、6軸の慣性センサ、赤外線反射センサ×5、モータ軸エンコーダ×2を使って自己位置を推定できるようにするつもりです。

赤外線センサの配置が肝になりそうです。
パーティクルフィルタは、パターンマッチングのような事をやるので、姿勢に対して特徴が強く出るようにセンサを配置する必要があります。

さらに、忘れがちな部分があります。
センシングを評価するためには、マスターとなるセンシング環境が必要になります。
これに関しては、暗い部屋の中でマイクロマウスのLEDを点滅させながら走行させ、
カメラを長時間露光することで、ストロボスコープのように動きの情報を取ろうという算段です。
迷路とカメラの相対的な姿勢の精度、レンズによる画像の歪みなど難しい課題があり、ここが一番うまくいくかどうか怪しい部分です。
だめだったら、高速撮影の動画を撮ってみて、ログと目視で比較するくらいでいいと考えています。この考え方はホビーだからこそですね。

③駆動系

前作通りで性能は十分なはずなので、クリアです。

まとめ

今回は、コンセプトとそれを実現する方法をご紹介しました。
細かな部分はすでに設計の域に入り始めています(センサの種類とか)。
ここに出しているのは、かなり練った後の情報です。設計しながら、実現不可能な部分が出たりした場合、ここを考えなおす必要があるでしょう。

最後に、物を作る上で重要な事として、引き下がれない状況を作る というのがあります。この記事のように・・・。

来週は、アルゴリズムについての記事が途中で切れたままになっていたため、アルゴリズムについての記事を書きます。


迷路

マイクロマウスを順次設計 + 実践KiCad ①

佐倉です。
今回からは数回に分けて、自分のマイクロマウスの設計過程をご紹介しつつ、(ついでに要望があったので)KiCadの実践的な解説を行います。
(KiCadの解説に入るのは、数回先からになりそうです。)

まず、マイクロマウスを作っていく際の私の中での流れをご紹介します。

  1. コンセプトを決める
  2. コンセプトを実現する方法を決める
  3. 設計する
  4. 作る、プログラムする

重要なのが1と2の部分です。
なんとなくロボットを作っているよりも、
「コレをやるためにこのロボットを作るんだ」
という気持ちでロボットを作ったほうが、まとまった物になります。
これが、コンセプトを決めるという部分です。

次は、コンセプトを実現する方法を決めるというターンです。
例えば、
「7分以内に月に行って戻ってきてからゴールするマイクロマウス」
なんてコンセプトを掲げても、現代には実現する手段がありません。
コンセプトが身の丈に合っているか、簡単な検証をする必要があります。
なんとか実現できそう、くらいの雰囲気で挑戦するのが一番楽しめると思います。

次に、設計と作成です。
このあたりは回を重ねながら書いていきます。

参考になるかはわかりませんが、歴代の私のマウスのコンセプトをご紹介します。

・マイクロマウスに参加するにあたってのコンセプト
人工知能が好きだったので、迷路探索に惹かれて参加しました。
人工知能や、自律的な機能と呼ばれるような部分に力を入れて参加しています。
タイムを競う競技会なので、速く走るというのももちろんコンセプトの1つです。

・さくらねずみ1
最初のマイクロマウスです。
SANYO DIGITAL CAMERA
コンセプトは最初なのでがむしゃらに作っていて、あまりありませんでした。
しかし、迷路探索に惹かれて入った事もあり、
全日本大会フレッシュマンクラスでは、最短経路が出るまで探索を続けるアルゴリズムを実装しました。

・さくらねずみ2
資料が何も残っていない、初のDCモータを使ったマウスです。
高価なDCモータが買うのが嫌だけれど、DCモータに挑戦したい という事で作成しました。
特にコンセプトがなかったように思います。当然開発は空中分解し、機体も写真も残っていないという有り様です。

・BasicMice
BasicMouseという、初心者のデファクトスタンダードなマイクロマウス(設計資料)があります。
BasicMiceは、BasicMouseの設計の古い部分を改定した、Mice(当時所属していたサークル)のためのBasicMouseです。
22
コンセプトは、シンプルで堅牢でドキュメントがある事。
作成後、数代、後輩のためのサンプルとして使われました。
シリアル通信や、モータを回すなどの軽いプログラムのサンプルも作成しました。
作成過程をまとめたページや、回路図などのドキュメントも作成し、今でも使われているようです?

・さくらねずみ3
探索中に既知区間を斜め走行をしている海外勢がうらやましく、自分も実装してやろう というコンセプトのマイクロマウスです。
23
探索中に斜め走行をするために、ソフトウェアのアーキテクチャというような部分から真剣に設計を行いました。
が、使っていたマイコンのRAMや処理性能の制約で、探索中の斜め走行には難がありました。
ただ、良いアーキテクチャ設計ができたため、走行が綺麗に行き、大会で良い結果が出ました。

・さくらねずみ4
さくらねずみ3で、ターンの調整が面倒だったので、簡単に調整できるように作ったマイクロマウスです。
20
19
PC側のソフトウェアを充実させ、モニタリングやターンの微調整などを簡単に行う事ができました。
しかし、機体の設計がぜい弱で、ハードウェアの面で調整にやさしいマイクロマウスではありませんでした。

・さくらねずみ5
19
さくらねずみ3で探索中の斜め走行を達成できていなかったので、続きのために作成したマイクロマウスです。
3年かけて目標を達成しました。

私はこんな感じでやってきました。
コンセプトを決めてやると、達成できた時の喜びも格別です。
さくらねずみ5は、最短走行でそこそこ速く走りますが、
コンセプトが探索走行中の斜め走行なので、探索走行を見ている時が一番楽しかったりします。

今回は設計の初期段階、コンセプトの部分について、例を挙げながらご紹介しました。
次回は、今回解説しながら設計していくマイクロマウスのコンセプトの発表と、設計のとっかかりを記事にする予定です。

Xtion PRO LIVE
ちょろ丸
RT-ADK&RT-ADS

Currenterの開発進捗 その2

佐倉です。

Currenterの進捗報告その2になります。
Currenterは、LifeMotionSystemというシステムの一部です。

LifeMotionSystemは、1つのマスターが全てのスレーブに(指令を出す/情報を引き出す)事で成り立つシステムです。
そのマスターを、我々はLifeMotionCoreと呼んでおり、こちらも開発を進めている所です。

2014-03-13 19.38.39
LifeMotionCoreのプロトタイプ
(開発しているのはマザーボード部分のみ。ドーターボード部分は市販品になります。)

LifeMotionSystemの最初のうちの製品は研究用途ということで、危ない動きをする場面も想定されます。
そのため、非常停止スイッチをターミナルブロックに取り付けられるようになっています。

Currenterの開発進捗

佐倉です。

本日は、NEKONOTEの中に使われているCurrenterプロトタイプの骨組みにアルマイトをかけた状態をご紹介します。

クリップボード-1

製品版もこのように、アルマイト加工された状態になる予定です。
また、形状もカマボコ型になり、ケーブルを逃がすスペースが確保されるようになります。

写真にも写っていますが、モータがエンコーダ付の物になり、より高精度な位置/速度データを取得できるようになります。

Currenterにはモータ付属のエンコーダの他に、出力軸に非接触のアブソリュートエンコーダが内蔵されています。
こちらはモジュール化されている物ではなく、磁気式の独自開発になります。
今回は、生のデータでリサージュを掃引してみました。
クリップボード-2

生のデータとしてはかなり綺麗に出ています。
これを真円に近くなるように補正し、アークタンジェントを取る事で絶対角度を算出します。

Currenterの開発は順調に進んでおりますので、6月の発売開始にご期待ください。



3Dプリンタ SCV-C170-BK


3Dプリンタ SCV-C170-S


超音波カッター ZO-40W(白)

PAWセンサをmbedから使ってみましょう。[更新]

こんにちは、水曜日に担当が変更になりました。佐倉です。

今回はマイクロマウスシリーズではなく、PAWセンサの使用方法を、mbedとの組み合わせの例でご紹介します。
PAWセンサは下の左側画像のようなセンサです。ウレタンスポンジ部分の、どのあたりがどれくらいの距離押し込まれているかを検知する事ができます。
PAWセンサ+mbed
PAWセンサの原理は、LEDとフォトトランジスタ(光検出器)を対向させて置き、密度の変化に伴う光の透過率の変化を検出するというものです。
PAWセンサの原理
PAWセンサには、LED2個×フォトトランジスタ2個による、4箇所の検出エリアが存在します。
PAWセンサの検出エリア
2つのLEDの出力を切り替えながら、フォトトランジスタの出力を見る事で、この4箇所のセンシングを行います。

しかし、フォトトランジスタの応答はあまり早くないため、LEDを切り替えてから一定期間以上待機する必要があります。
これに伴い、以下のようなシーケンスで使用する事が求められます。
PAWセンサのシーケンス

このシーケンスと、PCへの読み出し値の送信を行うmbedのソースコードが以下のものになります。
30msごとにPAWセンサの、その時の値をPCへ送信します。

2014/02/12更新
一時的なゼロ点を考慮したコードに更新しました。外乱光の影響を受けにくくなりました。
[c]
#include “mbed.h”

AnalogIn ain1(p15);
AnalogIn ain2(p16);

DigitalOut led1(p11);
DigitalOut led2(p12);

Serial pc(USBTX, USBRX); // tx, rx
Ticker pawtick;
Ticker serialtick;

unsigned short paw1, paw2, paw3, paw4;
unsigned short ain1_v0, ain2_v0;

typedef enum
{
CHARGE_1,
READ_1,
CHARGE_2,
READ_2,
}t_paw_state;

t_paw_state pawstat = CHARGE_1;

void periodicPawRead()
{
switch(pawstat)
{
case CHARGE_1:
ain1_v0 = ain1.read_u16();
ain2_v0 = ain2.read_u16();
led1 = 1;
break;

case READ_1:
paw3 = ain1.read_u16() – ain1_v0;
paw4 = ain2.read_u16() – ain2_v0;
led1 = 0;
break;

case CHARGE_2:
ain1_v0 = ain1.read_u16();
ain2_v0 = ain2.read_u16();
led2 = 1;
break;

case READ_2:
paw2 = ain1.read_u16() – ain1_v0;
paw1 = ain2.read_u16() – ain2_v0;
led2 = 0;
break;
}

switch(pawstat)
{
case CHARGE_1:
pawstat = READ_1;
break;
case READ_1:
pawstat = CHARGE_2;
break;
case CHARGE_2:
pawstat = READ_2;
break;
case READ_2:
pawstat = CHARGE_1;
break;
}

}

void periodicSerialSend()
{
pc.printf(“%05d,%05d,%05d,%05d\n”, paw1, paw2, paw3, paw4);
}

int main()
{
pc.baud(115200);

pawtick.attach_us(periodicPawRead, 500);
serialtick.attach_us(periodicSerialSend, 30000);
}

[/c]

旧バージョン(こちらでも動きますが、外乱光の影響を受けやすい可能性があります。)
[c]
#include “mbed.h”

//PAWセンサのシーケンスのステートを定義
typedef enum
{
CHARGE_1,
READ_1,
CHARGE_2,
READ_2,
}t_paw_state;

//PAWセンサのPhoto1をmbedのp15に接続
AnalogIn ain1(p15);
//PAWセンサのPhoto2をmbedのp16に接続
AnalogIn ain2(p16);

//mbedのp11をPAWセンサのLED1に接続
DigitalOut led1(p11);
//mbedのp12をPAWセンサのLED2に接続
DigitalOut led2(p12);

Serial pc(USBTX, USBRX); // tx, rx
Ticker pawtick;
Ticker serialtick;

unsigned short paw1, paw2, paw3, paw4;
t_paw_state pawstat = CHARGE_1;

void periodicPawRead()
{

//現在のステートに基いて処理を実行
switch(pawstat)
{
case CHARGE_1:
led1 = 1;
break;
case READ_1:
paw3 = ain1.read_u16();
paw4 = ain2.read_u16();
led1 = 0;
break;
case CHARGE_2:
led2 = 1;
break;
case READ_2:
paw2 = ain1.read_u16();
paw1 = ain2.read_u16();
led2 = 0;
break;
}

//次のステートに移行
switch(pawstat)
{
case CHARGE_1:
pawstat = READ_1;
break;
case READ_1:
pawstat = CHARGE_2;
break;
case CHARGE_2:
pawstat = READ_2;
break;
case READ_2:
pawstat = CHARGE_1;
break;
}

}

void periodicSerialSend()
{
//PCへ値を送信する。0~65535をとり得る。0~3.3Vに対応。paw1~paw4は、エリアの画像のch1~ch4に対応
pc.printf(“%05d,%05d,%05d,%05d\n”, paw1, paw2, paw3, paw4);
}

int main()
{
//PCと115200bpsで通信する
pc.baud(115200);

//PAWセンサの駆動用タイマー 500uS
pawtick.attach_us(periodicPawRead, 500);

//シリアル通信用タイマー 30mS
serialtick.attach_us(periodicSerialSend, 30000);
}

[/c]

このサンプルでは2つのタイマ割り込みが起こっていますが、優先順位が不明なので、シリアル通信中はPAWセンサを駆動するタイミングが狂っている可能性があります。
純粋なmbed的プログラミングでは割り込み優先順位の設定はできないようなので、このあたりは妥協するか、
PAWセンサのタイミングを優先する場合には、シリアル通信の処理を割り込み外のポーリングで行うようにしたほうが良いでしょう。

PAWセンサはあまりタイミングにシビアではないので、これくらい適当でもうまく動きます。

きちんとマイコンを使う場合には、タイマによる波形出力でLEDを駆動し、タイマトリガでA/D変換を開始し、A/D変換終了信号でDMAないしは割り込みを使って値を読み込むのが王道で、処理も食いません。

次回は、PCでの値の取り込みをご紹介します。

PAWセンサーの詳細なマニュアルはこちら

PAWセンサ PAWセンサー用ケーブル  mbed NXP LPC1768

PAWセンサの値をmbedを介してPCで取り込む

あけましておめでとうございます。佐倉です。
前回mbedを使って、PCにPAWセンサの値を送信する処理を書いたので、これを利用する例をご紹介します。
今回は、Windows上でVS Express for DesktopとC#を使って、どのあたりがどれくらい押されているかをビジュアライズするプログラムをご紹介します。
target
プログラムはこちらで配布しています。VS Express for Desktop 2012以降であれば開けるはずです。

まず、USBケーブルでmbedとPCがつながっていますが、mbedはこのUSBを使ってシリアル通信を行うことができます。
Linux, Macでは自動的にシリアルポートが認識されるようですが、Windowsの場合はドライバをインストールする必要があります。

通信が正しく行われている事を確認するために、ターミナルエミュレータ(TeraTermなど)で受信してみましょう。
シリアルポートの設定は以下のとおりです。

Baud:115200[bps]
データ長:8[bit]
パリティ:なし
ストップビット:1[bit]
フロー制御:なし

正しく通信できていれば、このような出力を見ることができます。
(ここに表示される値はPAWセンサにより個体差があります。)
term

次に、PAWセンサを使うキモとなっている部分をご紹介します。
肝心の部分はこれだけです。受信した文字列を分割し、文字列から電圧へ変換して、キャリブレーションデータを使用して押し込みの変位を計算しています。
[css]

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

//1行分以上データがあれば読み込み
while (sp.BytesToRead >= 30)
{
//読み込み
string line = sp.ReadLine();
//カンマ区切りを分割
string[] lines = line.Split(new char[] { ‘,’, ‘\n’ });

if (lines.Count() != 4)
return;

//読み出し値を電圧に変換
p1 = 3.3 * int.Parse(lines[0]) / 65535.0;
p2 = 3.3 * int.Parse(lines[1]) / 65535.0;
p3 = 3.3 * int.Parse(lines[2]) / 65535.0;
p4 = 3.3 * int.Parse(lines[3]) / 65535.0;

//初めてみ出しであれば、ゼロ点として保存
if (z1 == 0)
z1 = p1;
if (z2 == 0)
z2 = p2;
if (z3 == 0)
z3 = p3;
if (z4 == 0)
z4 = p4;

//ゼロ点を減算
p1 -= z1;
p2 -= z2;
p3 -= z3;
p4 -= z4;

//電圧から高さに変換
h1 = c1a * Math.Pow(p1, 4) + c1b * Math.Pow(p1, 3) + c1c * Math.Pow(p1, 2) + c1d * Math.Pow(p1, 1);
h2 = c2a * Math.Pow(p2, 4) + c2b * Math.Pow(p2, 3) + c2c * Math.Pow(p2, 2) + c2d * Math.Pow(p2, 1);
h3 = c3a * Math.Pow(p3, 4) + c3b * Math.Pow(p3, 3) + c3c * Math.Pow(p3, 2) + c3d * Math.Pow(p3, 1);
h4 = c4a * Math.Pow(p4, 4) + c4b * Math.Pow(p4, 3) + c4c * Math.Pow(p4, 2) + c4d * Math.Pow(p4, 1);

}
}

[/css]

シリアルの受信を含めて、たったのこれだけです。
上で配布しているプロジェクトにはビジュアライズする例が含まれています。是非、色々な物を作ってみてください。
また、PCレスで使用する際も、変位への変換(兼キャリブレーション)の計算は同様ですので、参考にしてみてください。

PAWセンサ
PAWセンサ用ケーブル
mbed NXP LPC1768

マイクロマウスのシステム考察①

日曜日はマウスの日です。というわけで、マイクロマウスのシステムについて考えていこうと思います。

さて、前回マイクロマウスの2割しか占めないと言ったハードウェアですが、非常にオーソドックスな移動型ロボットです。
系統も少ないので、よく見かけるものだけまとめてみると、

マウスのハードウェア

こんな感じです。

マイクロマウスのシステム考察①” の続きを読む