Menu

#47 jsJoystick::open() breaks system calibration on Linux

open
nobody
patch (1)
5
2015-05-21
2015-05-21
No

Hello,

Opening a joystick with plib on Linux breaks the in-kernel user settings for that joystick (as set by jscal(1)). More specifically, the lower and upper bounds of the dead band managed by the Linux joystick driver are both overwritten by jsJoystick::open() with their arithmetic mean (after integer truncation), effectively killing the dead band carefully configured by the user. This has bitten a few users, for instance http://forum.flightgear.org/viewtopic.php?f=24&t=26084.

To reproduce the problem, you can do:

jscal -s <joystick calibration settings with dead band(s)> /dev/input/js0
# (or 'jscal-restore /dev/input/js0')

# Should print the same 'jscal -s ...' command line (current settings)
jscal -p /dev/input/js0

[run a program that opens /dev/input/js0 with plib, for instance
 js_demo from the plib examples, or FlightGear]

# Print the new joystick settings, with the two parameters specifying
# the lower and upper bounds of the kernel driver dead band overwritten
# by the plib-using program
jscal -p /dev/input/js0

The modification of kernel driver settings happens in lines 84-94 of src/js/jsLinux.cxx and was introduced in revision 1982 of the Subversion repo after https://sourceforge.net/p/plib/mailman/message/13379198/. IMHO, these lines should be simply removed, as done in the attached patch:

  • this is not useful (if the user wants no dead band managed by the kernel joystick driver, jscal(1) is the right tool for the job);
  • this breaks the joystick configuration for all applications that respect the system calibration instead of blindly overwriting it!
  • this is not in the spirit of the plib documentation (http://plib.sourceforge.net/js/, "JS is essentially just a wrapper to make the various underlying OS mechanisms look the same to application code");
  • this is not consistent with the implementation for other platforms (I looked at the Windows and MacOS X code, none of which seems to alter the system settings).

The person who introduced this change (yup, in 2004) argued that:

At least my thrustmaster topgun joystick/thrust combo works much better with this patch. Without, the kernel driver introduces an unrecoverable deadband plateau in the area of 50% thrust, which is pretty senseless to have on the thrust axis. Even on the other axis I prefer to have exactly one deadband
parameter. Since plib has it's own ones, only take those ones.

If that person is bothered by the in-kernel dead band management, the correct solution is to use jscal(1) to remove that dead band, not to break all users settings. This is done by giving the same value to the two constants setting the lower and upper bounds of the dead band. For instance, the following command:

jscal -s 6,1,0,90,100,9256113,9760991,1,0,87,94,9256113,8947575,1,1,75,93,10956215,8388352,1,1,87,87,7354172,7254791,1,0,0,0,-2147483648,536854528,1,0,0,0,-2147483648,536854528 /dev/input/js0

defines the calibration settings for a joystick with 6 axes. The part corresponding to the first axis is "1,0,90,100,9256113,9760991". In this part, 90 and 100 define a dead band of width 10 (in the units sent by the hardware). Setting both to, for instance 95, will effectively remove this dead band while keeping the same center. The last two coefficients must be adapted accordingly; I can explain that, but I don't think this bug report is the right place for such an explanation.

Correctly calibrating an analog joystick takes some time. For users' sanity, applications must allow them to do that once, in a place that is used by all applications. If each application requires its own calibration, that is very annoying and time-consuming for users. And it is even worse if some applications arbitrarily overwrite the system settings...

As promised, I am attaching a patch removing the lines from src/js/jsLinux.cxx that cause this bug. Thanks for considering.

Regards

1 Attachments

Discussion


Log in to post a comment.