スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


にほんブログ村 その他趣味ブログ LEGO・ブロックへ

Androidの音声認識でアルファレックスを動かす - プログラミング編2

こんばんは、matkです。

まず音声認識部分ですが、このサイトを参考にしました。こんな感じで超簡潔に書けます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import android

droid = android.Android()
while True:
    word = droid.recognizeSpeech().result
    print word.encode('utf-8')
    if word == u'右に':
        turn_right()

はじめは音声認識だけでなく、傾きなどでも操作できるようにしていましたが、なかなか敏感で子供には操作が難しそうなので途中でやめました。センサーの値の取得の仕方は、これらのサイトが詳しいです([1,2,3])。

さて、今回のフェンダー(≒アルファレックス)のプログラムですが、以下になりました。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from time import sleep
import math
import thread
import sys
import android
from nxt.sensor import *
from nxt.motor import *
import nxt.locator

b = nxt.locator.find_one_brick()
m_face = nxt.Motor(b, nxt.PORT_A)
m_walk = nxt.Motor(b, nxt.PORT_B)
m_wave = nxt.Motor(b, nxt.PORT_C)
m_forward = nxt.SynchronizedMotors(m_walk, m_wave, 0)
t_walk = Touch(b, PORT_1)
t_wave = Touch(b, PORT_4)
color  = Color20(b, PORT_2)
irseeker = HTIRSeekerv2(b, PORT_3)

def wave_one_unit(ini_wait=1):
    m_wave.run(127)
    sleep(ini_wait)
    while t_wave.get_sample():
        sleep(0.05)
    sleep(0.37)
    m_wave.brake()
    sleep(0.5)

def walk_one_unit(ini_wait=0.5):
    m_walk.run(127)
    sleep(ini_wait)
    while not t_walk.get_sample():
        sleep(0.05)
    sleep(0.15)
    m_walk.brake()
    sleep(0.5)

def go_forward():
    for i in range(0,4):
        thread.start_new_thread(m_face.turn, (127, 1080))
        thread.start_new_thread(wave_one_unit, ())
        walk_one_unit()

def turn_left():
    for i in range(0,4):
        thread.start_new_thread(m_face.turn, (127, 1080))
        walk_one_unit()

def turn_right():
    m_forward.turn(127, 460)
    thread.start_new_thread(m_face.turn, (127, 1080*4))
    m_walk.turn(127, 1080*4)
    thread.start_new_thread(wave_one_unit, (0,))
    walk_one_unit(0)

def nanana():
    for i in range(0,2):
        wave_one_unit()
    b.play_sound_file(0,"nanana.rso")
    sleep(4)

def turn_to_me():
    dirix = irseeker.get_sample().direction
    print dirix
    if dirix in [0,5,6]:
        return
    sign = +1 if dirix - 5.5 > 0 else -1
    if sign == 1:
        m_forward.turn(127, 460)
        sleep(0.5)
    while math.fabs(dirix - 5.5) > 1:
        thread.start_new_thread(m_face.turn, (127, 1080))
        walk_one_unit()
        dirix = irseeker.get_sample().direction
        sleep(0.5)
        new_sign = +1 if dirix - 5.5 > 0 else -1
        if new_sign * sign < 0:
            break
    if sign == 1:
        thread.start_new_thread(wave_one_unit, (0,))
        walk_one_unit(0)
    sleep(1)

def voice_event_loop():
    droid = android.Android()
    while True:
        word = droid.recognizeSpeech().result
        print word.encode('utf-8')
        if word == u'右に':
            turn_right()
        elif word == u'左に':
            turn_left()
        elif word == u'アルク':
            go_forward()
        elif word == u'こっち向いて':
            turn_to_me()


thread.start_new_thread(voice_event_loop, ())
while True:
    #1:black/none, 2:blue, 3:green, 4:yellow, 5:red, 6:white/pink
    colorix = color.get_sample()
    if colorix == 2:
        nanana()
    elif colorix == 4:
        b.play_sound_file(0, "Goodbye.rso")
        sleep(2)
        sys.exit()
    elif colorix == 5:
        b.play_sound_file(0, "Red.rso")
        sleep(2)
