Skip to content

Mapping a Keyboard

dbankieris edited this page Apr 14, 2021 · 2 revisions

As with all devices in IDF, a keyboard's inputs are encapsulated in a derivative of InputLayout: Keyboard.hh.

class Keyboard : public virtual InputLayout {

    public:

    /** constructor */
    Keyboard();

    /** left Ctrl */
    SingleInput leftCtrl;

    /** left Shift */
    SingleInput leftShift;

    /** left Alt */
    SingleInput leftAlt;

    // many more not shown here!

Here you'll find a SingleInput for every key defined by the USB HID Usage Table (see section "10 KEYBOARD/KEYPAD PAGE"), but most keyboards only support a subset of the full table. You can figure out which keys you actually have by running make in examples/basic and then running the resulting keyboard executable. Be sure to edit keyboard.cpp with your keyboard's vendor and product IDs (use HID Scanner to obtain them). Then start mashing keys and see what you get!

When you have an idea of what keys you want to use, the next step is to pass them to the constructor of the controller you want to map them to. For instance, SingleFlightController's constructor requires the six Inputs you want to use for roll, pitch, yaw, x, y, and z.

    /**
     * constructs a new instance using the specified inputs
     *
     * @param roll the input to process as roll
     * @param pitch the input to process as pitch
     * @param yaw the input to process as yaw
     * @param x the input to process as x
     * @param y the input to process as y
     * @param z the input to process as z
     */
    SingleFlightController(
      const Input& roll, const Input& pitch, const Input& yaw,
      const Input& x, const Input& y, const Input& z);

For joysticks, you can usually directly pass a class member (such as Wingman::forwardBackwardPivot for pitch) since it can express the full range by itself. For binary inputs like a keyboard key, some extra effort is required. You probably want positive pitch in response to one key, negative pitch in response to another, and no pitch if neither is pressed. For this, we need a CompositeInput, which will allow us to combine two (or more) inputs into one. For instance:

UsbKeyboard keyboard(0x413C, 0x2101);
CompositeInput pitch = CompositeInput();
// command positive pitch when the up arrow is pressed
pitch.addInput(keyboard.upArrow);
// command negative pitch when the down arrow is pressed
pitch.addInput(keyboard.downArrow, -1);

Now we have an Input that we can pass to SingleFlightController's constructor as the pitch argument. Repeat for the other five parameters, and you've got yourself a flying keyboard! See SIM_composite_inputs for a working example.