def song(self, song: dict) -> task.Task: """ returns a Task object, that plays a song example: jukebox = ev3_sound.Jukebox(protocol=ev3.BLUETOOTH, host='00:16:53:42:2B:99') my_song = jukebox.song(ev3_sound.HAPPY_BIRTHDAY) my_song.start() """ tones = task.concat(task.Task(self._init_tone, action_stop=self.stop), task.Repeated(self._next_tone, args=(song, )), task.Task(self.stop)) colors = task.Periodic(60 * song["beats_per_bar"] / song["tempo"], self._next_color, args=(song, )) if "upbeat" in song: colors = task.concat( task.Sleep(60 * song["upbeat"] / song["tempo"]), colors) colors = task.concat( task.Task(self._init_color, action_stop=self.change_color, args_stop=(ev3.LED_GREEN, )), colors) return task.concat(task.Task(colors.start), task.Task(tones.start, join=True), task.Task(colors.stop))
def song(self, song: dict) -> task.Task: """ returns a Task object, that plays a song example: jukebox = ev3_sound.Jukebox(protocol=ev3.BLUETOOTH, host='00:16:53:42:2B:99') my_song = jukebox.song(ev3_sound.HAPPY_BIRTHDAY) my_song.start() """ tones = task.concat( task.Task( self._init_tone, action_stop=self.stop ), task.Repeated( self._next_tone, args=(song,) ), task.Task(self.stop) ) colors = task.Periodic( 60 * song["beats_per_bar"] / song["tempo"], self._next_color, args=(song,) ) if "upbeat" in song: colors = task.concat( task.Sleep(60 * song["upbeat"] / song["tempo"]), colors ) colors = task.concat( task.Task( self._init_color, action_stop=self.change_color, args_stop=(ev3.LED_GREEN,) ), colors ) return task.concat( task.Task(colors.start), task.Task(tones.start, join=True), task.Task(colors.stop) )
def sound(self, path: str, duration: float = None, repeat: bool = False) -> task.Task: """ returns a Task object, that plays a sound file Attributes: path: name of the sound file (without extension ".rsf") Keyword Attributes: duration: duration of the sound file (in sec.) repeat: flag, if repeatedly playing """ if repeat: ops = b''.join([ ev3.opSound, ev3.REPEAT, ev3.LCX(self._volume), # VOLUME ev3.LCS(path) # NAME ]) else: ops = b''.join([ ev3.opSound, ev3.PLAY, ev3.LCX(self._volume), # VOLUME ev3.LCS(path) # NAME ]) # pylint: disable=redefined-variable-type if not repeat and not duration: return task.Task(self.send_direct_cmd, args=(ops, )) elif not repeat and duration: t_inner = task.Task(self.send_direct_cmd, args=(ops, ), duration=duration, action_stop=self.stop) return task.Task(t_inner.start, join=True) elif repeat and not duration: t_inner = task.Task(self.send_direct_cmd, args=(ops, ), action_stop=self.stop, action_cont=self.send_direct_cmd, args_cont=(ops, ), duration=999999999) return task.Task(t_inner.start, join=True) elif repeat and duration: class _Task(task.Task): # pylint: disable=protected-access def _final(self, **kwargs): super()._final(**kwargs) if self._root._time_action: self._root._time_rest = self._root._time_action - time.time( ) self._root._time_action -= self._root._time_rest # pylint: enable=protected-access def _cont2(self, **kwargs): self._time_action += self._time_rest super()._cont2(**kwargs) t_inner = task.concat( _Task(self.send_direct_cmd, args=(ops, ), duration=duration, action_stop=self.stop, action_cont=self.send_direct_cmd, args_cont=(ops, )), _Task(self.stop)) # pylint: enable=redefined-variable-type return task.Task(t_inner.start, join=True)
colors = task.concat( task.Sleep(60 * song["upbeat"] / song["tempo"]), colors) colors = task.concat( task.Task(self._init_color, action_stop=self.change_color, args_stop=(ev3.LED_GREEN, )), colors) return task.concat(task.Task(colors.start), task.Task(tones.start, join=True), task.Task(colors.stop)) # pylint: disable=invalid-name if __name__ == "__main__": jukebox = Jukebox(protocol=ev3.BLUETOOTH, host='00:16:53:42:2B:99') jukebox.verbosity = 1 songs = task.concat(jukebox.song(HAPPY_BIRTHDAY), task.Sleep(1), jukebox.song(ALLE_MEINE_ENTCHEN)) songs.start() time.sleep(5) songs.stop() now = datetime.datetime.now().strftime('%H:%M:%S.%f') print(now, "*** stopped ***") time.sleep(3) songs.cont() now = datetime.datetime.now().strftime('%H:%M:%S.%f') print(now, "*** continued ***") time.sleep(14) jukebox.volume = 12 now = datetime.datetime.now().strftime('%H:%M:%S.%f') print(now, "*** volume 12 ***") time.sleep(5) jukebox.volume = 1
def sound(self, path: str, duration: float=None, repeat: bool=False) -> task.Task: """ returns a Task object, that plays a sound file Attributes: path: name of the sound file (without extension ".rsf") Keyword Attributes: duration: duration of the sound file (in sec.) repeat: flag, if repeatedly playing """ if repeat: ops = b''.join([ ev3.opSound, ev3.REPEAT, ev3.LCX(self._volume), # VOLUME ev3.LCS(path) # NAME ]) else: ops = b''.join([ ev3.opSound, ev3.PLAY, ev3.LCX(self._volume), # VOLUME ev3.LCS(path) # NAME ]) # pylint: disable=redefined-variable-type if not repeat and not duration: return task.Task( self.send_direct_cmd, args=(ops,) ) elif not repeat and duration: t_inner = task.Task( self.send_direct_cmd, args=(ops,), duration=duration, action_stop=self.stop ) return task.Task(t_inner.start, join=True) elif repeat and not duration: t_inner = task.Task( self.send_direct_cmd, args=(ops,), action_stop=self.stop, action_cont=self.send_direct_cmd, args_cont=(ops,), duration=999999999 ) return task.Task(t_inner.start, join=True) elif repeat and duration: class _Task(task.Task): # pylint: disable=protected-access def _final(self, **kwargs): super()._final(**kwargs) if self._root._time_action: self._root._time_rest = self._root._time_action - time.time() self._root._time_action -= self._root._time_rest # pylint: enable=protected-access def _cont2(self, **kwargs): self._time_action += self._time_rest super()._cont2(**kwargs) t_inner = task.concat( _Task( self.send_direct_cmd, args=(ops,), duration=duration, action_stop=self.stop, action_cont=self.send_direct_cmd, args_cont=(ops,) ), _Task(self.stop) ) # pylint: enable=redefined-variable-type return task.Task(t_inner.start, join=True)
), colors ) return task.concat( task.Task(colors.start), task.Task(tones.start, join=True), task.Task(colors.stop) ) # pylint: disable=invalid-name if __name__ == "__main__": jukebox = Jukebox(protocol=ev3.BLUETOOTH, host='00:16:53:42:2B:99') jukebox.verbosity = 1 songs = task.concat( jukebox.song(HAPPY_BIRTHDAY), task.Sleep(1), jukebox.song(ALLE_MEINE_ENTCHEN) ) songs.start() time.sleep(5) songs.stop() now = datetime.datetime.now().strftime('%H:%M:%S.%f') print(now, "*** stopped ***") time.sleep(3) songs.cont() now = datetime.datetime.now().strftime('%H:%M:%S.%f') print(now, "*** continued ***") time.sleep(14) jukebox.volume = 12 now = datetime.datetime.now().strftime('%H:%M:%S.%f') print(now, "*** volume 12 ***")
def task_factory(self, drive_type: str, **kwargs) -> task.Task: """ Returns as Task object, which moves or stops the vehicle Arguments: drive_type: type of movement 'straight': keyword arguments are speed, distance (optional for delimited movements) 'turn': keyword arguments are speed, radius_turn, angle (optional for delimited movements), right_turn (optional for turns on place) 'stop': keyword argument is brake (optional) 'rotate_to': keyword arguments are speed, orientation 'drive_to': keyword arguments are speed, pos_x, pos_y Keyword Arguments: speed: int=None -- speed in percent [-100 - 100] (direction depends on its sign) positive sign: forwards negative sign: backwards distance: float=None -- distance in meter, needs to be positive radius_turn: float=None -- radius of turn in meter positive sign: turn to the left side negative sign: turn to the right side angle: float=None -- absolute angle (needs to be positive) right_turn: bool=False -- flag if turn right (only in case of radius_turn == 0) pos_x: float=None -- x-component of position in meter pos_y: float=None -- y-component of position in meter brake: bool=False -- flag if stopping with activated brake exc: ExceptionHandler=None -- exception handler to coordinate exceptions """ speed = kwargs.pop('speed', None) distance = kwargs.pop('distance', None) radius_turn = kwargs.pop('radius_turn', None) angle = kwargs.pop('angle', None) right_turn = kwargs.pop('right_turn', False) orientation = kwargs.pop('orientation', None) pos_x = kwargs.pop('pos_x', None) pos_y = kwargs.pop('pos_y', None) brake = kwargs.pop('brake', False) exc = kwargs.pop('exc', None) assert isinstance(drive_type, str), 'drive_type needs to be a str type' assert drive_type in [ DRIVE_TYPE_STRAIGHT, DRIVE_TYPE_TURN, DRIVE_TYPE_ROTATE_TO, DRIVE_TYPE_DRIVE_TO, DRIVE_TYPE_STOP ], 'unknown drive_type: ' + drive_type assert speed is None or isinstance(speed, int), \ 'speed needs to be an integer' assert speed != None or drive_type is DRIVE_TYPE_STOP, \ drive_type + ' needs attribute speed' assert drive_type is DRIVE_TYPE_STOP or isinstance(speed, int), \ drive_type + ' needs parameter speed' assert distance is None or isinstance(distance, numbers.Number), \ "distance needs to be a number" assert distance is None or distance >= 0, \ "distance needs to be positive" assert radius_turn is None or isinstance(radius_turn, numbers.Number), \ "radius_turn needs to be a number" assert angle is None or isinstance(angle, numbers.Number), \ "angle needs to be a number" assert isinstance(right_turn, bool), \ "right_turn needs to be a bool value" assert orientation is None or isinstance(orientation, numbers.Number), \ "orientation needs to be a number" assert pos_x is None or isinstance(pos_x, numbers.Number), \ "pos_x needs to be a number" assert pos_y is None or isinstance(pos_y, numbers.Number), \ "pos_y needs to be a number" assert drive_type != DRIVE_TYPE_TURN or radius_turn != None, \ DRIVE_TYPE_TURN + ' needs parameter radius_turn' assert drive_type != DRIVE_TYPE_ROTATE_TO or orientation != None, \ DRIVE_TYPE_ROTATE_TO + ' needs parameter orientation' assert drive_type != DRIVE_TYPE_DRIVE_TO or pos_x != None, \ DRIVE_TYPE_DRIVE_TO + ' needs parameter pos_x' assert drive_type != DRIVE_TYPE_DRIVE_TO or pos_y != None, \ DRIVE_TYPE_DRIVE_TO + ' needs parameter pos_y' assert isinstance(brake, bool), \ "brake needs to be a bool value" assert exc is None or isinstance(exc, task.ExceptionHandler), \ "exc needs to be an ExceptionHandler" if not exc: exc = task.Task.exc_default class _Drive(task.Task): def stop(self): super().stop() self._time_action = time.time() # pylint: disable=redefined-variable-type if drive_type == DRIVE_TYPE_STRAIGHT: t_inner = _Drive( self._drive_straight, args=(speed, distance), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc ) if distance != None: t_inner.append(task.Repeated(self._test_pos)) elif drive_type == DRIVE_TYPE_TURN: t_inner = _Drive( self._drive_turn, args=(speed, radius_turn, angle, right_turn), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc ) if angle != None: t_inner.append(task.Repeated(self._test_o)) elif drive_type == DRIVE_TYPE_ROTATE_TO: t_inner = task.concat( _Drive( self._rotate_to, args=(speed, orientation), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc ), task.Repeated(self._test_o) ) elif drive_type == DRIVE_TYPE_DRIVE_TO: t_inner = task.concat( _Drive( self._drive_to_1, args=(speed, pos_x, pos_y), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc, ), task.Repeated(self._test_o), task.Task( self._drive_to_2, args=(speed, pos_x, pos_y) ), task.Repeated(self._test_pos) ) elif drive_type == DRIVE_TYPE_STOP: t_inner = task.Task( self.stop, args=(brake,), exc=exc ) # pylint: enable=redefined-variable-type if drive_type is DRIVE_TYPE_STRAIGHT and distance is None or \ drive_type is DRIVE_TYPE_TURN and angle is None: return task.Task(t_inner.start, exc=exc) else: return task.Task(t_inner.start, join=True, exc=exc)
def task_factory(self, drive_type: str, **kwargs) -> task.Task: """ Returns as Task object, which moves or stops the vehicle Arguments: drive_type: type of movement 'straight': keyword arguments are speed, distance (optional for delimited movements) 'turn': keyword arguments are speed, radius_turn, angle (optional for delimited movements), right_turn (optional for turns on place) 'stop': keyword argument is brake (optional) 'rotate_to': keyword arguments are speed, orientation 'drive_to': keyword arguments are speed, pos_x, pos_y Keyword Arguments: speed: int=None -- speed in percent [-100 - 100] (direction depends on its sign) positive sign: forwards negative sign: backwards distance: float=None -- distance in meter, needs to be positive radius_turn: float=None -- radius of turn in meter positive sign: turn to the left side negative sign: turn to the right side angle: float=None -- absolute angle (needs to be positive) right_turn: bool=False -- flag if turn right (only in case of radius_turn == 0) pos_x: float=None -- x-component of position in meter pos_y: float=None -- y-component of position in meter brake: bool=False -- flag if stopping with activated brake exc: ExceptionHandler=None -- exception handler to coordinate exceptions """ speed = kwargs.pop('speed', None) distance = kwargs.pop('distance', None) radius_turn = kwargs.pop('radius_turn', None) angle = kwargs.pop('angle', None) right_turn = kwargs.pop('right_turn', False) orientation = kwargs.pop('orientation', None) pos_x = kwargs.pop('pos_x', None) pos_y = kwargs.pop('pos_y', None) brake = kwargs.pop('brake', False) exc = kwargs.pop('exc', None) assert isinstance(drive_type, str), 'drive_type needs to be a str type' assert drive_type in [ DRIVE_TYPE_STRAIGHT, DRIVE_TYPE_TURN, DRIVE_TYPE_ROTATE_TO, DRIVE_TYPE_DRIVE_TO, DRIVE_TYPE_STOP ], 'unknown drive_type: ' + drive_type assert speed is None or isinstance(speed, int), \ 'speed needs to be an integer' assert speed != None or drive_type is DRIVE_TYPE_STOP, \ drive_type + ' needs attribute speed' assert drive_type is DRIVE_TYPE_STOP or isinstance(speed, int), \ drive_type + ' needs parameter speed' assert distance is None or isinstance(distance, numbers.Number), \ "distance needs to be a number" assert distance is None or distance >= 0, \ "distance needs to be positive" assert radius_turn is None or isinstance(radius_turn, numbers.Number), \ "radius_turn needs to be a number" assert angle is None or isinstance(angle, numbers.Number), \ "angle needs to be a number" assert isinstance(right_turn, bool), \ "right_turn needs to be a bool value" assert orientation is None or isinstance(orientation, numbers.Number), \ "orientation needs to be a number" assert pos_x is None or isinstance(pos_x, numbers.Number), \ "pos_x needs to be a number" assert pos_y is None or isinstance(pos_y, numbers.Number), \ "pos_y needs to be a number" assert drive_type != DRIVE_TYPE_TURN or radius_turn != None, \ DRIVE_TYPE_TURN + ' needs parameter radius_turn' assert drive_type != DRIVE_TYPE_ROTATE_TO or orientation != None, \ DRIVE_TYPE_ROTATE_TO + ' needs parameter orientation' assert drive_type != DRIVE_TYPE_DRIVE_TO or pos_x != None, \ DRIVE_TYPE_DRIVE_TO + ' needs parameter pos_x' assert drive_type != DRIVE_TYPE_DRIVE_TO or pos_y != None, \ DRIVE_TYPE_DRIVE_TO + ' needs parameter pos_y' assert isinstance(brake, bool), \ "brake needs to be a bool value" assert exc is None or isinstance(exc, task.ExceptionHandler), \ "exc needs to be an ExceptionHandler" if not exc: exc = task.Task.exc_default class _Drive(task.Task): def stop(self): super().stop() self._time_action = time.time() # pylint: disable=redefined-variable-type if drive_type == DRIVE_TYPE_STRAIGHT: t_inner = _Drive(self._drive_straight, args=(speed, distance), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc) if distance != None: t_inner.append(task.Repeated(self._test_pos)) elif drive_type == DRIVE_TYPE_TURN: t_inner = _Drive(self._drive_turn, args=(speed, radius_turn, angle, right_turn), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc) if angle != None: t_inner.append(task.Repeated(self._test_o)) elif drive_type == DRIVE_TYPE_ROTATE_TO: t_inner = task.concat( _Drive(self._rotate_to, args=(speed, orientation), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc), task.Repeated(self._test_o)) elif drive_type == DRIVE_TYPE_DRIVE_TO: t_inner = task.concat( _Drive( self._drive_to_1, args=(speed, pos_x, pos_y), action_stop=self.stop, action_cont=self._vehicle_cont, exc=exc, ), task.Repeated(self._test_o), task.Task(self._drive_to_2, args=(speed, pos_x, pos_y)), task.Repeated(self._test_pos)) elif drive_type == DRIVE_TYPE_STOP: t_inner = task.Task(self.stop, args=(brake, ), exc=exc) # pylint: enable=redefined-variable-type if drive_type is DRIVE_TYPE_STRAIGHT and distance is None or \ drive_type is DRIVE_TYPE_TURN and angle is None: return task.Task(t_inner.start, exc=exc) else: return task.Task(t_inner.start, join=True, exc=exc)