Archives

March 2009 の記事

PC-OP-RS1 (KURO-RS) を使って ROBO-Q と同じように調べてみました。
Q-TRAIN のコントローラの赤外線信号です。

TAKARA TOMY Q-TRAIN

●コマンドフォーマット

コマンドは 8bit 分
下記の順番で送信されています

先頭
  C C A 0 R L B F


 CC = BAND A~D (00,01,10,11)
 A = 自動移動の指定かどうか (左サイドのスイッチが on なら 1)
 0 = 常にゼロ
 R = 右ボタン (→)
 L = 左ボタン (←)
 B = 後退ボタン (↓)
 F = 前進ボタン (↑)

R L B F の各ボタンは同時押しが出来ます。
例えば前進+右旋回だと F + R が同時に ON になります。


コマンド組み合わせの例

BAND A 前進	00000001
BAND B 前進	01000001
BAND C 前進	10000001
BAND D 前進	11000001

BAND A 前進自動	00100001
BAND A 後退	00000010
BAND A 左	00000100
BAND A 右	00001000
BAND A 前進+左	00000101

●コマンドエンコード

ヘッダや 1bit 分の波形も長く取られており ROBO-Q とは異なっています。

ヘッダ常に H 6.3msec

bit
 0 = L 0.5msec + H 1.7msec
 1 = L 1.5msec + H 0.7msec

エンコードされた bit データは ROBO-Q と違い、0 でも 1 でも同じ長さになります。
よって 1コマンドはだいたい 23.9msec


例 BAND D 前進 + 左 で受け取った波形 (0.1msec 単位のサンプリング)

// ヘッダ
11111111111111111111111111111111111111111111111111111111111111
// 1
000000000000000 1111111
// 1
000000000000000 111111
// 0
00000 11111111111111111
// 0
00000 11111111111111111
// 0
00000 11111111111111111
// 1 (左ボタン)
000000000000000 1111111
// 0
00000 11111111111111111
// 1 (前進ボタン)
0000000000000000 111111


使用したツールは ROBO-Q 同様「スーの道具箱/分解してみよう/PC-OP-RS1」の
IrReceiver です。


関連エントリ
タカラトミー ROBO-Q (3) PC から操作する実験
タカラトミー ROBO-Q (2) 赤外線コマンドの解析
タカラトミー ROBO-Q



少々時間が無かったので昨日の解析結果が正しいかどうか確認するだけ。
BAND A/D の ROBO-Q も調達できたので 4バンド分の信号を確認できました。

実際にコマンド送信プログラムを作ってみます。
スーの道具箱/分解してみよう/PC-OP-RS1
のページを参考にさせていただきました。そのままです。

初期化

hPort= CreateFile(
		"COM4",
		GENERIC_WRITE|GENERIC_READ,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		0,
		NULL
	);
if( hPort == INVALID_HANDLE_VALUE ){
	// ERROR
	return;
}
DCB	dcb;
dcb.DCBlength= sizeof(DCB);
dcb.BaudRate= CBR_115200;
dcb.fBinary= TRUE;
dcb.fParity= FALSE;
dcb.fOutxCtsFlow= FALSE;
dcb.fOutxDsrFlow= FALSE;
dcb.fDtrControl= DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity= FALSE;
dcb.fTXContinueOnXoff= FALSE;
dcb.fOutX= FALSE;
dcb.fInX= FALSE;
dcb.fErrorChar= FALSE;
dcb.fNull= FALSE;
dcb.fRtsControl= RTS_CONTROL_DISABLE;
dcb.fAbortOnError= FALSE;
dcb.fDummy2= 0;
dcb.wReserved= 0;
dcb.XonLim= 0;
dcb.XoffLim= 0;
dcb.ByteSize= 8;
dcb.Parity= NOPARITY;
dcb.StopBits= ONESTOPBIT;
dcb.XonChar= 0;
dcb.XoffChar= 0;
dcb.ErrorChar= 0;
dcb.EofChar= 0;
dcb.EvtChar= 0;
dcb.wReserved1= 0;
SetCommState( hPort, &dcb );

送受信は WriteFile()/ReadFile() です。

PC-OP-RS1 用の送信データを組み立てます。
赤外線の On/Off 情報をビット列で指定。あくまで動作確認用なのでべたで。

int pushbit( char* ptr, int index, int flag, int length )
{
	if( flag ){
		for( int i= 0 ; i< length ; i++ ){
			int	byteoffset= index >> 3;
			int	bitoffset= index & 7;
			ptr[byteoffset] |=  (1<<bitoffset);
			index++;
		}
	}else{
		index+= length;
	}
	return	index;
}

