NAO V5の頭部を外して中を見る

ちょっと必要があって、大学においてあるNAO V5(ピッキー)の頭部を外して、中をチェックした。その時の記録映像は次のようなものである。(注:分解することは、破損の危険を伴いますので、自己責任でお願いします。メーカー保証とかがなくなりますので)

中を見た感想を書いておこう。
(1)ロボットの基本OSの入ったコンピュータが頭部に組み込まれているのだが、なぜ頭部なのかが不思議だった。倒れた時に一番ショックを受けるところなのだが、まあ、胴体はバッテリーやモーターなどで埋められているので、場所がなかったのだろうかと思ったりする。
(2)見た範囲では、コンピュータのケースに、冷却ファンが組み込まれているので、冷却ファンだけを取り替えるのはほぼ無理だろうと判断した。ネットオークションに、頭部ファンが回らないV5が出ていたが、その深刻さが評価できた。
(3)頭部の取り外しはとても簡単だった。現在はどうかわからないが、アルデバランの時は、頭部を取り替えるというのがユーザーフォーラムでよく議論されていた。
(4)相当密集して部品が組み込まれていたので、全体を綺麗に分解するのは、とても面倒な気がした。これ以上分解する気は今のところ起きない。

コンセプトの管理システムの必要性

今、サリーには、2万語以上のコンセプトが組み込めるようになっている。ただ、もう、絶対使わないだろうなというコンセプトも入っている。それは無駄だ。よく使いそうなコンセプトに入れ替えて、まあ、全体として2万語になればいい。

そのためのシステムなり、データベースが必要だ。潜在的可能性のあるコンセプトを貯めておいて、スコアを与え、スコアの高いものから順番に入れておくというのが望ましい。実際に、wikipediaとか、twitterで使われる頻度、辞書への掲載などの基準でスコア化する。もちろん、ライブでお客さんから出されたお題の場合は、さらにスコアを大きくすべきだろう。

Qichatでヴァーチャルなif文を作る(2)

まとめると、Qichatで、もし 変数 $varが1の時は、Aという処理、0の時はBという処理をするというのは次のように書く。

u:(実行しなさい) わかりました $exec1=1 $exec2=1
u:(e:exec1) $var==1 Aを実行します 
u:(e:exec2) $var==0 Bを実行します 

これだけのことである。もちろん、これ以外にもいろんなやり方はあるだろう。

u:(実行しなさい) わかりました $var==1 Aを実行します 
u:(実行しなさい) わかりました $var==0 Bを実行します 

これでもいいかと思ったのだが、私がやった場合は、動かなかった。このような単純化すれば動くかもしれない。ただ、ぱっと見、「実行しなさい」が二つのイベントルールにマッチするような書き方が違和感がある。

u:(実行しなさい $var==1) わかりました Aを実行します 
u:(実行しなさい $var==0) わかりました Bを実行します 

これでも動きそうな気がする。「実行しなさい」の代わりにイベントだったらどうなるだろう。

NAOの認識コンセプトの上限

サリーやマリーが、即興漫才や謎かけのお題を取得するのは、音声認識機能を使うが、クラウドを全く使わないので、全てローカルでやっている。googleのクラウドなんかも使えなくはないのだが、テレビのスタジオやライブの舞台にネットが繋がるとは限らない。テレビの収録では、ほぼ期待できない。そういうことがわかっているのに、クラウドでしか音声認識ができないというのは、馬鹿げた戦略である。

ローカルでNAOがお題を認識するためには、qichatのconceptを使う。この夏までは、コンセプトに2千数百個を入れて、お客さんのお題に対応していた。少ない。そこで、システムを変えて、日本語wikipediaや数千万のツイートを使って、自力でネタをその場で生成するシステムに変更し、お題の認識可能性も8000語に増やした。それが、10月の初め。

さらに今日、AI的手法で、ウィキペディアやツイートから取得した関連語20000語を識別させようと入力したら、認識のための音素にコンパイルするのに3分以上かかったが、できたのだ。ちゃんと認識する。

NAOのコンピュータは相当古いが、ネタに必要な自作ライブラリやスマホからコントロールするためのHTML5関係のファイルしか入れていないので、メインメモリにもディスクにも比較的余裕があった、ので可能になったのではないかと思っている。

今、実際のネタ作りは、同じローカルネット内のパソコンにお題を送って作成させている。インターネットにつなぐ必要はなく、サリーとマリーとパソコンがローカルネットに繋がっていれば良いので、閉鎖空間でも対応できる。

