Ejemplo n.º 1
0
bool InTurnSector(NMEA_INFO *Basic, DERIVED_INFO *Calculated, const int the_turnpoint) {
	if(!ValidTaskPoint(the_turnpoint)) return false;
	switch(SectorType) {
		case CIRCLE:
			if(Calculated->WaypointDistance < SectorRadius) return true;
			break;
		case SECTOR:
		case DAe: {
			if(SectorType==DAe) { // JMW added german rules
				if (Calculated->WaypointDistance<500) return true;
			}
			double AircraftBearing;
			LockTaskData();
			DistanceBearing(WayPointList[Task[the_turnpoint].Index].Latitude,
					WayPointList[Task[the_turnpoint].Index].Longitude,
					Basic->Latitude ,
					Basic->Longitude,
					NULL, &AircraftBearing);
			AircraftBearing = AircraftBearing - Task[the_turnpoint].Bisector;
			UnlockTaskData();
			while(AircraftBearing<-180) AircraftBearing+= 360;
			while(AircraftBearing>180) AircraftBearing-= 360;
			if(AircraftBearing>=-45 && AircraftBearing<=45) {
				if(SectorType==SECTOR) {
					if(Calculated->WaypointDistance < SectorRadius) return true;
				} else { //It's a DAe
					if(Calculated->WaypointDistance < 10000) return true; // JMW added german rules
				}
			}
		}   break;
		case LINE: {
			//First check if we simply passed the WayPoint
			LockTaskData();
			if(Calculated->LegDistanceToGo<Task[the_turnpoint].Leg && Calculated->LegDistanceCovered>=Task[the_turnpoint].Leg) {
				UnlockTaskData();
				return true;
			}
			//Then check if we passed the bisector
			bool bisectorOverpassed;
			if(AngleLimit360(Task[the_turnpoint].InBound-Task[the_turnpoint].Bisector) < 180)
				bisectorOverpassed = AngleInRange(Reciprocal(Task[the_turnpoint].Bisector),Task[the_turnpoint].Bisector,Calculated->WaypointBearing,true);
			else
				bisectorOverpassed = AngleInRange(Task[the_turnpoint].Bisector,Reciprocal(Task[the_turnpoint].Bisector),Calculated->WaypointBearing,true);
			UnlockTaskData();
			if(bisectorOverpassed) return true;
		}   break;
		default: //Unknown sector type
			break;
	}
	return false;
}
Ejemplo n.º 2
0
bool InAATTurnSector(const double longitude, const double latitude,
                    const int the_turnpoint)
{
  double AircraftBearing;
  bool retval = false;

  if (!ValidTaskPoint(the_turnpoint)) {
    return false;
  }

  double distance;
  LockTaskData();
  DistanceBearing(WayPointList[Task[the_turnpoint].Index].Latitude,
                  WayPointList[Task[the_turnpoint].Index].Longitude,
                  latitude,
                  longitude,
                  &distance, &AircraftBearing);

  if(Task[the_turnpoint].AATType ==  CIRCLE) {
    if(distance < Task[the_turnpoint].AATCircleRadius) {
      retval = true;
    }
  } else if(distance < Task[the_turnpoint].AATSectorRadius) {
    if (AngleInRange(Task[the_turnpoint].AATStartRadial,
                     Task[the_turnpoint].AATFinishRadial,
                     AngleLimit360(AircraftBearing), true)) {
      retval = true;
    }
  }

  UnlockTaskData();
  return retval;
}
Ejemplo n.º 3
0
// Used by dlgTarget only
// A note about this function. We are changing map drawing parameters here, but we paint from the winmain thread.
// We are NOT using this from drawthread! the dialog target pan is sort of an hack, and not a good example.
// Do not consider emulating the target dialog, because it should be moved to draw thread somehow.
void MapWindow::SetTargetPan(bool do_pan, int target_point, DWORD dlgSize /* = 0 */)
{
  static double old_latitude;
  static double old_longitude;

  if(dlgSize)
    targetPanSize = dlgSize;

  if (!mode.Is(Mode::MODE_TARGET_PAN) || (TargetPanIndex != target_point)) {
    targetMoved = false;
  }

  TargetPanIndex = target_point;

  if (do_pan && !mode.Is(Mode::MODE_TARGET_PAN)) {
    old_latitude = PanLatitude;
    old_longitude = PanLongitude;
    mode.Special(do_pan ? Mode::MODE_SPECIAL_TARGET_PAN : Mode::MODE_SPECIAL_PAN, true);
    zoom.SwitchMode();
  }
  if (do_pan) {
    LockTaskData();
    if (ValidTaskPoint(target_point)) {
      PanLongitude = WayPointList[Task[target_point].Index].Longitude;
      PanLatitude = WayPointList[Task[target_point].Index].Latitude;
      if (target_point==0) {
        TargetZoomDistance = max(2e3, (double)StartRadius*2);
      } else if (!ValidTaskPoint(target_point+1)) {
        TargetZoomDistance = max(2e3, (double)FinishRadius*2);
      } else if (AATEnabled) {
        if (Task[target_point].AATType == SECTOR) {
          const double start = Task[target_point].AATStartRadial;
          const double finish = Task[target_point].AATFinishRadial;
          const double xs = fastsine(start);
          const double ys = fastcosine(start);
          const double xf = fastsine(finish);
          const double yf = fastcosine(finish);
          
          // calculate rectangle area taken by the sector
          const double top    = AngleInRange(start, finish, 0,   true) ?  1 : max(max(ys, yf), 0.0);
          const double right  = AngleInRange(start, finish, 90,  true) ?  1 : max(max(xs, xf), 0.0);
          const double bottom = AngleInRange(start, finish, 180, true) ? -1 : min(min(ys, yf), 0.0);
          const double left   = AngleInRange(start, finish, 270, true) ? -1 : min(min(xs, xf), 0.0);
          
          // get area center
          const double radius = Task[target_point].AATSectorRadius;
          const double x = (left + right) / 2;
          const double y = (top + bottom) / 2;
          double bearing, range;
          xXY_Brg_Rng(0, 0, x, y, &bearing, &range);
          
          // find area center geographic data
          FindLatitudeLongitude(WayPointList[Task[target_point].Index].Latitude,
                                WayPointList[Task[target_point].Index].Longitude,
                                bearing, range * radius, &PanLatitude, &PanLongitude);
          TargetZoomDistance = max(2e3, max(right - left, top - bottom) * radius);
        } else {
          TargetZoomDistance = max(2e3, Task[target_point].AATCircleRadius*2);
        }
      } else {
        TargetZoomDistance = max(2e3, (double)SectorRadius*2);
      }
    }
    UnlockTaskData();
  }
  else if (mode.Is(Mode::MODE_TARGET_PAN)) {
    PanLongitude = old_longitude;
    PanLatitude = old_latitude;
    mode.Special(Mode::MODE_SPECIAL_TARGET_PAN, do_pan);
    zoom.SwitchMode();
    }
  mode.Special(Mode::MODE_SPECIAL_TARGET_PAN, do_pan);
  }