// H 1ms  + data x7
void SendCommand( int band, int speed, int turn )
{
	unsigned int	bitpattern=  ((speed<<5) & 0x60)
				|(( turn<<3) & 0x18)
				|(( band<<1) & 0x06);
	char	byte[240];
	memset( byte, 0, 240 );
	int	index= 0;
	index= pushbit( byte, index, TRUE, 10 ); // H 1ms
	for( int i= 0 ; i< 7 ; i++ ){
		if( bitpattern & (1<<(6-i)) ){
			index= pushbit( byte, index, TRUE, 10 ); // H 1ms
		}else{
			index= pushbit( byte, index, TRUE, 5 ); // H 0.5ms
		}
		index= pushbit( byte, index, FALSE, 5 ); // L 0.5ms
	}
	SendIR( byte, 240 );
}

データ送信

void SendIR( const char* command )
{
    iPort->Send( "t", 1 );
    iPort->Recv( rdata, 1 );	// 'Y'
    iPort->Send( "1", 1 );		// ch1
    iPort->Recv( rdata, 1 );	// 'Y'
    iPort->Send( command, 240 );
    iPort->Recv( rdata, 1 );	// 'E'
}

昨日のデータ通りです。すんなり動作しました。
PC で ROBO-Q を操作できます。

SendCommand( 1, 2, 0 ); // BAND B で中速(M)前進
SendCommand( 1, 1, 1 ); // BAND B で低速(L)右回転

でもデータ送信まで思ったより時間がかかるので、細かい制御をリアルタイムに
行うには少々厳しいです。要検討。

修正 2009/3/5 4:27 勘違いでした。十分な速度で操作できます。

きちんと使うなら 192ms 分複数のコマンドをパックして送る必要あります。


関連エントリ
タカラトミー ROBO-Q (2) 赤外線コマンドの解析
タカラトミー ROBO-Q



ROBO-Q のリモコンコマンドを調べてみました。

ROBO-Q 赤外線
コマンドは 7bit (最後は固定なので、data 6bit + 終端bit かもしれない)

先頭     終端
S S T T B B 0

SS = 速度
  00 = AUTO 等のコマンド送信
  01 = 前進 速度L
  10 = 前進 速度M
  11 = 前進 速度H

TT = ターン他 (bit が 1 の方の足を止める)
  00 = 前進 (両足とも止めない)
  01 = 右回転 (右足を止める) / 回避モード
  10 = 左回転 (左足を止める) / 回避モード
  11 = 追跡モード

BB = バンド
  00 = BAND A
  01 = BAND B
  10 = BAND C
  11 = BAND D


全部の組み合わせ

前進L   = 0100bb0
前進M   = 1000bb0
前進H   = 1100bb0
右回転L = 0101bb0
右回転M = 1001bb0
右回転H = 1101bb0
左回転L = 0110bb0
左回転M = 1010bb0
左回転H = 1110bb0
AI回避  = 0011bb0
AI追跡  = 0010bb0 / 0001bb0

移動はコマンドを送信し続ける必要があります。
何もコマンドが送られていない状態が停止です。


●解析に使用したもの

PC に USB 接続できる学習リモコンキットです。
BUFFALO と 玄人志向 どちらも同じものだそうです。

BUFFALO PC-OP-RS1
玄人志向 KURO-RS


●PC-OP-RS1 WindowsVista x64 用ドライバ

付属ドライバも web から落とせるドライバも Windows x64 に対応していません。
x64 で動作させるために下記のページを参考にさせていただきました。

プログラミング研究所 KURO-RSをWindows XP x64で使用する

上のページを参考にして FTDI Virtual COM Port Drivers の最新版を入れました。
これで PC-OP-RS1 を Vista x64 で使用することが出来ます。
以下詳細手順


● x64 ドライバ導入手順のメモ

(1) FTDI Virtual COM Port Drivers から 2.04.16 を download (CDM 2.04.16 WHQL Certified.zip)

(2) デバイスマネージャーから PC-OP-RS1 のデバイスIDを確認しておく
  不明なデバイスのままで構わない。
   プロパティ→詳細→ハードウエアID
  これで vid=0411, pid=00b3 であることがわかる

(3) (1) のアーカイブを展開しフォルダ内の *.inf ファイルを書き換える

2つあります。
どちらも [FtdiHw]/[FtdiHw.NTamd64] の項目の先頭行を複製して VID/PID を書き換える
だけです。[Strings] は書き換えなくてもインストールできました。

ftdibus.inf の対応する項目に追加する行(追加する行だけ記述)
[FtdiHw]
%USB\VID_0411&PID_00b3.DeviceDesc%=FtdiBus.NT,USB\VID_0411&PID_00b3

[FtdiHw.NTamd64]
%USB\VID_0411&PID_00b3.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0411&PID_00b3

[String]
USB\VID_0411&PID_00b3.DeviceDesc="USB Serial Converter"


