Esempio n. 1
0
def test_rover_create_and_setup(tmpdir):
    directory = str(tmpdir.realpath())
    pilot = QueueReceiver()
    teleop = QueueReceiver()
    ipc_chatter = QueueReceiver()
    ipc_server = CollectServer()

    app = RoverApplication(config_dir=directory)
    app.image_publisher = CollectPublisher()
    app.state_publisher = CollectPublisher()
    app.ipc_server = ipc_server
    app.pilot = lambda: pilot.get_latest()
    app.teleop = lambda: teleop.get_latest()
    app.ipc_chatter = lambda: ipc_chatter.pop_latest()

    try:
        # The application writes a new user configuration file if none exists at the configuration location.
        assert len(glob.glob(os.path.join(directory, 'config.ini'))) == 0
        app.setup()
        assert len(glob.glob(os.path.join(directory, 'config.ini'))) == 1

        # The settings must result in a workable instance.
        assert len(ipc_server.collect()) == 1
        assert not bool(ipc_server.get_latest())
        assert app.get_hz() > 0

        #
        # Change the configuration and request a restart.
        # Write a new config file.
        previous_process_frequency = app.get_hz()
        new_process_frequency = previous_process_frequency + 10
        _parser = SafeConfigParser()
        _parser.add_section('vehicle')
        _parser.set('vehicle', 'clock.hz', str(new_process_frequency))
        with open(os.path.join(directory, 'test_config.ini'), 'wb') as f:
            _parser.write(f)
        #
        # Issue the restart request.
        ipc_chatter.add(dict(command='restart'))
        app.step()
        assert len(ipc_server.collect()) == 2
        assert not bool(ipc_server.get_latest())
        assert app.get_hz() == new_process_frequency
    finally:
        app.finish()
Esempio n. 2
0
def test_command_history_reset():
    relay = MyRelay()
    publisher = CollectPublisher(topic='test/status')
    platform = MyPlatform()

    # With hz=1 the command history threshold is 180.
    application = MainApplication(relay=relay, hz=1)
    application.platform = platform
    application.publisher = publisher
    application.setup()

    # Send the first commands to do valid communication.
    command = dict(steering=0.1, throttle=0.2, reverse=0)
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=command)
            ), application.step()), list(range(10))))
    platform.send(
        dict(time=timestamp(), method='ras/servo/drive', data=dict(wakeup=1)))
    application.step()
    assert not relay.is_open()
    publisher.clear()

    # Send zero commands until just below the threshold.
    zero = dict(steering=0, throttle=0, reverse=0)
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=zero)),
                       application.step()), list(range(180))))
    assert not relay.is_open()
    publisher.clear()

    # And then a good command and some zero commands again.
    # The relay should remain open.
    platform.send(
        dict(time=timestamp(), method='ras/servo/drive', data=command))
    application.step()
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=zero)),
                       application.step()), list(range(10))))
    assert not relay.is_open()
    publisher.clear()

    application.finish()
Esempio n. 3
0
def test_relay_wakeup_reset():
    relay = MyRelay()
    publisher = CollectPublisher(topic='test/status')
    platform = MyPlatform()

    # With hz=1 the command history threshold is 180.
    application = MainApplication(relay=relay, hz=1)
    application.platform = platform
    application.publisher = publisher
    application.setup()

    # Send the first commands to do valid communication.
    command = dict(steering=0.1, throttle=0.2, reverse=0)
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=command)
            ), application.step()), list(range(10))))
    platform.send(
        dict(time=timestamp(), method='ras/servo/drive', data=dict(wakeup=1)))
    application.step()
    assert not relay.is_open()
    publisher.clear()

    # Send the zero commands and wakeup.
    zero = dict(steering=0, throttle=0, reverse=0)
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=zero)),
                       application.step()), list(range(180))))
    platform.send(
        dict(time=timestamp(), method='ras/servo/drive', data=dict(wakeup=1)))
    application.step()
    assert not relay.is_open()
    publisher.clear()

    # After wakeup the counters need to have been reset in order not to revert immediately.
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=zero)),
                       application.step()), list(range(10))))
    assert not relay.is_open()
    publisher.clear()

    application.finish()
Esempio n. 4
0
def test_create_and_setup(tmpdir):
    directory = str(tmpdir.realpath())
    ipc_server = CollectServer()
    pilot = QueueReceiver()
    teleop = QueueReceiver()
    ipc_chatter = QueueReceiver()

    runner = TFRunner(navigator=FakeNavigator())
    app = InferenceApplication(runner=runner,
                               config_dir=directory,
                               internal_models=directory)
    app.publisher = CollectPublisher()
    app.camera = QueueCamera()
    app.ipc_server = ipc_server
    app.teleop = lambda: teleop.get_latest()
    app.pilot = lambda: pilot.get_latest()
    app.ipc_chatter = lambda: ipc_chatter.pop_latest()

    try:
        # The default settings must result in a workable instance.
        app.setup()
        assert len(ipc_server.collect()) == 1
        assert not bool(ipc_server.get_latest())
        assert app.get_process_frequency() != 0

        #
        # Change the configuration and request a restart.
        # Write a new config file.
        previous_process_frequency = app.get_process_frequency()
        new_process_frequency = previous_process_frequency + 10
        _parser = SafeConfigParser()
        _parser.add_section('inference')
        _parser.set('inference', 'clock.hz', str(new_process_frequency))
        with open(os.path.join(directory, 'test_config.ini'), 'w') as f:
            _parser.write(f)
        #
        # Issue the restart request.
        ipc_chatter.add(dict(command='restart'))
        app.step()
        assert len(ipc_server.collect()) == 2
        assert not bool(ipc_server.get_latest())
        assert app.get_process_frequency() == new_process_frequency
    finally:
        app.finish()