プログラムの簡単な説明をします。
このアルファレックスは一アクション終えると常に右足が一歩前に出るように(左足に重心があるように)プログラムされています。ロジックを簡潔にするためです。
・turn_left()は足をバタバタさせる(walk_one_unit()を何回か呼ぶ)だけでOKです。
・turn_right()は半歩歩いて、右足に重心を移したのちに、足をバタバタさせています。
・nanana()はDVD中の腰振りダンスです。声とダンスを同時にすると、声がモーター音にかきけされますので、わざとずらしてあります。
・turn_to_me()は赤外線ボールの方を向きます。センサーの値が5,6はほぼ真正面を意味しますので、この数字を目標にしています(5.5を使っています)。

102行目からはメインです。
音声認識のループとカラーセンサーで行動を変える部分を別スレッドで走らせています。モーターの制御が変にバッティングしなければ、これぐらいルーズな並列化でOKと思います。正直pythonはまだまだ未熟ですので、もっと良い方法、もっとこう書くべき、というのがありましたらコメントで教えてくださいまし。

ちなみにnxt-pythonのせいなのか自分のカラーセンサーのせいなのかわかりませんが、緑色の識別がなかなかうまく行きません。緑は黒になりやすく、ピンクは白と判定されます。ちなみに指などは赤です。

音声認識の方は、「左」「アルク」は大丈夫ですが、「右」と「こっち」はかなり認識されにくいです。短い単語や撥音が含まれていると認識率が下がるようです。はじめは、以下のようにこれでもOKリストというのを作っていました。さすがに負けてる気がしてやめました。
migi_list = [u'右', 'muji', 'wiki', u'ネギ', 'mm', 'mugi', u'水着']
kocchi_list = [u'こっち', u'ごち', 'watch', u'東風', u'1', u'ぼっち', u'バッチ', u'腰', u'高知']
Googleの音声認識は学習データが共通で、万人向けの1つの判別器を作ろうとしているからこのようになるのだと思います。個人的には10時間ぐらい用意された文章を淡々と読む気力はありますので、個々人の判別器を作る方法というのを用意して欲しいと思います。カーナビもそうです。

にほんブログ村 その他趣味ブログ LEGO・ブロックへ
スポンサーサイト

Androidの音声認識でアルファレックスを動かす - プログラミング編1

こんばんは、matkです。

この記事では、Android上でnxt-pythonを動かすための準備を説明します。

●1. SL4Aのインストール
こちらの記事を参考にしました。入れたバージョンは、「sl4a_r4.apk」です。

●2. Py4Aのインストール
同じ記事を参考にしました。「PythonForAndroid-r7b1.apk」があったにもかかわらず、「PythonForAndroid_r4.apk」を入れました。ついうっかりです。uninstallの仕方がすぐに分からなかったのでそのままでいきました。Android初心者ですみません。誰か教えてください…。

●3. PyBluezのインストール
ここから「PyBluez-0.19-py2.6-linux-armv.egg」をダウンロードします。Python for Androidを起動して[Import Modules]をクリック。「PyBluez-0.19-py2.6-linux-armv.egg」を選ぶとインストールが始まります。

●4. nxt-pythonのインストール
ここから「nxt-python-2.2.1.zip」をダウンロード。AndroZipなどで解凍。僕は、/sdcard/sl4a/scripts/work/以下に自分のプログラムを入れて開発しているので、解凍してできたフォルダの中の「nxt」フォルダを丸ごと/sdcard/sl4a/scripts/work/以下に移動しました。

あとは、/sdcard/sl4a/scripts/work/alpharex_mod.pyなどを作って、nxt-pythonのexampleのようにimportしてスクリプトを書けばOKです。実行するにはSL4Aを立ち上げて、普通に選択すれば実行できます。

