Log in

View Full Version : reducing sensativity of joystick for precision?


windell747
17-02-2008, 07:43
Hi, we are using a joystick to act as a throttle. We realize that we don't need to move the joystick far to get the bot moving fast. I'm trying to reduce the sensativty of the joystick near the beginning of the swing for precise control. We could just scale the output down, but I would like to limit the max speed at the top of the swing. Does anyone have any suggestions? I heard of using a cubic equation, but I'm not sure how to impiment this in code. I was also think about using a sine or cos function to multiply to the throttle raw output, but then that would start getting floating point math involved in which i want to try to stay away from.

Thanks,
windell

BigJ
17-02-2008, 08:25
An easy way to stay away from the floating-point math is to do the calculations yourself, round to integers, and make a lookup table. There are way to accomplish these ideas in code though, through using bigger numbers to save precision while making calculations.

Jon Stratis
17-02-2008, 10:34
The cubic equation is actually fairly easy to use. It looks something like this:


long temp;
long answer;
long divisor = 127;
temp =((int)p1_y) - 127; //this centers the input range between -127 and 127
answer = (temp*temp*temp) / (divisor*divisor);
answer = answer + 127; //shift the answer back over to the range 0-255


Just make sure you use longs, because you'll overflow an int! The basic idea is that you have a very shallow curve near 0, and a steeper curve near the extremes (-127 and 127). You get all the way to the extremes because 127^3/127^2 is 127. Throw in a couple of more values, and you see that moving the joystick 30 away from center gives you an answer that's only 3 or 4 away, and it can really help.

jacobhurwitz
17-02-2008, 11:44
An easy way to stay away from the floating-point math is to do the calculations yourself, round to integers, and make a lookup table. There are way to accomplish these ideas in code though, through using bigger numbers to save precision while making calculations.

The disadvantage of a look-up table is that it is extremely difficult to change if the function doesn't work well. Imagine having to change 256 array entries! You can use the cubic code that Eagle gives above or your own quadratic code (which our team uses), while still staying away from floating-point math.

As long as you put all your division at the end of the line, everything will be integer operations and shouldn't take much longer than a LUT.

windell747
17-02-2008, 15:40
Thanks guys! I think ill use the cubic function since its startup time seems to be the lowest. Although I do like the lookup table idea as it is great for motor control! anyways thanks a lot! you're a life saver

windell

m3t4w0rm
17-02-2008, 16:39
just write a prog to write out the table then copy paste into code its really easy to change.

dcbrown
18-02-2008, 09:55
Attached is a EasyC program that has been used in various forms to build mapping tables for the robot in the past. You change the UserInclude.h to match the pwm/encoder pins you are using on the robot and then run the program with the robot up on chocks so the wheels are free to spin.

The program builds C rom data tables for unmapped, linear, two stage linear and a 4th user defined (whatever you want to add) mapping table. You capture the tables from hyperterminal and plug them back into your build environment. Yeah, this is done under no-load conditions, but it gets close enough.

The code determines slowest speed at which the wheels reliably turn, max speed and then derates that to 90% and then tries to match left/right wheel to the current formula with the least difference between left/right and desired mapping point.

The doc file shows uncompensated and linear mapping that results from the program. The program also generates a two step mapping with 80% of joystick travel covering 60% of the robot velocity. The mappings can be changed to whatever is desired.


An example of how the map tables are used.

<wheels.h - data from mapping program>


/* ***** Vector Motor Map 'map0' ***** */
/* ***** linear velocity mapping **** */
rom const unsigned char wheel_lft_map0[256] =
{
/* 0-15 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 28, 37, 46, 55, 64,
/* 16-31 */ 74, 83, 92, 101, 110, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
/* 32-47 */ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
/* 48-63 */ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
/* 64-79 */ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
/* 80-95 */ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
/* 96-111 */ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
/* 112-127 */ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 114, 115, 116, 127,
/* 128-143 */ 138, 139, 140, 148, 148, 149, 149, 150, 150, 151, 151, 151, 152, 152, 152, 152,
/* 144-159 */ 153, 153, 153, 154, 155, 156, 157, 157, 157, 158, 158, 159, 160, 160, 161, 161,
/* 160-175 */ 162, 162, 163, 164, 165, 165, 166, 168, 169, 170, 171, 171, 173, 174, 175, 176,
/* 176-191 */ 177, 180, 181, 183, 184, 186, 188, 192, 194, 198, 203, 208, 215, 221, 229, 232,
/* 192-207 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
/* 208-223 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
/* 224-239 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 253, 252, 252,
/* 240-255 */ 251, 250, 249, 249, 248, 247, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
};
:
.

<wheels.c - program uses currently selected mapping table>

void WheelLft_Set( unsigned char joystick )
{

if (_wheel_map_selected == 0)
_wheel_lft_pwm = wheel_lft_map0[ joystick ];
else if (_wheel_map_selected == 1)
_wheel_lft_pwm = wheel_lft_map1[ joystick ];
else if (_wheel_map_selected ==2)
_wheel_lft_pwm = wheel_lft_map2[ joystick ];
else
_wheel_lft_pwm = joystick;

SetPWM( WHEEL_LFT_PWM, _wheel_lft_pwm );
return;
}

Just something to play with.

Tom Line
18-02-2008, 10:10
Actually, you can create the lookup table in excel in a matter of seconds and copy and paste it over into your code. There's no disadvantage to using a LUT over the formula, other than memory, and since the LUT should be placed in ROM that's not much of an issue either.

Kev
18-02-2008, 10:15
pwm01 = pwm03 =(unsigned char)(((((((int)(p1_y) - NEUTRAL) * ((int)(p1_y) - NEUTRAL)) >> 8)*((int)(p1_y) - NEUTRAL))>>6) + NEUTRAL);


:eek: