Go to Post ...as one of my favorite students (they are all my favorites)... - JaneYoung [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 02-02-2008, 13:26
EHaskins EHaskins is offline
Needs to change his user title.
AKA: Eric Haskins
no team (CARD #6 (SCOE))
Team Role: College Student
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Elkhorn, WI USA
Posts: 998
EHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond repute
Send a message via MSN to EHaskins
Problem with negitive numbers

I've been working on a velocity PID for motor control, but I'm having trouble.

When the PID calculation returns a positive value the code runs fine, but when it return a negitice value the motor output begins jumping appearently randomly from very high(5 digit) to very low(-5 digit) values.

Once this happens the PID reacts correctly, but due to the values that a far outside of normal it never recovers.

Here is the code I think contains the issue, but I can't find it. I added some comments to help explain the issue.
Code:
void MotorControl (unsigned char motor)
{
         
    //The printfs in CalculateSpeed() give correct data. 

	int speed = CalculateSpeed(motor);
	int output;
	//printf("speed on motor %d = %d\r\n", motor);
	//printf("Speed Goal = %d\r\n", speedGoal[motor]);

    // Last line in PID prints the PID output, and it always appears correctly. 

	output = PID(speed, speedGoal[motor], &pidInfo[motor]);
 	currentOutput[motor] += output;

	if (loopCount == 0)
	{
          //This is where the issue is obvious. It prints strange values within
          //the same loop as PID() returns a negitive value, and then until reset.

        
		printf("Output %d = %d\r\n\r\n\r\n", motor, (int)currentOutput[motor]);
	}
	switch (motor)
	{
		case 0:
			MOTOR_ONE = LimitInput(currentOutput[motor] + 127, 0, 255);
			//printf("Motor one set during %d\r\n", motor);
			break;
		case 1:
			MOTOR_TWO = LimitInput(currentOutput[motor] + 127, 0, 255);
			//printf("Motor one set during %d\r\n", motor);
			break;
	}
}
__________________
Eric Haskins KC9JVH

Last edited by EHaskins : 03-02-2008 at 12:58.
  #2   Spotlight this post!  
Unread 02-02-2008, 14:06
usbcd36's Avatar
usbcd36 usbcd36 is offline
Registered User
AKA: "DOS"
FRC #2399 (The Fighting Unicorns)
Team Role: Mentor
 
Join Date: Jan 2007
Rookie Year: 2006
Location: Solon, OH
Posts: 151
usbcd36 is a jewel in the roughusbcd36 is a jewel in the roughusbcd36 is a jewel in the rough
Re: Problem with negitive numbers

What do your functions do? Could the problem exist there?

What variable types are you using? Unsigned variables dropping below zero and incorrect casting can cause problems similar to what you are describing.
  #3   Spotlight this post!  
Unread 02-02-2008, 15:49
dcbrown dcbrown is offline
Registered User
AKA: Bud
no team
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Hollis,NH
Posts: 236
dcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud of
Re: Problem with negitive numbers

Sounds like arithmatic wrap/overflow in a byte value. Check all the variable sizes. The compiler will choose to keep arithmetic in byte value instead of promoting to integer like ansi standard.
  #4   Spotlight this post!  
Unread 02-02-2008, 16:05
Jared Russell's Avatar
Jared Russell Jared Russell is offline
Taking a year (mostly) off
FRC #0254 (The Cheesy Poofs), FRC #0341 (Miss Daisy)
Team Role: Engineer
 
Join Date: Nov 2002
Rookie Year: 2001
Location: San Francisco, CA
Posts: 3,078
Jared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond repute
Re: Problem with negitive numbers

What type is "currentOutput[motor]"?

If currentOutput[motor] is, say, 0, and you try adding -5 to it, you will get overflow unless currentOutput[motor] is a signed type.
  #5   Spotlight this post!  
Unread 02-02-2008, 17:06
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,586
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Problem with negitive numbers

the maximum size for a signed integer is 2^15-1 or 32767. Since you talk about large 5 digit numbers, are you sure you aren't overflowing an int?
  #6   Spotlight this post!  
Unread 02-02-2008, 18:57
David Fort David Fort is offline
Registered User
FRC #1001
Team Role: Mentor
 
Join Date: Feb 2006
Rookie Year: 2003
Location: Cleveland, OH
Posts: 26
David Fort is on a distinguished road
Re: Problem with negitive numbers

When people say, "overflow", they mean the number goes from its lowest value it can represent to its highest value (or vice versa).

For example, and unsigned char can represent values from 0 to 255.

If you add 1 to 255, you get 0.
If you subtract 1 from 0, you get 255.

Suppose in this expression:
currentOutput[motor] + 127
currentOutput is declared something like this:
unsigned char currentOutput[2];

Then if the value is more than 127, you are going to have trouble. I presume that isn't your case, but I used that example because there is something more interesting:

when you add two things and assign to a larger thing, the promotion to the larger thing doesn't happen until the assignment.

suppose the example above, plus
int x;
x=currentOutput[motor] + 127;

now, since x is an int, you wouldn't (might not) expect the expression currentOutput[motor] + 127 to overflow just because currentOutput[motor] is, say 200, because 200 + 127 is just 327, and that will easily fit in an int.
However, C, first it will add currentOutput[motor] + 127
using byte sized math, and THEN "widen" it to 16 bits to promote it to an integer type. By then, the overflow has occured, you wrapped back around positive infinity to zero, and you have the wrong value.

(small caveat: If the compiler thinks of 127 as an "int" instead of as a "unsigned char" in the example above, then it will first promote both operands of the + to ints. I don't remember the rules for integer literals off hand, and this compiler may well bend them to save some space anyway. To make the example more precise, and applicable to any C compiler (including ANSI compliant ones), then I could have used two unsigned chars, like intX = ucY + ucZ; In this case, the addition of ucY + ucZ might overflow a byte).

I apologize if I went overboard on the detail. This is the sort of thing that confuzles the kids on our team frequently, so I thought maybe some background would help.

David Fort
Team 1001
Hacksaw
  #7   Spotlight this post!  
Unread 02-02-2008, 22:45
EHaskins EHaskins is offline
Needs to change his user title.
AKA: Eric Haskins
no team (CARD #6 (SCOE))
Team Role: College Student
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Elkhorn, WI USA
Posts: 998
EHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond repute
Send a message via MSN to EHaskins
Re: Problem with negitive numbers

Quote:
Originally Posted by usbcd36 View Post
What do your functions do? Could the problem exist there?

What variable types are you using? Unsigned variables dropping below zero and incorrect casting can cause problems similar to what you are describing.
Here are the prototypes for the other function involved.
Code:
void Motor(char motor, int speed); //Sets the goal for the PID calculation
void ProcessDrive(void); //Performs PID calculations for all motors, and sends outputs
void MotorControl(unsigned char motor); //Performs PID calc for each motor. Called from ProcessDrive
PIDInfo GetNewPIDInfo (void); //Creates a PIDInfo struct using default values.
void InitializeDrive(void); //Performs drive system initialization. Called from UserInit
int CalculateSpeed(unsigned char motor); //Calculates the speed of a given motor 
int PID (int input, int goal, PIDInfo *info); //Performs PID calc using the supplied params.
As I tried to explain, I have several printfs thoughout the different function, so I am confident that the values are correct until the first printf in the code in my first post.

I'm familiar with overflows, and have had them catch me before. I assumed that was the issue, but I couldn't where the it was happening.

Quote:
Originally Posted by Abwehr View Post
What type is "currentOutput[motor]"?

If currentOutput[motor] is, say, 0, and you try adding -5 to it, you will get overflow unless currentOutput[motor] is a signed type.
It is defined here.
Code:
int currentOutput[NUMBER_OF_MOTORS];




I'm confident the overflow is occuring in one of these two lines(comments added), since the printf at the end of PID has the correct value, and the printf immediatly following these lines shows the incorrect value.
Code:
	output = PID(speed, speedGoal[motor], &pidInfo[motor]); //returns int
 	currentOutput[motor] += output; //These are both ints
I was able to determine that the switching from high to low values is an overflow by examining the terminal info, but I still can't identify the primary issue.

Does anyone see an issue with my logic here? What am I missing?

If anyone want to see the full code I'll send it. I would post it, but I don't like posting large amounts of broken code.
__________________
Eric Haskins KC9JVH
  #8   Spotlight this post!  
Unread 02-02-2008, 23:10
Uberbots's Avatar
Uberbots Uberbots is offline
Mad Programmer
AKA: Billy Sisson
FRC #1124 (ÜberBots)
Team Role: College Student
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Avon
Posts: 739
Uberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond reputeUberbots has a reputation beyond repute
Re: Problem with negitive numbers

check your PID loop... maybe you inadvertedly got rid of a typecast.

also, are you sure you dont have any longs defined in there?
__________________
A few of my favorite numbers:
175 176 177 195 230 558 716 1024 1071 1592 1784 1816
RPI 2012
BREAKAWAY
  #9   Spotlight this post!  
Unread 03-02-2008, 00:14
dcbrown dcbrown is offline
Registered User
AKA: Bud
no team
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Hollis,NH
Posts: 236
dcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud of
Re: Problem with negitive numbers

If you suspect overflow in currentOutput, then bump it from int to short long type to see if the symptoms change.
  #10   Spotlight this post!  
Unread 03-02-2008, 10:47
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: Problem with negitive numbers

I don't see anything that defines the type of output. If it were an unsigned variable, it would give the behavior you describe.
  #11   Spotlight this post!  
Unread 03-02-2008, 13:05
EHaskins EHaskins is offline
Needs to change his user title.
AKA: Eric Haskins
no team (CARD #6 (SCOE))
Team Role: College Student
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Elkhorn, WI USA
Posts: 998
EHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond repute
Send a message via MSN to EHaskins
Re: Problem with negitive numbers

Quote:
Originally Posted by Uberbots View Post
check your PID loop... maybe you inadvertedly got rid of a typecast.

also, are you sure you dont have any longs defined in there?
I did a find in my code, and found only one long. It is used in CalculateSpeed, to store a local copy of the encoder count. The output from CalculateSpeed appears correctly in the printfs in both CalculateSpeed and PID.

Quote:
Originally Posted by Alan Anderson View Post
I don't see anything that defines the type of output. If it were an unsigned variable, it would give the behavior you describe.
It is defined in the code in my first post, line 7. It is an int.

Quote:
Originally Posted by dcbrown View Post
If you suspect overflow in currentOutput, then bump it from int to short long type to see if the symptoms change.
I will try that next time I have access to the robot.
__________________
Eric Haskins KC9JVH
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
Problem with Lofting cooker52 Inventor 14 04-11-2007 15:00
Problem With Footsteps Popper99 3D Animation and Competition 1 04-11-2007 09:34
Problem with RoboEmu2? Calvin Programming 1 12-02-2005 11:27
Problem with communicating with STAMP through serial port Skabana159 Technical Discussion 2 06-02-2003 21:10
Problem with OI / RC Jay Lundy Technical Discussion 2 29-03-2002 23:07


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

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