Ejemplo n.º 4
0
void CalculateAATTaskSectors()
{
  int i;
  int awp = ActiveTaskPoint;

  if(AATEnabled == FALSE || DoOptimizeRoute())
    return;

  double latitude = GPS_INFO.Latitude;
  double longitude = GPS_INFO.Longitude;
  double altitude = GPS_INFO.Altitude;

  LockTaskData();

  Task[0].AATTargetOffsetRadius = 0.0;
  Task[0].AATTargetOffsetRadial = 0.0;
  if (Task[0].Index>=0) {
    Task[0].AATTargetLat = WayPointList[Task[0].Index].Latitude;
    Task[0].AATTargetLon = WayPointList[Task[0].Index].Longitude;
  }

  for(i=1;i<MAXTASKPOINTS;i++) {
    if(ValidTaskPoint(i)) {
      if (!ValidTaskPoint(i+1)) {
        // This must be the final waypoint, so it's not an AAT OZ
        Task[i].AATTargetLat = WayPointList[Task[i].Index].Latitude;
        Task[i].AATTargetLon = WayPointList[Task[i].Index].Longitude;
        continue;
      }

      if(Task[i].AATType == SECTOR) {
        FindLatitudeLongitude (WayPointList[Task[i].Index].Latitude,
                                 WayPointList[Task[i].Index].Longitude, 
                               Task[i].AATStartRadial , 
                               Task[i].AATSectorRadius ,
                               &Task[i].AATStartLat,
                               &Task[i].AATStartLon);
        
        FindLatitudeLongitude (WayPointList[Task[i].Index].Latitude,
                               WayPointList[Task[i].Index].Longitude,
                               Task[i].AATFinishRadial , 
                               Task[i].AATSectorRadius,
                               &Task[i].AATFinishLat,
                               &Task[i].AATFinishLon);
      }

      // JMWAAT: if locked, don't move it
      if (i<awp) {
        // only update targets for current/later waypoints 
        continue;
      }

      Task[i].AATTargetOffsetRadius = 
        min(1.0, max(Task[i].AATTargetOffsetRadius,-1.0));

      Task[i].AATTargetOffsetRadial = 
        min(90.0, max(-90.0, Task[i].AATTargetOffsetRadial));

      double targetbearing;
      double targetrange;
      
      targetbearing = AngleLimit360(Task[i].Bisector+Task[i].AATTargetOffsetRadial);
      
      if(Task[i].AATType == SECTOR) {

        //AATStartRadial
        //AATFinishRadial

        targetrange = ((Task[i].AATTargetOffsetRadius+1.0)/2.0);

        double aatbisector = HalfAngle(Task[i].AATStartRadial, 
                                       Task[i].AATFinishRadial);

        if (fabs(AngleLimit180(aatbisector-targetbearing))>90) {
          // bisector is going away from sector 
          targetbearing = Reciprocal(targetbearing);
          targetrange = 1.0-targetrange;
        }
        if (!AngleInRange(Task[i].AATStartRadial,
                          Task[i].AATFinishRadial,
                          targetbearing,true)) {

          // Bisector is not within AAT sector, so
          // choose the closest radial as the target line

          if (fabs(AngleLimit180(Task[i].AATStartRadial-targetbearing))
              <fabs(AngleLimit180(Task[i].AATFinishRadial-targetbearing))) {
            targetbearing = Task[i].AATStartRadial;
          } else {
            targetbearing = Task[i].AATFinishRadial;
          }
        }

        targetrange*= Task[i].AATSectorRadius;

      } else {
        targetrange = Task[i].AATTargetOffsetRadius
          *Task[i].AATCircleRadius;
      }
      
      // TODO accuracy: if i=awp and in sector, range parameter needs to
      // go from current aircraft position to projection of target
      // out to the edge of the sector
      
      if (InAATTurnSector(longitude, latitude, i, altitude) && (awp==i) &&
          !Task[i].AATTargetLocked) {

        // special case, currently in AAT sector/cylinder
        
        double dist;
        double qdist;
        double bearing;
        
        // find bearing from last target through current aircraft position with offset
        DistanceBearing(Task[i-1].AATTargetLat,
                        Task[i-1].AATTargetLon,
                        latitude,
                        longitude,
                        &qdist, &bearing);

        bearing = AngleLimit360(bearing+Task[i].AATTargetOffsetRadial);

        dist = ((Task[i].AATTargetOffsetRadius+1)/2.0)*
          FindInsideAATSectorDistance(latitude, longitude, i, bearing);
        
        // if (dist+qdist>aatdistance.LegDistanceAchieved(awp)) {
        // JMW: don't prevent target from being closer to the aircraft
        // than the best achieved, so can properly plan arrival time        

        FindLatitudeLongitude (latitude,
                               longitude, 
                               bearing, 
                               dist,
                               &Task[i].AATTargetLat,
                               &Task[i].AATTargetLon);

        UpdateTargetAltitude(Task[i]);

        TargetModified = true;

        // }
        
      } else {
        
        FindLatitudeLongitude (WayPointList[Task[i].Index].Latitude,
                               WayPointList[Task[i].Index].Longitude, 
                               targetbearing, 
                               targetrange,
                               &Task[i].AATTargetLat,
                               &Task[i].AATTargetLon);
        
        UpdateTargetAltitude(Task[i]);
        TargetModified = true;
        
      }
    }
  }

  CalculateAATIsoLines();
  if (!TargetDialogOpen) {
    TargetModified = false;
    // allow target dialog to detect externally changed targets
  }

  UnlockTaskData();
}