I'm trying to write a in-app joystick axis calibration tool.

The joystick axis area should be a rectangle, but in the reality it's a non-linear closed curve and I want to increase the accuracy.

The calibration should work this way: we have a measured value, and this way we get the correct value:

Correct value = [(measured value)/range] * wantedrange

where range is the difference between the maximum and minimum value measured for that axis. But there is also an offset to move the center point to the right position, how to calculate it?

EDIT: I also made an image: green rectangle is the expected area, red shape is the "real" inaccurate measured area, finally blue is the wanted calibrated area that I shift to (0,0) so that I can use the ratio to convert coordinates to the bigger green rectangle.

enter image description here

EDIT2: This image explains how calibration can be even more accurate, thanks to zapl answer: If we find the blue rectangle center, we can divide the rectangle in 4 rectangles and calculate a ratio between that range and the green rectangle's range. And the code should be something like this:

if(value<axiscenter) correctedvalue = ((value-axismin)/(axiscenter-axismin)) * wantedaxisrange;
else correctedvalue = wantedaxisrange + ((value-offset-axiscenter)/(axismax-axiscenter-axismin)) * wantedaxisrange;

enter image description here

有帮助吗?

解决方案

You can get the position of the blue rectangle by instructing the user to move the joystick along the edges so that the values you see are the red curve. You should also instruct user to leave joystick in centered position since you usually need to know the center. Calcuated center is not always the real center position.

For each axis separate those values by the side of the center they are on and find those that are the closest to the center point. That would work with calculated center. Now you have the blue rectangle.

E.g. on X axis you see values ranging from 0-20 and 80-100, center is ~50 > blue rectangle is 20 - 80.

Assuming you want to calibrate it so that values are 0-100 (green) you calculate correction for the x axis as

calibratedX = (uncalibrated - 20) * 100 / 60

Values are shifted by 20 to the right (-20 to normalize them to 0-60) and their range is 60 (80 - 20) which you want to upscale to 0-100. After that clip values to 0-100 since they will be outside for every point on the red line that was outside the blue rectangle.

Result looks like this

where pink are the values after transformation, and the pink area outside the green rectangle is cut away.

Regarding the center point: just run it through those calculations as well.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top