2013年3月31日日曜日

Kinectでロビの右肘を動かしてみました。

 以前にKinectでポーズ認識してROBO XEROにコマンドを送るテストプログラムを作ったんですが、このプログラムを少しいじって、「右肘の角度」を検出してロビの右肘サーボを動かすようにしてみました。ROBO XEROのときはポーズ認識でROBO XERO側にプリセットしたポーズをとらせましたが、今回は右腕の上腕と肘先の要素のベクトルの内積のarccosで角度を算出してサーボに角度コマンドを直接送っています。



 サーボにTTL信号を送るのに自分はスイッチさんのUSBーUART変換アダプタを使いましたが、他の同様の(5V)ものでも大丈夫でしょう。GNDをサーボと変換アダプタとサーボ用電源を共通にして、変換アダプタの信号線をサーボの信号線に、サーボの電源入力をサーボ用電源に接続しました。

2013年3月26日火曜日

Raspberry Pi で ロビ のサーボを動かしてみる。

 Raspberry PiでROBO XEROのサーボをコマンドモードで動かしてみましたが、ROBOMICさんのページをみたところロビのサーボも中身(制御方法)は同じらしいことが書いてありました。そこでROBO XEROのサーボをロビのサーボに置き換えて試しに動かしてみました・・・といっても、問題はケーブルです。ロビのサーボは専用のヘンテコな表面実装型のコネクタになってしまっています。(ディジーチェーンできるのは面白いと思うんですが・・・)。



 そこで、思い切って、ロボのケーブルを一本犠牲にして、真ん中でちょん切って、2.54mmピッチの端子を付けてしまいました。


 ROBO XEROのサーボに付け替えて試してみると、


どうやら、動いてくれるようです。

 試しにロビの右腕を動かしてみました。グロ注意・・・・。




2013年3月23日土曜日

Raspberry Pi で DualShock3 のつづき

 前回、Raspberry Pi で DualShock3が使えるようになって、ROBO XEROのサーボをコマンド送信で動かしてみましたが、半年くらいまえにRaspberry Piで動かしたUSBスカッとミサイルランチャーを試しに操作できるようにしてみました。


 ボタンのマッピングがよくわからなかったので、右側のアナログスティックのY軸でミサイル発射を代用しています。DualShock3が /dev/input/js0 にマップされている前提で、こんな感じでとりあえずテスト。

2013年3月19日火曜日

Raspberry Pi で Dualshock3 (Bluetooth接続ゲームコントローラ)

 さて、前回、手元にあった Microsoftの Xbox 360 Wireless Controller for Windows を使って ROBO XERO のサーボを動かしてみましたが、XboxのコントローラはPC側送受信機(PCのUSBにつながる方)が大きい(1.5mくらいのUSBケーブルの先に40mm×50mmくらいの箱)ので、もう少し何とかならないかな?というところで、Bluetoothで接続できるようなゲームコントローラはどうかと思い、試して見ることにしました。世の中でBluetoothで接続できるゲームコントローラというと、やっぱり、WiiのコントローラとPlaystaiotn の Dualshock3あたりが有名ドコロではないでしょうか。
 そこで、今回は Dualshock3の利用に挑戦してみようと思います。まずは、Bluetoothを使えるようにしないといけません。そこで、Raspberry PiでBluetoothを使うために Planex の BT-Micro3H2X を使うことにしました。このアダプタは無線LANとBluetoothのコンボになっているため、1つのUSBポートで無線LANとBluetoothを利用できるようになります。無線LANとBluetoothが1つ(近く)にあって大丈夫なのか?っていうのはありますが、特に飛距離・感度や通信速度を気にするわけではないので、USBポートを節約できるっていう点をとることにして、既存のUSB無線LANアダプタを交換することにしました。
 で、今回も、Google先生にご教示頂くと、既にRaspberry PiでDualShock3を動かしている方がいらっしゃいましたので、そちらを丸々参考とさせて頂きました。

 まずは、Bluetoothを使えるようにするために、

   sudo apt-get update
   sudo apt-get install bluetooth bluez-utils bluez-compat bluez-hcidump
   sudo apt-get install libusb-dev libbluetooth-dev

