Guide to Exponential Drive Function

Hello everyone. Recently, my team made an exponential drive function for our robot’s drive base. It makes it easier to make small adjustments using the joysticks, while also allowing the robot to move at maximum power if necessary. I wanted to share it with the community.

First of all, let me explain what our drive base code looked like without exponential drive. There were two set____Drive functions that were used in the driver control section. For simplicity, I’ll only include the setLeftDrive function as the setRightDrive function is the same but with the right motors:

1

2

In the pictures above, the values coming from the joysticks are used as the percentages of power each side of the drive base gets. In other words, the percentage (of power) is dependent on the joystick values.

If we graph the relation between joystick values (which will be x-values) to percentage values (y-values), we get the following graph.

10

So when the joystick value is 20, the percentage is also 20 and so on for all the x-values between -100 and 100. But we want something that is not as sensitive. For that we need an exponential function that gives smaller y-values for any given x-value, unless the x-value is 100, in which case, the y-value is also 100 (or close to 100). I’ll skip the process used to find our exponential function (a lot of guess and check work), so here is our new graph with the exponential function (red):

8

The equation for this function is y = 1.2(1.043)^x - 1.2 + 0.2x. However, you may notice that only positive x-values are shown in the graph. That is because this function only works for positive values. In order to get negative percentages, we first need to turn the negative x-value (the joystick value) into a positive, then plug that into the exponential function, and then turn that answer into a negative. Hopefully the following graph will explain what I mean.

12
Capture%20-%20Copy

So now we have two functions for exponential drive (one for when the joystick value is 0 OR positive and one for when the joystick value is negative). When we plug these into the original setLeftDrive and setRightDrive functions from earlier, we get the following:

NOTE: We switched to a single-joystick code for the exponential drive and I suggest you do the same as it is very hard to drive with two joysticks.

13

14

I hope this guide was helpful. Feel free to ask questions or raise concerns.

9 Likes

I believe there is something called a non-linear regression that accomplishes the same thing. Nice code btw.

1 Like

hey, not bad! I might just have to use this…

I am not sure if you have seen the threads talking about using a cubic for this purpose.

Here is my reply on another thread explaining it

Your method seems to work and give reasonable results, it does seem however significantly more complicated and require different math for positive vs negative controller values.

Graphically the difference seems pretty insignificant.

image

graph source

1 Like

I prefer functional programming for this kind of tasks, you can use fabs and a sign function in one simple go, such as:
float output = sgn(input) * 1.2 * pow(1.043, fabs(input)) - 1.2 + 0.2*fabs(input);
sgn() could be implemented as, for example (input > 0) - (input < 0), so a one-liner, if you wish, would read:
float output = ((input > 0) - (input < 0)) * 1.2 * pow(1.043, fabs(input)) - 1.2 + 0.2*fabs(input);
Nice function you’ve got there. I have seen students using a bit simpler solutions, such as x^1.5 or something…

4 Likes

You’re right about a cubic function being a simpler solution to creating exponential drive. I originally tried using a cubic function, but I found that the y-values were too small when -20 < x < 20.

I have one team using cubic (built into PROS) and another doing squared. Main thing with squared is you have to manage the signs, but it gives more power, sooner by flattening out the curve somewhat.

1 Like