Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Trouble with Autonomous (http://www.chiefdelphi.com/forums/showthread.php?t=55006)

popnbrown 25-02-2007 20:00

Trouble with Autonomous
 
Well the title of the thread actually isnt exactly my problem. Autonomous works however one of my functions doesn't work. We are trying to get our robot to rotate (a 0 degree turn). I'm using WPILib so we have to write totally new code.

Well anways here is the function Rotate():
Code:


void Rotate(char direction, int degrees, char speed)
{
        int time = (1000 * (degrees/ 300));
        char RightMotor = NEUTRAL + (speed * direction * (SPEED_TO_PWM));
        char LeftMotor = NEUTRAL + (speed * direction * (SPEED_TO_PWM));
        //the SPEED_TO_PWM = 127/10 which converts the speed to PWM value

        printf("Rotate()\r");

        SetPWM(LEFT_WHEEL, LeftMotor);
        SetPWM(LEFT_FRONT_WHEEL, LeftMotor);
        SetPWM(RIGHT_WHEEL, RightMotor);
        SetPWM(RIGHT_FRONT_WHEEL, RightMotor);
       
        printf("time: %d\r", time);
       
        Wait(time);
       
        SetPWM(LEFT_WHEEL, NEUTRAL);
        SetPWM(LEFT_FRONT_WHEEL, NEUTRAL);
        SetPWM(RIGHT_WHEEL, NEUTRAL);
        SetPWM(RIGHT_FRONT_WHEEL, NEUTRAL);
      //NEUTRAL = 127

}

now the main problem is the time. When I pass for example:
Code:

Rotate(-1, 30, 10)
the time displays as 0. I find it really odd. However I ran time as a constant:
Code:

time = 300;
and the function worked perfectly. So the real problem here is one of the variables involved in the time equation and I dont know which one or what is wrong.

Any help would be appreciated

Racer26 25-02-2007 20:07

Re: Trouble with Autonomous
 
I can almost assure you the problem has to do with your equation in the line "int time...." you're generating a float in the middle of it (30/300)= 0.1, which the integer math in the PIC reduces to 0, before continuing with the rest of the math.

As for how to fix it, you could multiply all the numbers involved by say 1000, and divide by 1000 as your last step... or... something.

Joe Ross 25-02-2007 20:13

Re: Trouble with Autonomous
 
The problem is with your order of operations.

time = (1000 * (degrees/ 300)); is evaluated in the following order (with degrees being 30).

ime = (1000 * (degrees/ 300));
time = (1000 * (30/300));
time = (1000 * 0);
time = 0;

Since you don't really care what order the operations happen, the following will work for you.

time = (1000 * degrees) / 300;
time = (1000 * 30) / 300;
time = (30000) / 300;
time = 100;

The only problem with the above example is that if degrees gets above 32, you'd overflow the integer value. You could either declare time as a long, or change your constants, since multiplying by 1000 then dividing by 300 is the same as multiplying by 10 then dividing by 3.

TimCraig 25-02-2007 21:12

Re: Trouble with Autonomous
 
Quote:

Originally Posted by Joe Ross (Post 586305)
Since you don't really care what order the operations happen, the following will work for you.

time = (1000 * degrees) / 300;
time = (1000 * 30) / 300;
time = (30000) / 300;
time = 100;

The only problem with the above example is that if degrees gets above 32, you'd overflow the integer value. You could either declare time as a long, or change your constants, since multiplying by 1000 then dividing by 300 is the same as multiplying by 10 then dividing by 3.

If he doesn't want to declare time as a long and carry that through the rest of the calculations, the following will work with time left as an int.

time = (int) ((long) 1000 * degrees / 300);

or more simply if the compiler is really ANSI compliant

time = (int) (1000L * degrees / 300);

Alan Anderson 26-02-2007 00:17

Re: Trouble with Autonomous
 
The other problem I see is your putting parentheses around your SPEED_TO_PWM macro. With them there, you have a similar rounding issue, and the 127/10 ends up being truncated to 12. If you leave the paretheses off but everything else as it is, the division by 10 won't happen until after all the multiplications are done and you'll end up with more like what you want.

Bharat Nain 26-02-2007 00:19

Re: Trouble with Autonomous
 
Sometimes, really simple is really good.

Stvn 26-02-2007 01:14

Re: Trouble with Autonomous
 
I don't know if it makes a difference, but it might be better if you went:
Code:

int time;
char RightMotor;
char LeftMotor;

time = (1000 * (degrees/ 300));
RightMotor = NEUTRAL + (speed * direction * (SPEED_TO_PWM));
LeftMotor = NEUTRAL + (speed * direction * (SPEED_TO_PWM));


AustinSchuh 26-02-2007 01:21

Re: Trouble with Autonomous
 
Quote:

Originally Posted by TimCraig (Post 586338)
time = (int) (1000L * degrees / 300);

It might be better to simplify that further using some algebra to something like
Code:

time = (int)((long)10 * (long)degrees / (long)3)
That way, you won't run into interger or long overflow problems until degrees is 100 times as large as it would have had to be earlier.

popnbrown 27-02-2007 15:12

Re: Trouble with Autonomous
 
Well I decided to take advice. And:

Code:

long time = (1000 * degrees) / 300;
Yet When I call it as:

Code:

Rotate(-1, 30, 10);
and still time = 0;. This is really getting to me as we have two days till regional. Any1 know what is going on?

TimCraig 27-02-2007 15:39

Re: Trouble with Autonomous
 
Quote:

Originally Posted by popnbrown (Post 587223)
Well I decided to take advice. And:

Code:

long time = (1000 * degrees) / 300;
Yet When I call it as:

Code:

Rotate(-1, 30, 10);
and still time = 0;. This is really getting to me as we have two days till regional. Any1 know what is going on?

One problem but it's probably not your error is that making time long will not force the calculation on the right of the = to be done as long. C only looks at the participants in the equation to decide how to do the arithmetic, not what you're assigning the result to. So again, you need to cast one of one of the leading values on the right side as (long) or use 1000L. C will call 1000 an int and 1000L is a long.

How are you displaying time to know it's zero? Are you still using the %d specifier in your printf? I can't remember if the PICs are little endian or big endian. If they're big endian, you'll only see the high order half of the long value which in this case is zero.

TimCraig 27-02-2007 16:11

Re: Trouble with Autonomous
 
Quote:

Originally Posted by AustinSchuh (Post 586456)
It might be better to simplify that further using some algebra to something like
Code:

time = (int)((long)10 * (long)degrees / (long)3)
That way, you won't run into interger or long overflow problems until degrees is 100 times as large as it would have had to be earlier.

True, he doesn't gain anything in using 1000 and 300 vs 10 and 3. And in that case he doesn't need to force the compiler to do the computation as long. 10 * 360 = 3600 which fits quite comfortably in an int.

BTW, you only need the first (long) cast. Once one element of that calcuation is long, the compiler will force the rest to long to complete it. Actually, casting either the 10 or degrees will do it. Casting the 3 to long will force the result to long but the compiler is free to do the calculation in the parentheses as int then promote it to long before the division.

popnbrown 27-02-2007 19:12

Re: Trouble with Autonomous
 
I tried it this way too and it doesnt work.

Code:

long time = ((long)1000* degrees)/ 300; //degrees is 30
And BTW anyone have gmail and could possibly help me around 8:00 EST today, would reely appreciate it and thank you anyways for your help so far.

Dave Flowerday 27-02-2007 19:19

Re: Trouble with Autonomous
 
Quote:

Originally Posted by popnbrown (Post 587345)
And BTW anyone have gmail and could possibly help me around 8:00 EST today, would reely appreciate it and thank you anyways for your help so far.

You do realize it's illegal to be working on your robot code right now right?
Quote:

On the software side, developing detailed pseudo-code, writing actual lines of code, verification of syntax, final debugging, etc would all be considered development of the final software implementation, and must be completed during the approved fabrication periods.
No writing, no debugging allowed right now.

TimCraig 27-02-2007 19:21

Re: Trouble with Autonomous
 
Quote:

Originally Posted by popnbrown (Post 587345)
I tried it this way too and it doesnt work.

Code:

long time = ((long)1000* degrees)/ 300; //degrees is 30
And BTW anyone have gmail and could possibly help me around 8:00 EST today, would reely appreciate it and thank you anyways for your help so far.

But you didn't answer the burning question. How are you displaying time to get the value of zero?

If you're doing:

printf("Time = %d\r\n", time);

it won't work since %d is going to display a 2 byte integer and not the 4 byte long. It will only display either the upper or lower two bytes depending on whether the PIC is little or big endian.

You need to either:

printf("Time = %d\r\n", (int) time);

or

printf("Time = %ld\r\n", time);

Assuming the implementation of printf you're using is complete enough to accept the %ld specification to print longs.

I don't know this is your problem since you haven't shown your latest version with the printf, but it's a high probability on my list.

popnbrown 27-02-2007 20:32

Re: Trouble with Autonomous
 
O yea we're done working on our code. It's just that I'm gonna be programmin cap next year and I'm trying to get my stuff down. So sry if I seemd to be doin somethin against the rules but thank you for letting me now I guess. Well I'm done anyways. the printf("%ld") works. Thank you


All times are GMT -5. The time now is 21:42.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi