8.4 Pit Utility Functions

Introduction

In this section I show you the utility functions of the pit class. The functions responsible for the strategy will follow in the next section. Put the following code into pit.cpp.

The toSplineCoord Method

This method converts distances from the start line into distances from the pit entry.

/* Transforms track coordinates to spline parameter coordinates */
float Pit::toSplineCoord(float x)
{
    x -= pitentry;
    while (x < 0.0) {
        x += track->length;
    }
    return x;
}

First we subtract of the given value the distance of the pit entry from the start. Because the start line can lie between the pit entry and the pit exit, it is possible that the result becomes negative. In such a case we have to add a track length to correct that.

The getPitOffset Method

This method computes the pit offset for the path into the pit which is added to the target point. The arguments given are a current offset and the distance of the target point from the start.

/* computes offset to track middle for trajectory */
float Pit::getPitOffset(float offset, float fromstart)
{
    if (mypit != NULL) {
        if (getInPit() || (getPitstop() && isBetween(fromstart))) {
            fromstart = toSplineCoord(fromstart);
            return spline->evaluate(fromstart);
        }
    }
    return offset;
}

First we check if there is a pit available. If we have a pit we check if we are already performing a pit stop with getInPit() or if we plan a pit stop and the target point falls onto the pit path. If the expression evaluates to true we want to follow the pit path, therefore we compute a new offset and return it. If one of the above expressions fails, we simply return the given offset.

The setPitstop Method

This is the setter method for the pitstop variable. You should just access the pitstop variable through this method, because it makes sure that the variable is not set while we are on the track parallel to the pit lane. It is not allowed to set the variable to true in this range because we would start immediately to head to the pit path, which would lead to a crack in the path and probably cause an accident. Setting to false is allowed, because the inpit variable will indicate that we have to finish the pit stop.

/* Sets the pitstop flag if we are not in the pit range */
void Pit::setPitstop(bool pitstop)
{
    if (mypit == NULL) return;
    float fromstart = car->_distFromStartLine;

    if (!isBetween(fromstart)) {
        this->pitstop = pitstop;
    } else if (!pitstop) {
        this->pitstop = pitstop;
    }
}

If we do not own a pit return. If we have a pit do the above explained checks and leave the pitstop variable in the correct state.

The isBetween Method

Checks if the given argument (a distance from the startline) falls between the pit entry and the pit exit.

/* Check if the argument fromstart is in the range of the pit */
bool Pit::isBetween(float fromstart)
{
    if (pitentry <= pitexit) {
        if (fromstart >= pitentry && fromstart <= pitexit) {
            return true;
        } else {
            return false;
        }
    } else {
        if ((fromstart >= 0.0 && fromstart <= pitexit) ||
            (fromstart >= pitentry && fromstart <= track->length))
        {
            return true;
        } else {
            return false;
        }
    }
}

First we check if pitentry is smaller than pitexit. If that is the case the start line falls not into the pit range. So we can simply check if the given argument is greater than pitentry and smaller than pitexit.

If pitentry is greater than pitexit, then the start line is in the pit range. The given argument falls in this case in the pit range if it is between zero and pitexit or between pitentry and the track end (equals the length).

Summary

  • You have understood and implemented the above methods.