PaPeRo-i with Python(工事中)
ソフィアプランニング社が提供するPythonを使用したPaPeRo-i with Pythonをご紹介します。
PaPeRo-iのシナリオSDK
用語の定義
-
SGW
サービス・ゲートウェイ・プラットフォ-ムの略称
-
SGW-SDK
サービス・ゲートウェイ・プラットフォ-ムの開発キット
-
シナリオSDK
シナリオとは、PaPeRo-i上で動くアプリケーションのことで、 この開発キットを示す。
シナリオSDK
-
プリインシナリオ
サービス・ゲートウェイ・プラットフォ-ムの略称
-
アドオンシナリオ
アドオンシナリオ
利用(exploitation)と探索(exploration)のトレードオフの問題
WebSocketの概要
ソフィアプランニング社製の「PaPeRo-i用Pythonライブラリ」はWebSocketを使用します。
WebSocketの概要
WebSocketクライアントのログ
F:\python>python client.py ①ソケットをオープンする ②HTTP_GETを送信する ③HTTP_GET送信の応答を受信する 応答データ: HTTP/1.1 200 OK Server: TornadoServer/4.4.2 Date: Sat, 03 Dec 2016 00:59:37 GMT Content-Length: 310 Etag: "a12b5d690568e7c19a353c519f1cf447a40c9e5f" Content-Type: text/html; charset=UTF-8 <html> <head> <title>試験</title> <script language="javascript"> var ws = new WebSocket("ws://192.168.1.100:8080/ws"); ws.onopen = function() { ws.send("Hello, world"); }; ws.onmessage = function (evt) { document.write("<strong>" + evt.data + "</strong>"); }; </script> </head> <body> 試験 </body> </html> ④ヘッダーを送信する: GET /ws HTTP/1.1 Host: my.domain.com Sec-WebSocket-Version: 13 Connection: Upgrade Upgrade: websocket Sec-WebSocket-Key: 7soMwO46A89KLFBW0SSQlA== ⑤ヘッダー送信の応答を受信する: HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: /xIklbZumCegy38ALvQgxRwKWfI= ⑥Helloメッセージを送信する ⑦ソケットをクローズする F:\python>
WebSocketサーバ(server.py)
import tornado.ioloop import tornado.web import tornado.websocket from tornado import options class MainHandler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): print("MainHandler GET") self.render("index.html") class SubHandler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): print("SunHandler GET") self.render("favicon.ico") class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): print("open websocket connection") def on_message(self, message): print(message) self.write_message("Thank you!") def on_close(self): print("close websocket connection") app = tornado.web.Application([ (r"/", MainHandler), (r"/favicon.ico", SubHandler), (r"/ws", WebSocketHandler), ]) if __name__ == "__main__": options.parse_command_line() app.listen(8080) tornado.ioloop.IOLoop.instance().start()
WebSocketクライアント(client.py)
import time import os import base64 import socket import struct import array def make_ws_data_frame(data): FIN = 0x80 RSV1 = 0x0 RSV2 = 0x0 RSV3 = 0x0 OPCODE = 0x1 MASK = 0x80 payload = 0x0 frame = struct.pack('B', FIN | RSV1 | RSV2 | OPCODE) data_len = len(data) if data_len <= 125: payload = struct.pack('B', MASK | data_len) elif data_len < 0xFFFF: payload = struct.pack('!BH', 126 | MASK, data_len) else: payload = struct.pack('!BQ', 127 | MASK, data_len) frame += payload masking_key = os.urandom(4) mask_array = array.array('B', masking_key) unmask_data = array.array('B', data.encode('UTF-8')) for i in range(data_len): unmask_data[i] = unmask_data[i] ^ masking_key[i % 4] mask_data = unmask_data.tobytes() frame += masking_key frame += mask_data return [frame, len(frame)] HTTP_GET = """GET / HTTP/1.1\r Connection: Keep-Alive\r \r\n""" ws_upgrade_header = { 'Upgrade' : 'websocket', 'Connection' : 'Upgrade', 'Sec-WebSocket-Key' : base64.b64encode(os.urandom(16)).decode('UTF-8'), 'Sec-WebSocket-Version' : '13', } #sock = socket.create_connection(['127.0.0.1', 8080]) print("①ソケットをオープンする") sock = socket.create_connection(['192.168.1.7', 8080]) print("②HTTP_GETを送信する") sock.send(HTTP_GET.encode('UTF-8')) recv_buf = "" print("③HTTP_GET送信の応答を受信する") recv_buf = sock.recv(4096) print("応答データ:\n" + recv_buf.decode('UTF-8')) headers = "GET /ws HTTP/1.1\r\nHost: my.domain.com\r\n" for key in ws_upgrade_header: headers += key + ": " + ws_upgrade_header[key] + "\r\n" headers += "\r\n" print("④ヘッダーを送信する:\n" + headers) sock.send(headers.encode('UTF-8')) time.sleep(1) recv_buf = sock.recv(4096) print("⑤ヘッダー送信の応答を受信する:" + recv_buf.decode('UTF-8')) time.sleep(1) message, message_len = make_ws_data_frame('Hello') print("⑥Helloメッセージを送信する") sock.send(message) print("⑦ソケットをクローズする") sock.close()
Pythonライブラリ(ソフィアプランニング社製)
ソフィアプランニング社製の「PaPeRo-i用Pythonライブラリ」を使用してPaPeRo-iを制御しよう。
使い方の概要
1、pypaperoモジュールをインポートします。
import pypapero
※通信ログ出力について
2016/06/15公開版以降のpypapero.pyでは、デフォルトでは通信ログを出力しない設定となっています。
通信ログが必要な場合は、スクリプトの先頭で
from logging import basicConfig, DEBUG basicConfig(level=DEBUG)
とします。
2、Paperoオブジェクトを生成します。
papero = pypapero.Papero(simulator_id, robot_name, ws_server_addr)
引数の意味は以下のとおりです。
- simulator_id:シミュレータID(文字列)→””にすると、スクリプトと同一のPCで動作するシミュレータを指定した事になります。
- robot_name:ロボット名(文字列)→””にすると、シミュレータ上のデフォルトのロボットを指定した事になります。
- ws_server_addr:WebSocketサーバアドレス(文字列)→””にすると、デフォルトのWebScketサーバを指定した事になります。実機のPaPeRoを制御する場合は、ここにPaPeRoのWebSocketサーバアドレスを指定します。
Paperoオブジェクトの生成中に通信エラーが発生した場合、papero.errOccurredに0以外の値が入り、papero.errDetailにエラーの詳細を示す文字列が格納されます。
※get_params_from_commandline関数を用いる事により、上記 simulator_id, robot_name, ws_server_addr の値をコマンドライン引数から抽出する事ができます。
使用例:
simulator_id, robot_name, ws_server_addr = pypapero.get_params_from_commandline(sys.argv) papero = pypapero.Papero(simulator_id, robot_name, ws_server_addr)
3、paperoのメンバ関数を用いてPaPeRoを制御する為のコマンドを送信します。
また、PaPeRoからのメッセージの受信を行い、受信メッセージの内容に応じた処理を行います。
変数paperoにPaperoオブジェクトが入っていると仮定した場合、メッセージの受信は以下のようにして行います。
messages = papero.papero_robot_message_recv(recvWait)
- 引数recvWaitには、タイムアウトの秒数を与えます。
- recvWait秒以内にメッセージが受信できない場合、戻り値(上の例ではmessages)はNoneとなります。
- 受信中に通信エラーが発生した場合は、戻り値がNoneとなり、papero.errOccurredに0以外の値が入り、papero.errDetailにエラーの詳細を示す文字列が格納されます。
- messagesがNoneでない場合、messagesには受信メッセージの配列が格納されております。
- 配列は、現在0番目の要素のみ有効です。
- メッセージは辞書形式となっており、messages[0][“Name”]でメッセージの名前を参照できます。
- 名前以外に含まれる情報は、メッセージにより異なります。
※メッセージによっては、パラメータの値が”X,Y”の形式で格納される場合があります。
その場合、get_numstr_list_from_coord関数を用いる事により、XYそれぞれの値を取り出す事ができます。
例:
pos_str = “123,456” pos = pypapero.get_numstr_list_from_coord(pos_str) pos_x = int(pos[0]) pos_y = int(pos[1])
※モーターの動作コマンドmoveHeadの動作完了はmoveFinishイベントで、 LED点灯動作コマンドturnLedOnの動作完了はearFinish、foreheadFinish、cheekFinish、mouthFinish 、chestFinishイベントで知る事ができます。
発話コマンド(startSpeech)については、完了時に送られるイベントがありませんので、 発話が完了したかどうかを確認するにはgetSpeechStatusコマンドを使用する必要があります。
※時間を計測する必要がある場合、NTPによる自動時刻合わせの影響を回避する為、time.time()ではなくtime.monotonic()の使用を推奨します。
4、Paperoオブジェクトの使用を終了する時は、papero.papero_cleanup()を呼び出します。
papero.papero_cleanup()
「PaPeRo i 制御用WebSocket通信アドオンシナリオ」をダウンロード
「PaPeRo i 制御用WebSocket通信アドオンシナリオ」をダウンロード
- PaPeRo i でPythonを使えるようにするから、 「PaPeRo i 制御用WebSocket通信アドオンシナリオ」をダウンロードします。
- sce_websocket_v0_0_2.tar.gzと言うファイルをダウンドードします。
- sce_websocket_v0_0_2.tar.gzを解凍すると「sce_00010012.so.1.0.0」と言うファイルが生成されます。
「sce_00010012.so.1.0.0」と言うファイルをPaPeRo-iにコピーしてアドオンシナリオとして登録します。
- WinSCPなどで、「sce_00010012.so.1.0.0」と言うファイルを「PaPeRo-i」の/tmpディレクトリにコピーします。
-
TeraTermなどで、PaPeRo-iにログインします。
ユーザID:cli
パスワード:1234 - ログイン後に、su コマンドでルートユーザ になります。
-
以下のコマンドで、アドオンシナリオをインストールします。
# chmod +x /tmp/sce_00010012.so.1.0.0 # mv /tmp/sce_00010012.so.1.0.0 /Extension/robot_platform/lib/addon # cd /Extension/robot_platform/lib/addon # ln -s sce_00010012.so.1.0.0 sce_00010012.so
-
以下のコマンドで、/Extension/robot_platform/conf/sysmgr.confを以下のように修正します。
00010012,00000001
Paperoコマンド送信関数・レスポンス・イベント相互関係早見表
モーター関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
moveHead | 首振りを行う | send_move_head | moveHeadRes | moveFinish moveError |
stopHead | 実行中の首振りを停止する | send_stop_head | stopHeadRes | |
resetHead | 原点(正面位置)の補正を行う | send_reset_head | resetHeadRes | |
getHeadStatus | 首振りの動作中/停止中の状態を取得する | send_get_head_status | getHeadStatusRes |
LED関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
turnLedOn | LEDの点灯動作を行う | send_turn_led_on | turnLedOnRes | earFinish foreheadFinish cheekFinish mouthFinish chestFinish |
turnLedOff | LEDを消灯させる | send_turn_led_off | turnLedOffRes | |
setDefaultStatus | 輝度のデフォルト値を設定する | send_set_default_status_led | setDefaultStatusRes | |
getDefaultStatus | 輝度のデフォルト値を取得する | send_get_default_status_led | getDefaultStatusRes | |
getLedStatus | LED点灯動作の実行中/停止中の状態を取得する | send_get_led_status | getLedStatusRes |
音声合成関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
startSpeech | 音声合成による発話を開始する | send_start_speech | startSpeechRes | |
pauseSpeech | 実行中の発話を一時停止する | send_pause_speech | pauseSpeechRes | |
resumeSpeech | 一時停止させた発話を再開する | send_resume_speech | resumeSpeechRes | |
stopSpeech | 実行中の発話を終了する | send_stop_speech | stopSpeechRes | |
getSpeechStatus | 発話中/停止中の状態を取得する | send_get_speech_status | getSpeechStatusRes | |
setDefaultStatus | 音量、発話速度などのデフォルト値を設定する | send_set_default_status_speech | setDefaultStatusRes | |
getDefaultStatus | 音量、発話速度などのデフォルト値を取得する | send_get_default_status_speech | getDefaultStatusRes |
センサー関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
detectObjectIR detectButton detectHeadButton detectStepOut |
||||
getSensorValue | センサー値を取得する | send_get_sensor_value | getSensorValueRes | |
startAccSensor | 加速度センサによる計測を開始する | send_start_acc_sensor | startAccSensorRes | detectAccYaw |
stopAccSensor | 加速度センサによる計測を停止する | send_stop_acc_sensor | stopAccSensorRes | |
setAccSensor | 加速度センサを設定する | send_set_acc_sensor | setAccSensorRes | |
getAccSensorState | 加速度センサの状態を取得する | send_get_acc_sensor_state | getAccSensorStateRes | |
setAccSensorThreshold | 加速度センサ閾値を設定する | send_set_acc_sensor_threshold | setAccSensorThresholdRes | |
startLumSensor | 照度センサによる測定を開始する | send_start_lum_sensor | startLumSensorRes | |
stopLumSensor | 照度センサによるを測定を停止する | send_stop_lum_sensor | stopLumSensorRes | |
getLumSensorValue | 照度センサの測定値を読み出す | send_get_lum_sensor_value | getLumSensorValueRes | |
getLumSensorState | 照度センサの状態を取得する | send_get_lum_sensor_state | getLumSensorStateRes | |
cancelCommand | 未処理のコマンドをキャンセルする | send_cancel_command | cancelCommandRes |
音声認識関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
startSpeechRecognition | 音声認識を開始する | send_start_speech_recognition | startSpeechRecognitionRes | detectPhrase |
stopSpeechRecognition | 実行中の音声認識を終了する | send_stop_speech_recognition | stopSpeechRecognitionRes | |
getSpeechRecognitionStatus | 認識状態を取得する | send_get_speech_recognition_status | getSpeechRecognitionStatusRes | |
readDictionary | 音声認識辞書ファイルを読み込む | send_read_dictionary | readDictionaryRes | |
freeDictionary | 読み込んだ音声認識辞書を解放する | send_free_dictionary | freeDictionaryRes | |
addSpeechRecognitionRule | 音声認識開始時に使用する認識ルールを登録する | send_add_speech_recognition_rule | addSpeechRecognitionRuleRes | |
deleteSpeechRecognitionRule | 認識ルールを削除する | send_delete_speech_recognition_rule | deleteSpeechRecognitionRuleRes |
カメラ関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
takePicture | 静止画を撮影する | send_take_picture | takePictureRes | capturingError |
deleteCaptureData | 静止画データを削除する | send_delete_capture_data | deleteCaptureDataRes | |
startCapturing | 画像キャプチャを開始する | send_start_capturing | startCapturingRes | |
stopCapturing | 画像キャプチャを終了する | send_stop_capturing | stopCapturingRes | |
getCaptureData | 最新のキャプチャデータ(サイズ)を取得する | send_get_capture_data | getCaptureDataRes | |
setCameraStatus | カメラプロパティを設定する | send_set_camera_status | setCameraStatusRes | |
getCameraStatus | カメラプロパティを取得する | send_get_camera_status | getCameraStatusRes | |
getOneShotCaptureData | ワンショットキャプチャデータ取得 | send_get_one_shot_capture_data | getOneShotCaptureDataRes |
顔検出関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
startFaceDetection | 顔検出を開始する | send_start_face_detection | startFaceDetectionRes | detectFace undetectFace |
stopFaceDetection | 実行中の顔検出を終了する | send_stop_face_detection | stopFaceDetectionRes |
録音関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
startRecording | 録音を開始する | send_start_recording | startRecordingRes | |
stopRecording | 録音を終了する | send_stop_recording | stopRecordingRes | |
deleteRecordingData | 録音ファイルを削除する | send_delete_recording_data | deleteRecordingDataRes | |
getRecordingStatus | 録音状態を取得する | send_get_recording_status | getRecordingStatusRes | |
setDefaultStatus | 録音パラメータのデフォルト値を設定する | send_set_default_status_wavrec | setDefaultStatusRes | |
getDefaultStatus | 録音パラメータのデフォルト値を取得する | send_get_default_status_wavrec | getDefaultStatusRes |
再生関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
startPlaying | 再生を開始する | send_start_playing | startPlayingRes | |
stopPlaying | 再生を終了する | send_stop_playing | stopPlayingRes | |
deleteWaveData | 音声ファイルを削除する | send_delete_wave_data | deleteRecordingDataRes | |
getPlayingStatus | 再生状態を取得する | send_get_playing_status | getPlayingStatusRes | |
setDefaultStatus | 再生パラメータのデフォルト値を設定する | send_set_default_status_wavplay | setDefaultStatusRes | |
getDefaultStatus | 再生パラメータのデフォルト値を取得する | send_get_default_status_wavplay | getDefaultStatusRes |
汎用モーション関連
コマンド | 意味 | 送信関数 | レスポンス | 関連イベント |
startMotion | 汎用モーションを開始する | send_start_motion | startPlayingRes | |
stopMotion | 汎用モーションを停止する | send_stop_motion | stopMotionRes |
コマンド送信関数
モーター関連
送信関数呼び出し形式: papero.send_move_head(vertical, horizontal, repeat, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 縦移動パラメータと横移動パラメータは、”[位置指定][数値1][移動方法][数値2][加速度]”の書式の文字列をシーケンス数分リストに入れて指定します。
例:[“R120S15L”, “A60T200L”, …] 応答として、moveHeadResレスポンスを返信します。 |
||||||||||
送信関数呼び出し形式: papero.send_stop_head(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopHeadResを返信します。 |
||||||||||
送信関数呼び出し形式: papero.send_reset_head(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、resetHeadResレスポンスを返信します。 |
||||||||||
送信関数呼び出し形式: papero.send_get_head_status(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getHeadStatusResレスポンスを返信し、戻り値(Return)に0(停止中)、または1(動作中)のい ずれか、縦(Vertical)及び横(Horizontal)に頭の位置情報を格納します。 |
LED関連
送信関数呼び出し形式: papero.send_turn_led_on(part, pattern, repeat, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 パラメータとしては、以下に示す書式の文字列と時間(デシ秒単位)をシーケンス数分リストに入れて指定します。 part=”ear”の場合のpattern
例:[“W0W0”, “5”, “NN”, “5”, “W1W3”, “5”, …] part=”forehead”の場合のpattern
例:[“R0”, “5”, “N”, “10”, “Y1”, “5”, …] part=”cheek”の場合のpattern
例:[“R0R0”, “5”, “NN”, “5”, “R1R3”, “5”, …] part=”mouth”の場合のpattern
例:[“NG0Y0Y0R1G2Y3Y1R2”, “5”, “Y0Y1NNR1Y1Y1NN”, “5”, “G1R2Y1Y3G2G1R1Y2Y3”, “5”, …] part=”chest”の場合のpattern
例:[“R2”, “5”, “RGW0”, 5, “N”, “5”, …] 応答として、turnLedOnResレスポンスを返信します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_turn_led_off(part, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、turnLedOffResレスポンスを返信します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_set_default_status_led(status, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、setDefaultStatusResレスポンスを返信します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_get_default_status_led(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getDefaultStatusResレスポンスを返信し、戻り値(Return)にデフォルトの輝度を格納します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_get_led_status(part, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getLedStatusResレスポンスを返信し、戻り値(Return)に0(停止中)、または1(実行中)のいずれかを格納します。 |
音声合成関連
送信関数呼び出し形式: (pypapero.py Ver.1.00~) papero.send_start_speech(text, language, speaker_id, pitch, speed, volume, pause, comma_pause, urgent, priority) (pypapero.py ~2016/08/02公開版(β版)) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、startSpeechResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_pause_speech(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、pauseSpeechResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_resume_speech(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、resumeSpeechResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_stop_speech(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopSpeechResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_get_speech_status(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getSpeechStatusResレスポンスを返信し、戻り値(Return)に0(停止中)、1(発話中)、2(一時停止中)のいずれかがを格納します。 |
送信関数呼び出し形式: papero.send_set_default_status_speech(tempo, language, speaker_id, pitch, speed, volume, pause, comma_pause, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、setDefaultStatusResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_get_default_status_speech(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getDefaultStatusResレスポンスを返信し、tempoにグローバルなテンポを格納します。 |
センサー関連
送信関数呼び出し形式: papero.send_get_sensor_value(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getSensorValueResレスポンスを返信し、IRに赤外線センサ自体の温度と素子の値①~④、位置情報をコンマ区切りで格納し、TEM・HYG・LUXに温度・湿度・照度の値を格納します。
センサ素子の測定データと温度は以下のような関係となっています。
例1:内蔵温度 26.75℃、左で反応した場合、getSensorValueResレスポンスのIRの値は”0, -31, 32767, 32, -2294, Left”となります。 |
|||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_start_acc_sensor(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、startAccSensorResレスポンスを返信します。 |
|||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_stop_acc_sensor(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopAccSensorResレスポンスを返信します。 |
|||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_set_acc_sensor(mem_size, full_scale, data_rate, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 各引数の詳細は以下のとおりです。
|
応答として、setAccSensorResレスポンスを返信します。
エラーの場合は、戻り値(ret)に負の値を格納します。
送信関数呼び出し形式:
papero.send_get_acc_sensor_state(priority)
papero:Paperoオブジェクト
priority:優先度(“higher”又は”normal”)、省略時は”normal”
戻り値:メッセージID
説明
加速度センサの状態を取得します。
応答として、getAccSensorStateResレスポンスを返信し、戻り値(Return)に0(停止中)又は1(動作中)のいずれかを格納します。
エラーの場合は、戻り値(ret)に負の値を格納します。
送信関数呼び出し形式:
papero.send_set_acc_sensor_threshold(det_value, los_value, frequency, arg_time, priority)
papero:Paperoオブジェクト
det_value:揺れ開始閾値
los_value:揺れ終了閾値
frequency:揺れ開始閾値を超える回数
arg_time:揺れ終了閾値が連続して閾値を下回る期間
priority:優先度(“higher”又は”normal”)、省略時は”normal”
戻り値:メッセージID
説明
加速度センサ閾値を設定します。
各引の詳細は以下のとおりです。
det_value |
揺れ開始閾値(mg : ミリジー) XYZ 軸加速度閾値 √(X^2 + Y^2 + Z^2) 最小値 : 1 最大値 : 41569 (XYZ 軸全計測値 Max 24000mg の場合) Default : 1100 |
los_value |
揺れ終了閾値(mg : ミリジー) XYZ 軸加速度閾値 √(X^2 + Y^2 + Z^2) 最小値 : 1 最大値 : 41569 (XYZ 軸全計測値 Max 24000mg の場合) Default : 1030 |
frequency |
揺れ開始閾値を超える回数(回) 最小値 : 1 最大値 : 65535 Default : 10 |
arg_time |
揺れ終了閾値が連続して閾値を下回る期間(秒) 最小値 : 1 最大値 : 65535 (約 18 時間) Default : 3 |
応答として、setAccSensorThresholdResレスポンスを返信します。
エラーの場合は、戻り値(ret)に負の値を格納します。
送信関数呼び出し形式:
papero.send_start_lum_sensor(priority)
papero:Paperoオブジェクト
priority:優先度(“higher”又は”normal”)、省略時は”normal”
戻り値:メッセージID
説明
照度センサによる計測を開始します。
応答として、startLumSensorResレスポンスを返信します。
エラーの場合は、戻り値(ret)に負の値を格納します。
送信関数呼び出し形式:
papero.send_stop_lum_sensor(priority)
papero:Paperoオブジェクト
priority:優先度(“higher”又は”normal”)、省略時は”normal”
戻り値:メッセージID
説明
照度センサによる計測を停止します。
応答として、stopLumSensorResレスポンスを返信します。
エラーの場合は、戻り値(ret)に負の値を格納します。
送信関数呼び出し形式:
papero.send_get_lum_sensor_value(priority)
papero:Paperoオブジェクト
priority:優先度(“higher”又は”normal”)、省略時は”normal”
戻り値:メッセージID
説明
照度センサの測定値を読み出します。
応答として、getLumSensorValueResレスポンスを返信し、戻り値(Return)に照度データ値を格納します。
エラーの場合は、戻り値(ret)に負の値を格納します。
送信関数呼び出し形式:
papero.send_get_lum_sensor_state(priority)
papero:Paperoオブジェクト
priority:優先度(“higher”又は”normal”)、省略時は”normal”
戻り値:メッセージID
説明
照度センサの状態を取得します。
応答として、getLumSensorStateResレスポンスを返信し、戻り値(Return)に0(停止中)又は1(動作中)のいずれかを格納します。
送信関数呼び出し形式:
papero.send_cancel_command(priority, target_id)
papero:Paperoオブジェクト
priority:優先度(“higher”又は”normal”)、省略時は”normal”
戻り値:メッセージID
説明
未処理のコマンドをキャンセルします。
応答として、cancelCommandResレスポンスを返信します。
エラーの場合は、戻り値(ret)に負の値を格納します。
音声認識関連
送信関数呼び出し形式: papero.send_start_speech_recognition(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、startSpeechRecognitionResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_stop_speech_recognition(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopSpeechRecognitionResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_get_speech_recognition_status(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getSpeechRecognitionStatusResレスポンスを返信し、戻り値(Return)に0(認識をしていない状態)、1(認識をを開始し発話を待っている状態)、2(発話を検知し認識動作中)のいずれかを格納します。 |
送信関数呼び出し形式: papero.send_read_dictionary(mrg_file_name, priority) papero:Paperoオブジェクト 説明 応答として、readDictionaryResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_free_dictionary(mrg_file_name, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、freeDictionaryResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_add_speech_recognition_rule(rule_name, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、addSpeechRecognitionRuleResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_delete_speech_recognition_rule(rule_name, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、deleteSpeechRecognitionRuleResレスポンスを返信します。 |
カメラ関連
送信関数呼び出し形式: papero.send_take_picture(format, filename, camera, priority) papero:Paperoオブジェクト format:”RGB”/”JPEG” filename:ファイル名、省略可 camera:”VGA”/”SXGA”、省略可 priority:優先度(“higher”又は”normal”)、省略時は”normal” 戻り値:メッセージID 説明 応答として、takePictureResレスポンスを返信し、CaptureDataSizeに出力したバイト数を、Filenameに出力したファイル名(フルパス)を格納します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_delete_capture_data(filename, priority) filename:ファイル名 戻り値:メッセージID 説明 応答として、deleteCaptureDataResレスポンスを返信します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_start_capturing(share_mem_id, share_mem_size, camera, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、startCapturingResレスポンスが返信します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_stop_capturing(share_mem_id, camera, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopCapturingResレスポンスを返信します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_get_capture_data(share_mem_id, camera, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getCaptureDataResレスポンスを返信し、CaptureDataSizeにキャプチャデータのサイズ(バイト)を格納します。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_set_camera_status(self, brightness, contrast, hue, saturation, sharpness, gamma, white_balance, auto_white_balance, iris, camera, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明
省略したパラメータについては変更されません。 応答として、setCameraStatusResレスポンスを返信します。その際、変更されたパラメータの設定前の値を共通レスポンスに追加します。追加する項目名は、上記の表の項目名となります。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_get_camera_status(object, camera, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getCameraStatusResレスポンスを返信します。その際、指定された項目を共通レスポンスに追加します。追加する項目名は、setCameraStatusの説明の表の項目名となります。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_get_one_shot_capture_data(share_mem_id, share_mem_size, camera, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getOneShotCaptureDataResレスポンスを返信し、CaptureDataSizeにキャプチャデータのサイズ(バイト)を格納します。 |
顔検出関連
送信関数呼び出し形式: papero.send_start_face_detection(min_eye_distance, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、startFaceDetectionResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_stop_face_detection(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopFaceDetectionResレスポンスを返信します。 |
録音関連
送信関数呼び出し形式: papero.send_start_recording(filename, bitlength, bitrate, channel, recordingtime, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、startRecordingResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_stop_recording(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopRecordingResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_delete_recording_data(filename, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、deleteRecordingDataResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_get_recording_status(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getRecordingStatusResレスポンスを返信し、戻り値(Return)に0(アイドル)又は1(録音中)を格納します。 |
送信関数呼び出し形式: papero.send_set_default_status_wavrec(bitrate, channel, bitlength, recordingtime, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、setDefaultStatusResレスポンスを返信し、変更されたパラメータの設定前の値を共通レスポンスに追加します。 |
送信関数呼び出し形式: papero.send_get_default_status_wavrec(object, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getDefaultStatusResレスポンスを返信します。その際、指定された項目を共通レスポンスに追加します。 |
再生関連
送信関数呼び出し形式: papero.send_start_playing(filename, volume, category, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 |
送信関数呼び出し形式: papero.send_stop_playing(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、stopPlayingResレスポンスを返信します。 |
送信関数呼び出し形式: papero.send_delete_wave_data(filename, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 |
送信関数呼び出し形式: papero.send_get_playing_status(priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getPlayingStatusResレスポンスを返信し、戻り値(Return)に0(アイドル)又は1(録音中)を格納します。 |
送信関数呼び出し形式: papero.send_set_default_status_wavplay(volume, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、setDefaultStatusResレスポンスを返信し、変更されたパラメータの設定前の値を共通レスポンスに追加します。 |
送信関数呼び出し形式: papero.send_get_default_status_wavplay(object, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 応答として、getDefaultStatusResレスポンスを返信します。その際、指定された項目を共通レスポンスに追加します。 |
汎用モーション関連
送信関数呼び出し形式: papero.send_start_motion(self, motion_id, sound, text, priority) papero:Paperoオブジェクト 戻り値:メッセージID 汎用モーション一覧
説明 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
送信関数呼び出し形式: papero.send_stop_motion(self, priority) papero:Paperoオブジェクト 戻り値:メッセージID 説明 |
レスポンス
共通項目
項目名 | 値 |
Name | レスポンス名称を指定するための文字列。レスポンス毎に異なる。 |
Type | “Response” |
Destination | “Script” |
Source | “MotorController”(モーター関連)、”LEDController”(LED関連)、”SpeechSynthesizer”(音声合成関連)、”SensorController”(センサー関連)、”SpeechRecognizer”(音声認識関連)、”CameraController”(カメラ関連)、”FaceDetection”(顔検出関連)のいずれか |
Time | レスポンスの送信時刻を示す文字列。 フォーマットは YYYY-MM-DD hh:mm:ssとし、タイムゾーンは端末に従う。 例) Time=2012-03-05 13:00:00 |
MessageID | PaPeRoが生成するメッセージID |
OrgMessageID | 対応するコマンドに含まれていたメッセージID |
Return | 戻り値(0) |
rtn | エラー時の戻り値(負の値)(正常時は、この項目は省略される) |
モーター関連
moveHeadRes
|
LED関連
turnLedOnRes
|
音声合成関連
startSpeechRes
|
センサー関連
getSensorValueRes
cancelCommandRes
|
音声認識関連
startSpeechRecognitionRes
deleteSpeechRecognitionRuleRes
|
カメラ関連
takePictureRes
|
顔検出関連
startFaceDetectionRes
|
録音関連
startRecordingRes
|
再生関連
startPlayingRes
|
汎用モーション関連
startMotionRes
|
イベント
共通項目
項目名 | 値 |
Name | レスポンス名称を指定するための文字列。レスポンス毎に異なる。 |
Type | “Response” |
Destination | “Script” |
Source | “MotorController”(モーター関連)、”LEDController”(LED関連)、”SensorController”(センサー関連)、”SpeechRecognizer”(音声認識関連)、”CameraController”(カメラ関連)、”FaceDetection”(顔検出関連)のいずれか |
Time | レスポンスの送信時刻を示す文字列。 フォーマットは YYYY-MM-DD hh:mm:ssとし、タイムゾーンは端末に従う。 例) Time=2012-03-05 13:00:00 |
Expiration | イベントの有効期間(秒)を示す数値文字列 |
Priority | イベントに対する優先度を示す文字列。”higher”又は”normal” |
モーター関連
moveFinish (首振り動作(moveHead)が正常に終了した事を通知する)
moveError
|
LED関連
earFinish (耳 LED点灯動作が正常に終了したことを通知する)
foreheadFinish
cheekFinish
mouthFinish
chestFinish
|
センサー関連
detectObjectIR (赤外線センサで熱源物体を見つけたことを通知する)
detectButton
detectHeadButton
detectStepOut
detectAccYaw
|
音声認識関連
detectPhrase (認識結果が得られたことおよび、認識結果を通知する)
|
カメラ関連
capturingError (エラーの発生を通知する)
|
顔検出関連
detectFace (顔を検出したことを通知する。連続検出している場合は、1度だけ発行する。)
undetectFace
|
Pythonライブラリを使用したアプリケーション例(工事中)
音声の出力
papero_test_3.py
音声の出力を4つのテキストに分けて行います。
# -*- coding:utf-8 -*- import sys import time from enum import Enum import pypapero class State(Enum): st0 = 10 st1 = 11 st2 = 12 st3 = 13 st4 = 14 st5 = 15 end = 999 def main(papero, speech_words): state = State.st0 last_time = time.monotonic() past_time = 0 speech_idx = 0 left_right=0 while state != State.end: messages = papero.papero_robot_message_recv(1.0) now_time = time.monotonic() delta_time = now_time - last_time last_time = now_time if messages is not None: msg_dic_rcv = messages[0] else: msg_dic_rcv = None if papero.errOccurred != 0: print("------Error occured(main()). Detail : " + papero.errDetail) break # 連続発話 if state == State.st0: papero.send_turn_led_on("mouth", ["G3G3G3G3G3G3G3G3G3", "2", "NNG3G3G3G3G3NN", "2", "NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2"], repeat=True) state = State.st1 elif state == State.st1: if(left_right==0): papero.send_move_head(["A0S120L"],["A50S120L"]) else: papero.send_move_head(["A0S120L"],["A-50S120L"]) left_right = 1-left_right; papero.send_start_speech(speech_words[speech_idx]) print("会話 id = " + str(speech_idx)) speech_idx += 1 if speech_idx >= len(speech_words): speech_idx = 0 past_time = 0 state = State.st2 elif state == State.st2: past_time += delta_time if past_time >= 1.0: papero.send_get_speech_status() state = State.st3 elif state == State.st3: if msg_dic_rcv is not None: if msg_dic_rcv["Name"] == "getSpeechStatusRes": if str(msg_dic_rcv["Return"]) == "0": if speech_idx == 0: state = State.st4 else: state = State.st1 else: past_time = 0 state = State.st2 elif state == State.st4: papero.send_move_head(["A0T500L", "A-15T500L", "R0T1000L", "A0T500L"], ["A0T500L", "R0T2000L"]) papero.send_start_speech("どうも、ありがとうございました。") state = State.st5 elif state == State.st5: if msg_dic_rcv is not None: if msg_dic_rcv["Name"] == "moveFinish": papero.send_turn_led_off("mouth") state = State.end # ボタンの監視 if msg_dic_rcv is not None: if msg_dic_rcv is not None: if msg_dic_rcv["Name"] == "detectButton": state = State.st4 print("ボタン押下 ボタン = " + msg_dic_rcv["Name"]) if __name__ == "__main__": simulator_id, robot_name, ws_server_addr = pypapero.get_params_from_commandline(sys.argv) papero = pypapero.Papero(simulator_id, robot_name, "ws://192.168.2.1:8088/papero") speech_words = ["こんにちわ。ヨシコ様。ようこそ、いらっしゃいました。いつもお美しいですね。", "今日は東京電機大学の大学祭の旭さいの日です。ゆっくり、ご覧ください。", "この後、北千住の街をご案内しますが、今日は、居酒屋の大橋がお休みです。", "別の、お店にご案内します。"] if papero.errOccurred == 0: main(papero, speech_words) papero.papero_cleanup()
タブレット(Android)からRaspberryPIを制御する
まず、RaspberryPIにWebサーバアプリを構築します。
以下の例では、「Flask」ライブラリを使用してWebサーバアプリを構築しています。
タブレット(Android)からは、以下の例のようなURLでRaspberryPIを制御します。
「http://192.168.1.102:5000/papero/speech?string1=こんにちわ。ヨシコ様。ようこそ、いらっしゃいました。いつもお美しいですね。&string2=今日は東京電機大学の大学祭の旭さいの日です。ゆっくり、ご覧ください。&string3=この後、北千住の街をご案内しますが、16時にお迎えの車が来ます。&string4=まずは、居酒屋の大橋にご案内します。」
server.py
# server.py from flask import Flask from flask import request import netifaces import json import app_05_db from package_parts.parts import Led import sys import time from enum import Enum import pypapero import threading import papero_test_3 # -- 定数宣言 -- # LED_PINS = [4] # LEDのGPIO番号 LED_PINS1 = [5] # LED1のGPIO番号 2016/9/22 LED_PINS2 = [6] # LED12のGPIO番号 2016/9/22 BUTTON_PINS = [13] # ボタンのGPIO番号 BUTTON_PINS1 = [16] # ボタン1のGPIO番号 2016/9/22 BUTTON_PINS2 = [19] # ボタン2のGPIO番号 2016/9/22 GPIO_HIGH = 1 GPIO_LOW = 0 # PWCのGPIO番号 PWC_PIN = 17 # 2016/9/29 4->17 # -- 初期化、 Flaskアプリの用意 -- # app = Flask(__name__) pwc = Led(PWC_PIN) simulator_id, robot_name, ws_server_addr = pypapero.get_params_from_commandline(sys.argv) papero = pypapero.Papero(simulator_id, robot_name, "ws://192.168.2.1:8088/papero") class SpeechThread(threading.Thread): """docstring for SpeechThread""" def __init__(self, n): super(SpeechThread, self).__init__() self.n = n #self.t = t def run(self): print(" === start sub thread (sub class) === ") papero_test_3.main(papero, self.n) #for i in range(self.n): # time.sleep(self.t) # print("sub thread (sub class) : " + str(datetime.datetime.today())) print(" === end sub thread (sub class) === ") # -- ルーティング -- # @app.route("/papero/speech") def papero_speech(): #"""おしゃべりをする""" # request.argsにクエリパラメータが含まれている string1 = request.args.get("string1", "おはようございます") string2 = request.args.get("string2", "") string3 = request.args.get("string3", "") string4 = request.args.get("string4", "") #papero.send_start_speech(val) #papero_test_3.main(papero) #speech_words = ["こんにちわ。ヨシコ様。ようこそ、いらっしゃいました。いつもお美しいですね。", # "今日は東京電機大学の大学祭の旭さいの日です。ゆっくり、ご覧ください。", # "この後、北千住の街をご案内しますが、16時にお迎えの車が来ます。", # "まずは、居酒屋の大橋にご案内します。"] speech_words = [string1, string2, string3, string4] th_cl = SpeechThread(speech_words) th_cl.start() dict = {'sensor':'speech','string':val} jsonstring = json.dumps(dict) return jsonstring @app.route("/button/status") def button_status(): #"""ボタンの状態を取得""" # request.argsにクエリパラメータが含まれている val = request.args.get("id", "0") running, led_values, button_values = app_05_db.load_app_05_status() status = button_values[int(val)] if not running: status = 0 dict = {'sensor':'button','id':int(val),'status':status} jsonstring = json.dumps(dict) return jsonstring @app.route("/pwc/set") def pwc_set(): #"""ボタンの状態を取得""" # request.argsにクエリパラメータが含まれている val = request.args.get("operation", "0") pwc.set_status(int(val)) # val=0:PWC消灯,val=1:PWC点灯 dict = {'sensor':'pwc','operation':int(val)} jsonstring = json.dumps(dict) return jsonstring ip_address = netifaces.ifaddresses('wlan0')[netifaces.AF_INET][0]['addr'] #ip_address = "192.168.1.104"; if __name__ == "__main__": app.run(ip_address)
森の小径1