1
0
mirror of https://github.com/undera/pylgbst.git synced 2020-11-18 19:37:26 -08:00
2017-09-16 16:19:17 +03:00

172 lines
5.7 KiB
Python

# coding=utf-8
import hashlib
import os
import re
import subprocess
import gtts
import six
from pylgbst import *
forward = FORWARD = right = RIGHT = 1
backward = BACKWARD = left = LEFT = -1
straight = STRAIGHT = 0
def say(text):
if isinstance(text, str):
text = text.decode("utf-8")
md5 = hashlib.md5(text.encode('utf-8')).hexdigest()
fname = "/tmp/%s.mp3" % md5
if not os.path.exists(fname):
myre = re.compile('[[A-Za-z]', re.UNICODE)
lang = 'en' if myre.match(text) else 'ru'
logging.getLogger('requests').setLevel(logging.getLogger('').getEffectiveLevel())
tts = gtts.gTTS(text=text, lang=lang, slow=False)
tts.save(fname)
with open(os.devnull, 'w') as fnull:
subprocess.call("mplayer %s" % fname, shell=True, stderr=fnull, stdout=fnull)
class Vernie(MoveHub):
def __init__(self):
try:
conn = DebugServerConnection()
except BaseException:
logging.debug("Failed to use debug server: %s", traceback.format_exc())
conn = BLEConnection().connect()
super(Vernie, self).__init__(conn)
while True:
required_devices = (self.color_distance_sensor, self.motor_external)
if None not in required_devices:
break
log.debug("Waiting for required devices to appear: %s", required_devices)
time.sleep(1)
self._head_position = 0
self.motor_external.subscribe(self._external_motor_data)
self._color_detected = COLOR_NONE
self._sensor_distance = 10
self.color_distance_sensor.subscribe(self._color_distance_data)
time.sleep(1)
self._reset_head()
time.sleep(1)
log.info("Vernie is ready.")
def _external_motor_data(self, data):
log.debug("External motor position: %s", data)
self._head_position = data
def _color_distance_data(self, color, distance):
log.debug("Color & Distance data: %s %s", COLORS[color], distance)
self._sensor_distance = distance
self._color_detected = color
def _reset_head(self):
self.motor_external.timed(1, -0.2)
self.head(RIGHT, angle=45)
def head(self, direction=RIGHT, angle=25, speed=0.1):
if direction == STRAIGHT:
angle = -self._head_position
direction = 1
self.motor_external.angled(direction * angle, speed)
def turn(self, direction, degrees=90, speed=0.3):
self.head(STRAIGHT, speed=1)
self.head(direction, 35, 1)
self.motor_AB.angled(225 * degrees / 90, speed * direction, -speed * direction)
self.head(STRAIGHT, speed=1)
def move(self, direction, distance=1, speed=0.3):
self.head(STRAIGHT, speed=0.5)
self.motor_AB.angled(distance * 450, speed * direction, speed * direction)
def program_carton_board(self):
self.move(FORWARD)
self.move(FORWARD)
self.turn(RIGHT)
self.move(FORWARD)
self.turn(LEFT)
self.move(FORWARD)
self.turn(RIGHT)
self.move(BACKWARD)
self.move(BACKWARD)
self.turn(LEFT)
self.move(FORWARD)
self.move(FORWARD)
self.turn(RIGHT)
self.move(FORWARD)
self.turn(RIGHT)
self.move(FORWARD, 3)
self.turn(LEFT)
self.turn(LEFT)
self.move(BACKWARD, 2)
def read_typed_commands(self):
say("Печатайте команды")
while True:
cmd = six.moves.input("COMMAND >")
cmd = cmd.split(' ')
if cmd[0].lower() in ("head", "голова", "голова"):
if cmd[-1] in ("right", "вправо", "направо"):
say("ok")
self.head(RIGHT)
elif cmd[-1] in ("left", "влево", "налево"):
say("ok")
self.head(LEFT)
else:
say("ok")
self.head(STRAIGHT)
elif cmd[0].lower() in ("say", "скажи", "сказать"):
say(' '.join(cmd[1:]))
elif cmd[0].lower() in ("forward", "вперёд", "вперед"):
try:
dist = int(cmd[-1])
except:
dist = 1
say("ok")
self.move(FORWARD, distance=dist)
elif cmd[0].lower() in ("backward", "назад"):
try:
dist = int(cmd[-1])
except:
dist = 1
say("ok")
self.move(BACKWARD, distance=dist)
elif cmd[0].lower() in ("turn", "поворот", 'повернуть'):
if cmd[-1] in ("right", "вправо", "направо"):
say("ok")
self.turn(RIGHT)
elif cmd[-1] in ("left", "влево", "налево"):
say("ok")
self.turn(LEFT)
else:
say("ok")
self.turn(RIGHT, degrees=360)
else:
say("Неизвестная команда")
say("Доступные команды это:")
say("вперёд, назад, поворот влево, поворот вправо, голову влево, голову вправо, голову прямо, скажи")
say("Печатайте команды")
# TODO: distance sensor game
# TODO: find and follow the lightest direction game
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
comms.log.setLevel(logging.INFO)
vernie = Vernie()
say("Робот Веернии 01 готов к работе")
vernie.read_typed_commands()