Quote:
Originally Posted by Mark McLeod
When you max out a gyro it just gives the max rate until it drops below the max again. There is no lag in the gyro output itself. What it sends is what it sees at that instant. It'd need to be able to store information in order to even remember what any lag was.
However, that doesn't mean code on the RC couldn't introduce a lag in the readings, but I too, doubt it.
None of our gyro's have ever exhibited a lag. We use 300 deg/sec gyro's on the robot, but other gyro's in demonstrations.
The gyro values in your sample printout seem very odd. Where exactly are you getting your gyro values from and what do they represent?
|
Our code for getting the gyro value says the following:
Code:
unsigned char ucGyroValue = (Get_Analog_Value(rc_ana_in01)) >> 2
Basically, we are getting the analog value from the RC and shifting it two bits to get a value between 0 and 255. I thought maybe the shifting was the problem, but I also encountered the lag with Kevin's gyro code, which doesn't shift.
The thing is, only a turn triggers the lag. Like I said, if we tell the robot to go straight, it does just fine. If we print out the gyro value in main.c every loop, it prints a constant neutral or something very close to neutral when the robot is stationary. If we manually nudge the robot, the printed gyro value changes instantly with almost no lag at all. But if we make a sharp turn during autonomous, the value lags considerably.
In case it matters, we are calling a separate function to calculate motor corrections. It gets the gyro value, calculates a motor correction percentage, and return the correction percentage to the caller.
Here's the entire function if it matters. There is one fabs but from what I've read that shouldn't be a problem if we only use it once.
Code:
static float fCorrectMotorsForOutOfAlignmentGyro (
eDecreaseWhichMotorEnum *peDecreaseWhichMotor) // tells the calling function which
// which motor needs the adjustment on
{
unsigned int uiGyroValue = GET_ANALOG_VALUE(GYRO_INPUT);
// The analog value from the gyro at present
float fPercentageOfChangeToMotors = 1.0; // The number that will be multiplied by the current motor speed to slow
// it down for a correction (i.e. 0.99 will slow down the motor by 1%)
// Positive values indicate we are too far right. Negative values indicate we
// are too far left
//-------------------------------------
// if the caller didn't pass in the correct
// argument type, simply return a NO_CHANGE
// value. Preset the change goes to the
// LEFT motor
//-------------------------------------
*peDecreaseWhichMotor = DECREASE_LEFT_MOTOR;
if (peDecreaseWhichMotor == NULL)
return (fPercentageOfChangeToMotors);
//--------------------------------------------------------------------------------
// Depending on the direction we are turning, increase or decrease our total
//--------------------------------------------------------------------------------
iGyroTotalError = iGyroTotalError + (uiGyroValue - iGetGyroStartingValue());
//--------------------------------------------------------------------------------
// Calculate the percentage of change based on how far off we are (gyro error) and our constant
// motor correction curve valuee (FACTOR and CURVE)
//--------------------------------------------------------------------------------
fPercentageOfChangeToMotors = 1.0 -
MIN((MOTOR_CORRECTION_FACTOR * fabs(iGyroTotalError / MOTOR_CORRECTION_CURVE)), 1.0);
//-------------------------------------
// if we are drifting to the left
// then we need to let the called
// functions know by denoting that we
// want the RIGHT motor to be decreased
//-------------------------------------
if(iGyroTotalError < 0)
*peDecreaseWhichMotor = DECREASE_RIGHT_MOTOR;
# define DEBUG
# ifdef DEBUG
printf("The gyro value is %d." EOL, (int)uiGyroValue);
printf("The gyro error is %d." EOL, (int)iGyroTotalError);
printf("The percentage of change %d.%d" EOL, (int)fPercentageOfChangeToMotors, (int)FLOAT_FRAC_PART(fPercentageOfChangeToMotors));
# endif // DEBUG
# undef DEBUG
return (fPercentageOfChangeToMotors);
} // end fCorrectMotorsForOutOfAlignmentGyro
GET_ANALOG_VALUE is a macro we wrote that gets an analog value and shifts it two bits.
You'll notice the function has an accumulator, iGyroTotalError, which keeps track of how far off of a zero heading we are. The robot will actually try to turn back to a zero heading based on this value.
iGetGyroStartingValue() gets the gyro neutral value, which we measure right before we start autonomous mode.
MOTOR_CORRECTION_FACTOR and MOTOR_CORRECTION_CURVE are defines that control how large the corrections to the motors are.
EOL is a define we made that inserts whatever this years "go to the next line of the terminal screen" command happens to be. Sometimes it's \r, sometimes it's \n, sometimes it's \r\n...so we just made a macro to avoid having to change every single printf statement if the command changes again.