で、Bluetooth 周りのインストールを行います。
 これで、lsusb でドングルが認識されていることと、

   /etc/init.d/bluetooth status

として、bluetooth in running. のメッセージが返ってくることを確認します。

 この先は、さきのこちらのページ を見て頂ければ、手順が親切に解説されていますが、一応、写しを掲載させて頂きます。
 まず、ペアリング用のツールを準備します。

   wget "http://www.pabr.org/sixlinux/sixpair.c" -O sixpair.c

として、ここからペアリングツールをおとしてきて、コンパイルします。

   gcc -o sixpair sixpair.c -lusb

コンパイルが通ったら、一旦、USBケーブルでDualShock3とRaspberry Piを接続して、




PSボタンを押して、DualShock3のスイッチを入れて、

   sudo ./sixpair

とすると、

   Current Bluetooth master: xx:xx:xx:xx:xx:xx
   Setting master bd_addr to: xx:xx:xx:xx:xx:xx

のような表示が出てペアリングが行われます。DualShock3とRaspberry Pi のUSBケーブルを外します。

 次に QtSixA のソースコードをダウンロードして、そのうちの、sixadの部分をコンパイルします。

   wget "https://sourceforge.net/projects/qtsixa/files/QtSixA%201.5.1/QtSixA-1.5.1-src.tar.gz/download” -O QtSixA-src.tar.gz

展開します。

   tar zxvf QtSixA-src.tar.gz

sixad のディレクトリに移動して、コンパイルしてインストールします。

   cd QtSixA-1.5.1/sixad
   make
   sudo make install

sixadを起動します。

   sudo sixad -start

DualShock3のPSボタンを押して接続します。Connected Sony Entertainment Wireless Controllerと表示されて、接続されます。とりあえず、

   cat /dev/input/js0

して、コントローラを傾けたり、ボタンやアナログスティックを操作すると何かしらのバイナリっぽいデータが画面に出力されるのが確認できるはずです。Ctrl+Cで中断します。



 これで、Xboxのレシーバをぶら下げた状態に比べると随分スッキリしました。USBポートも片方空いた状態にできました。




2013年3月12日火曜日

Raspberry Pi でJoystick (Xboxワイヤレスコントローラ)

 さて、今回は、Raspberry Pi でJoystick を使えないか、調べて見ることにしました。と言っても、自分はゲームは殆どやらないので、今回もJoystick(ゲームパッド)を使って、Raspberry Piでゲームをやろうというわけではありません。
 じゃあ、なぜ、Raspberry Pi でJoystick を試そうと思ったかというと・・・、そこにRaspberry Pi と JoyStick (今回はXbox 360 Wireless Controller for Windows )があったから・・・。

 で、Google先生の案内で、ネット上を徘徊していると、このようなものを発見、Linux でXboxのコントローラを動かすためのドライバってことで、まさに、これじゃないですか。というわけで、試しに Raspberry Pi 上で

   sudo apt-get install xboxdrv

おっ、インストール出来た。マニュアル を参照したんですが、使い方が今ひとつ理解できず、コンソールの1つで

   sudo xboxdrv

で、起動して、別のコンソールで自分のプログラムを走らせて、動作確認しました。本当は、ドライバなりサービスとして組み込むと、勝手に /dev/input/js* とかが出来て使えるようになると思うんですが、今回は方法がわからず、片方のコンソールでxboxdrvを実行することで、/dev/input/js0 ができるので、そこに自分のプログラムでアクセスする、という方法を取りました。


 Xbox Controller のワイヤレスアダプタをRaspberry Pi のUSBに接続して、


 Xbox Contoroller のアナログ軸を操作すると、Raspberry Pi の GPIO のTxピンに操作量に対応したコマンドを送出するような、そんなプログラムを試しに作って見ました。参考にしたのは、xboxdrv のソースについてきたサンプルコードです。

 で、UARTのTxピンに操作量に対応したコマンドを送出して、その先に何をつなぐかというと、ROBO XEROのサーボをつないでみようと思います。ROBO XEROのサーボは通常のPWM幅でのアナログ的なコントロールの他、TTLレベルでシリアル通信でコマンドを送ることでのコントロールも可能です。FutabaのRS303等のサーボの相当品(コマンド互換)と思われます。サーボを始めとするROBO XEROの情報はROBOMICさんのブログが大変参考になります。ROBO XEEROユーザの方は必見だと思います。



 さて、ROBO XEROのサーボをRaspberry Pi に接続するには3.3VのIOを5Vに変換する必要があります。そこで、以前に作ったアダプタを使いましたが、トランジスタなどで簡単なスイッチ回路を構成してもいいでしょう。


 今回は動かすサーボが1個で、負荷もなしなので、アダプタ経由でRaspberry PiのGPIOコネクタの5Vを電源として使用しました。


 こんな感じでTxをサーボの信号線、+5VとGNDをそれぞれ配線して、


 コントローラのアナログスティックのX軸に応じてサーボの位置が変わります。
 相変わらず纏まっていない汚いソースですが、参考程度にここにおいてあります。なお、UART通信をはじめて使うには設定が必要です。

