Example #1
0
    def __init__(self, active_ports):
        '''
        Instantiates the Revvy motor controller and configures the list
        of motor ports for the Revolution Robotics DC Motor.

        :active_ports: a list of ports on the
            revvy bot that actually have motors plugged into them, 
            ex: ['M1','M4'].
        '''

        # Remove duplicates
        active_ports = set(active_ports)

        # instantiate MCU controller and motor handler
        self.hw_controller = RevvyControl(
            RevvyTransport(RevvyTransportI2CDevice(0x2D, SMBus(1))))
        self.motor_handler = create_motor_port_handler(self.hw_controller)

        self.ports = {}

        # configure active ports for Revvy DC motpr
        for p in active_ports:
            if p in MOTOR_PORTS:
                port = self.motor_handler._ports[int(p.lstrip('M'))]
                port.configure(Motors.RevvyMotor)
                self.ports[p] = DcMotorController(port,
                                                  Motors.RevvyMotor['config'])
            else:
                raise ValueError(f'Invalid motor port {p}')
Example #2
0
    def __init__(self):

        self._comm_interface = RevvyTransportI2C(1)
        self._robot_control = self._comm_interface.create_application_control()
        self._ring_led = RingLed(self._robot_control)

        self._sound = SoundControlV2()

        #self._status = RobotStatusIndicator(self._robot_control)
        self._status_updater = McuStatusUpdater(self._robot_control)
        self._status_updater.reset()

        self._battery = BatteryStatus(0, 0, 0)
        self._imu = IMU()

        self._motor_ports = create_motor_port_handler(self._robot_control)
        self._sensor_ports = create_sensor_port_handler(self._robot_control)

        self.disabled = False

        # Need to enable battery and IMU
        self._status_updater.enable_slot("battery", self._process_battery_slot)
        self._status_updater.enable_slot("axl", self._imu.update_axl_data)
        self._status_updater.enable_slot("gyro", self._imu.update_gyro_data)
        self._status_updater.enable_slot("yaw", self._imu.update_yaw_angles)

        #set led color to purple on init
        self.set_led_color(0x6600cc)
    def test_constructor_reads_port_amount_and_types(self):
        mock_control = Mock()
        mock_control.get_motor_port_amount = Mock(return_value=6)
        mock_control.get_motor_port_types = Mock(return_value={"NotConfigured": 0, "DcMotor": 1})

        ports = create_motor_port_handler(mock_control)

        self.assertEqual(1, mock_control.get_motor_port_amount.call_count)
        self.assertEqual(1, mock_control.get_motor_port_types.call_count)

        self.assertEqual(6, ports.port_count)
    def test_configure_raises_error_if_driver_is_not_supported_in_mcu(self):
        mock_control = Mock()
        mock_control.get_motor_port_amount = Mock(return_value=6)
        mock_control.get_motor_port_types = Mock(return_value={"NotConfigured": 0})
        mock_control.set_motor_port_type = Mock()

        ports = create_motor_port_handler(mock_control)

        self.assertIs(PortInstance, type(ports[1]))
        self.assertEqual(0, mock_control.set_motor_port_type.call_count)

        self.assertRaises(KeyError, lambda: ports[1].configure({"driver": TestDriver, "config": {}}))
        self.assertEqual(0, mock_control.set_motor_port_type.call_count)
Example #5
0
    def __init__(self, interface: RevvyControl, sound_paths, sw_version):
        self._interface = interface

        self._start_time = time.time()

        # read versions
        hw = interface.get_hardware_version()
        fw = interface.get_firmware_version()
        sw = sw_version

        print('Hardware: {}\nFirmware: {}\nFramework: {}'.format(hw, fw, sw))

        self._version = RobotVersion(hw, fw, sw)

        setup = {
            Version('1.0'): setup_sound_v1,
            Version('1.1'): setup_sound_v1,
            Version('2.0'): setup_sound_v2,
        }
        play = {
            Version('1.0'): play_sound_v1,
            Version('1.1'): play_sound_v1,
            Version('2.0'): play_sound_v2,
        }

        self._ring_led = RingLed(interface)
        self._sound = Sound(setup[hw], play[hw], sound_paths or {})

        self._status = RobotStatusIndicator(interface)
        self._status_updater = McuStatusUpdater(interface)
        self._battery = BatteryStatus(0, 0, 0)

        self._imu = IMU()

        def _motor_config_changed(motor: PortInstance, config_name):
            callback = None if config_name == 'NotConfigured' else motor.update_status
            self._status_updater.set_slot(mcu_updater_slots["motors"][motor.id], callback)

        def _sensor_config_changed(sensor: PortInstance, config_name):
            callback = None if config_name == 'NotConfigured' else sensor.update_status
            self._status_updater.set_slot(mcu_updater_slots["sensors"][sensor.id], callback)

        self._motor_ports = create_motor_port_handler(interface, Motors)
        for port in self._motor_ports:
            port.on_config_changed(_motor_config_changed)

        self._sensor_ports = create_sensor_port_handler(interface, Sensors)
        for port in self._sensor_ports:
            port.on_config_changed(_sensor_config_changed)

        self._drivetrain = DifferentialDrivetrain(interface, self._motor_ports.port_count)
    def test_motor_ports_are_indexed_from_one(self):
        mock_control = Mock()
        mock_control.get_motor_port_amount = Mock(return_value=6)
        mock_control.get_motor_port_types = Mock(return_value={"NotConfigured": 0})

        ports = create_motor_port_handler(mock_control)

        self.assertRaises(KeyError, lambda: ports[0])
        self.assertIs(PortInstance, type(ports[1]))
        self.assertIs(PortInstance, type(ports[2]))
        self.assertIs(PortInstance, type(ports[3]))
        self.assertIs(PortInstance, type(ports[4]))
        self.assertIs(PortInstance, type(ports[5]))
        self.assertIs(PortInstance, type(ports[6]))
        self.assertRaises(KeyError, lambda: ports[7])
