Ejemplo n.º 1
0
//==========================================================================*
// Get information to the point nearest the given position
//--------------------------------------------------------------------------*
bool TLane::GetLanePoint(double TrackPos, TLanePoint& LanePoint) const
{
  int Count = oTrack->Count();

  int Idx0 = oTrack->IndexFromPos(TrackPos);
  int Idxp = (Idx0 - 1 + Count) % Count;
  int Idx1 = (Idx0 + 1) % Count;
  int Idx2 = (Idx0 + 2) % Count;

  double Dist0 = oPathPoints[Idx0].Dist();
  double Dist1 = oPathPoints[Idx1].Dist();
  if (Idx1 == 0)
    Dist1 = oTrack->Length();

  TVec3d P0 = oPathPoints[Idxp].CalcPt();
  TVec3d P1 = oPathPoints[Idx0].CalcPt();
  TVec3d P2 = oPathPoints[Idx1].CalcPt();
  TVec3d P3 = oPathPoints[Idx2].CalcPt();

  double Crv1 = TUtils::CalcCurvatureXY(P0, P1, P2);
  double Crv2 = TUtils::CalcCurvatureXY(P1, P2, P3);
  double Crv1z = TUtils::CalcCurvatureZ(P0, P1, P2);
  double Crv2z = TUtils::CalcCurvatureZ(P1, P2, P3);

  double Tx = (TrackPos - Dist0) / (Dist1 - Dist0);

  LanePoint.Index = Idx0;
  LanePoint.Crv = (1.0 - Tx) * Crv1 + Tx * Crv2;
  LanePoint.Crvz = (1.0 - Tx) * Crv1z + Tx * Crv2z;
  LanePoint.T = Tx;
  LanePoint.Offset =
	(oPathPoints[Idx0].Offset)
	+ Tx * (oPathPoints[Idx1].Offset - oPathPoints[Idx0].Offset);

  double Ang0 = TUtils::VecAngXY(oPathPoints[Idx1].CalcPt() -
	oPathPoints[Idx0].CalcPt());
  double Ang1 = TUtils::VecAngXY(oPathPoints[Idx2].CalcPt() -
	oPathPoints[Idx1].CalcPt());

  double DeltaAng = Ang1 - Ang0;
  DOUBLE_NORM_PI_PI(DeltaAng);
  LanePoint.Angle = Ang0 + LanePoint.T * DeltaAng;

  TVec2d Tang1, Tang2;
  TUtils::CalcTangent(P0.GetXY(), P1.GetXY(), P2.GetXY(), Tang1);
  TUtils::CalcTangent(P1.GetXY(), P2.GetXY(), P3.GetXY(), Tang2);
  //TVec2d Dir = TUtils::VecUnit(Tang1) * (1 - Tx) + TUtils::VecUnit(Tang2) * Tx;

  Ang0 = TUtils::VecAngle(Tang1);
  Ang1 = TUtils::VecAngle(Tang2);
  DeltaAng = Ang1 - Ang0;
  DOUBLE_NORM_PI_PI(DeltaAng);

  LanePoint.Speed = oPathPoints[LanePoint.Index].Speed + (oPathPoints[Idx1].Speed
	- oPathPoints[LanePoint.Index].Speed) * LanePoint.T;
  LanePoint.AccSpd = oPathPoints[LanePoint.Index].AccSpd + (oPathPoints[Idx1].AccSpd
	- oPathPoints[LanePoint.Index].AccSpd) * LanePoint.T;

  return true;
}
Ejemplo n.º 2
0
//==========================================================================*
// Update
//
// ATTENTION oCar ist opponents car, so we can use our shortcuts!!!
//--------------------------------------------------------------------------*
void TOpponent::Update(
  const PCarElt MyCar,
  double MyDirX,
  double MyDirY,
  float &MinDistBack,
  double &MinTimeSlot)
{
  if((CarState & RM_CAR_STATE_NO_SIMU) &&        // omit cars out of race
    (CarState & RM_CAR_STATE_PIT) == 0 )         //   if not in pit
    return;

  oInfo.State.Speed = myhypot(CarSpeedX,CarSpeedY);// Speed of car

  // Track relative speed of opponents car
  TVec2d ToRight = oTrack->Normale(DistanceFromStartLine);
  oInfo.State.TrackVelLong = ToRight.x * CarSpeedY - ToRight.y * CarSpeedX;
  oInfo.State.TrackVelLat = ToRight.x * CarSpeedX + ToRight.y * CarSpeedY;

  // Track relative yaw of other car.
  oInfo.State.TrackYaw = CarYaw - TUtils::VecAngle(ToRight) - PI / 2;
  DOUBLE_NORM_PI_PI(oInfo.State.TrackYaw);

  // Average velocity of other car.
  oInfo.State.AvgVelLong = oInfo.State.AvgVelLong * AVG_KEEP + CarPubGlobVelX * AVG_CHANGE;
  oInfo.State.AvgVelLat = oInfo.State.AvgVelLat * AVG_KEEP + CarPubGlobVelY * AVG_CHANGE;
  oInfo.State.CarAvgVelLong = MyDirX * oInfo.State.AvgVelLong + MyDirY * oInfo.State.AvgVelLat;
  //oInfo.State.CarAvgVelLat = MyDirY * oInfo.State.AvgVelLong - MyDirX * oInfo.State.AvgVelLat;

  // Average acceleration of other car.
  oInfo.State.AvgAccLong = oInfo.State.AvgAccLong * AVG_KEEP + CarPubGlobAccX * AVG_CHANGE;
  oInfo.State.AvgAccLat = oInfo.State.AvgAccLat * AVG_KEEP + CarPubGlobAccY * AVG_CHANGE;
  oInfo.State.CarAvgAccLong = MyDirX * oInfo.State.AvgAccLong + MyDirY * oInfo.State.AvgAccLat;
  oInfo.State.CarAvgAccLat = MyDirY * oInfo.State.AvgAccLong - MyDirX * oInfo.State.AvgAccLat;

  // Offset from track center line.
  oInfo.State.Offset = -CarToMiddle;

  if(oCar == MyCar)
    return;

  // Car-Car relative calculations ...

  // calc other cars position, velocity relative to my car (global coords).
  double DistX = CarPubGlobPosX - MyCar->pub.DynGCg.pos.x;
  double DistY = CarPubGlobPosY - MyCar->pub.DynGCg.pos.y;
  double DiffVelX = CarSpeedX - MyCar->_speed_X;
  double DiffVelY = CarSpeedY - MyCar->_speed_Y;

  // work out relative position, velocity in local coords (coords of my car).
  oInfo.State.CarDistLong = MyDirX * DistX + MyDirY * DistY;
  oInfo.State.CarDistLat = MyDirY * DistX - MyDirX * DistY;
  oInfo.State.CarDiffVelLong = MyDirX * DiffVelX + MyDirY * DiffVelY;
  oInfo.State.CarDiffVelLat = MyDirY * DiffVelX - MyDirX * DiffVelY;

  oInfo.State.MinDistLong = (MyCar->_dimension_x + CarLength) / 2;
  oInfo.State.MinDistLat = (MyCar->_dimension_y + CarWidth) / 2;

  double MyVelAng = atan2(MyCar->_speed_Y, MyCar->_speed_X);
  double MyYaw = MyCar->_yaw - MyVelAng;
  DOUBLE_NORM_PI_PI(MyYaw);

  double OppYaw = CarYaw - MyVelAng;
  DOUBLE_NORM_PI_PI(OppYaw);

  // Additional distance needed while yawing of both cars
  double ExtSide = (oInfo.State.MinDistLong - oInfo.State.MinDistLat) *
    (fabs(sin(MyYaw)) + fabs(sin(OppYaw)));

  oInfo.State.MinDistLat += ExtSide + SIDE_MARGIN;
  oInfo.State.MinDistLong += TDriver::LengthMargin;

  // Distance of car from start of track.
  double MyPos = RtGetDistFromStart((tCarElt*)MyCar);
  double HisPos = RtGetDistFromStart((tCarElt*)oCar);
  double RelPos = HisPos - MyPos;
  double TrackLen = oTrack->Length();
  if (RelPos > TrackLen / 2)
    RelPos -= TrackLen;
  else if (RelPos < -TrackLen / 2)
    RelPos += TrackLen;

  oInfo.State.RelPos = RelPos;

  if (fabs(CarToMiddle) - oTrack->Width() > 1.0) // If opponent is outside of track
  {                                              // we assume it is in the pitlane

    if ((RelPos > MinDistBack)                   // Opponent is near
	  && (RelPos < 5))                           // and not in front
    {
      MinDistBack = (tdble) RelPos;
    }

    double T = -RelPos/oInfo.State.TrackVelLong; // Time to start out of pit
    if ((T > 0)                                  // Opponent is back or aside
	  && (T < 200))                              // and arrives within 20 sec
    {
      if (MinTimeSlot > T)
	    MinTimeSlot = T;
    }
  }
}