3
\$\begingroup\$

What is the proper way to process joystick input?

Take, for example, the Xbox One controller. XInput returns joystick input along the x and y axis. I'm not sure if the hardware just measures voltage across the two axis, or not; I'm not very knowledgeable, in the hardware domain.

I'm unsure what data processing is done by API's like XInput already - but since the dead zone is still prevalent, I'm assuming XInput does very little input massaging. This leaves me with a few questions:

  • Should the dead zone be clipped circularly or rectangularly?
  • What type of low-pass filter should be applied, if any? Perhaps a moving average should be applied?
  • Should a bias be introduced into the input based on the resting input?
\$\endgroup\$
  • \$\begingroup\$ Quick note: analog joysticks are generally created using two potentiometers, one for each axis. The voltage range is usually either 0-5 or 0-3.3 volts. ADCs typically convert to an n-bit integer, which is then converted to the float input seen by your program. \$\endgroup\$ – XNargaHuntress Mar 11 '15 at 19:31
2
\$\begingroup\$

Most API's don't do much processing. It's best done in hardware or in a device specific driver anyway. There's too much variety in hardware to create the one true processing method. That being said, at the application level most joysticks will need to be processed the same way just to different degrees.

Filtering

Most modern joysticks have little to no noise in the analog sticks so filtering is unnecessary. If your stick does have noise, however, lowpass and moving average filtering are a blunt instrument that will make the input feel soggy/laggy. Your best bet is a Kalman filter which adapts the filter strength based on motion and predicted motion. Here is a demo.

Deadzoning

Square vs circle depends on the stick. Circle is a safe default but the correct deadzone exactly matches the shape of the slop in the stick.

A different style is independent axes, where you deadzone each axis independently. Use this when you're controlling unrelated things like x-axis turning with y-axis movement.

A consideration, based on your game, is whether or not to normalize the position so that the rim of the deadzone has a magnitude of 0. If you don't then the player won't be able to make a movement slower than the size of the deadzone.

Bias

Don't bias based on resting position. This is what the deadzone is for. The stick will rest in a different position every time the player lets go.

Shaping

Something you didn't mention is shaping which adjusts the sensitivity. You'll want to do this after deadzoning (if at all). A simple method is to use the pow function like so: x = pow(x, 1.5) To make the joystick less sensitive, for sniping for example, use a power > 1. To make them more sensitive use a power <1 but >0.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.