PDA

View Full Version : Turn 90 Degrees

Mike
12-04-2004, 12:26 PM
Hey guys, recently my team (237) gave me the Robovation kit. I'm still looking around the source code, but i'm starting to understand it. Right now I'm trying to make a function that'll make it turn 90 degrees. I have a good idea on how to do it via the programming aspect, but im mind blocked on the math part.

Heres a pic I drew in paint.
http://img.photobucket.com/albums/v71/mikeperson/mathhelp.jpg

Whats the formula to figure out how many times the wheel needs to turn to go 90 degrees? I'm sure I can just go manually turn it and figure it out, but the formula would be better when I need to have it turn other angles.

:confused: I probably didn't make much sense... it's a saturday.

colt527
12-04-2004, 12:47 PM
Well, it's not that simple. In the code there is no direct way to make the robot turn 90 degrees. You control the motors through the PWM variables. And in that you do not control how many times they turn directly. You control the amount of power that is sent to the individual motor. For example, if pwm01 and pwm02 control the left and right side of you mini-bot:

pwm01 = 0;
pwm02 = 255;

Your robot would go spining to the left, it would not stop until you set pwm01 and pwm02 back to 127. The easiest, but least accurate method of doing what you are talking about would be "dead reconing" in which you just set pwm01 = 0 and pwm02 = 255 for a certain amount of time, which you can control by using a simple incrementing variable.

Here is some source to help you out. I'm just typing it in here, so I don't know if I made a stupid syntax error, but the general logic should all be there.

long int timer = 0; //Declare this globally at the top of the file. Right under the includes.

... //Code left out for posting purposes.

//Here is you main function you will be editing in.
//This function gets called every 17ms, so you can make a simple timer based off that

void Process_Data_From_Master_uP(void)
{
Getdata(&rxdata); /* Get fresh data from the master microprocessor. */

Default_Routine(); /* Optional. See below. */

//Start 90 degree turn code
//All this is doing is saying send 12 volts to the motor hooked up to pwm07 and send -12 volts to the motor hooked up to pwm08 for 1 second. After 1 second is done make both motors neutral. 1 second = about 59 loops though the code since it updates every 17ms. If you use a stop watch to grab the amount of time it takes to turn 90 degrees you can use the following equation to figure out what to put in.
//Number got on stop watch * 1000/17. Then just throw that in place of 59.

if(timer > 0 && timer < 59)
{
pwm07 = 255;
pwm08 = 0;
}
else
{
pwm07 = 127;
pwm08 = 127;
}

timer++;//Increment the timer variable by 1, this says 17ms has passed.

printf("PWM OUT 7 = %d, PWM OUT 8 = %d\n",(int)pwm07,(int)pwm08); /* printf EXAMPLE */

Putdata(&txdata); /* DO NOT CHANGE! */
}

I hope I helped, if its still confusing IM me at coltfive2seven on AIM

The next ways which are more advanced but still not 100% accurate would be to use a gyroscope, which sences angular rate. So if the robot is turning to the right then it would sence it. You could use that in combination with some guese and check to get a reasonable accurate 90 degree turn.

Mike
12-04-2004, 01:01 PM
Well, it's not that simple. In the code there is no direct way to make the robot turn 90 degrees. You control the motors through the PWM variables. And in that you do not control how many times they turn directly. You control the amount of power that is sent to the individual motor. For example, if pwm01 and pwm02 control the left and right side of you mini-bot:

pwm01 = 0;
pwm02 = 255;

Your robot would go spining to the left, it would not stop until you set pwm01 and pwm02 back to 127. The easiest, but least accurate method of doing what you are talking about would be "dead reconing" in which you just set pwm01 = 0 and pwm02 = 255 for a certain amount of time, which you can control by using a simple incrementing variable. Ill post some source code for that in a second.

btw: IM me on AIM @ coltfive2seven if you want some more in-depth explination.

The next ways which are more advanced but still not 100% accurate would be to use a gyroscope, which sences angular rate. So if the robot is turning to the right then it would sence it. You could use that in combination with some guese and check to get a reasonable accurate 90 degree turn.
I think a gyroscope is out of the question, i'll be sure to IM you later. Thanks.

