|
|
|
![]() |
|
|||||||
|
||||||||
12/22/2010 Vary the joystick (or any signal which has range -1 to +1) response curve from linear (y=x) to cubic (y=x^3) or anywhere in-between.
12/27/2010 updated to 2-parameter function with tunable inverse deadband
06/05/2014 added piecewise linear gain shaping alternative, with tunable constants a b c
sensitivity adjustment.gif
sensitivity adjustment.txt
2parm-b.pdf
Joystick_Gain_Shaping.png
12-23-2010 06:24 AM
RogerI had fiddled with this off and on years before, but never really worked it out properly or had the time (or a spare robot) during build season. It's nice to see it formalized and posted here.
Just to make it clear (or correct me if I'm wrong), the X and Y are not the actual joystick numbers from the X and Y axis (eg, in y = x^3, axis x number doesn't produce axis y number), but the input and output from each direction, so really you should have two formulas:
AxisX_output = AxisX_input ^ 3
AxisY_output = AxisY_input ^ 3
The deadzone or band would be a separate calculation (at least programming-wise); a simple "if input is between -0.2 and +0.2 then Y= 0". Whilst doing it all at once would be elegant, it would be a nightmare to debug. Though looking at the graph for f(x)=x^3, in all practicallity the robot motors might not overcome robot weight at all under +/-0.3.
I wonder what the effect would be if a<0? That is, more power near zero (to overcome the robot weight) and leveling off at higher speeds.
In practice this would have to be adjusted to each individual robot; even similar robots (a prototype and competition robot for example) would have different results. Also adjust to the driver, as different drivers like different reactions. If the driver doesn't notice it, then it works!
12-23-2010 07:39 AM
Ether
12-23-2010 07:59 AM
Ether|
I had fiddled with this off and on years before, but never really worked it out properly or had the time (or a spare robot) during build season. It's nice to see it formalized and posted here.
Just to make it clear (or correct me if I'm wrong), the X and Y are not the actual joystick numbers from the X and Y axis |
| ...looking at the graph for f(x)=x^3, in all practicallity the robot motors might not overcome robot weight at all under +/-0.3. |
| I wonder what the effect would be if a<0? That is, more power near zero (to overcome the robot weight) and leveling off at higher speeds. |
| In practice this would have to be adjusted to each individual robot; even similar robots (a prototype and competition robot for example) would have different results. Also adjust to the driver, as different drivers like different reactions. |
12-23-2010 05:05 PM
Tom LineWe take a somewhat different approach.
We use four linear equations (y=mx+b). First, we test our robot. So far, every robot we have built has been skid-steer. This means that there is an appreciable amount of motor force that it takes to break the robot into a skid to turn. Utilizing a control on the dashboard, we watch the values required to break it free using only one side. This is the B-intercept of our equation, so that the instant you move the joysticks out of the controller's preprogrammed deadband, you have enough power to turn the robot at the slowest possible speed.
So we use one equation from 0 to about 80% power. This portion has a gentle slope. After that, the slope goes from that point up to 1 (maximum joystick), 1 (maximum motor output). The nice part is that we only need to enter two values into our custom VI. The "B" y-intercept value that the drivetrain manages to start turning the robot at, and the intersection point of the two slopes.
For instance, if you were to graph it, the positive domain of the joystick would have these x,y points:
(X,Y)
(0,0.2)
(0.7,0.7)
(1,1)
I'm trying to attach a picture, but it doesn't appear I can do so in this forum.
12-23-2010 05:09 PM
Ether|
I'm trying to attach a picture, but it doesn't appear I can do so in this forum.
|
12-26-2010 11:26 PM
JogoReally like the idea of that use of throttle.
Out of curiosity, is there anything special about the function x^3+x?
Recently we've used an exponential graph:
Let min = lowest desired value (min>0, usually the highest value at which the robot doesn't move)
Let max = highest desired value (usually, max = 1.0)
Then, output = min(max/min)^joystick value.
This also enables us to vary the max value for the turning axes based on the robot's forward speed.
12-27-2010 10:12 AM
Ether|
Really like the idea of that use of throttle.
Out of curiosity, is there anything special about the function x^3+x? |
|
Recently we've used an exponential graph: Let min = lowest desired value (min>0, usually the highest value at which the robot doesn't move) Let max = highest desired value (usually, max = 1.0) Then, output = min(max/min)^joystick value. |
g(x) = b + (1-b)*[a*x^3 + (1-a)*x] for x>=0 g(x) = -b + (1-b)*[a*x^3 + (1-a)*x] for x<0
| This also enables us to vary the max value for the turning axes based on the robot's forward speed. |
12-27-2010 10:17 AM
EricVanWyk|
Out of curiosity, is there anything special about the function x^3+x? |
12-27-2010 01:36 PM
Jogo@Ether
Cool, will try it with the y-intercept. Really curious if I'll be able to feel a significant difference at different a-values.
When I stated "This also enables us to vary the max value for the turning axes based on the robot's forward speed," I meant that we found at high speeds, a slight tap to the side on the joystick will send the robot flying away. So, for example, when the robot is moving 1.0 (full speed) in the y-direction, then we might only allow the robot to move up to 0.1 in the x-direction. When the robot isn't moving in the y-direction, then we allow the full 1.0 turning speed.
@EricVanWyk
As a student, steering curves was the first time I went from problem->math; it was definitely among my fav. robotics experiences. I will try this with some of the rookie programmers, and maybe my calc teacher 
12-27-2010 02:15 PM
Ether|
When I stated "This also enables us to vary the max value for the turning axes based on the robot's forward speed," I meant that we found at high speeds, a slight tap to the side on the joystick will send the robot flying away. So, for example, when the robot is moving 1.0 (full speed) in the y-direction, then we might only allow the robot to move up to 0.1 in the x-direction. When the robot isn't moving in the y-direction, then we allow the full 1.0 turning speed.
|
12-27-2010 03:49 PM
Ether|
We use four linear equations (y=mx+b). First, we test our robot. So far, every robot we have built has been skid-steer. This means that there is an appreciable amount of motor force that it takes to break the robot into a skid to turn. Utilizing a control on the dashboard, we watch the values required to break it free using only one side. This is the B-intercept of our equation, so that the instant you move the joysticks out of the controller's preprogrammed deadband, you have enough power to turn the robot at the slowest possible speed.
So we use one equation from 0 to about 80% power. This portion has a gentle slope. After that, the slope goes from that point up to 1 (maximum joystick), 1 (maximum motor output). The nice part is that we only need to enter two values into our custom VI. The "B" y-intercept value that the drivetrain manages to start turning the robot at, and the intersection point of the two slopes. For instance, if you were to graph it, the positive domain of the joystick would have these x,y points: (X,Y) (0,0.2) (0.7,0.7) (1,1) |
if (x>=a) then y := c+(x-a)*((1-c)/(1-a)) else if (x>=0) then y :=b + ((c-b)/a)*x else if (x>=-a) then y := -b + ((c-b)/a)*x else y:= -c + (x+a)*((1-c)/(1-a));
12-27-2010 06:48 PM
Ether
01-01-2011 10:59 AM
RogerYesterday I gave this to one of my programmers to put into our LabVIEW code, as a sort of a warm-up exercise. An added bonus was making it a sub-vi to plug into future code.
There is a difference in driving, though perhaps not enough to change a good driver with careful joystick control. We didn't test it fully however.
A suggetion that simplifies changing "a" from rewriting code to letting the driver change it on the fly: use the thumb-thingie on the KOP joystick (it's at the base in the front and is known as axis3). It's range is -1 to +1, but with simple math can be converted to 0 to +1.
01-01-2011 12:44 PM
Ether|
Yesterday I gave this to one of my programmers to put into our LabVIEW code, as a sort of a warm-up exercise. An added bonus was making it a sub-vi to plug into future code.
There is a difference in driving, though perhaps not enough to change a good driver with careful joystick control. We didn't test it fully however. |
01-01-2011 01:55 PM
RogerOh dear, I'm way behind, aren't I? We were using the original y = a(x^3) + (1-a)x formula. That "2parm" looks interesting for Monday's programming session.
I think we might be running out of joystick buttons. We've got 2 buttons already for switching gear speed up and down -- yet another parameter in the mix, as "Full cubic" in first gear is really slow.
Another thing I might mention is that we are changing only the "forward/backward" axis of the joystick, and the "left/right" axis is not being changed. (The robot is a standard drive left/right sides.) General thought of the group is that this gives full turning power always.
01-01-2011 05:17 PM
Ether|
...the "left/right" axis is not being changed...General thought of the group is that this gives full turning power always.
|
01-01-2011 05:35 PM
AustinSchuhThis probably should go in another paper, but it helps handling a lot if you get some speed vs PWM data, and then curve fit it so that you can convert the nonlinear response of the Victors to a nicer linear response. I ended up using a 7th order polynomial last year to do that, and it helped quite a bit.
01-01-2011 05:53 PM
Ether|
This probably should go in another paper, but it helps handling a lot if you get some speed vs PWM data, and then curve fit it so that you can convert the nonlinear response of the Victors to a nicer linear response. I ended up using a 7th order polynomial last year to do that, and it helped quite a bit.
|
01-01-2011 06:05 PM
AustinSchuh# Speed Power Data on blocks. 0.103448 0.020000 -0.103448 -0.020000 0.252874 0.043000 -0.252874 -0.043000 0.333333 0.059000 -0.333333 -0.059000 0.454023 0.082000 -0.454023 -0.082000 0.517241 0.098000 -0.517241 -0.098000 0.614943 0.145000 -0.614943 -0.145000 0.724138 0.184000 -0.724138 -0.184000 0.793103 0.223000 -0.793103 -0.223000 0.885057 0.363000 -0.885057 -0.363000 0.965517 0.559000 -0.965517 -0.559000 1.000000 0.918000 -1.000000 -0.918000
01-01-2011 08:16 PM
Joe Ross
By default, RobotDrive squares the inputs before it outputs the PWM, so you should consider the affects of that on any input adjustments.
01-01-2011 09:44 PM
AustinSchuh|
By default, RobotDrive squares the inputs before it outputs the PWM, so you should consider the affects of that on any input adjustments.
|
01-04-2011 11:22 AM
Roger|
Originally Posted by Ether
What kind of drivetrain are you using, and what type of driver interface?
|
06-20-2014 05:59 PM
jhebbelSorry to revive a more than dead thread but its really the only relevant thread I could find. Im intrigued by the b + (1-b)*[a*x^3 + (1-a)*x] equation, but also confused, doesnt this need to be formated to solve for x and not y? Has anybody done this yet?
06-21-2014 08:00 AM
jhebbelFor anybody else that lands here from Google like I did wondering the similar, The reason I though the equation needed to be formatted to solve for X is I didn't realize this was for inverse deadzone, to calculate for traditional deadzone it is y=G*((x-D)/(1-D))^3+(1-G)*(x-D)/(1-D); Where X is in value, D is Deadzone and G is Gain.