Example #7
0
    def test_unconfiguring_not_configured_port_does_nothing(self):
        configs = {
            "NotConfigured": {
                'driver': 'NotConfigured',
                'config': {}
            },
            "Test": {
                'driver': "NonExistentDriver"
            }
        }

        mock_control = Mock()
        mock_control.get_motor_port_amount = Mock(return_value=6)
        mock_control.get_motor_port_types = Mock(
            return_value={"NotConfigured": 0})
        mock_control.set_motor_port_type = Mock()

        ports = create_motor_port_handler(mock_control, configs)

        self.assertIs(PortInstance, type(ports[1]))
        self.assertEqual(0, mock_control.set_motor_port_type.call_count)

        ports[1].configure("NotConfigured")
        self.assertEqual(0, mock_control.set_motor_port_type.call_count)
Example #8
0
    def test_configure_raises_error_if_driver_is_not_supported_in_mcu(self):
        configs = {
            "NotConfigured": {
                'driver': 'NotConfigured',
                'config': {}
            },
            "Test": {
                'driver': "NonExistentDriver"
            }
        }

        mock_control = Mock()
        mock_control.get_motor_port_amount = Mock(return_value=6)
        mock_control.get_motor_port_types = Mock(
            return_value={"NotConfigured": 0})
        mock_control.set_motor_port_type = Mock()

        ports = create_motor_port_handler(mock_control, configs)

        self.assertIs(PortInstance, type(ports[1]))
        self.assertEqual(0, mock_control.set_motor_port_type.call_count)

        self.assertRaises(KeyError, lambda: ports[1].configure("Test"))
        self.assertEqual(0, mock_control.set_motor_port_type.call_count)
Example #9
0
    def __enter__(self):
        self._comm_interface = self._bus_factory()

        self._robot_control = self._comm_interface.create_application_control()
        self._bootloader_control = self._comm_interface.create_bootloader_control(
        )

        self._stopwatch = Stopwatch()

        # read versions
        while True:
            try:
                self._hw_version = self._robot_control.get_hardware_version()
                self._fw_version = self._robot_control.get_firmware_version()
                break
            except OSError:
                try:
                    self._hw_version = self._bootloader_control.get_hardware_version(
                    )
                    self._fw_version = Version('0.0.0')
                    break
                except OSError:
                    self._log('Failed to read robot version')

        from revvy.firmware_updater import update_firmware
        update_firmware(os.path.join('data', 'firmware'), self)

        # read version again in case it was updated
        self._fw_version = self._robot_control.get_firmware_version()

        self._log(f'Hardware: {self._hw_version}')
        self._log(f'Firmware: {self._fw_version}')

        setup = {
            Version('1.0'): SoundControlV1,
            Version('1.1'): SoundControlV1,
            Version('2.0'): SoundControlV2,
        }

        self._ring_led = RingLed(self._robot_control)
        self._sound = Sound(setup[self._hw_version](),
                            self._assets.category_loader('sounds'))

        self._status = RobotStatusIndicator(self._robot_control)
        self._status_updater = McuStatusUpdater(self._robot_control)
        self._battery = BatteryStatus(0, 0, 0)

        self._imu = IMU()

        def _set_updater(slot_name, port, config_name):
            if config_name is None:
                self._status_updater.disable_slot(slot_name)
            else:
                self._status_updater.enable_slot(slot_name, port.update_status)

        self._motor_ports = create_motor_port_handler(self._robot_control)
        for port in self._motor_ports:
            port.on_config_changed.add(
                partial(_set_updater, f'motor_{port.id}'))

        self._sensor_ports = create_sensor_port_handler(self._robot_control)
        for port in self._sensor_ports:
            port.on_config_changed.add(
                partial(_set_updater, f'sensor_{port.id}'))

        self._drivetrain = DifferentialDrivetrain(self._robot_control,
                                                  self._imu)

        self.update_status = self._status_updater.read
        self.ping = self._robot_control.ping

        return self