View Single Post
  #6   Spotlight this post!  
Unread 03-12-2011, 08:09 PM
mikets's Avatar
mikets mikets is offline
Software Engineer
FRC #0492 (Titan Robotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Bellevue, WA
Posts: 667
mikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of light
Re: Line Tracking Code Help

Our line following algorithm uses PID control. Basically, we combined the readings of the three light sensors into a 3-bit value (0-7) and used it to index a table. If the line is right at the center, it maps to 0.0. If the line is slightly to the left, it maps to 1.0, more to the left maps to 2.0. If the line is slightly to the right, its maps to -1.0 and -2.0 if further right. 999.0 is just a number used to indicate no valid line is found. The number -2.0 to 2.0 is then used as the current input in PID control calculation and the setpoint is 0.0 (the center). The turning power is proportional on how far we are "off course". The speed driving forward is inversely proportional to the turning power. So the harder we turn, the slower we go. Our algorithm is actually more complicated than that but a simplified version is shown below.
Code:
UINT32
GetRawValue(
    void
    )
{
    UINT32 value = 0;
 
    value = m_leftLightSensor->Get() << 2;
    value |= m_centerLightSensor->Get() << 1;
    value |= m_rightLightSensor->Get();
 
    return value;
}   //GetRawValue
 
static float inputMap[8] =
{
    999.0, //000: n/a (No light)
    -2.0,   //001: Extreme right
    0.0,    //010: Center
    -1.0,   //011: Slight right
    2.0,    //100: Extreme left
    999.0, //101: n/a (At Y)
    1.0,    //110: Slight left
    999.0  //111: n/a (At T)
};
 
UINT32 sensorRawValue = GetRawValue();
if (sensorRawValue == 0)
{
    //
    // deal with losing the line.
    //
}
else if (sensorRawValue == 0x5)
{
    //
    // deal with the Y fork.
    //
}
else if (sensorRawValue == 0x7)
{
    //
    // deal with the T-end.
    //
}
else
{
    float sensorMappedValue = inputMap[sensorRawValue];
    float turnPower = CalcPIDOutput(sensorMappedValue);
    float drivePower = m_maxDrivePower*(1.0 - fabs(turnPower));
    ArcardeDrive(drivePower, turnPower);
}
__________________

Last edited by mikets : 03-12-2011 at 08:16 PM.
Reply With Quote