Esempio n. 5
0
def test_relay_cycle():
    relay = MyRelay()
    publisher = CollectPublisher(topic='test/status')
    platform = MyPlatform()

    application = MainApplication(relay=relay)
    application.platform = platform
    application.publisher = publisher
    application.setup()

    # Without reliable communication the relay is open.
    application.step()
    assert relay.is_open()
    publisher.clear()

    # A non-zero command.
    command = dict(steering=0.1, throttle=0.2, reverse=0)

    # Send the first commands to do valid communication.
    # The integrity protocol does not assume valid by default.
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=command)
            ), application.step()), list(range(10))))
    assert relay.is_open()
    publisher.clear()

    # Send wakeup to close the relay after startup.
    platform.send(
        dict(time=timestamp(), method='ras/servo/drive', data=dict(wakeup=1)))
    application.step()
    assert not relay.is_open()
    publisher.clear()

    # Simulate communication violations.
    list(
        map(
            lambda i: (platform.send(
                dict(time=timestamp() + i * 1e6,
                     method='ras/servo/drive',
                     data=command)), application.step()), list(range(10))))
    assert relay.is_open()
    publisher.clear()

    # And resume.
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(), method='ras/servo/drive', data=command)
            ), application.step()), list(range(10))))
    assert not relay.is_open()
    publisher.clear()

    # Pretend missing commands but valid communication.
    _null_command = dict(steering=0, throttle=0, reverse=0)
    list(
        map(
            lambda _: (platform.send(
                dict(time=timestamp(),
                     method='ras/servo/drive',
                     data=_null_command)), application.step()),
            list(range(5000))))
    assert relay.is_open()
    publisher.clear()

    # The communication requirements must still be met to let the other side know we are operational.
    platform.send(
        dict(time=timestamp(), method='ras/servo/drive', data=_null_command))
    application.step()
    assert len(publisher.collect()) > 0
    publisher.clear()

    # Wakeup again.
    platform.send(
        dict(time=timestamp(), method='ras/servo/drive', data=dict(wakeup=1)))
    application.step()
    assert not relay.is_open()
    application.finish()
    assert relay.is_open()
Esempio n. 6
0
def test_create_and_setup(tmpdir):
    directory = str(tmpdir.realpath())
    publisher = CollectPublisher()
    ipc_server = CollectServer()
    teleop = QueueReceiver()
    ros = QueueReceiver()
    vehicle = QueueReceiver()
    ipc_chatter = QueueReceiver()
    route_store = ReloadableDataSource(
        FileSystemRouteDataSource(directory=directory, load_instructions=True))
    app = PilotApplication(CommandProcessor(route_store), config_dir=directory)
    app.publisher = publisher
    app.ipc_server = ipc_server
    app.teleop = lambda: teleop.get_latest()
    app.ros = lambda: ros.get_latest()
    app.vehicle = lambda: vehicle.get_latest()
    app.inference = lambda: None
    app.ipc_chatter = lambda: ipc_chatter.get_latest()

    try:
        # The default settings must result in a workable instance.
        app.setup()
        assert len(ipc_server.collect()) == 1
        assert not bool(ipc_server.get_latest())

        #
        # Switch to direct driver mode.
        teleop.add(dict(time=timestamp(), navigator=dict(), button_b=1))
        app.step()
        teleop.add(dict(time=timestamp(), navigator=dict()))
        vehicle.add(dict(time=timestamp()))
        app.step()
        status = publisher.get_latest()
        assert status.get('driver') == 'driver_mode.teleop.direct'
        map(lambda x: x.clear(), [teleop, vehicle, publisher])

        #
        # Change the configuration and request a restart.
        # Write a new config file.
        previous_process_frequency = app.get_process_frequency()
        new_process_frequency = previous_process_frequency + 10
        _parser = SafeConfigParser()
        _parser.add_section('pilot')
        _parser.set('pilot', 'clock.hz', str(new_process_frequency))
        with open(os.path.join(directory, 'test_config.ini'), 'wb') as f:
            _parser.write(f)
        #
        # Issue the restart request.
        ipc_chatter.add(dict(command='restart'))
        app.step()
        assert len(ipc_server.collect()) == 2
        assert not bool(ipc_server.get_latest())
        assert app.get_process_frequency() == new_process_frequency

        # The driver should still be in direct mode.
        teleop.add(dict(time=timestamp(), navigator=dict()))
        vehicle.add(dict(time=timestamp()))
        app.step()
        status = publisher.get_latest()
        assert status.get('driver') == 'driver_mode.teleop.direct'
        map(lambda x: x.clear(), [teleop, vehicle, publisher])
    finally:
        app.finish()