Thread: Gyro problem
View Single Post
  #23   Spotlight this post!  
Unread 24-03-2009, 07:22
yoyodyne yoyodyne is offline
Registered User
AKA: Greg Smith
FRC #0116 (Epsilon Delta)
Team Role: Engineer
 
Join Date: Jan 2006
Rookie Year: 2004
Location: Reston, VA
Posts: 61
yoyodyne is a splendid one to beholdyoyodyne is a splendid one to beholdyoyodyne is a splendid one to beholdyoyodyne is a splendid one to beholdyoyodyne is a splendid one to beholdyoyodyne is a splendid one to beholdyoyodyne is a splendid one to behold
Re: Gyro problem

We combined gyro and one channel of accelerometer processing so that we could use the same calibration interval for both (and changed the calibration period to 2 seconds which seems to be plenty). Also, we wanted functions to return the filtered angular rate for the gyro and the acceleration and speed from the accelerometer. Anyway, we also used a known good 300 degrees/sec gyro as well as this year's KOP gyro. To do this we copied the WPILib code into our project and then modified it. Part of our modified code is below - notice that we set the deadband for both to 10.

Hope this helps.

The code that set's up the gyro and accelerometer is here:

#ifdef PRACTICE_BOT
#define GYRO_SENSETIVITY 0.0055 /* LAST YEAR's GYRO */
#else
#define GYRO_SENSETIVITY 0.006966667 /* 2009 Gyro */
#endif

void InitializeUtilities()
{
m_gyro = new GYRO_ACC(1,1,1,2);

m_pressure_switch = new DigitalInput(6,14);

m_autonomous_alliance = new DigitalInput(4,6);

m_initial_position1 = new DigitalInput(4,7);
m_initial_position2 = new DigitalInput(4,8);

m_play_1s = new AnalogChannel(2,3);
m_play_10s = new AnalogChannel(2,4);

// m_compressor_relay = new Relay(4, 1, Relay::kForwardOnly);

m_gyro->SetSensitivity(GYRO_SENSETIVITY);
m_gyro->SetAccSensitivity(0.009666207);
m_gyro->Reset();

m_right_odo = new Encoder(6,3,6,4,false,CounterBase::k1X);
m_left_odo = new Encoder(6,1,6,2,false,CounterBase::k1X);


m_right_drive = new Encoder(6,7,6,8,false);
m_left_drive = new Encoder(6,5,6,6,false);


}








/**
* Initialize the GYRO_ACC.
* Calibrate the GYRO_ACC by running for a number of samples and computing the center value for this
* part. Then use the center value as the Accumulator center value for subsequent measurements.
* It's important to make sure that the robot is not moving while the centering calculations are
* in progress, this is typically done when the robot is first turned on while it's sitting at
* rest before the competition starts.
*/
void GYRO_ACC::InitGYRO_ACC()
{
if (!m_analog->IsAccumulatorChannel())
{
wpi_fatal(GyroNotAccumulatorChannel);
if (m_channelAllocated)
{
delete m_analog;
m_analog = NULL;
}
return;
}

if (!m_ana_accel->IsAccumulatorChannel())
{
wpi_fatal(GyroNotAccumulatorChannel);
if (m_accel_channelAllocated)
{
delete m_ana_accel;
m_ana_accel = NULL;
}
return;
}




m_voltsPerDegreePerSecond = kDefaultVoltsPerDegreePerSecond;
m_analog->SetAverageBits(kAverageBits);
m_analog->SetOversampleBits(kOversampleBits);

m_voltsPerG = kDefaultVoltsPerG;
m_ana_accel->SetAverageBits(kAverageBits);
m_ana_accel->SetOversampleBits(kOversampleBits);



float sampleRate = kSamplesPerSecond *
(1 << (kAverageBits + kOversampleBits));
m_analog->GetModule()->SetSampleRate(sampleRate);
Wait(0.25);

m_analog->InitAccumulator();
m_ana_accel->InitAccumulator();
Wait(kCalibrationSampleTime);

INT64 value;
UINT32 count;

m_analog->GetAccumulatorOutput(&value, &count);

UINT32 center = (UINT32)((float)value / (float)count + .5);

gyro_center = (float)value/(float)count;

m_offset = ((float)value / (float)count) - (float)center;

m_analog->SetAccumulatorCenter(center);
m_analog->SetAccumulatorDeadband(10); ///< TODO: compute / parameterize this
m_analog->ResetAccumulator();


m_ana_accel->GetAccumulatorOutput(&value, &count);

center = (UINT32)((float)value / (float)count + .5);

accel_center = (float)value/(float)count;

m_acc_offset = ((float)value / (float)count) - (float)center;

m_ana_accel->SetAccumulatorCenter(center);
m_ana_accel->SetAccumulatorDeadband(10); ///< TODO: compute / parameterize this
m_ana_accel->ResetAccumulator();

}

/**
* GYRO_ACC constructor given a slot and a channel.
*
* @param slot The cRIO slot for the analog module the GYRO_ACC is connected to.
* @param channel The analog channel the GYRO_ACC is connected to.
*/
GYRO_ACC::GYRO_ACC(UINT32 slot, UINT32 channel, UINT32 accel_slot, UINT32 accel_channel)
{
m_analog = new AnalogChannel(slot, channel);
m_channelAllocated = true;

m_ana_accel = new AnalogChannel(accel_slot, accel_channel);
m_accel_channelAllocated = true;
InitGYRO_ACC();
}

/**
* GYRO_ACC constructor with only a channel.
*
* Use the default analog module slot.
*
* @param channel The analog channel the GYRO_ACC is connected to.
*/
GYRO_ACC::GYRO_ACC(UINT32 channel, UINT32 accel_channel)
{
m_analog = new AnalogChannel(channel);
m_channelAllocated = true;

m_ana_accel = new AnalogChannel(accel_channel);
m_accel_channelAllocated = true;
InitGYRO_ACC();
}