何れにしても、今日はNAOが2万語以上も識別可能性を持っていることにただ驚愕した。下手すれば、メモリのある限り認識するのではないか。上限が推測できない。まだまだいけそうな気はする。

(その後、2万3千語あたりが、実質的限界であることがわかってきた。それ以上にすると、コンピュータの実行速度が低下する。メモリの誓約だと思われる 2018年11月24日追記)

Intelのスティックコンピュータを購入した: BOXSTCK1A8LFC

ネタの会場に、ロボット二台と、パソコンも運ぶというのがとても面倒だ。サリーとハルのときは、ハルにネタデータの作成機能が入っていたので、ロボット二台のことだけを考えればよかったが、サリーとマリーになってから、ネタ作りコンピュータを会場まで持ち込まなくてはならなくなった。とても面倒。

そこで、もっとシンプルなコンピュータはないかと探すと、スティック型コンピュータというのが安く手に入る。次のような代物を購入した。


インテルの「Intel Compute Stick スティック型コンピューター LinuxUBUNTU搭載モデル BOXSTCK1A8LFC」という名前で、アマゾンで売っているもので、7000円弱の値段だった。まあ、試してみようという意味もある。

もう少し値段が高くて性能のいいスティックコンピュータもあるが、ウィンドウズが入っているので、linuxに入れ替えなければならなくなる。購入したものは、ubuntu-14.04だいぶ古いが、linuxなので、入れ替えが不可欠というわけではないので、これにした。(というか、ネットワークに繋ぐと、400数十メガバイトのアップデートがあるというメッセージが出てくるが、何気にやってみたら、途中でフリーズして、工場出荷時に戻さなくてはならなくなった、笑)

なお、工場出荷時に戻すためには、説明文にもなかったが、電源切った状態で、電源ボタンを押したままで電源コンセントをつないで通電する。しばらくでubuntuの初期化用のページが表示される。

ちょっと動かしてみると、CPUはそれほど悪くはない。印象としては、raspberrypi よりも少しいい感じがする。微妙だが。ただ、ストレージが、ubuntuの工場出荷時のものをストレージの一部に保存していて、いつでも戻せるようになっているぶん、実際のシステムとして使えるのは、10Gもないような感じで、そのままでは使い物にならない。

メインメモリも1Gでは弱い。

マイクロSDカードがさせるので、それを使うことにした。64ギガのものを用意した。昔の癖みたいなもので、fdiskでパーティションを設定して、と思っていたら、partedを使えと言われてしまった。使ったことがないが、使うと、結構便利だった。まあ、それで、全体を一つのパーティションにした。

ここを /altでマウントしてとか思っていたのだが、何しろ、システムの余裕が殊の外なく。ちょっとしたアプリを入れても、容量がなくなり、システムダウンになってしまう。そのほかも含めて、トライアルエラーで、5,6回は、工場出荷時に戻した。その度に1時間以上時間をロスしている。

そこで、こんなことは今までやったことはないのだが、一番システム的に容量を取っている /usrをmicroSDに載せるしかないと思った。/usrを64Gにおけば、まあ、だいぶ余裕が出てくる。ただ、手続きが面倒だ。

