こんにちは、上津原です。
缶コーヒーのテレビCMでもPepperくんを見るようになって、なんだかPepperくん変なタレントみたいな立ち位置になってきてますね。
というわけでまたPepperの話題です。
遠隔で色々喋らせたい
Pepperの開発をやっていると、インストールしておいたものしか動かせないのにやきもきしてきます。
なので、PepperとMacをつないで、こっちからテキストをを送ればそれを喋るようにしてみました。
pythonで書きます。
基本は普通のソケット通信のコードと同じです。サーバーサイドとクライアントサイドのスクリプトを書きます。
今回はMacをサーバーとして、Pepperをクライアントとして作りました。
サーバーサイド
import os import sys import socket HOST = '' PORT = 50008 def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) print 'waiting for client...' s.listen(1) (conn, addr) = s.accept() print 'Connected by', addr pid = os.fork() if pid == 0: print "child process" while 1: msg = raw_input(">> ") conn.send('%s' % msg ) if msg == "quit": break; sys.exit() else: print "parent process" while 1: data = conn.recv(1024) if not data: print 'End' break elif data == "": print "Client is closed" os.kill(pid, 9) break print "pepper: ", data conn.close() sys.exit() if __name__ == '__main__': main()
クライアントサイド(Pepper)
import os import sys from socket import * HOST = '192.168.XXX.XXX' #ここは設定に合わせて PORT = 50008 class MyClass(GeneratedClass): def __init__(self): GeneratedClass.__init__(self) def onLoad(self): #put initialization code here pass def onUnload(self): #put clean-up code here pass def onInput_onStart(self): # ソケット接続 try: #接続処理 self.s = socket(AF_INET, SOCK_STREAM) self.s.connect((HOST, PORT)) except: #接続失敗したらソケットを閉じて終了へ self.s.close() self.onStopped() return # 子プロセスの作成 try: pid = os.fork() except: return # つながったらテキストの送受信を行う self.log("pid :" + str(pid)) # 子プロセスの場合の処理 if pid == 0: # 一旦未使用 pass # 親プロセスの場合 else: while 1: self.log("pid else") data = self.s.recv(1024) if not data: break elif data == "quit": os.kill(pid, 9) break self.log(data) # Stopの何かがないか確認 stop = self.stopVerification(data) if stop == False: self.outputStringFromServer(data) self.s.close() self.onStopped() pass def onInput_inputString(self, p): # PCからインプットされたテキストをmsgに入れて、喋らせる self.log("Recieve String " + p) # Stopの何かがないか確認 stop = self.stopVerification(p) # Stopではなかったらメッセージをサーバに送る if stop == False: self.s.send(p) def onInput_onStop(self): self.onUnload() #it is recommended to reuse the clean-up as the box is stopped self.onStopped() #activate the output of the box def stopVerification(self,inputString): if inputString == "ストップ": self.log("stop!!") self.outputStopBehavior() return True else: return False
補足説明
outputStringFromServer()部分がサーバーから受け付けたテキストをノードからアウトプットするものになってます。
ここから先にAnimatedSayなどをつなげればそのとおりに喋ってくれます。
stopVerification()というのも作っていますが、これは「ストップ」という単語が届いたらアプリケーションを停止する挙動なども取り入れています。特定のテキストを送ればこの挙動をする、とかそういった物を簡単に設定することが出来るようになります。
forkを使って、好き勝手やりとりできるように作っているので、pepperのSpeechRecoを使って特定の言葉をサーバ側に送ったりもできます。onInput_inputString()はSpeechRecoから受け付けた単語を得てうごかしてます。
とりあえずコレを使えば、人力でPepperくんと人の会話ができるようになります!
人力でやってどーする!と思うかもしれませんが、人力でもそれはそれで楽しいのでやってみてください。