jgannon
12-04-2004, 01:13 PM
The way that is more accurate than dead reckoning but not as complex as a gyroscope is an encoder. You can use either an optical sensor, like the Banner sensor in the KOP, or a potentiometer that has no stop (multi-turn, you call that?). Either one of these will count the revolutions of the wheel, which makes it easier to measure how far it has gone. To implement the optical sensor, you'd have to paint white dots on the wheels so the sensor can have something to count. You wouldn't have to do that, and you'd have less error with a pot, but it's a little trickier to figure out how to mount a pot on the EDU bot. There are numerous coding examples on these forums that will explain how you can program this.

Matt Attallah
12-04-2004, 01:22 PM
...Shouldn't this be under Programming?

Mike
12-04-2004, 01:51 PM
...Shouldn't this be under Programming?
I thought it was more of a math question then a programming one.

EDIT: Mods feel free to move it if I was wrong

Tom Bottiglieri
12-04-2004, 02:34 PM

check that thread for info on encoders

jgannon
12-04-2004, 02:39 PM
Thanks, Tom. I knew there was a thread around here somewhere. :)

Mike
12-04-2004, 02:46 PM

check that thread for info on encoders
Thanks, heres what I'm going to do.

Somehow measure the amount of time it takes for the wheel to spin one revolution at speed x.
Set it to run at speed x for the needed amount of length/time.

EDIT: thats not exactly what im going to do, I can't explain it... but it'll work

Alan Anderson
12-04-2004, 05:42 PM
Whats the formula to figure out how many times the wheel needs to turn to go 90 degrees?
You'll have to start by figuring out how far the wheel has to travel. Then you can divide by the circumference of the wheel to turn that into the number of revolutions.

To compute the required travel, you'll need to know the position of the stationary center of rotation and the distance from that point to the wheel. If you're trying to turn by applying power to one of the rear wheels, the other wheel is the stationary point and the turning radius is the distance between the wheels. If you're going to apply forward power to one wheel and reverse power to the other, the stationary point is directly between them and the turning radius is 1/2 the distance.

Then just use the simple formula for the circumference of a circle (C = 2*pi*r) and divide by four to find out how far the wheel has to go for a quarter turn. Now divide by the circumference of the wheel itself et voila! you now know how many revolutions the wheel must make to perform the 90 degree turn.

Making the wheel turn that many times is left to you as an exercise.

Salik Syed
12-04-2004, 07:51 PM
i think it is only simple to do it mathematically w/ a 2 wheel drive robots... .use the distance between two wheels as your turning diameter multiply that times pi for circumferance... now to turn 90 deg it is the (circumferance / 4 )/(wheel circumfrence) to get revoutions of wheel needed....
now if you have four wheels i think it gets trickier because the radius along which each wheel / side turns seems to be uncalculable ...easily ... at least i can't think of a way... also the other side kinda affects it...

jgannon
12-04-2004, 08:52 PM
Somehow measure the amount of time it takes for the wheel to spin one revolution at speed x.
Set it to run at speed x for the needed amount of length/time.
Here's what I would suggest. This is kinda pseudo-code, but you'll get the idea.

#define COUNT 20 //determine this number experimentally

void turn90(void)
{
int i=0;
int last=0;
while(i<COUNT)
{
pwm01=255;
pwm02=0;
if(rc_ana_in01<last)
i++;
last=rc_ana_in01;
}
pwm01=127;
pwm02=127;
}

