Go to Post Remember to ALWAYS use physics in engineering discussions. There is really no room for "feelings" in this sort of thing. - JVN [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 06-02-2007, 18:21
kitscuzz's Avatar
kitscuzz kitscuzz is offline
Not alotta posts
AKA: Kit
FRC #1389 (Worst Case Scenario)
Team Role: Programmer
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Home
Posts: 47
kitscuzz will become famous soon enough
Unhappy Bizarre Driving Issue

So we're using four wheels, four motors.

We set them up to run through some deadzone code, then perform some calculations, and assign the power to the PWMs in pairs.

The idea is to have the simpliest of holonomic drive code possible.

Here's the jist of it:
Code:
	if(!p2_sw_trig) //if not turning
	{	//deadzone
		if(p2_x<122) 	//more than 5 below 127
		{
			deadx = ((p2_x - 122) * 127)/122 + 127;	//scaling so we don't just jump from 127 to 121 but can still reach 0
		} else if(p2_x>132)	//more than 5 above 127
		{
			deadx = ((p2_x - 132) * 127)/122 + 127;	//scaling
		} else
		{
			deadx = 127;	//don't move if within 5 of 127
		}

		printf("deadx=%d\r",(int)deadx);
		//same stuff for y axis
		if(p2_y<122)
		{
			deady = ((p2_y - 122) * 127)/122 + 127;
		} else if(p2_y>132)
		{
			deady = ((p2_y - 132) * 127)/122 + 127;
		} else
		{
			deady = 127;
		}

		printf("deady=%d\r",(int)deady);

		pair1 = deady+127-deadx;	//holonomictastic
		pair2 = deady+deadx-127;	//holonomictastic

		printf("pair1=%d\r",(int)pair1);
		printf("pair2=%d\r\r",(int)pair2);
	
		if(pair1>254)	//so moving the controller diagonally does not go outside valid values
			pair1 = 254;
		else if(pair1<0)
			pair1 = 0;
	
		if(pair2>254)
			pair2 = 254;
		else if(pair2<0)
			pair2 = 0;

		pwm04 = (pair1 - 127)/2 + 127;	//halving
		pwm01 = (127 - pair1)/2 + 127;	//halving and reversing
		pwm03 = (pair2 - 127)/2 + 127;	//halving
		pwm02 = (127 - pair2)/2 + 127;	//halving and reversing
	} else	//spinning in place
	{
		pwm01 = pwm02 = 107;	
		pwm03 = pwm04 = 107;
	}
First problem is that it doesn't drive properly when we move the controller backwards or right. Basically, it considers the y axis neutral for all values below 127 and the x axis neutral for all values above 127. For example, if we moved the controller forward and to the right then it would be the same as just forward. And pulling straight back will not move anything (and the printfs() indicated that the value was 127 being sent to both motors). It went away when we removed the deadzone code, the motors move properly in all directions.

The other problem we're having is that when we try and go foward the left two wheels (pwm01,pwm02) get up to about 20 or 30 before the right wheels begin responding. When we go backwards the right two wheels (pwm3,pwm4) get up to 20 or 30 before the left two wheels respond. When pressing left the back two wheels (pwm2, pwm4) get up to speed first. When pressing right the front two wheels act similarly.

We know that we could fix this by using four geartooth sensors, but the code behind that would be monstrous and confusing, and require four sensors!

Any help would be appreciated.
  #2   Spotlight this post!  
Unread 06-02-2007, 20:00
Kelly Kelly is offline
Registered User
FRC #1418
 
Join Date: Jan 2007
Location: VA
Posts: 78
Kelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud of
Re: Bizarre Driving Issue

p2_x and p2_y are unsigned integers. When your subtract from them to end up with a negative value, the computer will start to have problems. Store them in signed integers before you try to subtract 122.

basically change this:
Code:
if(p2_x<122) 	//more than 5 below 127
{
 deadx = ((p2_x - 122) * 127)/122 + 127;
  }
to
Code:
if(p2_x<122) 	//more than 5 below 127
{
    int drive_x=p2_x;
    deadx = ((drive_x - 122) * 127)/122 + 127;
}
Also, my team has found that the outputs from the victors is way asymetrical, and that they have their own, fairly large dead zone that doesn't happen to be centered about 127.
  #3   Spotlight this post!  
Unread 06-02-2007, 21:02
kitscuzz's Avatar
kitscuzz kitscuzz is offline
Not alotta posts
AKA: Kit
FRC #1389 (Worst Case Scenario)
Team Role: Programmer
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Home
Posts: 47
kitscuzz will become famous soon enough
Re: Bizarre Driving Issue

Can that be fixed through recalibration? Or have you found another method? But this is probably it! Thanks!

And the part where you said that they're usigned integers wouldn't make sense mainly because the negative works for the p2_x but not for p2_y and that doesn't explain why p2_x doesn't work when positive. We'll try both typecasting and storing it in a smaller variable, but I don't think that's the solution for why the deadzone code isn't working.
  #4   Spotlight this post!  
Unread 06-02-2007, 22:25
tdlrali tdlrali is offline
Registered User
FRC #0469 (Las Guerrillas)
Team Role: Programmer
 
Join Date: Sep 2006
Rookie Year: 2006
Location: MI
Posts: 377
tdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud of
Re: Bizarre Driving Issue

Quote:
p2_x and p2_y are unsigned integers. When your subtract from them to end up with a negative value, the computer will start to have problems. Store them in signed integers before you try to subtract 122.
AFAIK, this shouldn't be a problem.
You are not actually changing the values of p2_y and p2_x, are you? If you are just using the for calculations, it shouldn't matter what type they are.

Sorry if I'm wrong, I can't test it right now. Otherwise I would just cast p2_y as an int instead of declaring a separate variable.

Last edited by tdlrali : 06-02-2007 at 22:37.
  #5   Spotlight this post!  
Unread 06-02-2007, 22:26
Kelly Kelly is offline
Registered User
FRC #1418
 
Join Date: Jan 2007
Location: VA
Posts: 78
Kelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud of
Re: Bizarre Driving Issue

Recalibration didn't help. We made a graph of PWM output vs wheel speed and then made a lookup table of the PWM values required to achieve the desired wheel speeds. I'll post more details about it when I have time tomorrow if you want.

When we were initially messing around with holonomic driving, my team did run into a few problems with subtracting from unsigned variables, so it's definitely worth a try.
Have you tried following the values of your variables with the MPLab debugger? That can be an easier way to test different situations without using the robot.
  #6   Spotlight this post!  
Unread 06-02-2007, 22:36
tdlrali tdlrali is offline
Registered User
FRC #0469 (Las Guerrillas)
Team Role: Programmer
 
Join Date: Sep 2006
Rookie Year: 2006
Location: MI
Posts: 377
tdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud oftdlrali has much to be proud of
Re: Bizarre Driving Issue

Also, here's a general thing that will cut down code, therefore space used, will "upload" faster and run faster

Turn this:
Code:
if(p2_x<122) 	//more than 5 below 127
		{
			deadx = ((p2_x - 122) * 127)/122 + 127;	//scaling so we don't just jump from 127 to 121 but can still reach 0
		} else if(p2_x>132)	//more than 5 above 127
		{
			deadx = ((p2_x - 132) * 127)/122 + 127;	//scaling
		} else
		{
			deadx = 127;	//don't move if within 5 of 127
		}
into

Code:
if(p2_x>=122 && p2_x<=132) 	//within deadzone
	deadx = 127; //dont move
else //outside deadzone
	deadx = ((p2_x - 132) * 127)/122 + 127;	//scaling
  #7   Spotlight this post!  
Unread 06-02-2007, 23:15
Bio's Avatar
Bio Bio is offline
Registered User
AKA: Brian Dellon
None #1389 (Worst Case Scenario)
Team Role: Programmer
 
Join Date: Mar 2004
Rookie Year: 2003
Location: Bethesda, MD
Posts: 8
Bio is an unknown quantity at this point
Re: Bizarre Driving Issue

tdlrali: It would be nice if things worked that way, but the point of the code is to find the difference between the input and the end of the deadzone then scaling it to cover 127 values. Finding that difference requires a separate case for above and below, with below subtracting 122 rather than 132. With the code you suggest, holding the controller at full reverse would result in deadx equaling -10.

Kelly: Considering our build team, I'm sort of doubtful we'd ever find enough time with the robot to make an accurate lookup table, but all suggestions are definitely appreciated. Also, no, we have not tried the debugger. I, at least, was not even aware of its existence, though kitscuzz is generally much better informed than I am.

Last edited by Bio : 06-02-2007 at 23:22.
  #8   Spotlight this post!  
Unread 07-02-2007, 00:15
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: Bizarre Driving Issue

you are overflowing, i can guarantee it. The type of the variable is an unsigned char, and none of the numbers are larger than that range within the calculation. Therefore, your values overflow when you multiply by that huge number.

Typecast "p2_x" and whatnot into signed ints, and this should rectify that issue.

(note that you could also use encoders which are much more accurate and friendly)
__________________
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 07-02-2007, 00:22
Bio's Avatar
Bio Bio is offline
Registered User
AKA: Brian Dellon
None #1389 (Worst Case Scenario)
Team Role: Programmer
 
Join Date: Mar 2004
Rookie Year: 2003
Location: Bethesda, MD
Posts: 8
Bio is an unknown quantity at this point
Re: Bizarre Driving Issue

It still seems strange that an overflow would create such specific fail points and be different for p2_x and p2_y, but it's not like typecasting is very difficult. We'll give it a shot, whether it's an issue for your reason, Kelly's, or something none of us has thought of.

Last edited by Bio : 07-02-2007 at 00:25.
  #10   Spotlight this post!  
Unread 07-02-2007, 00:30
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: Bizarre Driving Issue

well it will create fail points because that is where your numbers will overflow. believe me, i have seen it all too many times.
__________________
A few of my favorite numbers:
175 176 177 195 230 558 716 1024 1071 1592 1784 1816
RPI 2012
BREAKAWAY
  #11   Spotlight this post!  
Unread 07-02-2007, 00:46
Bio's Avatar
Bio Bio is offline
Registered User
AKA: Brian Dellon
None #1389 (Worst Case Scenario)
Team Role: Programmer
 
Join Date: Mar 2004
Rookie Year: 2003
Location: Bethesda, MD
Posts: 8
Bio is an unknown quantity at this point
Re: Bizarre Driving Issue

I don't doubt you, but doesn't overflow involve the numbers becoming too large? Given the code, the largest numbers should occur at full forward and full reverse, but the failure occurs for all inputs below 122 and none above with p2_y and for all inputs above 132 and none below with p2_x. I mean, the largest number that occurs at any point is 15494 (from p2_y=254) and that works just fine. Of course, I sort of get the feeling I'm displaying some horrible ignorance here. Too bad it's sort of difficult to get into the school and test these things out at 12:44 AM.
  #12   Spotlight this post!  
Unread 07-02-2007, 02:20
AndrewN's Avatar
AndrewN AndrewN is offline
it's alive!
AKA: Andrew Nicholson
FRC #1778 (Chill Out)
Team Role: Mentor
 
Join Date: Jan 2007
Rookie Year: 2006
Location: Edmonds, WA
Posts: 48
AndrewN is just really niceAndrewN is just really niceAndrewN is just really niceAndrewN is just really niceAndrewN is just really nice
Re: Bizarre Driving Issue

p2_x and deadx are (unsigned char), a single byte, and can only hold the values 0 to 255.

unsigned char p2_x;
unsigned char deadx;

We all use them to hold PWM values where 127 is neutral, 255 full forward, 0 full reverse.

For an example set p2_x to be 50, a value less than the 122 that you are having problems with. The code looks like:
deadx = ((p2_x - 122) * 127)/122 + 127;

Now subtract the 122: p2_x = p2_x - 122; /* or p2_x -= 122; or (p2_x-122) */

What's the value of p2_x, it's not -72 like we wanted it's instead now 184. The math overflowed the range of values, the result became 256-72 instead. Think of it as
wrapping around, instead of going from 2, 1, 0, -1, it goes 2, 1, 0, 255, 254, 253 ...

That's the first problem, now imagine we do the multiplication, it's going to wrap around many times and come to rest somewhere unexpected, (n*127 mod 256). Then division will only return 0, 1, 2 and that's all folks.

So how do you fix it? Take care of the typecasting to a (signed int) that is 2 bytes wide
and can be both positive and negative, once you have finished the scaling calculation, cast the result back to an (unsigned char)
deadx = (unsigned char) (( ((int)p2_x - 122) * 127 )/122 + 127 );

C always does math using the widest type (most number of bytes) of the two values.

Aside: The last cast to (unsigned char) is actually unnecessary as we are assigning it
to an unsigned char variable and C will do the typecast for us. However by including the typecast we are making clear our intent and it'll help remind us what is going on.

Short answer: the problem with negative values occurs because all numbers must have a positive result with (unsigned char) or it overflows. The problem with some +ve numbers happens because the result of the *127 won't fit in a single byte. Casting to (int) will fix those problems.

However, the other comments about how to handle a deadzone are correct too., there may still be other problems.

Note: The code that reverses the motors (127-pwm) could be simplifed if you just reverse the motor connection to the victors, of one of the motor pairs. It'll also help getting matched speeds as the speeds 127+n and 127-n are not necessarily the same.

Don't forget that the victors also have a deadband around 127 too.
Happy coding
  #13   Spotlight this post!  
Unread 07-02-2007, 07:33
Kelly Kelly is offline
Registered User
FRC #1418
 
Join Date: Jan 2007
Location: VA
Posts: 78
Kelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud ofKelly has much to be proud of
Re: Bizarre Driving Issue

I'm pretty sure your current problems are caused by overflowing unsigned variables, however, if you're like us, the next problem you'll have is with your robot listing to one side or another as it drives. We fixed it by collecting data about the pwms and making a lookup table that relates desired wheel speeds and actual pwms.

We collected this data by hooking the robot to the computer and cycling through all the possible pwms. The units on wheel speeds are not actually RPMs, but encoder counts per 115 program loops, because there was no need to convert units.

Note the fact that the maximum speeds in each direction are not the same and also the fact that the dead zone is centered about 132. This was causing our robot to drift, because wheels that were supposed to be going in the same speeds with opposite directions weren't. Also, notice that the slope gets really steep in the middle and flatten out at the end. We wanted our robot to accelerate linearly.

To fix this, we made a list of what the motor speeds would be if they were increasing linearly from 0 - the maximum and put it in a new column lining up with the old columns. We made our lookup table by looking at our list of "desired speeds" and finding a pwm setting that would create that speed. Unfortunately, that work is on the computer at school, but I'll post it soon.

I'm actually considering putting together a whitepaper on the topic of holonomic driving, assuming ours works out.
Attached Files
File Type: xls graphForCD.xls (24.0 KB, 26 views)
  #14   Spotlight this post!  
Unread 07-02-2007, 12:21
kitscuzz's Avatar
kitscuzz kitscuzz is offline
Not alotta posts
AKA: Kit
FRC #1389 (Worst Case Scenario)
Team Role: Programmer
 
Join Date: Jan 2006
Rookie Year: 2005
Location: Home
Posts: 47
kitscuzz will become famous soon enough
Re: Bizarre Driving Issue

AndrewN:
We'll definitely try this, but I repeat that it's strange because in the example you've provided we actually get the correct values. when ps_x is less than 122, the code behaves as we originally expected. Where it doesn't behave properly is when p2_x exceeds 132, a case where there shouldn't even be a plausible overflow.

When it does exceed 132, the deadzone code returns 127. I guess that does seem to fit into the idea that it would only return 0, 1, or 2 after the division. But I guess I'm just looking for a reason why they would both work in completely opposite positions.

But then again, all things considered, you're all probably smarter than me anyway and this definitely fits the problem, because checking back in the notes, we got 128 occasionally.

Thanks.
  #15   Spotlight this post!  
Unread 07-02-2007, 12:34
65_Xero_Huskie's Avatar
65_Xero_Huskie 65_Xero_Huskie is offline
One T
AKA: Mat
no team
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2004
Location: Michigan
Posts: 697
65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute65_Xero_Huskie has a reputation beyond repute
Re: Bizarre Driving Issue

Check and make sure your drives are going the right way, i dont think its your program, i hate to admit it but we could only go forward and backwards for about 6 hours because we didnt have the PWM;s in the right spots, and then we couldnt go right because the trim on our controller was wrong. So before you think its the program ( its usually that ) but u should check your robot and the controls aswell. Just my two cents.
__________________
Min-Max to the Max!
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
Driving Experience Revolverx7 Rules/Strategy 20 27-03-2005 11:11
Driving at Last! The_Goodie Robot Showcase 4 10-02-2005 20:23
driving at noon Adam Collet General Forum 6 20-09-2003 23:40
Driving a clutch Kevin A Chit-Chat 18 03-07-2003 16:02
Driving Skill Andy Grady General Forum 24 23-03-2003 02:34


All times are GMT -5. The time now is 00:23.

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