cameron5906 / OverkillFramework

A .NET Core framework for building telepresent robots with modular functionality through plugins and custom drivers. Overkill is meant to allow for the easy development of robots controllable from anywhere.
0 stars 0 forks source link

Change the way manual driving input works #16

Closed cameron5906 closed 4 years ago

cameron5906 commented 4 years ago

Instead of having a single Locomotion Message that user interfaces send to the vehicle, this allows the vehicle to declare valid inputs itself - even registering default bindings for keyboard keys and gamepad buttons.

This change allows user interfaces to not need to care about logic that is used to decide what values are sent to the vehicle's interface (speed, how far to turn the wheels, etc) and leave that up to the vehicle driver instead.

The Locomotion message and topic still remain in case there is a use case where someone needs direct angle and speed control - and so Plugins may still instruct the vehicle to move.

Example from the Traxxas test project:

public void Initialize()
{
    SetupInputs();
}

void SetupInputs()
{
    inputService.Keyboard("TurnLeft", KeyboardKey.A, state =>
    {
        Console.WriteLine($"TurnLeft {state}");
        inputSteering = state == InputState.Pressed ? 0 : NeutralSignal;
        SendPacket(inputThrottle, inputSteering);
    });

    inputService.Keyboard("TurnRight", KeyboardKey.D, state =>
    {
        Console.WriteLine($"TurnRight {state}");
        inputSteering = state == InputState.Pressed ? 100 : NeutralSignal;
        SendPacket(inputThrottle, inputSteering);
    });

        inputService.Keyboard("MoveForward", KeyboardKey.W, state =>
        {
            inputThrottle = state == InputState.Pressed ? NeutralSignal + powerLimit : NeutralSignal;
            SendPacket(inputThrottle, inputSteering);
        });

        inputService.Keyboard("MoveBackward", KeyboardKey.S, state =>
        {
            inputThrottle = state == InputState.Pressed ? NeutralSignal - powerLimit : NeutralSignal;
            SendPacket(inputThrottle, inputSteering);
        });

        inputService.GamepadJoystick("Steering", GamepadInput.JoystickL, axes =>
        {
            inputSteering = Math.Abs(axes.x) < 0.05 ? NeutralSignal : NeutralSignal + (int)(axes.x * 50);
            SendPacket(inputThrottle, inputSteering);
        });

        inputService.GamepadJoystick("Throttle", GamepadInput.JoystickR, axes =>
        {
            inputThrottle = Math.Abs(axes.y) < 0.05 ? NeutralSignal : NeutralSignal - (int)(axes.y * 50);
            SendPacket(inputThrottle, inputSteering);
        });
}

These controls have names so that the user interface can re-map to any other key or gamepad button - the second argument is just the default suggested button. These inputs are specified in the configuration file like so:

"Input": {
    "Keyboard": {
      "TurnLeft": "A",
      "TurnRight": "D",
      "MoveForward": "W",
      "MoveBackward": "D",
      "Horn": "Space"
    },
    "Gamepad": {
      "Steering": "JoystickL",
      "Throttle": "JoystickR",
      "Horn": "X"
    }
  }

If a vehicle driver attempts to register an input that is not named in this file, the value in the file is incorrect, or a handler has already been registered, a relevant exception is thrown.

cameron5906 commented 4 years ago

Tested and working