ディアゴ ロビ (Robi) 8号から11号まで組立て

 昨年末にRobiを7号まで組み立てた後、12号まで溜まったので、8~12号を組み立てることにしました。まあ、どうせまた、あとで、「組み立てた何々を分解して・・・」ってなるような気もしますが・・・。

 まず、8号では、 


 耳?を付けます。これも、頭部の実装の際に外すことになると思うので、あまりきつくはネジ止めしません。

 7号で保管していたパーツと9号のパーツで、右前腕部を組み立てます。


 なんと、ここで成形不良を発見。なんか、パーツが歪んでます。不良品で交換してもらえると思うんですが、めんどくさいので、今回はスルー。今回だけは大目に見てやろう、ディアゴ、1回だけだぞ。


 さて、ロビの組立だけでは、口が寂しいので、


 サンクトガーレンのブラウンポーターを頂きました。チョコビールまで行かないまろやかな黒ビールです。
さて、右前腕部が組み上がったところ。一つ目のサーボが組み込まれています。


 10号では2つ目のサーボを使って、右上腕部を作成。


 11号の部品で肩の一部を組み立てます。


 本日の二本目は同じくサンクトガーレンのさくらビール。今の時期にピッタリ。桜葉で風味漬けしたビールです。


 せっかくなので、桜餅と一緒に頂きました。


 ちなみに、この桜餅は大雄山駅前の加藤屋菓子店 のもの。実は、自分は和菓子は苦手なんですが、ここのお店のものは大好きです。あんこが甘すぎなくていいです。


 11号まで組立が終わりました。

 ためしにサーボをコントロールして動かしてみたいのですが、独特のサーボケーブルをどうにかしないと、接続が出来ません。このコネクタとかケーブルって市販品として入手できるのかな?RSとかでケーブル作ってもらったら高そうだし・・・。



2013年3月8日金曜日

Raspberry Pi で UART通信

 今回は、Raspberry Pi でUART通信を試して見ることにしました。I2C は過去に何度か試しているんですが、そういえば、UARTを使っていませんでした。UARTが使えれば、別のマイコンとインタフェースしたり、何かと便利だと思われます。
 Raspberry Pi の IOは3.3Vなので、5V TTL - USB変換アダプタに抵抗分圧してつなごうかと思いましたが、 ランニングエレクトロニクスさんのSBDBTがあったので、これを使って、一気にUARTの無線(Bluetooth)化です。



 しかし、当初、単純に配線するだけでは上手く動いてくれませんでした。そこで、Google先生に助けを求め、先人の知恵を借りる事にしました。こちらのClick Labさんのサイトに解決方法が掲載されていました。Click LabさんはInterfaceにRaspberry Piのラジコンカーの記事を書かれた方のようです。丸々転載で申し訳ないですが、

/boot/cmdline.txt の

 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

記述を

 dwc_otg.lpm_enable=0 rpitestmode=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

のように変更し、

/etc/inittab の

 TO:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

の先頭に#を付けてコメントアウトします。

 #TO:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

設定変更後リブートすることで、UARTが利用可能になりました。デフォルトではUARTはシリアルコンソールに割り当てられているそうです。

 これらの設定をすることで、UARTを(Bluetooth経由で)利用できるようになりました。


 配線はこんな感じ。Raspberry Pi の拡張端子のピン配置はこちらを参照して下さい。


 動作確認用のプログラムは、せっかくなので、先日用意したクロス開発デバッグ環境です。


 Eclipse 上で、ブレークポイントを設定して、Bluetooth接続でコンソールに接続、"Hello~"のメッセージをコンソール側に表示後、コンソールに文字を入力すると、UART受信関数が文字を取得してブレークがかかります。変数にマウスを当てると、変数の値も表示されます。Raspberry Pi上でGeanyを使えばいいんですが、何気にクロス開発環境でeclipseも便利かも。

以下、テストに使ったソース。


#define _POSIX_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <sys/signal.h>
#include <unistd.h>
#include <fcntl.h>

// グローバル変数宣言。
int fd;
struct termios old_term_io;  // 現在の設定の退避用。

// 関数プロトタイプ宣言。
int UART_open_port(char *serial_dev);
void UART_close_port(void);
int UART_put_char(unsigned char c);
int UART_put_string(char *s);
int UART_get_char(void);

int main() {

 char uart_rBuffer[1024];
 char uart_sBuffer[256];
 char *uart_dev = "/dev/ttyAMA0";
 int c;

 // シリアル通信用バッファの初期化。NULL終端文字で埋める。
 memset(uart_rBuffer, '\0', 1024);
 memset(uart_sBuffer, '\0', 256);

 // テスト送信データの設定。
 sprintf(uart_sBuffer, "Hello,UART!!\r\n");

 // UARTの初期化。
 UART_open_port(uart_dev);

 // UART送信。
 UART_put_string(uart_sBuffer);

 // メインループ。
 while(1)
 {
  c = 0;

  /// 1バイト受信。データが来るまでブロックされる。
  c = UART_get_char();

  if (c != 0)
   UART_put_char((unsigned char)c);
 }

 return 0;
}


int UART_open_port(char *serial_dev)
{
 struct termios new_term_io;

 // デバイスをオープン。
 fd = open(serial_dev, O_RDWR | O_NOCTTY);
 if (fd < 0)
 {
  /// デバイスオープンに失敗。
  perror(serial_dev);
  exit(-1);
 }

 // 既存の設定を取得・保存。
 tcgetattr(fd, &old_term_io);

 // new_term_ioの制御文字の初期化。
 new_term_io.c_iflag = 0;
 new_term_io.c_oflag = 0;
 new_term_io.c_cflag = 0;
 new_term_io.c_lflag = 0;
 new_term_io.c_line = 0;
 //bzero(new_term_io.c_cc, sizeof(new_term_io.c_cc));
 memset(new_term_io.c_cc, '\0', sizeof(new_term_io.c_cc));

 // ポートの設定。
 //  B9600 = 9600bps
 //  CS8 = 8bit, no parity, 1 stopbit
 //  CLOCAL = ローカル接続(モデム制御なし)
 //  CREAD = 受信文字有効。
 new_term_io.c_cflag = B9600 | CS8 | CLOCAL | CREAD;

 // パリティデータエラーは無視に設定。
 new_term_io.c_iflag = IGNPAR;

 // Rawモード出力。
 new_term_io.c_oflag = 0;
 // 入力モード設定。non-canonical, no echo,
 new_term_io.c_lflag = 0;
 // inter-character timer
 new_term_io.c_cc[VTIME] = 0;
 // 1文字来るまで読み込みをブロック。
 new_term_io.c_cc[VMIN] = 1;

 // モデムラインのクリア。
 tcflush(fd, TCIFLUSH);

 // 新しい設定を適用。
 tcsetattr(fd, TCSANOW, &new_term_io);

 return(0);
}

void UART_close_port(void)
{
 tcsetattr(fd, TCSANOW, &old_term_io);
 close(fd);
}
int UART_put_char(unsigned char c)
{
 if (write(fd, &c, 1) != 1)
  return(-1);

 return(0);
}

int UART_put_string(char *s)
{
 if (write(fd, s, strlen(s)) != 1)
  return(-1);

 return(0);
}
int UART_get_char(void)
{
 unsigned char c;
 int res;

 res = read(fd, (char *)&c, 1);

 return(c);
}

2013年3月1日金曜日

ロビ 宇宙に行く?

 ネットでニュースを見てたら、こんなのがあった。これの原型って、もしかして、ディアゴのロビなのかな?