implemented reset command.
fixing bugs in statemachine and storyboard.
This commit is contained in:
parent
927204b00a
commit
7ce7b70499
4 changed files with 76 additions and 42 deletions
|
@ -58,6 +58,7 @@ class SerialCommands(Enum):
|
|||
RECORD = b'C'
|
||||
|
||||
REWIND = b'R'
|
||||
RESET = b'X'
|
||||
|
||||
DEBUG_SCROLL = b'S'
|
||||
DEBUG_SENSORS = b'Z'
|
||||
|
@ -106,6 +107,24 @@ class PizzaHAL:
|
|||
"""
|
||||
return self.lid_switch.is_pressed
|
||||
|
||||
@property
|
||||
def helo1(self) -> bool:
|
||||
"""
|
||||
Returns the status of the HELO1 pin
|
||||
"""
|
||||
return bool(self.helo1.value)
|
||||
|
||||
@helo1.setter
|
||||
def helo1(self, value: bool):
|
||||
self.helo1.value = 1 if value else 0
|
||||
|
||||
@property
|
||||
def helo2(self) -> bool:
|
||||
"""
|
||||
Returns the value of the HELO2 pin (read only)
|
||||
"""
|
||||
return bool(self.helo2.value)
|
||||
|
||||
def init_connection(self):
|
||||
"""
|
||||
Set HELO1 pin to `High`, wait for HELO2 to be set `High` by microcontroller.
|
||||
|
@ -213,6 +232,9 @@ class PizzaHAL:
|
|||
return resp
|
||||
|
||||
def flush_serial(self):
|
||||
"""
|
||||
Clear the serial connection from unhandled responses.
|
||||
"""
|
||||
self.serialcon.read_all()
|
||||
|
||||
|
||||
|
@ -240,6 +262,13 @@ def rewind(hal: PizzaHAL, **kwargs):
|
|||
hal.send_cmd(SerialCommands.REWIND, ignore_lid=True)
|
||||
|
||||
|
||||
def reset(hal: PizzaHAL, **kwargs):
|
||||
"""
|
||||
Prepare microcontroller for reset.
|
||||
"""
|
||||
hal.send_cmd(SerialCommands.RESET, ignore_lid=True)
|
||||
|
||||
|
||||
def turn_off(hal: PizzaHAL, **kwargs):
|
||||
"""
|
||||
Turn off the lights.
|
||||
|
@ -303,15 +332,15 @@ def wait_for_input(hal: PizzaHAL,
|
|||
|
||||
resp = resp[1]
|
||||
if resp == 1:
|
||||
blue_cb(**kwargs)
|
||||
blue_cb()
|
||||
elif resp == 2:
|
||||
red_cb(**kwargs)
|
||||
red_cb()
|
||||
elif resp == 4:
|
||||
yellow_cb(**kwargs)
|
||||
yellow_cb()
|
||||
elif resp == 8:
|
||||
green_cb(**kwargs)
|
||||
green_cb()
|
||||
elif timeout_cb is not None:
|
||||
timeout_cb(**kwargs)
|
||||
timeout_cb()
|
||||
|
||||
|
||||
def set_light(hal: PizzaHAL,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from email.policy import default
|
||||
import sys
|
||||
|
||||
import click
|
||||
|
@ -11,18 +12,17 @@ logger = logging.getLogger('pizzactrl.main')
|
|||
|
||||
|
||||
@click.command()
|
||||
@click.option('--move', is_flag=True)
|
||||
@click.option('--test', is_flag=True, default=False)
|
||||
@click.option('--debug', is_flag=True, default=False)
|
||||
@click.option('--loop', is_flag=True, default=False)
|
||||
def main(move: bool=False, test: bool=False, debug: bool=False, loop: bool=False):
|
||||
def main(test: bool=False, debug: bool=False, loop: bool=False):
|
||||
if debug or test:
|
||||
logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
|
||||
|
||||
hal = PizzaHAL()
|
||||
sm = Statemachine(hal, STORYBOARD, move=move, loop=loop, test=test)
|
||||
sm = Statemachine(hal, STORYBOARD, loop=loop, test=test)
|
||||
|
||||
sm.test = test
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from enum import Enum, auto
|
|||
|
||||
from pizzactrl import fs_names
|
||||
from .storyboard import Language, Storyboard
|
||||
from .hal_serial import SerialCommunicationError, CommunicationError, PizzaHAL, wait_for_input, play_sound, turn_off
|
||||
from .hal_serial import SerialCommunicationError, CommunicationError, PizzaHAL, wait_for_input, play_sound, turn_off, reset
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -32,7 +32,6 @@ class Statemachine:
|
|||
hal: PizzaHAL,
|
||||
story: Storyboard,
|
||||
default_lang=Language.NOT_SET,
|
||||
move: bool = False,
|
||||
loop: bool = True,
|
||||
test: bool = False):
|
||||
self.hal = hal
|
||||
|
@ -41,7 +40,7 @@ class Statemachine:
|
|||
self.lang = None
|
||||
|
||||
self.story = story
|
||||
self.story.MOVE = move
|
||||
self.story.MOVE = True
|
||||
|
||||
self.test = test
|
||||
self.loop = loop
|
||||
|
@ -71,8 +70,7 @@ class Statemachine:
|
|||
State.IDLE_END: self._idle_end
|
||||
}
|
||||
|
||||
while (self.state is not State.ERROR) and \
|
||||
(self.state is not State.SHUTDOWN):
|
||||
while (self.state is not State.ERROR) and (self.state is not State.SHUTDOWN):
|
||||
logger.debug(f'Run(state={self.state})')
|
||||
try:
|
||||
choice[self.state]()
|
||||
|
@ -185,22 +183,24 @@ class Statemachine:
|
|||
turn_off(self.hal)
|
||||
self.story.skip_flag = False
|
||||
self.story.rewind()
|
||||
|
||||
if self.loop:
|
||||
self.state = State.IDLE_START
|
||||
else:
|
||||
self._next_state()
|
||||
|
||||
self._next_state()
|
||||
|
||||
def _idle_end(self):
|
||||
"""
|
||||
Initialize shutdown
|
||||
Initialize shutdown or go back to POST if `self.loop=True`
|
||||
"""
|
||||
self._next_state()
|
||||
reset(self.hal)
|
||||
self.hal.helo1 = False
|
||||
|
||||
if self.loop:
|
||||
self.state = State.POST
|
||||
else:
|
||||
self._next_state()
|
||||
|
||||
def _shutdown(self):
|
||||
"""
|
||||
Clean up, end execution
|
||||
"""
|
||||
self.hal.pin_helo1.off()
|
||||
del self.hal
|
||||
del self.story
|
||||
|
||||
|
|
|
@ -25,10 +25,11 @@ class Option(Enum):
|
|||
"""
|
||||
Options can be chosen by the user in WAIT_FOR_INPUT
|
||||
"""
|
||||
CONTINUE = {'skip_flag': False} # Continue with chapter. Set `skip_flag=True` to skip all chapters marked with `skip_flag`
|
||||
REPEAT = {'rewind': True} # Repeat chapter from beginning. `rewind=True`: reset scrolls to starting position
|
||||
GOTO = {'chapter': 0} # Jump to chapter number
|
||||
QUIT = {'quit': True} # End playback.
|
||||
CONTINUE = {'skip_flag': None} # Continue with chapter. Set `skip_flag=True` to skip all chapters marked with `skip_flag`
|
||||
REPEAT = {'rewind': True} # Repeat chapter from beginning. `rewind=True`: reset scrolls to starting position
|
||||
GOTO = {'chapter': 0,
|
||||
'skip_flag': None} # Jump to chapter number
|
||||
QUIT = {} # End playback. Will cause restart if `statemachine.loop=True`
|
||||
|
||||
|
||||
class Select:
|
||||
|
@ -65,10 +66,10 @@ class Activity(Enum):
|
|||
RECORD_VIDEO = {'duration': 60.0,
|
||||
'filename': ''}
|
||||
TAKE_PHOTO = {'filename': ''}
|
||||
ADVANCE_UP = {'steps': 46,
|
||||
ADVANCE_UP = {'steps': 48,
|
||||
'scroll': Scrolls.VERTICAL,
|
||||
'speed': 3}
|
||||
ADVANCE_LEFT = {'steps': 96,
|
||||
ADVANCE_LEFT = {'steps': 92,
|
||||
'scroll': Scrolls.HORIZONTAL,
|
||||
'speed': 3}
|
||||
LIGHT_FRONT = {'r': 0,
|
||||
|
@ -211,7 +212,7 @@ class Storyboard:
|
|||
|
||||
self.skip_flag = False # Set `True` to skip chapters marked with skip_flag
|
||||
|
||||
self.MOVE = False # self.move is reset to this value
|
||||
self.MOVE = True # self.move is reset to this value
|
||||
self._move = self.MOVE
|
||||
|
||||
self._lang = Language.NOT_SET
|
||||
|
@ -255,39 +256,40 @@ class Storyboard:
|
|||
Return a callback for the appropriate option and parameters.
|
||||
Callbacks set the properties of `Statemachine` to determine it's behaviour.
|
||||
"""
|
||||
# rewind = selection.values.get('rewind', Option.REPEAT.value['rewind'])
|
||||
# next_chapter = selection.values.get('chapter', Option.GOTO.value['chapter'])
|
||||
# shutdown = selection.values.get('shutdown', Option.QUIT.value['shutdown'])
|
||||
_rewind = selection.values.get('rewind', None)
|
||||
_next_chapter = selection.values.get('chapter', None)
|
||||
_skip_flag = selection.values.get('skip_flag', None)
|
||||
if _skip_flag is not None:
|
||||
self.skip_flag = _skip_flag
|
||||
|
||||
def _continue(**kwargs):
|
||||
def _continue():
|
||||
"""
|
||||
Continue in the Storyboard. Prepare advancing to the next chapter.
|
||||
"""
|
||||
logger.debug('User selected continue')
|
||||
if len(self.story) > (self._index + 1):
|
||||
self.next_chapter = self._index + 1
|
||||
if _skip_flag is not None:
|
||||
self.skip_flag = _skip_flag
|
||||
else:
|
||||
self.next_chapter = None
|
||||
|
||||
def _repeat(rewind: bool=None, **kwargs):
|
||||
def _repeat():
|
||||
"""
|
||||
Repeat the current chapter. Do not rewind if the selection says so.
|
||||
"""
|
||||
logger.debug('User selected repeat')
|
||||
self.next_chapter = self._index
|
||||
self.move = rewind
|
||||
self.move = _rewind
|
||||
|
||||
def _goto(chapter: int=None, **kwargs):
|
||||
def _goto():
|
||||
"""
|
||||
Jump to a specified chapter.
|
||||
"""
|
||||
logger.debug(f'User selected goto {chapter}')
|
||||
self.next_chapter = chapter
|
||||
logger.debug(f'User selected goto {_next_chapter}')
|
||||
self.next_chapter = _next_chapter
|
||||
if _skip_flag is not None:
|
||||
self.skip_flag = _skip_flag
|
||||
|
||||
def _quit(**kwargs):
|
||||
def _quit():
|
||||
logger.debug('User selected quit')
|
||||
self.next_chapter = None
|
||||
|
||||
|
@ -346,6 +348,8 @@ class Storyboard:
|
|||
|
||||
def _move(hal, do_now=True, **kwargs):
|
||||
logger.debug(f'Storyboard._move({kwargs})')
|
||||
if not self.move:
|
||||
return
|
||||
set_movement(hal, **kwargs)
|
||||
if do_now:
|
||||
do_it(hal)
|
||||
|
@ -421,12 +425,12 @@ class Storyboard:
|
|||
steps = ch.rewind()
|
||||
h_steps += steps['h_steps']
|
||||
v_steps += steps['v_steps']
|
||||
|
||||
elif diff > 0:
|
||||
"""
|
||||
Skip all chapters up to target
|
||||
"""
|
||||
for ch in self.story[self._index:self._next_chapter]:
|
||||
logger.debug(f'Queueing chapter {ch} for skipping')
|
||||
steps = ch.skip()
|
||||
h_steps += steps['h_steps']
|
||||
v_steps += steps['v_steps']
|
||||
|
@ -438,6 +442,7 @@ class Storyboard:
|
|||
h_steps = steps['h_steps']
|
||||
v_steps = steps['v_steps']
|
||||
|
||||
logger.debug(f'storyboard.move={self.move} and h_steps={h_steps}, v_steps={v_steps}.')
|
||||
if self.move and ((h_steps != 0) or (v_steps != 0)):
|
||||
set_movement(self.hal, scroll=Scrolls.HORIZONTAL, steps=h_steps, speed=4)
|
||||
set_movement(self.hal, scroll=Scrolls.VERTICAL, steps=v_steps, speed=4)
|
||||
|
|
Loading…
Reference in a new issue