|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
||||
|
||||
|
Drive Straight C Code using Encoders without PID?
I am helping our team out again with another problem. We are using 2WD, and trying to make our robot drive straight based on encoder feedback.
We have come up with our own code, but we really don't like it that well and it doesn't update fast enough. What we probablly need is a nice PID, but we don't have room in our controller to use any nice PID controls, like the Kevin W NAV code... Has anyone come up with some slick ways to monitor your encoders and balance your drive system? Attached is what we have come up with, works great when your robot is blocked up on blocks but when on the ground, I don't think the the logic can control the "loop" control fast enough and our robot is driving all over the place. Sometimes it goes straight as an arrow, other times not. Anyone care to share what they got in their pocket for driving straight querying your encoders? Code:
long drv_left_encoder;
long drv_right_encoder;
long drv_diff_left;
long drv_diff_right;
static int DRV_DEADBAND = 5; //only correct left or right side if encoder difference is greater than deadband
static int DRV_BOOST = 10; //turbo boost if button pressed
int print_counter;
int print_counter_before;
relay1_fwd = 0; //turn off lights, not in automous mode anymore.
camera_find_color( 0 ); //turn off vision system.
p1_y = (p1_y / 3) + ((127 / 3) * 2); //scale down Y axis
p1_x = (p1_x / 3) + ((127 / 3) * 2); //scale down X axis
left_pwm = Limit_Mix(2000 + p1_y - p1_x + 127); //limit pwm
right_pwm = Limit_Mix(2000 + p1_y + p1_x - 127); //limit pwm
drv_left_encoder = Get_Left_Encoder_Count(); //get encoder count
drv_right_encoder = Get_Right_Encoder_Count(); //get encoder count
drv_diff_left = drv_left_encoder - drv_right_encoder; //subtract left from right because I dunno if ABS is supported in this dumb PIC
drv_diff_right = drv_right_encoder - drv_left_encoder; //subtract right from left because I dunno if ABS is supported in this dumb PIC
if ((p1_y <= 135) && (p1_y >= 120)) //reset encoder counts
{
Set_Left_Encoder_Count(0);
Set_Right_Encoder_Count(0);
drv_diff_left = 0;
drv_diff_right = 0;
}
#ifdef DEBUG_DRVMAN //uncomment DEBUG_DRVMAN in robot.c to get this to excute.
if (++print_counter_before >= 2)
{
print_counter_before = 0;
printf( "BY=%d BLE=%d BLD=%d BRE=%d BRD=%d BLPWM=%d bRPWM=%d\r",p1_y,(int)(drv_left_encoder),(int)(drv_diff_left),(int)(drv_right_encoder),(int)(drv_diff_right),left_pwm,right_pwm);
}
#endif
if ((p1_x <= 135) && (p1_x >= 120)) //not turning
{
if (p1_y >= 145) //check to see if we are driving straight forward
{
if (drv_diff_left >= DRV_DEADBAND) //increase power to the right drive pwm12
{
if (drv_diff_left > DRV_DEADBAND)
{
right_pwm = right_pwm + 6;
}
if (drv_diff_left > DRV_DEADBAND + 10)
{
right_pwm = right_pwm + 8;
}
if (drv_diff_left > DRV_DEADBAND + 20)
{
right_pwm = right_pwm + 10;
}
}
if (drv_diff_right >= DRV_DEADBAND) //increase power to the left drive pwm11
{
if (drv_diff_right > DRV_DEADBAND)
{
left_pwm = left_pwm + 6;
}
if (drv_diff_right > DRV_DEADBAND + 10)
{
left_pwm = left_pwm + 8;
}
if (drv_diff_right > DRV_DEADBAND + 20)
{
left_pwm = left_pwm + 10;
}
}
}
if (p1_y <= 120) //check to see if we are driving straight backwards
{
if (drv_diff_left >= DRV_DEADBAND) //increase power to the right drive pwm12
{
if (drv_diff_left > DRV_DEADBAND)
{
right_pwm = right_pwm - 3;
}
if (drv_diff_left > DRV_DEADBAND + 10)
{
right_pwm = right_pwm - 4;
}
if (drv_diff_left > DRV_DEADBAND + 20)
{
right_pwm = right_pwm - 5;
}
}
if (drv_diff_right >= DRV_DEADBAND) //increase power to the left drive pwm11
{
if (drv_diff_right > DRV_DEADBAND)
{
left_pwm = left_pwm - 3;
}
if (drv_diff_right > DRV_DEADBAND + 10)
{
left_pwm = left_pwm - 4;
}
if (drv_diff_right > DRV_DEADBAND + 20)
{
left_pwm = left_pwm - 5;
}
}
}
}
else //if we are turning, then don't try to drive straight
{
Set_Left_Encoder_Count(0);
Set_Right_Encoder_Count(0);
drv_diff_left = 0;
drv_diff_right = 0;
}
/*
if (p1_y >= 130 && p1_sw_trig) //forward boost, will be used later for turbo boost pushing power
{
pwm11 = left_pwm + DRV_BOOST;
pwm12 = right_pwm + DRV_BOOST;
}
*/
/*
pwm11 = left_pwm;
pwm12 = right_pwm;
#ifdef DEBUG_DRVMAN //uncomment DEBUG_DRVMAN in robot.c to get this to excute.
if (++print_counter >= 2)
{
print_counter = 0;
printf( "AY=%d ALE=%d ALD=%d ARE=%d ARD=%d ALPWM=%d ARPWM=%d\r",p1_y,(int)(drv_left_encoder),(int)(drv_diff_left),(int)(drv_right_encoder),(int)(drv_diff_right),left_pwm,right_pwm);
}
#endif
}
|
|
#2
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
Quote:
On the field, it more often than not resulted in the robot lurching downfield briefly and coming to a complete halt, and we were very pressed for time, so rather than spend a lot of effort debugging the software we abandoned the scheme. It turns out the code was fine, and the problem was actually with the gearbox, where a poorly held bearing was letting the gears disengage whenever it tried to move suddenly in reverse. Our autonomous setup happened to involve starting the robot at full speed in reverse to "back up" down the field to a turning point. One side would fail to drive, and the algorithm dutifully increased power to the disengaged drivetrain while decreasing power to the working one. The error would quickly reach the point where the working side was being throttled all the way back to zero. |
|
#3
|
||||
|
||||
|
Re: Drive Straight C Code using Encoders without PID?
Quote:
-Kevin |
|
#4
|
||||
|
||||
|
Re: Drive Straight C Code using Encoders without PID?
Great suggestion, if you can tell us how to cram 40K of program into a 32K CPU?
GYROs, and PID had to go in the Nav code, we got so much other code that we need with using the camera that we can't fit it all in there....once we intergrated the encoders, camera into the navigation code, and using a multi pointer struct commands to drive our automous mode, our program had to go on a slim fast diet... That's why we can't use the PID code that we deleted.. Quote:
|
|
#5
|
||||
|
||||
|
Re: Drive Straight C Code using Encoders without PID?
Take out some of the comments.
|
|
#6
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
Are you using any floating point calculations? Even multiplying by a constant that has a decimal point in it constitutes a floating point operation. Find ways to use integers instead.
For example: Need to multiply by pi? Forget 3.14159! Multiply by 355, then divide by 113. Make sure you do it in that order (don't divide first -- the answer is different). |
|
#7
|
||||
|
||||
|
Re: Drive Straight C Code using Encoders without PID?
Hi Norm,
Thanks for bringing that up and reminding everyone that floating point also sucks the life out of these controllers, but nope we are not using an floating point. We wanted too SOOOOO bad. We wanted to use an X,Y, Theta position system, but it would require SIN and COS. We did try the one math library in the whitepapers section, even deleted some math we wasn't using be it was still too much on the controller. Quote:
|
|
#8
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
Quote:
To all who flinch at the "inaccuracies" of integer math: engineering is the art of compromise. sin(x) = x, when x is small. If it's good enough, it just may be perfect. Just say no to floating point! |
|
#9
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
Quote:
|
|
#10
|
||||
|
||||
|
Re: Drive Straight C Code using Encoders without PID?
I hope you mean DEBUG printf statements right? Comments aren't suppose to be stored in the controller to my knowledge...??? Are they?
Quote:
|
|
#11
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
A quick thing to point out.
You are reading the map files and not looking at the pure size of the hex files right? Because if you are just looking at the hex files, the size does not reflect usage of the 32k space. I guess if you guys know about it, will be helpful to someone else. But VERY important to keep in mind. |
|
#12
|
||||
|
||||
|
Re: Drive Straight C Code using Encoders without PID?
Good point too. But actually we are looking at the LST file.
When you complie, go to FILE, OPEN and change your extension browse to .LST. Then find the list file in your project folder. Find the last HEX entry in the left side. Should be no bigger than 7FFF. Use Windows Calculator, (change to scientific mode) to convert HEX to DEC. Actually what will happen first is your complier will give you and error something like this. Can not fit robot.io or something like that..actually I should have this error memorizes because I've seen it like 100 times already. Quote:
|
|
#13
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
Quote:
And I recently was shown (here) that the difference between Code:
#define BEGIN 0 #define MIDDLE 1 #define END 2 Code:
enum
{
BEGIN,
MIDDLE,
END
}
|
|
#14
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
Quote:
Am I correct? |
|
#15
|
|||||
|
|||||
|
Re: Drive Straight C Code using Encoders without PID?
Quote:
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| 1 stick drive to 2 stick drive | wayne 05 | Programming | 18 | 01-04-2004 16:41 |
| Direct drive or Chain? | Suneet | Technical Discussion | 32 | 27-03-2003 23:00 |
| TechnoKats Automated Test Drive Code | Greg McCoy | Programming | 1 | 16-01-2003 17:45 |
| what's your most important drive train advice? | Ken Leung | Technical Discussion | 42 | 07-01-2003 09:58 |
| "Motors and Drive train edition" of Fresh From the Forum | Ken Leung | CD Forum Support | 6 | 29-01-2002 12:32 |