ftdiport.inf の対応する項目に追加する行(追加する行だけ記述)
[FtdiHw]
%VID_0411&PID_00b3.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0411&PID_00b3

[FtdiHw.NTamd64]
%VID_0411&PID_00b3.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0411&PID_00b3

[String]
VID_0411&PID_00b3.DeviceDesc="BUFFALO RemoteStation PC-OP-RS1"


ドライバインストール時は、上記フォルダを手動で指定します。
ドライバを検索せずにディスク使用まで持って行く。
KURO-RS でもおそらく同じです。


● PC-OP-RS1 を使ったデータ取り込み

すべて下記のページを参考にさせていただきました。
ツールも下記ページからダウンロードできる IrReceiver/IrSender を使用しています。

スーの道具箱/分解してみよう/PC-OP-RS1


● ROBO-Q 赤外線コマンドの信号

スーの道具箱/分解してみよう/PC-OP-RS1」によると、受信データは
0.1ms のサンプリング情報とのこと。
240byte x 8bit = 1920bit が 0.1ms 単位だとすると 192ms 分の情報が一度に
取れます。

実際にサンプリングした bit パターンを見てみると下記のようになっています。
実際には 1bit 程度の誤差が入ります。

111111111111111100000111111111100000111111000011111100000111110000011111111110000011111100000000


・信号と思われるところ = 5個並んだ1(H) または 10個並んだ1(H)
・区切り = 5個並んだ0(L)

よって
0.5ms の連続する H = データの 0
1.0ms の連続する H = データの 1
0.5ms の連続する L = 区切り

とみなすと、一番最初に書いた 7bit のデータが得られます。
データの先頭は 1ms 程度の H が続きます。

コマンドの長さは

1.0 + 1.5*6 + 1.0 = 11ms
1.0 + 1.0*6 + 1.0 = 8ms

なので、送信に 8~11ms かかります。
連続歩行の場合 170ms 程度の間を空けているようです。
スライダを L→H と移動する場合やターンの開始時などは、間無しにほぼ連続して
コマンドが送られています。


●障害物認識ユニット

障害物認識ユニットは、上記のコマンドとは全く異なるパターンが送られています。

1111110000000000111111000000

最初の H が 0.5ms でデータ区切りが 1ms あるためコマンドと区別可能です。
左右の違いが無かったため、どのように区別しているのかはまだわかりませんでした。


●参考にさせていただきました

下記のページが無かったら調べることが出来ませんでした。
JuJu 様、NMVL 様に感謝します。

スーの道具箱/分解してみよう/PC-OP-RS1
プログラミング研究所 KURO-RSをWindows XP x64で使用する


関連エントリ
タカラトミー ROBO-Q



非常に小さいです。

TAKARA TOMY ROBO-Q

ROBO-Q

とことこ歩きます。
付属のコントローラを使えば、こんなに小さいのに歩かせたり回転したりと操縦できるんです。
ゆっくり動けるので、EIZO のモニタの上の縁なども端から端まで歩くことが出来ました。

さらにユニークなのは自律モードがあること。
左右に障害物認識ユニット(マニュアルに記載された名称)があって、
障害物をよけたり目の前のものを追跡したりします。

コントローラは TV リモコンのように赤外線を使っています。
ロボット側の赤外線受光部はちょうど顔の位置、正面です。


赤外線なのでおそらくリモコンのようにパルス信号でコマンドを識別しています。
ROBO-Q は A BAND ~ D BAND と 4種類あり、4台までは同時に操作しても混信しません。
前進や回転などの赤外線コマンドも 4セット用意されているのだと考えられます。

ちなみに同じ BAND タイプの ROBO-Q が 2台あると、1つのコントローラで同時に
操作できます。


自律モードではいったいどうやって障害物を見ているんでしょう。
小さいし価格も安いし、あまり複雑な仕組みは使っていないはずです。
障害物認識ユニットはちょうど顔の横についており、それぞれ右側と左側の障害物を
感知できます。
このセンサー赤外線発信部にそっくりです。

ROBO-Q

おそらく想像ですが、コントローラと同じように左右に赤外線のコマンドを発信して
いるのだと思われます。
赤外線の届く距離をうまく調整すれば、目の前に障害物が来たときだけ反射して
顔の正面の受光部でコマンドを受けることが出来ます。
受光部は共有できるし仕組みも単純にできて非常にうまい方法だと思います。

考えられる赤外線コマンドの種類は下記の通り。

・両足を動かす x3速度
・左足を動かす x3速度
・右足を動かす x3速度
・AI回避モードへ移行
・AI追跡モードへ移行
・右側障害物認識ユニット
・左側障害物認識ユニット

前進は左右のコマンドを同時に送ってるだけかもしれません。
障害物認識ユニットも微弱ながら学習リモコンが反応しました。
まだ障害物の再現は出来ていないので想像の範囲を超えてないです。