PaPeRo i の照度センサーと時間指定での発話を組み合わせた機能がなかったため、実装してみました。
PaPeRo i の照度センサーとは
照度センサーとはPaPeRo i に実装されている機能の一つで、周りの明るさを自動的に検知します。
検知した明るさの度合いによって発話内容を変化させることが可能です。
使用するハード
・PaPeRo i 実機、またはPaPeRo i シミュレーター
使用するソフト
・Windows 10
・テキストエディタ(Visual Studio Code)
・Google Chrome
・Python 3.7
1・下記のソースをコピーし、night.pyという名前でファイルを保存する。
2・papero.pyと同じフォルダにnight.pyを移動させる。
# -*- coding:utf-8 -*-
##############################################################
# 照度センサーを使った時間指定発話
# Copyright (c) 2016 Sophia Planning Inc. All Rights Reserved
# ライセンス:MIT
##############################################################
#from logging import basicConfig, DEBUG
#basicConfig(level=DEBUG)
import sys
import time
import datetime
from enum import Enum
import pypapero
class State(Enum):
st0 = 10
st1 = 11
st2 = 12
st3 = 13
st4 = 14
st5 = 15
st6 = 16
st7 = 17
st8 = 18
st9 = 19
st10 = 20
end = 999
class SpeechManager:
def __init__(self):
self.past_time = 0
self.count_text = 0
self.state = State.end
def start(self, papero, list_pat, motor=False):
self.motor = motor
self.list_pat = list_pat
self.count_text = 0
self.speech_time = len(self.list_pat[self.count_text][0]) * 0.2
if self.motor:
papero.send_move_head(["A5T400L", "A-5T400L", "A5T400L", "A-5T400L",
"A5T400L", "A-5T400L", "A5T400L", "A-5T400L", "A5T400L", "A0T400L"],
["A-9T400L", "A-12T400L", "A-3T400L", "A6T400L",
"A15T400L", "A6T400L", "A-3T400L", "A-12T400L", "A-9T400L", "A0T400L"],
repeat=True)
papero.send_turn_led_on("mouth", self.list_pat[self.count_text][1])
papero.send_turn_led_on("cheek", ["R3R3", "1"], repeat=True)
papero.send_set_default_status_speech(pitch=120, speed=75)
papero.send_start_speech(self.list_pat[self.count_text][0])
self.past_time = 0
self.state = State.st0
def forward(self, papero, msg_dic_rcv, delta_time):
if self.state == State.st0:
self.past_time += delta_time
if self.past_time >= self.speech_time:
self.state = State.st1
elif self.state == State.st1:
papero.send_get_speech_status()
self.past_time = 0
self.state = State.st2
elif self.state == State.st2:
if (msg_dic_rcv is not None) and (msg_dic_rcv["Name"] == "getSpeechStatusRes"):
if str(msg_dic_rcv["Return"]) == "0":
self.count_text += 1
if self.count_text >= len(self.list_pat):
self.state = State.st3
else:
self.speech_time = len(self.list_pat[self.count_text][0]) * 0.2
papero.send_turn_led_on("mouth", self.list_pat[self.count_text][1])
papero.send_start_speech(self.list_pat[self.count_text][0])
self.state = State.st0
if self.state == State.st2:
self.past_time += delta_time
if self.past_time >= 1.0:
self.state = State.st1
elif self.state == State.st3:
papero.send_turn_led_off("cheek")
if self.motor:
papero.send_move_head(["A0T500L"], ["A0T500L"])
self.state = State.st4
else:
papero.send_set_default_status_speech(pitch = 100)
self.state = State.end
elif self.state == State.st4:
if (msg_dic_rcv is not None) and (msg_dic_rcv["Name"] == "moveFinish"):
papero.send_set_default_status_speech(pitch=100, speed=100)
self.state = State.end
class LuxMeasure:
def __init__(self):
self.state = State.st0
self.valid = False
self.value = 0
self.past_time = 0
def forward(self, papero, msg_dic_rcv, delta_time):
if self.state == State.st0:
papero.send_start_lum_sensor()
papero.send_get_lum_sensor_value()
self.past_time = 0
self.state = State.st1
elif self.state == State.st1:
self.past_time += delta_time
if self.past_time >= 3:
self.state = State.st0
if (msg_dic_rcv is not None) and (msg_dic_rcv["Name"] == "getLumSensorValueRes"):
if "Return" in msg_dic_rcv:
self.value = int(msg_dic_rcv["Return"])
self.valid = True
papero.send_stop_lum_sensor()
print("lux = " + str(self.value))
def lengthen_sp_led(list_sp, sec):
i = 0
while i < len(list_sp):
j = 1
while j < len(list_sp[i][1]):
list_sp[i][1][j] = str(sec)
j += 4
i += 1
def main(papero):
state = State.st0
lux_measure = LuxMeasure()
lux_threshold = 100
speech_manager = SpeechManager()
prev_time = time.monotonic()
cnt_wkup = 0
tried = False
sheep_unit = 10
sheep_count = 0
sheep_subcount = 0
must_count = False
now_time = 0
past_time = 0
btn_pushed = False
list_sp_init = [["寝る時間になったよ!",
["NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2", "NNG3G3G3G3G3NN", "2",
"NG3G3G3G3G3G3G3N", "2", "G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2",
"NG3G3G3G3G3G3G3N", "2", "NNNG3G3G3NNN", "3", "G3NG3NG3NG3NG3", "2",
"NG3G3G3G3G3G3G3N", "2", "NG3G3G3G3G3G3G3N", "2", "G3NG3NG3NG3NG3", "2"]],
["今日もお疲れ様!おやすみなさい",
["G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2",
"NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2", "NNNG3G3G3NNN", "2",
"NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2", "NNNG3G3G3NNN", "2",
"NNG3G3G3G3G3NN", "2", "NNNG3G3G3NNN", "2", "NNNG3G3G3NNN", "2",
"G3NG3NG3NG3NG3", "2", "G3NG3NG3NG3NG3", "2", "NG3G3G3G3G3G3G3N", "2",
"NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2", "NNG3G3G3G3G3NN", "2",
"NG3G3G3G3G3G3G3N", "2", "NNG3G3G3G3G3NN", "2", "NNG3NG3NG3NN", "2",
"NNG3NG3NG3NN", "2"]]]
lengthen_sp_led(list_sp_init, 3)
list_sp_init2 = [["眠れないの? 眠れない時は、",
["NNG3G3G3G3G3NN", "2", "NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2",
"NG3G3G3G3G3G3G3N", "2", "G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2",
"NNG3G3G3G3G3NN", "2", "NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2",
"NNG3G3G3G3G3NN", "2", "NNG3NG3NG3NN", "2", "NNG3G3G3G3G3NN", "2",
"NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2", "NG3G3G3G3G3G3G3N", "2",
"G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2"]],
["羊の数をかぞえるといいかもしれないよ!",
["G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2",
"NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2", "NNNG3G3G3NNN", "2",
"NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2", "NNNG3G3G3NNN", "2",
"NNG3G3G3G3G3NN", "2", "NNNG3G3G3NNN", "2", "NNNG3G3G3NNN", "2",
"G3NG3NG3NG3NG3", "2", "G3NG3NG3NG3NG3", "2", "NG3G3G3G3G3G3G3N", "2",
"NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2", "NNG3G3G3G3G3NN", "2",
"NG3G3G3G3G3G3G3N", "2", "NNG3G3G3G3G3NN", "2", "NNG3NG3NG3NN", "2",
"NNG3NG3NG3NN", "2"]]]
lengthen_sp_led(list_sp_init2, 3)
list_sp_init3 = [["まだ眠れないの? それじゃ、",
["NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2", "NG3G3G3G3G3G3G3N", "2",
"G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2",
"NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2", "NNG3G3G3G3G3NN", "2",
"NNNG3G3G3NNN", "2", "NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2",
"G3NG3NG3NG3NG3", "2", "NG3G3G3G3G3G3G3N", "2", "NNG3NG3NG3NN", "2"]],
["電気をけしてくれたら",
["G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2", "NNNG3G3G3NNN", "2",
"NNG3G3G3G3G3NN", "2", "G3NG3NG3NG3NG3", "2", "NNG3G3G3G3G3NN", "2",
"NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2", "NG3G3G3G3G3G3G3N", "2",
"NG3G3G3G3G3G3G3N", "2"]],
["パペロがかわりに羊を数えてあげるね。",
["NG3G3G3G3G3G3G3N", "2", "NNG3G3G3G3G3NN", "2", "NNNG3G3G3NNN", "2",
"NG3G3G3G3G3G3G3N", "2", "NG3G3G3G3G3G3G3N", "2", "NG3G3G3G3G3G3G3N", "2",
"G3NG3NG3NG3NG3", "2", "G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2",
"NNNG3G3G3NNN", "2", "NNG3NG3NG3NN", "2", "NNG3G3G3G3G3NN", "2",
"NNG3G3G3G3G3NN", "2", "NG3G3G3G3G3G3G3N", "2", "NNG3G3G3G3G3NN", "2",
"NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2"]],
["じゅっぴき言い終わるごとにやめるから、続けたい場合は",
["G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2", "NNNG3G3G3NNN", "2",
"G3NG3NG3NG3NG3", "2", "G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2",
"NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2", "NG3G3G3G3G3G3G3N", "2",
"NNG3G3G3G3G3NN", "2", "NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2",
"NG3G3G3G3G3G3G3N", "2", "NNG3NG3NG3NN", "2", "NNNG3G3G3NNN", "2",
"NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2", "NNG3G3G3G3G3NN", "2",
"NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2", "NG3G3G3G3G3G3G3N", "2",
"NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2", "NG3G3G3G3G3G3G3N", "2"]],
["どれか座布団のボタンをおしてね",
["NNNG3G3G3NNN", "2", "NNG3G3G3G3G3NN", "2", "NG3G3G3G3G3G3G3N", "2",
"NNNG3G3G3NNN", "2", "NG3G3G3G3G3G3G3N", "2", "NNG3NG3NG3NN", "2",
"NNNG3G3G3NNN", "2", "NNNG3G3G3NNN", "2", "G3NG3NG3NG3NG3", "2",
"NNG3G3G3G3G3NN", "2", "NNG3G3G3G3G3NN", "2"]]]
lengthen_sp_led(list_sp_init3, 3)
list_sp_wkup1 = [["起きて起きて起きて!朝だよー!",
["A15T500L", "R0T1500L", "A0T500L", "A-15T200L", "A15T500L", "A-15T500L",
"A15T500L", "A0T300L", "A-15T200L", "A15T500L", "A-15T500L", "A15T500L", "A0T300L"]]]
lengthen_sp_led(list_sp_wkup1, 3)
list_sp_wkup2 = [["おはよう!今日もいちにち頑張ろう!",
["A15T500L", "R0T1500L", "A0T500L", "A-15T200L", "A15T500L", "A-15T500L",
"A15T500L", "A0T300L", "A-15T200L", "A15T500L", "A-15T500L", "A15T500L", "A0T300L"]]]
lengthen_sp_led(list_sp_wkup2, 3)
speech_flag_morning = 0
speech_flag_night = 0
while state != State.end:
messages = papero.papero_robot_message_recv(1.0)
now_time = time.monotonic()
delta_time = now_time - prev_time
prev_time = now_time
past_time += delta_time
dt_now = datetime.datetime.now()
dt_now = dt_now.replace(microsecond = 0)
print(dt_now)
#起床時刻の設定
if dt_now.hour==7 and dt_now.minute==00 and dt_now.second==00:
if speech_flag_morning == 0:
if lux_measure.value >= lux_threshold:
speech_manager.start(papero, list_sp_wkup2, motor=True)
state = State.st9
speech_flag_morning = 1
elif lux_measure.value <= lux_threshold:
speech_manager.start(papero, list_sp_wkup1, motor=True)
state = State.st8
speech_flag_morning = 1
else:
time.sleep(1)
speech_flag_morning = 0
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
lux_measure.forward(papero, msg_dic_rcv, delta_time)
speech_manager.forward(papero, msg_dic_rcv, delta_time)
#就寝時刻の設定
if dt_now.hour==23 and dt_now.minute==00 and dt_now.second==00:
if speech_flag_night == 0:
if lux_measure.valid:
if lux_measure.value >= lux_threshold:
speech_manager.start(papero, list_sp_init, motor=True)
state = State.st1
speech_flag_night = 1
else:
state = State.st4
else:
time.sleep(1)
speech_flag_night = 0
elif state == State.st1:
if speech_manager.state == State.end:
past_time = 0
state = State.st2
elif state == State.st2:
past_time += delta_time
if past_time >= 10:
if lux_measure.valid:
if lux_measure.value >= lux_threshold:
speech_manager.start(papero, list_sp_init2, motor=True)
state = State.st3
else:
past_time = 0
state = State.st4
elif state == State.st3:
if speech_manager.state == State.end:
past_time = 0
state = State.st2
elif state == State.st4:
past_time += delta_time
if lux_measure.valid:
if lux_measure.value >= lux_threshold:
if past_time >= 10:
if (cnt_wkup <= 0) or (not tried):
speech_manager.start(papero, list_sp_init3, motor=True)
must_count = True
state = State.st5
else:
tried = True
if past_time >= 3:
state = State.st6
elif state == State.st5:
if speech_manager.state == State.end:
past_time = 0
state = State.st4
elif state == State.st6:
if lux_measure.valid:
if lux_measure.value >= lux_threshold:
past_time = 0
state = State.st4
else:
if (sheep_subcount >= sheep_unit) and btn_pushed:
must_count = True
sheep_subcount = 0
btn_pushed = False
if must_count:
if sheep_subcount < sheep_unit:
sheep_count += 1
sheep_subcount += 1
speech_manager.start(papero, [["羊が" + str(sheep_count) + "匹",
["G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2",
"G3NG3NG3NG3NG3", "2", "NG3G3G3G3G3G3G3N", "2",
"G3NG3NG3NG3NG3", "2", "NNNG3G3G3NNN", "2",
"G3NG3NG3NG3NG3", "2", "G3NG3NG3NG3NG3", "2"]]],
motor=False)
state = State.st7
else:
btn_pushed = False
must_count = False
past_time = 0
state = State.st4
else:
state = State.st4
elif state == State.st7:
if speech_manager.state == State.end:
state = State.st6
elif state == State.st8:
if lux_measure.value >= lux_threshold:
speech_manager.start(papero, list_sp_wkup2, motor=True)
state = State.st9
elif state == State.st9:
state = State.st10
elif state == State.st10:
state = State.st9
# ボタンの監視
if msg_dic_rcv is not None:
if msg_dic_rcv is not None:
if msg_dic_rcv["Name"] == "detectButton":
btn_pushed = True
if state != State.st6 and state != State.st7:
if (sheep_unit > sheep_subcount) and btn_pushed:
state = State.end
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_server_addr)
if papero.errOccurred == 0:
main(papero)
papero.papero_cleanup()
3・DOS窓を開き、cdコマンドでカレントディレクトリを上記フォルダに変更
4・DOS窓に以下のコマンドを入力
シミュレータの PaPeRo i を動かす場合:
python night.py -sim シミュレータID
実機を動かす場合:
python night.py -wssvr ws://実機のIPアドレス:8088/papero
・起床時刻(デフォルトだと7時)になり、部屋が暗い場合は起床を促す発話を行います。
・起床時刻に既に部屋が明るい場合は、応援メッセージを発話します。
・起床を促す発話を行った後に部屋を明るくすると、応援メッセージを発話します。
・指定時刻(デフォルトだと23時)になると就寝を促す発話を行います。
・3秒毎に照度を測定し、就寝時刻に部屋が明るい(照度100ルクス以上)場合、羊を数える事を提案します。
・再度暗くなった後で再び明るくなると、今度は羊を数える事を申し出て、次に暗くなると、羊を数え始めます。
・羊を数える声は10回毎に止まりますが、座布団のボタンをどれか押せば続きを数えてくれます。
・羊の数を数える時以外で座布団のボタンを押すと、プロセスが終了します。