How to read joysticks and custom controllers built from LEGO(r) bricks.
Among other things, we are building custom controllers out of LEGO(r) bricks by connecting them to optomechanical USB computer mice. This allows the easy conversion of mechanical motion to digital input. Inside the computer, we need to make it easy to access the axes as well.
We want to know the current positions of different controllers. There are up to three axes per controller attached to x, y and mouse wheel.
To make things difficult, there are different types of axes:
There are also different uses for the axes inside:
Now, the usual (but not only) way to map the axes to meanings is to use "limited, with friction" for absolute values, "limited with tension" for first derivatives and "unlimited, with friction" for relative control.
There are, of course, also connected 2D axes but as those are dealt with by existing mice &c, we will concentrate on single, independent axes.
Need to support both axes received from mice and actual joysticks.
The system has to be extensible to several input devices.
The calibration process needs to be trivial: press a key, wriggle the device to extreme positions, and press another key.
When several input devices are used, they should detect among themselves, which ones of them the user is trying to calibrate.
Each input device should define names and characteristics for the axes, for programs to show the user what can be connected to what.
The *Model classes are a central piece of the API. This is a design similar to swing: for each controlled "thing" there is a Model object which implements a relevant interface. This allows us to, e.g., use special models in Jython code so that the variable controlled is actually directly an object attribute - the intent is to use this code in vob.putil.demokeys.
The models are connected to the axes through absolute and relative axis listeners:
There can only be one main model per axis - to not confuse the user. If desired, we may later add the capability to put in "non-main" listeners, but this is not a priority.
The input devices, on the other hand, are represented by a central class which allows programs to access the currently configured input devices: InputDeviceManager. From this class, users may get instances of the InputDevice class. This class also contains the methods for beginning and ending calibration and choosing axes by moving them. The InputDevice classes again allow users to get the axes.