def test_last_analog_channel_state_can_be_read(self):
        rc = RemoteController()

        for i in range(10):
            analog = [0] * 10
            # ith button is pressed
            analog[i] = 255

            rc.tick(
                RemoteControllerCommand(buttons=[False] * 32, analog=analog))

            for j in range(10):
                self.assertEqual(analog[i], rc.analog_value(i))
Ejemplo n.º 2
0
    def test_requested_channels_are_passed_to_analog_handlers(self):
        rc = RemoteController()
        mock24 = Mock()
        mock3 = Mock()
        mock_invalid = Mock()

        rc.on_analog_values([2, 4], mock24)
        rc.on_analog_values([3], mock3)
        rc.on_analog_values([3, 11], mock_invalid)

        rc.tick(RemoteControllerCommand(buttons=[False] * 32, analog=[255, 254, 253, 123, 43, 65, 45, 42]))

        self.assertEqual(mock24.call_count, 1)
        self.assertEqual(mock3.call_count, 1)

        # invalid channels are silently ignored
        self.assertEqual(mock_invalid.call_count, 0)

        self.assertEqual(mock24.call_args[0][0], [253, 43])
        self.assertEqual(mock3.call_args[0][0], [123])
Ejemplo n.º 3
0
    def __init__(self,
                 interface: RevvyControl,
                 revvy,
                 sound_paths,
                 sw_version,
                 default_config=None):
        print("RobotManager: __init__()")
        self.needs_interrupting = True

        self._configuring = False
        self._robot = Robot(interface, sound_paths, sw_version)
        self._interface = interface
        self._ble = revvy
        self._default_configuration = default_config or RobotConfig()

        self._status_update_thread = periodic(self._update, 0.02,
                                              "RobotStatusUpdaterThread")
        self._background_fn_lock = Lock()
        self._background_fns = []

        rc = RemoteController()
        rcs = RemoteControllerScheduler(rc)
        rcs.on_controller_detected(self._on_controller_detected)
        rcs.on_controller_lost(self._on_controller_lost)

        self._remote_controller = rc
        self._remote_controller_scheduler = rcs
        self._remote_controller_thread = create_remote_controller_thread(rcs)

        self._resources = {
            'led_ring': Resource(),
            'drivetrain': Resource(),
            'sound': Resource(),
            **{
                'motor_{}'.format(port.id): Resource()
                for port in self._robot.motors
            },
            **{
                'sensor_{}'.format(port.id): Resource()
                for port in self._robot.sensors
            }
        }

        revvy['live_message_service'].register_message_handler(
            self._remote_controller_scheduler.data_ready)
        revvy.on_connection_changed(self._on_connection_changed)

        self._scripts = ScriptManager(self)
        self._config = self._default_configuration

        self._status_code = RevvyStatusCode.OK
        self.exited = False
    def test_buttons_are_edge_triggered(self):
        rc = RemoteController()
        mocks = []
        for i in range(32):
            mock = Mock()
            rc.on_button_pressed(i, mock)
            mocks.append(mock)

        for i in range(32):
            buttons = [False] * 32

            rc.tick(RemoteControllerCommand(buttons=buttons, analog=[0] * 10))

            # ith button is pressed
            buttons[i] = True
            rc.tick(RemoteControllerCommand(buttons=buttons, analog=[0] * 10))

            # button is kept pressed
            rc.tick(RemoteControllerCommand(buttons=buttons, analog=[0] * 10))

            for j in range(32):
                self.assertEqual(mocks[j].call_count, 1 if i == j else 0)
                mocks[j].reset_mock()
    def test_last_button_pressed_state_can_be_read(self):
        rc = RemoteController()
        rc.tick(RemoteControllerCommand(buttons=[False] * 32, analog=[0] * 10))

        for i in range(32):
            buttons = [False] * 32
            # ith button is pressed
            buttons[i] = True

            rc.tick(RemoteControllerCommand(buttons=buttons, analog=[0] * 10))

            for j in range(32):
                self.assertEqual(buttons[i], rc.is_button_pressed(i))
    def __init__(self, robot: Robot, sw_version, revvy_ble):
        self._log = get_logger('RobotManager')
        self._log('init')
        self.needs_interrupting = True

        self._configuring = False
        self._robot = robot
        self._ble = revvy_ble
        self._sw_version = sw_version

        self._status_update_thread = periodic(self._update, 0.005,
                                              "RobotStatusUpdaterThread")
        self._background_fns = []

        rc = RemoteController()
        rcs = RemoteControllerScheduler(rc)
        rcs.on_controller_detected(self._on_controller_detected)
        rcs.on_controller_lost(self._on_controller_lost)

        self._remote_controller = rc
        self._remote_controller_thread = create_remote_controller_thread(rcs)

        self._resources = {
            'led_ring': Resource('RingLed'),
            'drivetrain': Resource('DriveTrain'),
            'sound': Resource('Sound'),
            **{
                f'motor_{port.id}': Resource(f'Motor {port.id}')
                for port in self._robot.motors
            },
            **{
                f'sensor_{port.id}': Resource(f'Sensor {port.id}')
                for port in self._robot.sensors
            }
        }

        revvy_ble['live_message_service'].register_message_handler(
            rcs.data_ready)
        revvy_ble.on_connection_changed(self._on_connection_changed)

        self._scripts = ScriptManager(self)
        self._config = empty_robot_config

        self._status_code = RevvyStatusCode.OK
        self.exited = Event()

        self.start_remote_controller = self._remote_controller_thread.start
    def test_reset_removed_button_and_analog_handlers_and_clears_stored_data(
            self):
        mock = Mock()
        rc = RemoteController()
        rc.tick(RemoteControllerCommand(buttons=[False] * 32, analog=[]))

        rc.on_analog_values([2, 4], mock)
        rc.on_analog_values([3], mock)

        rc.on_button_pressed(5, mock)

        rc.tick(
            RemoteControllerCommand(
                buttons=[True] * 32,
                analog=[255, 254, 253, 123, 43, 65, 45, 42]))

        self.assertEqual(3, mock.call_count)
        self.assertEqual(254, rc.analog_value(1))
        self.assertTrue(rc.is_button_pressed(1))

        mock.reset_mock()

        rc.reset()

        self.assertEqual(0, rc.analog_value(1))
        self.assertFalse(rc.is_button_pressed(1))

        rc.tick(
            RemoteControllerCommand(
                buttons=[True] * 32,
                analog=[255, 254, 253, 123, 43, 65, 45, 42]))

        self.assertEqual(0, mock.call_count)
 def test_error_raised_for_invalid_button(self):
     rc = RemoteController()
     self.assertRaises(IndexError,
                       lambda: rc.on_button_pressed(32, lambda: None))
    def test_remote_controller_buttons_need_initial_zero_state(self):
        mock = Mock()
        rc = RemoteController()

        rc.on_button_pressed(5, mock)

        rc.tick(RemoteControllerCommand(buttons=[True] * 32, analog=[]))

        self.assertEqual(0, mock.call_count)
        self.assertFalse(rc.is_button_pressed(1))

        rc.tick(RemoteControllerCommand(buttons=[False] * 32, analog=[]))
        rc.tick(RemoteControllerCommand(buttons=[True] * 32, analog=[]))

        self.assertEqual(1, mock.call_count)
        self.assertTrue(rc.is_button_pressed(1))

        rc.tick(RemoteControllerCommand(buttons=[False] * 32, analog=[]))
        mock.reset_mock()
        rc.reset()

        rc.tick(RemoteControllerCommand(buttons=[True] * 32, analog=[]))
        rc.tick(RemoteControllerCommand(buttons=[True] * 32, analog=[]))

        self.assertEqual(0, mock.call_count)
        self.assertFalse(rc.is_button_pressed(1))