예제 #1
0
    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))
예제 #2
0
    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)
        )
예제 #3
0
    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)
예제 #4
0
            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
예제 #5
0
    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)
예제 #6
0
            ),
            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 ***")
예제 #7
0
    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)
예제 #8
0
    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)