COUNT is the number of revolutions it takes for your robot to turn 90 degrees. You have two servos connected to pwm01 and pwm02. You have a multi-turn pot on analog input 01. The value from the pot goes from 0 to 1023, and then starts over at 0 again. (That's just how the processor does it, for some reason. I dunno why they went with 10 bits instead of 8.) If the number is suddenly less than it was last time it checked, then the pot has made a complete revolution. This is more precise than measuring time, because the values needed for other angles are not 1:1, due to inertia and stall friction. If you wanted an angle of 45º, change it to while(i<COUNT/2). If you want 180º, change it to while(i<COUNT*2). I'm not sure if I'm making any sense, so ask me if you don't understand it.

Mike
12-05-2004, 11:08 AM
Here's what I would suggest. This is kinda pseudo-code, but you'll get the idea.

#define COUNT 20 //determine this number experimentally

void turn90(void)
{
int i=0;
int last=0;
while(i<COUNT)
{
pwm01=255;
pwm02=0;
if(rc_ana_in01<last)
i++;
last=rc_ana_in01;
}
pwm01=127;
pwm02=127;
}

COUNT is the number of revolutions it takes for your robot to turn 90 degrees. You have two servos connected to pwm01 and pwm02. You have a multi-turn pot on analog input 01. The value from the pot goes from 0 to 1023, and then starts over at 0 again. (That's just how the processor does it, for some reason. I dunno why they went with 10 bits instead of 8.) If the number is suddenly less than it was last time it checked, then the pot has made a complete revolution. This is more precise than measuring time, because the values needed for other angles are not 1:1, due to inertia and stall friction. If you wanted an angle of 45º, change it to while(i<COUNT/2). If you want 180º, change it to while(i<COUNT*2). I'm not sure if I'm making any sense, so ask me if you don't understand it.
Thanks, a few questions tho.

You keep on mentioning "the pot"... whats that?
A member on my team said that doing it this way wouldn't be reliable, because as the battery dies it won't be able to spin the wheel as fast as it did before. Will this fix that?

I'd rather ask questions then just copy/paste... =/

jgannon
12-05-2004, 05:54 PM
You keep on mentioning "the pot"... whats that?
I'm referring to a potentiometer that has no stopping point. I believe this is called a multi-turn potentiometer. If you don't know what this is, one of your mentors probably does. It's a fairly fundamental electronic component.

A member on my team said that doing it this way wouldn't be reliable, because as the battery dies it won't be able to spin the wheel as fast as it did before.
Right... that's the problem I was trying to point out with the method of Somehow measure the amount of time it takes for the wheel to spin one revolution at speed x. Set it to run at speed x for the needed amount of length/time. As the battery wears out, or if you just want to use a different speed, the amount of time to do something will vary. A potentiometer used in this manner measures revolutions, not speed. The amount of revolutions to go a certain distance or make a certain turn will be the same at any speed, assuming that your wheels are not slipping on the driving surface. Does it make more sense now?

Mike
12-05-2004, 06:46 PM
I'm referring to a potentiometer that has no stopping point. I believe this is called a multi-turn potentiometer. If you don't know what this is, one of your mentors probably does. It's a fairly fundamental electronic component.

Right... that's the problem I was trying to point out with the method of As the battery wears out, or if you just want to use a different speed, the amount of time to do something will vary. A potentiometer used in this manner measures revolutions, not speed. The amount of revolutions to go a certain distance or make a certain turn will be the same at any speed, assuming that your wheels are not slipping on the driving surface. Does it make more sense now?
Yes, thanks :o

Tom Bottiglieri
12-05-2004, 08:36 PM
A potentiometer.. or "pot" for short is a electrical component that increases or decreases resistance to flow based on the position of a lead which is attached to a cylinder. A common use for these are volume controls or light dimmer switches.

We can use these on our robots by utilizing the analog input pins. These pins are able to read an analog value, which will give you the amount of voltage flowing into them, rather than just a 1 or 0 from a digital input. As the resistance increases in the pot, the analog value on the RC goes down because more voltage is being dropped in the pot. So, using that value we can figure out how far something is rotated.

The difference between a multi turn pot and an encoder is that one is analog and one is digital. A multi turn pot works on the same basis as a regular pot, but it is able to revolve many times. An encoder is basically a switch that gets turned on a set number of times in a full rotation.

jgannon
12-05-2004, 09:22 PM
Yes, thanks :o
Glad to hear it. PM me if you have any issues with implementing this, and be sure to stop by and say hey to team 1388 when you go to Atlanta.