void opponent::update(carData *myCar){ //TODO there we compute the path followed by the car if(car->_state & RM_CAR_STATE_NO_SIMU) return; /* we don't need to compute if we are the car of the car is no longer in the simulation */ pos.x = car->_pos_X; pos.y = car->_pos_Y; currentSeg = car->_trkPos.seg; trackAngle = RtTrackSideTgAngleL(&(car->_trkPos)); if(car == myCar->getCarPnt()) distToStart = car->_distFromStartLine; else distToStart = currentSeg->lgfromstart + getDistToSegStart(); /* update speed in track direction */ speed = getSpeed(); float cosa = speed/sqrt(car->_speed_X*car->_speed_X + car->_speed_Y*car->_speed_Y); float alpha = acos(cosa); width = car->_dimension_x*sin(alpha) + car->_dimension_y*cosa; }
void Opponent::update(tSituation *s, Driver *driver) { tCarElt *mycar = driver->getCarPtr(); // Init state of opponent to ignore. state = OPP_IGNORE; // If the car is out of the simulation ignore it. if (car->_state & (RM_CAR_STATE_NO_SIMU & ~RM_CAR_STATE_PIT)) { return; } // Updating distance along the middle. float oppToStart = car->_trkPos.seg->lgfromstart + getDistToSegStart(); distance = oppToStart - mycar->_distFromStartLine; if (distance > track->length/2.0f) { distance -= track->length; } else if (distance < -track->length/2.0f) { distance += track->length; } float SIDECOLLDIST = MIN(car->_dimension_x, mycar->_dimension_x); // Is opponent in relevant range -BACKCOLLDIST..FRONTCOLLDIST m. if (distance > -BACKCOLLDIST && distance < FRONTCOLLDIST) { // Is opponent in front and slower. if (distance > SIDECOLLDIST && getSpeed() < driver->getSpeed()) { state |= OPP_FRONT; distance -= MAX(car->_dimension_x, mycar->_dimension_x); distance -= LENGTH_MARGIN; // If the distance is small we compute it more accurate. if (distance < EXACT_DIST) { straight2f carFrontLine( mycar->_corner_x(FRNT_LFT), mycar->_corner_y(FRNT_LFT), mycar->_corner_x(FRNT_RGT) - mycar->_corner_x(FRNT_LFT), mycar->_corner_y(FRNT_RGT) - mycar->_corner_y(FRNT_LFT) ); float mindist = FLT_MAX; int i; for (i = 0; i < 4; i++) { vec2f corner(car->_corner_x(i), car->_corner_y(i)); float dist = carFrontLine.dist(corner); if (dist < mindist) { mindist = dist; } } if (mindist < distance) { distance = mindist; } } catchdist = driver->getSpeed()*distance/(driver->getSpeed() - getSpeed()); float cardist = car->_trkPos.toMiddle - mycar->_trkPos.toMiddle; sidedist = cardist; cardist = fabs(cardist) - fabs(getWidth()/2.0f) - mycar->_dimension_y/2.0f; if (cardist < SIDE_MARGIN) { state |= OPP_COLL; } } else // Is opponent behind and faster. if (distance < -SIDECOLLDIST && getSpeed() > driver->getSpeed() - SPEED_PASS_MARGIN) { catchdist = driver->getSpeed()*distance/(getSpeed() - driver->getSpeed()); state |= OPP_BACK; distance -= MAX(car->_dimension_x, mycar->_dimension_x); distance -= LENGTH_MARGIN; } else // Is opponent aside. if (distance > -SIDECOLLDIST && distance < SIDECOLLDIST) { sidedist = car->_trkPos.toMiddle - mycar->_trkPos.toMiddle; state |= OPP_SIDE; } else // Opponent is in front and faster. if (distance > SIDECOLLDIST && getSpeed() > driver->getSpeed()) { state |= OPP_FRONT_FAST; } } // Check if we should let overtake the opponent. updateOverlapTimer(s, mycar); if (overlaptimer > OVERLAP_WAIT_TIME) { state |= OPP_LETPASS; } }
/* Update the values in Opponent */ void opponent_update(tCarElt *car, tSituation *s, Driver *driver) { tCarElt *mycar = driver->getCarPtr(); /* init state of opponent to ignore */ state = OPP_IGNORE; /* if the car is out of the simulation ignore it */ if (car->_state & RM_CAR_STATE_NO_SIMU) { return; } // First we get a pointer to the drivers car, set the initial state to ignore // the opponent and if the opponent is not longer part of the simulation we return. /* updating distance along the middle */ float oppToStart = car->_trkPos.seg->lgfromstart + getDistToSegStart(); distance = oppToStart - mycar->_distFromStartLine; if (distance > track->length/2.0) { distance -= track->length; } else if (distance < -track->length/2.0) { distance += track->length; } // Now we compute the distance of the center of the drivers car to the center // of the opponents car. We achieve that by computing the distances to the // start line and taking the difference. If you think about that you will //recognize that this is just an approximation of the real distance. If you // want a more accurate value you have to compute it with the cars corners // (look up car.h). The if part is to "normalize" the distance. From our // position up to a half track length the opponent is in front of us (distance // is positive), else it is behind (distance is negative). A detail is that // we can't use _distFromStartLine of the opponent, because it is a private field. /* update speed in track direction */ speed = Opponent::getSpeed(car); float cosa = speed/sqrt(car->_speed_X*car->_speed_X + car->_speed_Y*car->_speed_Y); float alpha = acos(cosa); width = car->_dimension_x*sin(alpha) + car->_dimension_y*cosa; float SIDECOLLDIST = MIN(car->_dimension_x, mycar->_dimension_x); // We update the speed with the previously introduced getSpeed() method. // Then we compute the width of the opponents car on the track (think the // car is turned 90 degrees on the track, then the needed "width" is its length). /* is opponent in relevant range -50..200 m */ if (distance > -BACKCOLLDIST && distance < FRONTCOLLDIST) { /* is opponent in front and slower */ if (distance > SIDECOLLDIST && speed < driver->getSpeed()) { catchdist = driver->getSpeed()*distance/(driver->getSpeed() - speed); state |= OPP_FRONT; distance -= MAX(car->_dimension_x, mycar->_dimension_x); distance -= LENGTH_MARGIN; float cardist = car->_trkPos.toMiddle - mycar->_trkPos.toMiddle; sidedist = cardist; cardist = fabs(cardist) - fabs(width/2.0) - mycar->_dimension_y/2.0; if (cardist < SIDE_MARGIN) state |= OPP_COLL; } else // Here we check if the opponent is in the range we defined as relevant. // After that the classification of the opponent starts. In this part we // check if it is in front of us and slower. If that is the case we compute // the distance we need to drive to catch the opponent (catchdist, we assume // the speeds are constant) and set the opponents flag OPP_FRONT. Because // the "distance" contains the value of the cars centers we need to subtract // a car length and the safety margin. At the end we check if we could // collide with to opponent. If yes, we set the flag OPP_COLL. /* is opponent behind and faster */ if (distance < -SIDECOLLDIST && speed > driver->getSpeed()) { catchdist = driver->getSpeed()*distance/(speed - driver->getSpeed()); state |= OPP_BACK; distance -= MAX(car->_dimension_x, mycar->_dimension_x); distance -= LENGTH_MARGIN; } else // Here we check if the opponent is behind us and faster. We won't use that // in the tutorial robot, but you will need it if you want to let overlap // faster opponents. /* is opponent aside */ if (distance > -SIDECOLLDIST && distance < SIDECOLLDIST) { sidedist = car->_trkPos.toMiddle - mycar->_trkPos.toMiddle; state |= OPP_SIDE; } } }