Create a low speed drive in programming

Our robots are a little too fast for anyone other than the driver to control. Since we take our robots out for demos and stuff, I being the programmer would want it to be safe. So I have been trying to come up with a program to drive this thing at half speed when the joystick are at full forward. We can’t just divide all the values by 2 because that moves the center from 127 to 63.5. Anybody done such a thing, or can come up with a working program for this? I would appreciate any help
Thanks,
-Bharat

You can divide by 2 then add 63.5.

[edit]

You might want to tweak that reduction ratio a little, though. For example, you might want to multiply by 2/3 or 3/4 instead of 1/2. Whatever you decide to do, you can recenter your range by adding whatever it takes to get your center back to 127.

So a formula would be:

x1reduction_ratio + (127-127reduction_ratio)

And the same for y1

Two simple ways that I can think of off the top of my head:

  1. convert the speeds to signed values then divide by two:
int signValue(int value)				
   {
   	return value - 127;
   }

divide by two then:

int unsignValue(int value)
   {
   	return value + 127;
   }
  1. This one allows for some interesting possibilities. An open-filter system.
char filter[255] = [64,64,65,65,etc,etc];
   motorOutput = filter[joystickInput];

You can simply fill the filter array with [64,196] (middle 50% of speed range) in with a constant slope, or you can experiment with having a curve to, for example, put values near the center closer together to give even greater very low speed control. In fact, you may decided to leave the full range of possible speeds, just make it so the joystick has to be at the far extremes to reach full speed.

Another good way is look up tables. Then you can also set it up so it “ramps” (eg: if you move the joystick 1/2 of the way, it will only bring it up to 1/4 the possible speed, then when you push the joystick all the way, the robot will go up to 1/2 speed (or what have you). The code would look something like this:


const rom unsigned char mytable[256] = {
     56,56,55,55....
};

I wrote a little python script (which I promptly lost) that would generate them for me. There is also an auto-generator here (but your gonna need M$ excel to open it =)

Or perhaps have it divide the difference from 127 in half, add/subtract them and send that to PWMs

Like if your joystick is at 250

250 - 127 = 123 / 2 = 61.5 + 127 = 188.5


int DriveLimiter(int joyvalue)
{
	if(joyvalue > 127)
	{
		return ((joyvalue - 127) / 2) + 127;
	}
	if(joyvalue < 127)
	{
		return 127 - ((127 - joyvalue) / 2);
	}
}

I just did that off top of my head, don’t shoot me if it’s wrong, but that’s the general idea. I think. :slight_smile:

Just to clarify, my second method is the same as Wun’s and my first method is (essentially) the same as Matt’s.

One year, we had our programmer’s make it so the dial on the joystick controlled this scaling factor. This allowed the robot max speed to be dynamically adjusted.

I just do the gearboxes. :wink: Any programmers wanna explain how this is possible?

John

Well I’m not sure what dial you are referring to, but I assume it is a one axis analog input. You could simply multiply the joystick input by a scaling factor (of course after first centering the joystick input around zero by subtracting 127) based on the value of this dial. It would probably be something like this (using the functions from my first example):

motorOutput = unsignValue(signValue(joystickInput) * (dialInput/255));

That is a pretty cool feature, but I think an open loop filter on the inputs should probably give you enough control without doing that.

Here’s another possible solution.


motor=y-((y-center)/factor)

So for example:
y=168 center=127 and factor=2

148=168 - (( 168 - 127 ) / 2 )


‘y’ is the joysticj y-axis, center would be you center value for that joystick(normaly 127) and factor could be changed to scale up or down the output speed.

This code will not work for joystick values less than 127.

The wheel that John is talking about was on the old joysticks. It was a thumb wheel located opposite the y axis trim adjustment wheel. The input was analog and reffered to in the code with a variable name similar to “thumb_wheel.”

Here’s the code to have the thumb wheel control the scaling on a joystick input.

if (joystick < 127) {
     motor = 127 - ((127 - joystick) * (thumb_wheel/254));
} else if (joystick > 127) {
     motor = 127 + ((joystick - 127) * (thumb_wheel/254));
}

Now, I’m not sure about this, but I know the PIC processor is not very good with things like division. This makes me wonder if it would be faster to generate a lookup table before hand, or if the overhead of the division is so minuscule it will not make any real difference.