Go to Post the political parties should consist of AndyMarkcrats and IFI-icans.... - Josh Hambright [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 08-02-2005, 21:43
Calvin Calvin is offline
Registered User
no team
 
Join Date: Feb 2005
Location: Portland OR
Posts: 105
Calvin has a spectacular aura aboutCalvin has a spectacular aura about
Question Negative numbers?

Taking in the input as p1_y, and output as pwn01... I'm having some problems.

When the joystick is moved the the direction of "128 - 254" it works, yet when "126 - 0" it starts of to work (motor turning) but then full blast turns the other direction. I do not understand what might be the problem. The Code worked fine in the RoboEmu.

Here is a part of the code
Code:
if (p1_y > 127) // This part works
{
pwm01 = (0.007874015748031496062992125984252) * (p1_y - 127) * (p1_y - 127) + 127;
}

else // Does not work
{
pwm01 = (-0.007874015748031496062992125984252) * (p1_y - 127) * (p1_y - 127) + 127;
}
The only differenece it that the 2nd part has " (-0.00787..." a negative number.
Is that the Problem? If not, what am I doing wrong?
  #2   Spotlight this post!  
Unread 08-02-2005, 22:08
Workaphobia Workaphobia is offline
Registered User
AKA: Jon
FRC #1546 (Chaos Inc.)
Team Role: Alumni
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Long Island
Posts: 26
Workaphobia will become famous soon enough
Re: Negative numbers?

You'll find that it's easier to work with the pwm values if at the beginning of your user code you copy the numbers into a signed char, manipulate those, and then at the end translate that back into the unsigned world. This eliminates all this 127 business, so for example you can simply halve your output by dividing by two.
This would look something like "signed char pwm01S = (signed char)pwm01 - 127;".

In the code you posted, it looks like both sections would have problems. You have to take into account two problems with calculations in programming: overflow and round-off error. Even if you know that the final value must fall within the proper range for the type that is expected, the intermediate values may be too extreme. Two chars multiplied by each other is not that safe - what if they're both 255? You get 65025, and even if you subtract 65000 right after that, you still overflowed and get unpredictable results from that point onward in the formula. The solution is to cast to a larger type - instead of "(p1_y - 127) * (p1_y - 127)" it would be "(int)(p1_y - 127) * (p1_y - 127)". The first term is promoted to an integer before multiplication, and the second value is implicitly promoted as well (at least I think; an integer times a smaller value should yield an integer).

Also, since you have a floating point number, you have to make sure it's treated as a float and not an int or char during calculations, using similar casts. Actually, because the float comes first in the formula, you may be in the clear - everything after it might get promoted to a float. I wouldn't be able to tell you without testing it right in front of my face.

To be safe, you can add in redundant casts all over the place for debug purposes. If that doesn't work, add a printf statement that outputs the values at different stages in the calculation, and find out where the discrepancy lies.



Remember that this is an integer processor, and floating point operations are implemented in software. You'll want to avoid calculations in floats when they can be performed using simpler types.
  #3   Spotlight this post!  
Unread 08-02-2005, 22:11
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,113
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: Negative numbers?

The joystick inputs are of type unsigned char. Trying to do arithmetic with them that yields negative results (e.g. p1_x - 127 when p1_x is less than 127) is just asking for things to blow up.

I get around the problem by reading the joystick input values into a temporary int first, and do all the computations with that.
  #4   Spotlight this post!  
Unread 08-02-2005, 22:16
probizzle's Avatar
probizzle probizzle is offline
Registered User
AKA: Prabhas Pokharel
#0639 (Code Red)
Team Role: Programmer
 
Join Date: Dec 2004
Rookie Year: 2003
Location: Ithaca
Posts: 78
probizzle will become famous soon enoughprobizzle will become famous soon enough
Send a message via AIM to probizzle
Re: Negative numbers?

Also,
Code:
...
pwm01 = (-0.007874015748031496062992125984252) * (p1_y - 127) * (p1_y - 127) + 127;...
You will notice that
Code:
...
((p1_y - 127) * (p1_y - 127) + 127) / 127
...
will work much much better for your purposes. Since pwm01 is an unsigned char and the whole thing will be converted to a char later, it does not matter that you are doing integer division.

Sometimes you have to forget the lessons you're taught so well in Comp Sci.
__________________
Code Red Team 639 Winners of the 2005 FingerLakes Regional with 191 and 494.
--
http://pset.deu83.com << my baby
http://www.setgame.com/set/ << it's mother
  #5   Spotlight this post!  
Unread 08-02-2005, 22:41
Workaphobia Workaphobia is offline
Registered User
AKA: Jon
FRC #1546 (Chaos Inc.)
Team Role: Alumni
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Long Island
Posts: 26
Workaphobia will become famous soon enough
Re: Negative numbers?

Quote:
Originally Posted by probizzle
Since pwm01 is an unsigned char and the whole thing will be converted to a char later, it does not matter that you are doing integer division.
Actually when I said it would partly help him, I meant because it's pretty hard to overflow a float by multiplying integers.
  #6   Spotlight this post!  
Unread 09-02-2005, 01:08
Calvin Calvin is offline
Registered User
no team
 
Join Date: Feb 2005
Location: Portland OR
Posts: 105
Calvin has a spectacular aura aboutCalvin has a spectacular aura about
Re: Negative numbers?

Thanks for the fast reply, I'll test the revisions tomorrow at school and see if it works.
  #7   Spotlight this post!  
Unread 09-02-2005, 10:46
Rocketboy's Avatar
Rocketboy Rocketboy is offline
Programmer at work, Pilot by heart
AKA: Daniel Schoessler
FRC #1317 (Digital Fusion)
Team Role: College Student
 
Join Date: Apr 2004
Rookie Year: 2003
Location: Westerville, Ohio
Posts: 67
Rocketboy will become famous soon enough
Send a message via ICQ to Rocketboy Send a message via AIM to Rocketboy
Re: Negative numbers?

I used the same exact process to debug my drive protocol. I wrote a "rampPWMs" feature which ramps the output once every loop. Heres the idea (not actual code):

Code:
getData

unsigned char driveRobot (motor, joystick, sensitivity){

set joystick = p1_y;
set motor = pwm01;
set sensitivity = 5;

if (the joystick is in the dead zone){
return 127
}

else if (the joystick is NOT in the dead zone){


   if (((joystick + sensitivity)is greater than (the motor value + sensitivity))
   && ((the motor value + sensitivity) < MAX_SPEED){
   // IF we get here the motor is accelerating, and has not reached it's goal
   yet.
   return motor + sensitivity;
   }


   else if (((joystick + sensitivity) is less than (the motor value - sensitivity)) 
   && ((the motor value - sensitivity) > MIN_SPEED){
   // IF we get here the motor is decellerating, and has not reached it's goal
   yet.
   return motor - sensitivity;
   }


   else return joystick // We have reached our goal PWM setting.

}

else FUBAR;

}

As you might see, this function adds a value named "sensitivity" to the "current motor value" each time it goes through the loop until the value is within "range" (joystick +||- sensitivity) of the joystick. As sensitivity increases, the robot will accelerate faster, and vice-versa. I had to cast temporary int types to each variable to keep them from looping around.

The FUBAR case should never occur (where the joystick is neither in the dead zone nor out of it). But if there was a short in the electrical system or something the process could get FUBAR and the robot might do some strange things.

Anyway, I had the same problems you have until I cast in a signed variable type.
__________________
-- Unofficial Google Advocate --

I soloed my
"Skyhawk" before I even soloed my car!
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Field Elements errors in part numbers Mike Martus Kit & Additional Hardware 0 08-01-2005 19:05
Pneumatic Part Numbers CyberWolf_22 Pneumatics 3 01-10-2004 11:19
A couple of noodle scratchers Cheese Head Programming 11 07-12-2002 09:59
Even more interesting numbers: Division of regional winners archiver 2001 8 24-06-2002 03:10
More interesting numbers...specific to big-ball matches archiver 2001 13 24-06-2002 02:51


All times are GMT -5. The time now is 19:53.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


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