今回は、DroidEditというAndroidアプリのエディタ上で開発しました。他のアプリだと、色がつかない、行番号の表示がバグる等ありまして、ここに行き着きました。ShiftEdit等のWebブラウザを使ったエディタはレスポンスが不満でやめました。また、Eee Pad Transformer TF101がキーボードつきなのですが、妻も使っている都合上、キーバインドをバリバリにカスタマイズしているわけではありませんで、かなり開発しづらかったです。まだまだAndroid上での開発は厳しそうです。まああと2,3年もすれば十分なエディタやIDEが出てくると思いますので期待しています。

次回はプログラムの説明をします。

にほんブログ村 その他趣味ブログ LEGO・ブロックへ

Androidの音声認識でアルファレックスを動かす - 組み立て編

こんばんは、matkです。

組み立て自体は、ここからダウンロードできるNXT1.0のアルファレックスを参考にしました。理由はNXT2.0のアルファレックスは少し大きくて手順が多いからです。パーツは少し違いがありますが、まあ問題なく組めます。そこからフェンダーっぽく赤いパーツをこころもち増やしたり、髪の毛みたいな部分をつけました。

P1000084.jpg P1000085.jpg P1000086.jpg

娘がよくボールを落としてなくしそうになるので、ボール置き場を作りました。

P1000093.jpg

苦労したのは足の位相(≒周期)を合わせるためにタッチセンサを強引に取り付けた点です。周期があっていないと、歩くことすらできません。詳しくは大庭氏のこの記事を参照。また、プログラミング編とも関係しますが、nxt-pythonはモーターを同期した時の回転角度の精度がどうもよくありません。これは困ります。今回は同期しないで、足ごとに、左足は「タッチセンサから離れるまで回転」、右足は「タッチセンサが押されるまで回転」で指定しています。これでも完璧にうまく行くわけではないですが、何度も歩かせてもズレが蓄積しませんので、破綻はなくなります。
 
P1000090.jpg P1000092.jpg 

あとは、右手にカラーセンサー、左手にはNXT IRSeeker V2を持たせています。これは赤外線を出す物体の方向を検出するセンサーです。もともとNXTのサッカー競技用途らしく、ボールもえらい高い値段で売られています。作れる人は作った方がいいでしょうね。このセンサーを使うことで、ボール持って「こっち向いて」が可能になりました。結構楽しいです。

これでセンサの合計が4つになったので、顔の超音波センサはもれなく飾りになりました…。まあたまにはよかろ。

にほんブログ村 その他趣味ブログ LEGO・ブロックへ

Androidの音声認識でアルファレックスを動かす - 動画編

こんばんは、matkです。

ここ最近はアルファレックスを少しいじったものを作っていました。というのも、2歳の娘が映画「ロボッツ」のフェンダー(Fender)という赤いキャラの大ファンなのです。DVDで30周は軽く見ています。どんなキャラかの日本語の説明はここ。一言で言えばひょうきんなロボットです。クリスマスプレゼントのつもりでしたが、遅れに遅れて今頃完成です。

さて、娘が遊ぶということで、6月頃に購入したAndroidのタブレットPC(Eee Pad Transformer TF101)の音声認識を使うことにしました。


結果的には、2歳児の発音ではほとんど正常に認識されないため、娘→僕→音声認識という通訳を挟むことになりました。でもとても喜んでくれているのでひとまずはよかったです。動画は以下になります。



組み立て自体はNXT1.0のアルファレックスから大きく外れたものではないので難しくはありません。今回頑張ってのはプログラミング編です。次回からはそれらの説明をします。

にほんブログ村 その他趣味ブログ LEGO・ブロックへ
リンク
フリーエリア
プロフィール

tsukuba.lego

Author:tsukuba.lego
●主な登場人物
koba : 会長. RCX, WeDo, NXT1.0, NXT2.0を持つ.
matk : 副会長. 2010年夏にNXT2.0を購入, 20年来のレゴ熱復活.
●会員募集中です!小学生から歓迎. 近日月1ぐらいで集まる予定.
mail:tsukuba.lego@gmail.com
YouTube (tsukubalego)
Twitter(tsukubalego)

カテゴリ
最新記事
最新コメント
月別アーカイブ
検索フォーム
RSSリンクの表示
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
最新トラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。