まず、/usrにあるものを全部、 cp -rpfa /usr/* /alt でsdに移した。これで、完コピになっているかといえば、多分なっていないんじゃないかと思うが、まあ、他にやり方がわからないのでそうした。

さらにマウントテーブル /etc/fstab に partedで作成したパーティションを/usrにマウントする手続きを記載しなければならない。以下の通りだ。

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
#              
# / was on /dev/mmcblk0p3 during installation
UUID=a5973b07-3927-4d2c-8e88-da8c9f63f97d /               ext4    errors=remount-ro 0       0
# /boot/efi was on /dev/mmcblk0p1 during installation
UUID=59AE-C1C8  /boot/efi       vfat    defaults        0       1
# swap was on /dev/mmcblk0p4 during installation
UUID=b6e64128-dd57-461e-9904-43ac60967745 none            swap    sw              0       0
UUID=fb8aede3-36bd-4659-abb7-b7f8f03c7148 /usr ext4 defaults 0 0

最後の行が、付け加えたものだ。UUIDは、パーディションの固有IDだが、取得は次のようにする。/dev/mmcblk1p1と記載されているものは、今回作成したパーディションである。デバイスmmcblk1の第一パーティションの意味。

$ sudo blkid /dev/mmcblk1p1
/dev/mmcblk1p1: UUID="fb8aede3-36bd-4659-abb7-b7f8f03c7148" TYPE="ext4"

あっさり、現在の /usrは削除した。どうせ、何度も何度も工場出荷時に戻しているので、うまくいかなければまたそうすればいい。という、いい加減さ。

これで再起動したら、うまいこと/usrは、microSDにマウントされていた。現時点でのファイルシステムの使用状況は次のようになっている。/usrには、emacsやnetbeans、mariadbなど、apt-get install で重たいアプリをインストールしたが全然余裕である。

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/mmcblk0p3   4954848 1992248   2687864  43% /
none                   4       0         4   0% /sys/fs/cgroup
udev              448532       8    448524   1% /dev
tmpfs              92712     732     91980   1% /run
none                5120       0      5120   0% /run/lock
none              463540      76    463464   1% /run/shm
none              102400      32    102368   1% /run/user
/dev/mmcblk0p1     48698    4546     44152  10% /boot/efi
/dev/mmcblk1p1  61256732 4974448  53147564   9% /usr

最後の行に、/usrの 使用状況が記載されている。圧倒的なストレージの余裕感がある。邪道だが /usrの下に、私が所有者になっているフォルダーも用意して、ストレージを使うようなファイルはそこに置いている。

ストレージは以上だが、アプリでも手間取った。何よりも、javaを入れなければならないのだが、まあ、netbeansを入れることによって全てクリアしようとしたが、これがなかなか入らない。まあ、java開発環境が有料化するという大きな変わり目ということもある。いや、関係ないか。古いjdkでもいいのだ。sudo apt-get install netbeansとしてもさっぱりうまくは入らない。(本来は、jdkそのものじゃなくて、実行環境のjreだけでいいのだが、もしものためにnetbeansも入れたという感じ)

jdkとnetbeansをそれぞれのダウンロードサイトから入れようとしたのだが、理由がわからないままにうまくいかない。結局、以下のサイトを参考にして、ほぼうまくいった。
https://websiteforstudents.com/how-to-install-netbeans-on-ubuntu-16-04-17-10-18-04/

ubuntuのバージョンが上記サイトが想定しているものより、一段も二段も古いのだが、ほぼ、そんな感じでインストールできた。

ぞれでも、エラーが発生したのは、netbeansの起動時にjdkのフォルダが見つからないことだった。そこで、

/usr/local/netbeans-8.2/bin/netbeans --jdkhome /usr/lib/jvm/java-8-oracle/

と--jdkhome を指定してやれば、全てうまくいった。これは、環境変数JAVA_HOMEを指定すればいいはずなのだが、なぜかうまくいかないので、これを書いたシェルスクリプトで起動させることにした。素人か!(笑)

あと、mariadbも入れて、ただ、データのフォルダが/var/lib/mysqlになっているので、それを/usr配下に変更する必要があった。これは、/etc/mysql/my.cnfの

datadir        = /var/lib/mysql

を変更し、そこに cp -rfp で元データを丸ごとコピーするだけで済んだ。他のところは、特に容量を取らないのでそのままにした。というよりも、socketの位置などを変えたら、なんだかおかしくなった。私の場合は必要ない。

(追記:実際使ってわかったことで、1ギガとかでっかいデータを入れると、ログもまたとてつもなくでかくなるので、/var/lib/mysql 以下のログフォルダも、新しいmicroSDの場所に移さなくてはならなかった!my.cnfの該当箇所を変更。そうしないとrootパーティションを使い切って動きが取れなくなる)

mariadbのインストールは以下のサイトを参考させてもらった。
https://qiita.com/cherubim1111/items/61cbc72673712431d06e

私のubuntuは14.04で上記のは、18.04で相当違うのだが、ほぼ、その通りにできた。

NAOのUSBをストレージとして使う

NAO2台で、即興漫才はできるようになったが、HALと違って、NAOはCPUもストレージもパワーと容量がない。現在は、ノートパソコン(MAC)を持ち込んで、即興のネタ作りはそれにやらせる形になっているが、ロボットを3台扱うような面倒くささがある。

そこで、CPUパワーはどうしようもないが、NAOのストレージを頭にさせるUSBにできないかと思っている。頭にUSBをさせば醜いが、なるべく短くして、リボンでも飾れば、なんとかなるのではないかと思う。

今、NAOを今日のオーディション用にパッキングしてしまっているので、試せないが、
https://medium.com/@heatherkemp_89938/interfacing-nao-robots-with-the-arduino-in-depth-tutorial-284ecba0b0aa
に手続きが書いてある。全体が面白い記事だが、USBマウントのところだけメモしておく。

(1)NAOにrootユーザーとしてログインしておく。
(2)USBをマウントするフォルダを作っておく(フォルダ名は任意)

# mkdir /mnt/usb

(3)ブロックIDを確認する

# blkid /dev/sdb*
/dev/sdb1: UUID=”04D9–7E06" TYPE=”vfat”

(4)フォルダをマウントする

# mount /dev/sdb1 /mnt/usb

以上である。まだ試していない。

NAO、コンセプトの搭載可能数

Pepperは、クラウドで、qichatのワイルドカード認識に対応しているようなのだが、NAOについては、NAOQIバージョンもPepperほどにも更新されておらず、対応していないようだ。それはそれでいい。というのは、Qichatでは、conceptにリストアップしておけば、ロボットはかなり正確に人の言葉を認識できるからだ。だから、conceptにどれだけのワードが載せられるかは、非常に重要な仕様になっている。
まえから、幾つもに切り分けしていれば、500個以上のコンセプトを識別できることはわかっていた。それは、実際使っているものだ。
しかし、一つのconceptのなかに、幾つ詰め込むことができるかは調べたことがなかった。実は、多くのコンセプトに分けるよりも、一つに詰め込むと便利なことがある。とても便利になるのだ。今日試してみてとても驚いた。なんと、一つのコンセプトに、2000個以上のワードを詰め込んでも、識別できたのだ。つまり、トピックファイルの中に、
concept:(words) [今日 明日 ロボット などなど ・・・・・・]
と2000個以上の言葉をwordsというコンセプトで登録しておいても、たとえば
u:(お題は _~words です) なになに $1・・・・・・
というかたちで、言葉の認識、変数 $1 への代入が可能になるのだ。もちろん、ALDialogで、そのトピックファイルを読み込み、コンパイルするのには多少時間がかかる。20秒くらいか。それは、スタート時だけだから、全然大したロスではない。
2000個も入れると、言葉の中に変な文字、つまり、ロボットが発音できない文字が入っていると、コンパイルに失敗してトピックファイルが有効化されない。アンダースコアとか、全角の数字(これがエラーになるのはちょっと不思議だが)とか、「つ」の小さい版「っ」がワードの最後に発音しにくい形で入っていても、コンパイルエラーになった。しかし、数の大きさは平気だったのだ。
NAOがワイルドカードの認識が下手なので、やむ負えず、Googleのcloud APIで変換させたりしていたのだが、音源ファイルで送ろうとも、ストリーミングにしようとも、やはり、人が喋ってからその結果をロボットに返すまでに10秒余のロスが発生して、ネタの120秒などという短い尺には、耐えられない長さになってしまう。conceptにおいて、聞き取られレベ、ほぼリアルタイムで時間のロスがない。
2000個というのは相当のキーワード数だ。実際それ以上が可能かもしれない。それ以上を試す気になれないほど、2000という数字は大きかった。

研究室のロボット、ピッキーもノッキーも修理から帰ってきた

肩を脱臼して動かなくなっていたのっきーは少し前に修理が終わって帰ってきた。指が二本折れてしまっていたぴっきーも昨日帰ってきて、研究室のロボット2台は完全復活した。ぴっきーのOSがふるいままなので、時間が空いている日にバージョンアップしたい。上がぴっきー、下がのっきー。二人合わせてピノッキオ。(私の私的なロボットサリーは自宅に置いてある)

AIモジュールの作成

AIモジュールを作成しつつある。仕組みはこうだ。
(1)パソコン上に、情報、知識、ネタに関するデータベースをMysqlで作成しておく。
(2)パソコン上に、JAVAで、こうしたAI関係の情報を処理するサーバーを動かす。
(3)ロボットに、それに対応するクライアントモジュールを、C++のライブラリとして作成する。
(4)qichatのトピックファイルで、変数イベントを発生させてサーバー上から必要な情報を獲得する。獲得したことに対するイベント、変数を同じトピックファイル上で取得し、会話的に使用する。
ほぼできた。明日、多王するトピックファイルを作成して、ロボットで試そう。

人の問いかけにWikipediaを答えさせた

今日は1日、時間が取れたので、午後ずっと、ロボットのプログラミングをやっていた。なんとか、ロボットにお題を問いかけて、そのお題をWikipediaにアクセスして調べさせて、主要な答えを返すというところまでやらせたが、まだまだ不安定で、実用性が低い。他の言葉は、ランダムにボケさせただけ。
不安定さについては、また別に書こうと思う。