Logarithmic Drive is another way to solve the same problem as Precision Mode, but it isn’t exactly the same. With a logarithmic drive, you don’t need a button to change you into precision mode; it automatically goes into precision mode while the joystick is near the center, and goes into high-speed mode near the edges.
You are looking for a function that takes a ±127 speed value and transforms it into a new speed value, also in the ±127 range, but with the values “pulled” towards 0.
There are a couple ways to do this, but an easy way is to apply an exponent or inverse log function to the speed, and then scale the result back to ±127. If the function you used looses the sign (such as squaring a number will do), then you need to restore the sign.
Here is a simple squaring function:
if (RawSpeed >= 0) {
LogSpeed = (RawSpeed * RawSpeed) / 127
} else {
LogSpeed = (RawSpeed * RawSpeed) / -127
}
You can try some numbers and see what you get, but these sample points give you an idea of the result:
[INDENT]If RawSpeed=0 (0%), then LogSpeed=0 (0%)
If RawSpeed=±32 (25%), then LogSpeed=±8 (6%)
If RawSpeed=±64 (50%), then LogSpeed=±32 (25%)
If RawSpeed=±96 (75%), then LogSpeed=±72 (57%)
If RawSpeed=±127 (100%), then LogSpeed=±127 (100%)
[/INDENT]
Another way to solve this is to divide the throttle range into a few “zones” and scale each zone separately. This give you more control to tweak the algorithm until it drives just right, since you can decide the exact points in the range that you will shift from accurate to fast, and you can decide exactly how much each zone “feels” different to drive. This code usually takes the form of several if() statements to pick apart the raw speed value into ranges, and then apply the appropriate linear transformation.
You can also do this with a lookup table. An array of 256 bytes will allow you to explicitly map each joystick setting to an exact speed value. Total control, but a pain to change anything, since you have to manually recompute much or all of the table each time you tweak it.
Cheers,