We created this RobotC function for our FTC robot because we wanted finer joystick control at slower speeds without needing to depress a button.
Try it out and see if your team likes it as much as we do.
Last year we had a button that would scale down or up drive motor power if a button was held down while operating the joysticks. This was hard for our driver to do, and eventually she just gave up and operated continuously at a medium range with a maximum power of 75%.
Pushing a bowling ball up this year's "Bowled Over!" ramp meant we needed 100% power, but fine joystick control was also desired for picking up crates and balls. So, we created a simple function that related joystick values to motor power. First, we tried a squared relationship, but this was too abrupt. Then we used RobotC's POW function to raise the joystick value to a power of 1.4. Then we changed the way a typical dead-zone region worked around zero joystick values, to make it more appropriate for exponential values (basically we weren't moving for the first half of the joystick movement).
Note: computers can't deal with raising negative values to non-integer powers, so we first take the absolute value (ABS) of the joystick values. At the end we multiply everything by 1 or -1 using RobotC's SGN math function.
Place the following 3 variable definitions where you can access them easily for making adjustments based on your robot's characteristics and desired performance.
const int cJoyDead = 8; // joystick range in which movement is considered accidental
const int cMotorMin = 15; // minimum drive motor power
const float cDriveExp = 1.4; // exponent for drive power calculations (1 = linear, 2 = squared)
Then place the Exponential Drive function where your joystick handler can call it:
int expDrive (int joyVal, float driveExp, int joyDead, int motorMin)
int joyMax = 128 - joyDead;
int joySign = sgn(joyVal);
int joyLive = abs(joyVal) - joyDead;
return joySign * (motorMin + ((100 - motorMin) * pow(joyLive, driveExp) / pow(joyMax, driveExp)));
Finally, replace your current driving statements with the following code:
motor[yourLeftMotorName] = -1 * expDrive(joystick.joy1_y1, cDriveExp, cJoyDead, cMotorMin);
motor[yourRightMotorName] = -1 * expDrive(joystick.joy1_y2, cDriveExp, cJoyDead, cMotorMin);
Note: In the above statement, you redefine which end is the "front" of your robot by changing -1 to 1.