To me, the most fun part of flight simulators is experiencing different vehicles and mastering a control scheme to the point that it feels second-nature. You know…simulating the experience of flying a vehicle. It all starts with having controls that are a good analog for the vehicle in the simulation, so I made a simple human interface device (HID) in an attempt to improve my performance in complex flight simulators.
Many modern flight simulators and all good space flight simulators have control schemes with 6 degrees of freedom (6DOF). My first exposure to this control method was with Descent 2, which came out in 1996. The 6DOF control scheme is especially useful in space flight because it represents every way that a vehicle could move. Since nothing prevents a vehicle from moving in any of those ways in space, it makes sense to take advantage of all of them and give the operator as much control as possible. After watching Starbuck flip her Viper 180 degrees to wreck Cylons while flying backward in Battlestar Galactica, one might wonder why Luke Skywalker couldn’t pull the same stunt while being chased by Darth Vader. The Viper has 6 degrees of freedom and the X-Wing only has 4 (not much of a threat after all, I guess).
Positioning rockets have existed to move craft vertically and laterally for a long time, and are necessary in maneuvers like docking with another craft in orbit. If, for example, it makes sense for my spaceship to strafe left or right whilst shooting, I should be able to make that happen without thinking about it.
I started off looking for a joystick that would meet the following criteria:
- 3 degrees of rotation controlled symmetrically
- 2 degrees of translation controlled symmetrically
- forward and backwards throttle, not necessarily symmetrical
- lots of buttons, especially trigger buttons
By symmetrical, I mean that if I move the controller in some way, such as pushing a slider or a lever to the right of center resting position, moving it the opposite direction should produce the opposite results. A car accelerator pedal is asymmetrical because moving the pedal backwards does not accelerate the car backwards. So that’s 5 symmetrical axis and one not necessarily symmetrical axis. Finding a controller that can make those easy to operate, though, is harder than you might think. There are a few commonly used control schemes for flight simulators, but I wasn’t happy with them.
I thought of the Xbox controller (6-axis gamepad), hands-on-throttle-and-stick (HOTAS) airplane controls, Wiimote, and the Steam controller, but I didn’t find most of them to be intuitive and none of them seemed to meet the requirements. I had written a 2-page manifesto about SDL2, input resolution, and tilt controls, but I cut it because I correctly assumed no one wants to read that.
To make a long story short, I landed on using a combination of devices:
- an expression pedal for forward thrust
- a pedal switch for thrust reversal
- a 2-axis joystick for up/down/left/right
- a 3-axis joystick for pitch/yaw/roll
An expression pedal is the kind of pedal you would find on an organ. It pivots around the middle, has enough friction to stay where you put it when you take your foot off, and is nice and big for high-resolution volume control. There are expression pedals for electric organs that have 3 signal lines and are electrically just potentiometers.
I decided to use an electric piano sustain pedal for the reverse pedal, which was a little tricky because there are several varieties of sustain pedal and they are not all electrically compatible. I used analog inputs for the pedal signals so that the controller could handle any kind of pedal with a software change. This one is normally open but has internal resistance when closed. I used jumpers on the circuit board to configure each device for use with pull-up or pull-down resistors as-needed.
For the 2-axis joystick, I decided to use this “PCFlight Pro” that I picked up at a thrift store and it is bad. I had to rewire the sensors to get better resolution, but the signal was still very noisy. It’s basically an Atari controller, so I treated it like one and wrote software to reduce its resolution to 5 positions per axis: 0, +/-50%, and +/-100%.
All 3 of these devices are managed by a Teensy 3.2 on a perfboard in a 3D-printed enclosure with plenty of room for the nest of solid wires. The software is very simple and customized to these specific parts, but it works great and is compatible with standard gameport devices. Old joysticks and gamepads with gameport cables were limited to 4 analog inputs and 4 button inputs, so the manufacturers started making their own special joystick drivers so that they could get better performance out of joysticks back in the ’90s and ’00s, using multiplexing or digital signals. As a result of that wild west period for computer controllers, only very old or very cheap joysticks interface correctly with my device because, for better or worse, it actually follows the original gameport layout.
For a 3-axis joystick, I already had a very old Microsoft Sidewinder. This thing has a proprietary gameport to USB adapter, so I just plugged it straight into the computer.
The thing works great. It makes intuitive sense to me that the left hand controls translation movement and the right hand controls rotation: after all, I have played a first-person shooter with an Xbox controller before. The pedal controls make similar sense: right foot forward makes vehicle go forward, just like I’m used to, except that taking my foot off the pedal instantly engages cruise control. Doing a dogfight in the Elite Dangerous training scenario, I had the occasion to want to fly backwards, so I bound thrust reversal to the left pedal switch. Stomping down on that pedal to make the evasive maneuver just feels right.
This is my new favorite control setup for flight sims, and in total the parts probably cost about $75-100. I’ve never seen an expression pedal used for this before, but it just makes intuitive sense. The only real problem that I have with it is that some games, like X3: Reunions and X3:Terran Conflict, only support 1 controller input device, so I would like to have all the joysticks managed by the Teensy. That would be great, except that the Sidewinder is not compliant with the simple gameport pinout. In fact, it uses a digital signal through the gameport pins. I did find an AVR driver for it, but there is no official Sidewinder documentation, and I didn’t want to run the risk of setting it up wrong and having to rebuild my controller.
I played some KSP and ED with this setup already, and I’m happy with it. Now that I’m satisfied with my hardware, I’ll just have to actually git gud.