From Team 449 Wiki
OI stands for Operator Input, and is how we refer to the input gathering and processing part of the code, e.g. joysticks and button-to-command mapping.
We use multiple different kinds of button objects to represent using different things as buttons- FactoryJoystickButton represents a typical button that's activated when pressed, TriggerButton is for triggers and joysticks that are activated when pushed a certain amount in a certain direction, and dPadButton is activated when the D-pad on a controller is pressed in a certain direction. All of these extend FactoryButton, an abstract class that both acts as a Jackson-compatible wrapper on WPILib's Button class and a Factory that can produce any of the three kinds of buttons. Any future types of buttons made should extend FactoryButton as well, and once you make the button type, change FactoryButton's static factory method to be able to create your new type of button.
Buttons are mapped to commands via having a List of CommandButton objects in the config file. A CommandButton take a command, a button object, and an action of the button (e.g. being pressed, being released, while held, etc.) We don't need to do anything with the list, as the construction of the CommandButton does the binding.
Throttles are what we call our wrapper objects for a single joystick axis. Currently there are 4, Throttle, ThrottleSmoothed, ThrottleExponential, and ThrottlePolynomial. Throttle is a simple, Jackson-compatible wrapper that adds functionality for inversion. ThrottleSmoothed extends Throttle and adds a deadband and an IIR filter. ThrottleExponential extends ThrottleSmoothed and adds exponential scaling. ThrottlePolynomial also extends ThrottleSmoothed and adds polynomial scaling. All scaling and smoothing is applied properly to the deadband so the deadband only rescales the input, rather than creating an abrupt jump.
The actual OI objects are contain multiple Throttles and occasionally some Buttons, and do math and logic with the throttle outputs and occasionally a D-pad to turn user input into numbers the drive code understands. Currently all OI objects extend OIUnidirectional, which is for tank-style robots that have a left side and a right side, but that will change when we start using holonomic drive systems like Meccanum and swerve. The two types of OIUnidirectional we have are OITank, where the left and right sticks control the velocities of the left and right sides of the drive directly, and OIArcade, where one stick controls forward-back velocity and the other controls turning, such that the output to the left is forward+rot and the right is forward-rot. However, for arcade, we often scale the rotational throttle's output by the output of the forwards throttle, so we get fine control of the angle while standing still and fast turning while going fast. This is implemented in OIArcadeWithDPad.