コード例 #1
0
ファイル: LKUtils.cpp プロジェクト: acasadoalonso/LK8000
void GotoWaypoint(const int wpnum) {
  if (!ValidWayPoint(wpnum)) {
	DoStatusMessage(_T("ERR-639 INVALID GOTO WPT"));
	return;
  }
  if (ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
	TCHAR wpname[NAME_SIZE+1];
	_tcscpy(wpname,WayPointList[wpnum].Name);
	wpname[10] = '\0';

	if (MessageBoxX(
	// LKTOKEN  _@M158_ = "CONFIRM GOTO, ABORTING TASK?" 
	gettext(TEXT("_@M158_")),
	// LKTOKEN  _@M40_ = "A task is running!" 
	gettext(TEXT("_@M40_")),
	mbYesNo) == IdYes) {
		LockTaskData();
		FlyDirectTo(wpnum);
		OvertargetMode=OVT_TASK;
		UnlockTaskData();
        }
  } else {
	LockTaskData();
	FlyDirectTo(wpnum);
	OvertargetMode=OVT_TASK;
	UnlockTaskData();
  }
}
コード例 #2
0
  bool CheckCondition(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {    
    if (!Calculated->Flying || !ValidTaskPoint(ActiveWayPoint)) {
      return false;
    }

    tad = Calculated->TaskAltitudeDifference*0.2+0.8*tad;

    bool BeforeFinalGlide = 
      (ValidTaskPoint(ActiveWayPoint+1) && !Calculated->FinalGlide);

    if (BeforeFinalGlide) {
      Interval_Notification = 60*5;
      if ((tad>50) && (last_tad< -50)) {
        // report above final glide early
        return true;
      } else if (tad< -50) {
        last_tad = tad;
      }
    } else {
      Interval_Notification = 60;
      if (Calculated->FinalGlide) {
        if ((last_tad< -50) && (tad>1)) {
          // just reached final glide, previously well below
          return true;
        } 
        if ((last_tad> 1) && (tad< -50)) {
          // dropped well below final glide, previously above
	  last_tad = tad;
          return true; // JMW this was true before
        }
      }
    } 
    return false;
  };
コード例 #3
0
static void OnLoadClicked(WndButton* pWnd){ // 091216
  TCHAR file_name[MAX_PATH];

  WndProperty* wp;
  DataFieldFileReader *dfe;

  wp = (WndProperty*)wf->FindByName(TEXT("prpFile"));
  if (!wp) return;

  wp->OnLButtonDown((POINT){0,0});
  
  dfe = (DataFieldFileReader*) wp->GetDataField();

  int file_index = dfe->GetAsInteger();
  if (file_index>0) {
	if (ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
		_stprintf(file_name, TEXT("%s '%s' ?"), gettext(TEXT("_@M891_")), dfe->GetAsString()); // Clear old task and load
		if(MessageBoxX(file_name, _T(" "), mbYesNo) == IdNo) {
			return;
		}
	}
  } else {
	// LKTOKEN  _@M467_ = "No Task to load" 
	MessageBoxX(gettext(TEXT("_@M467_")),_T(" "), mbOk);
	return;
  }

  if (file_index>0) {
      LPCTSTR szFileName = dfe->GetPathFile();
      LPCTSTR wextension = _tcsrchr(szFileName, _T('.'));
      if(wextension) {
          bool bOK = false;
          if(_tcsicmp(wextension,_T(LKS_TSK))==0) {
              CTaskFileHelper helper;
              bOK = helper.Load(szFileName);
          } 
#ifdef OLDTASK_COMPAT
          else if (_tcsicmp(wextension,_T(LKS_OLD_TSK))==0) {
              LoadNewTask(szFileName);
              bOK = true;
          } 
#endif          
          else if (_tcsicmp(wextension,_T(LKS_WP_CUP))==0) {
              bOK = LoadCupTask(szFileName);
          } else if (_tcsicmp(wextension,_T(LKS_WP_GPX))==0) {
              bOK = LoadGpxTask(szFileName);
          }
          if(!bOK) {
              MessageBoxX(gettext(TEXT("_@M467_")),_T(" "), mbOk);
              return;
          }
          OverviewRefreshTask();
          UpdateFilePointer();
          UpdateCaption();
      }
  }
}
コード例 #4
0
double AdjustAATTargets(double desired) {
  int i, istart, inum;
  double av=0;
  istart = max(1,ActiveTaskPoint);
  inum=0;

  LockTaskData();
  for(i=istart;i<MAXTASKPOINTS-1;i++)
    {
      if(ValidTaskPoint(i)&&ValidTaskPoint(i+1) && !Task[i].AATTargetLocked)
	{
          Task[i].AATTargetOffsetRadius = max(-1.0,min(1.0,
                                          Task[i].AATTargetOffsetRadius));
	  av += Task[i].AATTargetOffsetRadius;
	  inum++;
	}
    }
  if (inum>0) {
    av/= inum;
  }
  if (fabs(desired)>1.0) {
    // don't adjust, just retrieve.
    goto OnExit;
  }

  // TODO accuracy: Check here for true minimum distance between
  // successive points (especially second last to final point)

  // Do this with intersection tests

  desired = (desired+1.0)/2.0; // scale to 0,1
  av = (av+1.0)/2.0; // scale to 0,1

  for(i=istart;i<MAXTASKPOINTS-1;i++)
    {
      if((Task[i].Index >=0)&&(Task[i+1].Index >=0) && !Task[i].AATTargetLocked)
	{
	  double d = (Task[i].AATTargetOffsetRadius+1.0)/2.0;
          // scale to 0,1

          if (av>0.01) {
            d = desired; 
	    // 20080615 JMW
	    // was (desired/av)*d;
	    // now, we don't want it to be proportional 
          } else {
            d = desired;
          } 
          d = min(1.0, max(d, 0.0))*2.0-1.0;
          Task[i].AATTargetOffsetRadius = d;
	}
    }
 OnExit:
  UnlockTaskData();
  return av;
}
コード例 #5
0
ファイル: TimeGates.cpp プロジェクト: PhilColbert/LK8000
// ALL TIME VALUES ARE IN SECONDS! 
bool UseGates() {
  if (!ISPARAGLIDER ) return(false);
  if (PGNumberOfGates>0) {
	if (ValidTaskPoint(0) && ValidTaskPoint(1)) {
		return(true);
	} else
		return(false);
  } else
	return(false);
}
コード例 #6
0
static void OnLoadClicked(WindowControl * Sender, WndListFrame::ListInfo_t *ListInfo){ // 091216
  (void)ListInfo; (void)Sender;

  TCHAR file_name[MAX_PATH];

  WndProperty* wp;
  DataFieldFileReader *dfe;

  wp = (WndProperty*)wf->FindByName(TEXT("prpFile"));
  if (!wp) return;

  HWND hwnd = wp->GetHandle();
  SendMessage(hwnd,WM_LBUTTONDOWN,0,0);
  dfe = (DataFieldFileReader*) wp->GetDataField();

  int file_index = dfe->GetAsInteger();
  if (file_index>0) {
	if (ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
		_stprintf(file_name, TEXT("%s '%s' ?"), gettext(TEXT("_@M891_")), dfe->GetAsString()); // Clear old task and load
		if(MessageBoxX(hWndMapWindow, file_name, _T(" "), MB_YESNO|MB_ICONQUESTION) == IDNO) {
			return;
		}
	}
  } else {
	// LKTOKEN  _@M467_ = "No Task to load" 
	MessageBoxX(hWndMapWindow, gettext(TEXT("_@M467_")),_T(" "), MB_OK|MB_ICONEXCLAMATION);
	return;
  }

  if (file_index>0) {
      LPCTSTR szFileName = dfe->GetPathFile();
      LPCTSTR wextension = _tcsrchr(szFileName, _T('.'));
      if(wextension) {
          bool bOK = false;
          if(_tcsicmp(wextension,_T(LKS_TSK))==0) {
              CTaskFileHelper helper;
              bOK = helper.Load(szFileName);
          } else if (_tcsicmp(wextension,_T(LKS_OLD_TSK))==0) {
              LoadNewTask(szFileName);
              bOK = true;
          } else if (_tcsicmp(wextension,_T(LKS_WP_CUP))==0) {
              bOK = LoadCupTask(szFileName);
          } else if (_tcsicmp(wextension,_T(LKS_WP_GPX))==0) {
              bOK = LoadGpxTask(szFileName);
          }
          if(!bOK) {
              MessageBoxX(hWndMapWindow, gettext(TEXT("_@M467_")),_T(" "), MB_OK|MB_ICONEXCLAMATION);
              return;
          }
          OverviewRefreshTask();
          UpdateFilePointer();
          UpdateCaption();
      }
  }
}
コード例 #7
0
ファイル: LKUtils.cpp プロジェクト: acasadoalonso/LK8000
bool DoOptimizeRoute() {

  if (AircraftCategory != (AircraftCategory_t)umParaglider) return false;
  if (!PGOptimizeRoute) return false;

  if (!ValidTaskPoint(0) || !ValidTaskPoint(1)) return false;
  if (!ValidTaskPoint(ActiveWayPoint)) return false;

  return true;

}
コード例 #8
0
ファイル: SpeedToFly.cpp プロジェクト: acasadoalonso/LK8000
//
// Sollfarh / Dolphin Speed calculator
//
void SpeedToFly(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {


    if (((AutoMcMode == amcFinalGlide) || (AutoMcMode == amcFinalAndClimb)) 
            && DoOptimizeRoute() && Calculated->NextAltitude > 0.) {

        // Special case for Conical end of Speed section
        int Type = -1;
        double ConeSlope = 0.0;
        LockTaskData();
        if (ValidTaskPoint(ActiveWayPoint)) {
            GetTaskSectorParameter(ActiveWayPoint, &Type, NULL);
            ConeSlope = Task[ActiveWayPoint].PGConeSlope;
        }
        UnlockTaskData();
        if (Type == CONE && ConeSlope > 0.0) {
            double VOpt = GlidePolar::FindSpeedForSlope(ConeSlope);
            double eqMC = GlidePolar::EquMC(VOpt);
            if(eqMC <= MACCREADY ) {
                Calculated->VOpt = VOpt;
                return;
            }
        }
    }

    double HeadWind = 0;
    if (Calculated->FinalGlide && ValidTaskPoint(ActiveWayPoint)) {
        // according to MC theory STF take account of wind only if on final Glide
        // TODO : for the future add config parameter for always use wind.
        if (Calculated->HeadWind != -999) {
            HeadWind = Calculated->HeadWind;
        }
    }

    // this is IAS for best Ground Glide ratio acounting current air mass ( wind / Netto vario )
    double VOptnew = GlidePolar::STF(MACCREADY, Calculated->NettoVario, HeadWind);

    // apply cruises efficiency factor.
    VOptnew *= CRUISE_EFFICIENCY;
    
    if (Calculated->NettoVario > MACCREADY) {
        // this air mass is better than maccready, so don't fly at speed less than minimum sink speed adjusted for load factor
        double n = fabs((Basic->AccelerationAvailable) ? Basic->AccelZ : Calculated->Gload);
        VOptnew = max(VOptnew, GlidePolar::Vminsink() * sqrt(n));
    } else {
        // never fly at speed less than min sink speed
        VOptnew = max(VOptnew, GlidePolar::Vminsink());
    }

    // use low pass filter for avoid big jump of value.
    Calculated->VOpt = LowPassFilter(Calculated->VOpt, VOptnew, 0.6);
}
コード例 #9
0
ファイル: PGTaskMgr.cpp プロジェクト: LK8000/LK8000
void PGTaskMgr::Initialize() {

    std::for_each(m_Task.begin(), m_Task.end(), safe_delete());
    m_Task.clear();

    // build Mercator Reference Grid
    // find center of Task
    double minlat = 0.0, minlon = 0.0, maxlat = 0.0, maxlon = 0.0;
    for (int curwp = 0; ValidTaskPoint(curwp); ++curwp) {
        if (curwp == 0) {
            maxlat = minlat = WayPointList[Task[curwp].Index].Latitude;
            maxlon = minlon = WayPointList[Task[curwp].Index].Longitude;
        } else {
            minlat = std::min(minlat, WayPointList[Task[curwp].Index].Latitude);
            maxlat = std::max(maxlat, WayPointList[Task[curwp].Index].Latitude);

            minlon = std::min(minlon, WayPointList[Task[curwp].Index].Longitude);
            maxlon = std::max(maxlon, WayPointList[Task[curwp].Index].Longitude);
        }
    }

    m_Grid.lat0 = deg2rad(minlat + maxlat) * 1 / 2;
    m_Grid.lon0 = deg2rad(minlon + maxlon) * 1 / 2;
    m_Grid.k0 = 1;
    m_Grid.false_e = 0.0; // ????
    m_Grid.false_n = 0.0; // ????

    // build task point list
    for (int curwp = 0; ValidTaskPoint(curwp); ++curwp) {
        int TpType = 0;
        double Radius;
        GetTaskSectorParameter(curwp, &TpType, &Radius);
        switch (TpType) {
            case CIRCLE:
                AddCircle(curwp);
                break;
            case SECTOR:
            case DAe:
                AddSector(curwp);
                break;
            case LINE:
                AddLine(curwp);
                break;
            case CONE:
                AddCone(curwp);
                break;
            case ESS_CIRCLE:
                AddEssCircle(curwp);
                break;
        }
    }
}
コード例 #10
0
ファイル: CTaskFileHelper.cpp プロジェクト: Tomas1/LK8000
bool CTaskFileHelper::LoadTaskPointList(XMLNode node) {
    mFinishIndex = 0;
    if (node) {
        int i = 0;
        XMLNode nodePoint = node.getChildNode(_T("point"), &i);
        while (nodePoint) {
            if (!LoadTaskPoint(nodePoint)) {
                return false;
            }
            nodePoint = node.getChildNode(_T("point"), &i);
        }
    }


    ///////////////////////////////////////////////////////////////
    // TODO : this code is temporary before rewriting task system
    if (AATEnabled || DoOptimizeRoute()) {
        if (ValidTaskPoint(mFinishIndex)) {
            switch (Task[mFinishIndex].AATType) {
                case CIRCLE:
                    FinishRadius = (DWORD)Task[mFinishIndex].AATCircleRadius;
                    FinishLine = 0;
                    break;
                case LINE:
                    FinishRadius = (DWORD)Task[mFinishIndex].AATCircleRadius;
                    FinishLine = 1;
                case SECTOR:
                    FinishRadius = (DWORD)Task[mFinishIndex].AATSectorRadius;
                    FinishLine = 2;
            }
        }
        if (ValidTaskPoint(0)) {
            switch (Task[0].AATType) {
                case CIRCLE:
                    StartRadius = (DWORD)Task[0].AATCircleRadius;
                    StartLine = 0;
                    break;
                case LINE:
                    StartRadius = (DWORD)Task[0].AATCircleRadius;
                    StartLine = 1;
                case SECTOR:
                    StartRadius = (DWORD)Task[0].AATSectorRadius;
                    StartLine = 2;
            }
        }
    }
    ///////////////////////////////////////////////////////////////


    return true;
}
コード例 #11
0
ファイル: dlgTaskWaypoint.cpp プロジェクト: miza/LK8000
static void UpdateCaption(void) {
  TCHAR sTmp[128];
  TCHAR title[128];
  if (ValidTaskPoint(twItemIndex)) {
    switch (twType) {
    case 0:
	// LKTOKEN  _@M657_ = "Start" 
      _stprintf(title, gettext(TEXT("_@M657_")));
      break;
    case 1:
	// LKTOKEN  _@M749_ = "Turnpoint" 
      _stprintf(title, gettext(TEXT("_@M749_")));
      break;
    case 2:
	// LKTOKEN  _@M299_ = "Finish" 
      _stprintf(title, gettext(TEXT("_@M299_")));
      break;
    };
    _stprintf(sTmp, TEXT("%s: %s"), title,
              WayPointList[Task[twItemIndex].Index].Name);
    wf->SetCaption(sTmp);
  } else {
	// LKTOKEN  _@M9_ = "(invalid)" 
    wf->SetCaption(gettext(TEXT("_@M9_")));
  }
}
コード例 #12
0
ファイル: dlgTaskWaypoint.cpp プロジェクト: Acrobot/LK8000
static void UpdateCaption(void) {
  TCHAR sTmp[128];
  TCHAR title[128];
  if (ValidTaskPoint(twItemIndex)) {
    switch (twType) {
    case 0:
	// LKTOKEN  _@M657_ = "Start" 
      _stprintf(title, gettext(TEXT("_@M657_")));
      break;
    case 1:
	// LKTOKEN  _@M749_ = "Turnpoint" 
      _stprintf(title, gettext(TEXT("_@M749_")));
      break;
    case 2:
	// LKTOKEN  _@M299_ = "Finish" 
      _stprintf(title, gettext(TEXT("_@M299_")));
      break;
    };

    TCHAR landableStr[5] = TEXT(" [X]");
    // LKTOKEN _@M1238_ "L"
    landableStr[2] = gettext(TEXT("_@M1238_"))[0];
    
    _stprintf(sTmp, TEXT("%s: %s%s"), title,
              WayPointList[Task[twItemIndex].Index].Name,
              (WayPointList[Task[twItemIndex].Index].Flags & LANDPOINT) ? landableStr : TEXT(""));
    wf->SetCaption(sTmp);
  } else {
	// LKTOKEN  _@M9_ = "(invalid)" 
    wf->SetCaption(gettext(TEXT("_@M9_")));
  }
}
コード例 #13
0
ファイル: AATInTurnSector.cpp プロジェクト: Acrobot/LK8000
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;
}
コード例 #14
0
ファイル: AATDistance.cpp プロジェクト: LK8000/LK8000
double AATDistance::DistanceCovered_inside(double longitude,
                                           double latitude) {

  int taskwaypoint = ActiveTaskPoint;

  double best_achieved_distance = 0;

  int nthis = num_points[taskwaypoint];
  if (nthis>0) {
    int kbest = 0;
    for (int k=0; k<nthis; k++) {
      double achieved_distance = Dmax[taskwaypoint][k];
      if (achieved_distance>best_achieved_distance) {
        best_achieved_distance = achieved_distance;
        best[taskwaypoint] = k;
        kbest = k;
      }
    }
    if (ValidTaskPoint(taskwaypoint+1)) {
      ShiftTargetFromBehind(longitude, latitude, taskwaypoint);
    }
    return distance_achieved(taskwaypoint, kbest, longitude, latitude);
  } else {
    // not actually in this sector?
    return 0.0;
  }
}
コード例 #15
0
ファイル: MapWindowZoom.cpp プロジェクト: JanezKolar/LK8000
/** 
 * @brief Sets requested zoom scale for AUTO_ZOOM mode
 */
void MapWindow::Zoom::CalculateAutoZoom()
{
  static int autoMapScaleWaypointIndex = -1;
  
  double wpd = DerivedDrawInfo.ZoomDistance; 
  if(wpd > 0) {
    double AutoZoomFactor;
    if( (DisplayOrientation == NORTHTRACK && !mode.Is(Mode::MODE_CIRCLING)) ||
        DisplayOrientation == NORTHUP ||
        DisplayOrientation == NORTHSMART ||
        ((DisplayOrientation == NORTHCIRCLE || DisplayOrientation == TRACKCIRCLE) && mode.Is(Mode::MODE_CIRCLING)) )
      AutoZoomFactor = 2.5;
    else
      AutoZoomFactor = 4;
    
    if(wpd < AutoZoomFactor * _scaleOverDistanceModify) {
      // waypoint is too close, so zoom in
      _modeScale[SCALE_CRUISE] = LimitMapScale(wpd * DISTANCEMODIFY / AutoZoomFactor);
    }
  }
  
  LockTaskData();  // protect from external task changes
#ifdef HAVEEXCEPTIONS
  __try{
#endif
    // if we aren't looking at a waypoint, see if we are now
    if(autoMapScaleWaypointIndex == -1) {
      if(ValidTaskPoint(ActiveWayPoint))
        autoMapScaleWaypointIndex = Task[ActiveWayPoint].Index;
    }
    
    if(ValidTaskPoint(ActiveWayPoint)) {
      // if the current zoom focused waypoint has changed...
      if(autoMapScaleWaypointIndex != Task[ActiveWayPoint].Index) {
        autoMapScaleWaypointIndex = Task[ActiveWayPoint].Index;
        
        // zoom back out to where we were before
        _modeScale[SCALE_CRUISE] = _modeScale[SCALE_AUTO_ZOOM];
      }
    }
#ifdef HAVEEXCEPTIONS
  }__finally
#endif
     {
       UnlockTaskData();
     }
}
コード例 #16
0
 bool CheckCondition(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {    
   if (!AATEnabled || !ValidTaskPoint(ActiveWayPoint) 
       || !(Calculated->ValidStart && !Calculated->ValidFinish)
       || !Calculated->Flying) {
     return false;
   }
   bool OnFinalWaypoint = !ValidTaskPoint(ActiveWayPoint);
   if (OnFinalWaypoint) {
     // can't do much about it now, so don't give a warning
     return false;
   }
   if (Calculated->TaskTimeToGo < Calculated->AATTimeToGo) {
     return true;
   } else {
     return false;
   }
 };
コード例 #17
0
  bool CheckCondition(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {    
    if (!ValidTaskPoint(ActiveWayPoint) || !Calculated->Flying
        || (ActiveWayPoint>0) || !ValidTaskPoint(ActiveWayPoint+1)) {
      return false;
    }
    if (Calculated->LegDistanceToGo>StartRadius) {
      return false;
    }
    if (ValidStartSpeed(Basic, Calculated, StartMaxSpeedMargin) && InsideStartHeight(Basic, Calculated, StartMaxHeightMargin))
    {
      withinMargin = true;
    } else {
      withinMargin = false;
    }
    return !(ValidStartSpeed(Basic, Calculated) 
	     && InsideStartHeight(Basic, Calculated));
  };
コード例 #18
0
ファイル: MapWindowZoom.cpp プロジェクト: Acrobot/LK8000
/** 
 * @brief Sets requested zoom scale for AUTO_ZOOM mode
 */
void MapWindow::Zoom::CalculateAutoZoom()
{
  static int autoMapScaleWaypointIndex = -1;
  static int wait_for_new_wpt_distance = 0;
  double wpd = DerivedDrawInfo.ZoomDistance; 
  
  if (wait_for_new_wpt_distance>0) wait_for_new_wpt_distance--;		//This counter is needed to get new valid waypoint distance after wp changes
  if ( (wpd > 0) && (wait_for_new_wpt_distance==0) ) {
    double AutoZoomFactor;
    if( (DisplayOrientation == NORTHTRACK && !mode.Is(Mode::MODE_CIRCLING)) ||
        DisplayOrientation == NORTHUP ||
        DisplayOrientation == NORTHSMART ||
        ((DisplayOrientation == NORTHCIRCLE || DisplayOrientation == TRACKCIRCLE) && mode.Is(Mode::MODE_CIRCLING)) )
      AutoZoomFactor = 2.5;
    else
      AutoZoomFactor = 4;
    
    if ( ( !ISPARAGLIDER && (wpd < AutoZoomFactor * _scaleOverDistanceModify) ) ||
	 ( ISPARAGLIDER  && (wpd < PGAutoZoomThreshold)) ) {
      // waypoint is too close, so zoom in
      LKASSERT(AutoZoomFactor!=0);
      _modeScale[SCALE_CRUISE] = LimitMapScale(wpd * DISTANCEMODIFY / AutoZoomFactor);
    }
  }
  
  LockTaskData();  // protect from external task changes
    // if we aren't looking at a waypoint, see if we are now
    if(autoMapScaleWaypointIndex == -1) {
      if(ValidTaskPoint(ActiveWayPoint))
        autoMapScaleWaypointIndex = Task[ActiveWayPoint].Index;
    }
    
    if(ValidTaskPoint(ActiveWayPoint)) {
      // if the current zoom focused waypoint has changed...
      if(autoMapScaleWaypointIndex != Task[ActiveWayPoint].Index) {
        autoMapScaleWaypointIndex = Task[ActiveWayPoint].Index;
        wait_for_new_wpt_distance = 3;
        // zoom back out to where we were before
        _modeScale[SCALE_CRUISE] = _modeScale[SCALE_AUTO_ZOOM];
      }
    }
     {
       UnlockTaskData();
     }
}
コード例 #19
0
ファイル: AltitudeRequired.cpp プロジェクト: Mazuk/LK8000
// Current Waypoint calculations for task (no safety?) called only once at beginning
// of DoCalculations, using MACCREADY
void AltitudeRequired(NMEA_INFO *Basic, DERIVED_INFO *Calculated, 
                      const double this_maccready)
{
  //  LockFlightData();
  (void)Basic;
  LockTaskData();
  if(ValidTaskPoint(ActiveWayPoint))
    {
 	int index;
      double wp_alt = FAIFinishHeight(Basic, Calculated, ActiveWayPoint); 
      double height_above_wp = Calculated->NavAltitude + Calculated->EnergyHeight - wp_alt;

      Calculated->NextAltitudeRequired = GlidePolar::MacCreadyAltitude(this_maccready,
                        Calculated->WaypointDistance,
                        Calculated->WaypointBearing, 
                        Calculated->WindSpeed, Calculated->WindBearing, 
                        0, 0, 
			true,
			NULL, height_above_wp, CRUISE_EFFICIENCY
                        );

	if (this_maccready==0 ) Calculated->NextAltitudeRequired0=Calculated->NextAltitudeRequired;
        else
	      Calculated->NextAltitudeRequired0 = GlidePolar::MacCreadyAltitude(0,
				Calculated->WaypointDistance,
				Calculated->WaypointBearing, 
				Calculated->WindSpeed, Calculated->WindBearing, 
				0, 0, 
				true,
				NULL, height_above_wp, CRUISE_EFFICIENCY
				);


      Calculated->NextAltitudeRequired += wp_alt;
      Calculated->NextAltitudeRequired0 += wp_alt; // VENTA6

      Calculated->NextAltitudeDifference = Calculated->NavAltitude + Calculated->EnergyHeight - Calculated->NextAltitudeRequired;
      Calculated->NextAltitudeDifference0 = Calculated->NavAltitude + Calculated->EnergyHeight - Calculated->NextAltitudeRequired0;

	// We set values only for current destination active waypoint.
	index=TASKINDEX;
	WayPointCalc[index].AltArriv[ALTA_MC]=1111.0;
	WayPointCalc[index].AltArriv[ALTA_SMC]=2222.0; // FIX 091012
	WayPointCalc[index].AltArriv[ALTA_MC0]=3333.0;
	WayPointCalc[index].AltArriv[ALTA_AVEFF]=1234.0;

    }
  else
    {
      Calculated->NextAltitudeRequired = 0;
      Calculated->NextAltitudeDifference = 0;
      Calculated->NextAltitudeDifference0 = 0; // VENTA6 
    }
  UnlockTaskData();
  //  UnlockFlightData();
}
コード例 #20
0
ファイル: LoadCupTask.cpp プロジェクト: PhilColbert/LK8000
    void UpdateToNextSector() {
        if (ValidTaskPoint(mIdx + 1)) {
            const WAYPOINT *CurrPt = TaskWayPoint(mIdx);
            const WAYPOINT *NextPt = TaskWayPoint(mIdx + 1);
            // bearing to next
            DistanceBearing(CurrPt->Latitude, CurrPt->Longitude,
                    NextPt->Latitude, NextPt->Longitude, NULL, &mA12);

            UpdateFixedSector();
        }
    }
コード例 #21
0
ファイル: LoadCupTask.cpp プロジェクト: PhilColbert/LK8000
    void UpdateToPrevSector() {
        if (ValidTaskPoint(mIdx - 1)) {
            const WAYPOINT *CurrPt = TaskWayPoint(mIdx);
            const WAYPOINT *PrevPt = TaskWayPoint(mIdx - 1);
            // bearing to prev
            DistanceBearing(CurrPt->Latitude, CurrPt->Longitude,
                    PrevPt->Latitude, PrevPt->Longitude, NULL, &mA12);

            UpdateFixedSector();
        }
    }
コード例 #22
0
ファイル: InTurnSector.cpp プロジェクト: LK8000/LK8000
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;
}
コード例 #23
0
ファイル: devLXMiniMap.cpp プロジェクト: IvanSantanna/LK8000
BOOL DevLXMiniMap::SendPFLX4(DeviceDescriptor_t *d)
{
	/*PFLX4 Sc, Netto, Relativ, gl.dif, leg speed, leg time, integrator, flight time, battery voltage *CS<CR><LF>
	· Sc float (m/s)
	· Netto float (m/s)
	· Relativ float (m/s)
	· Distance float (m)
	· gl.dif int (ft)
	· leg speed (km/h)
	· leg time (km/h)
	· integrator float (m/s)
	· flight time unsigned in seconds
	· battery voltage float (V)*/




			double finalGlide = 0;
		//	double distance = 0;
			if ( ValidTaskPoint(ActiveWayPoint) != false )
			{
				int index = Task[ActiveWayPoint].Index;
				if (index>=0)
				{
						// don't use current MC...
						double value=WayPointCalc[index].AltArriv[AltArrivMode];
						if ( value > -3000 )
						{
							finalGlide =value;

						}
				//		distance = DerivedDrawInfo.WaypointDistance*DISTANCEMODIF;
				}
			}



			TCHAR mcbuf[100];

		    _stprintf(mcbuf, TEXT("PFLX4,,,,%.2f,%d,,,,,"),
		//	 CALCULATED_INFO.NettoVario,
			 CALCULATED_INFO.WaypointDistance,
			 (int)(finalGlide  * M2FT)
		//	 CALCULATED_INFO.LegSpeed
			);
			devWriteNMEAString(d, mcbuf);

	 return(TRUE);

}
コード例 #24
0
void dlgTaskCalculatorShowModal(void){

  TCHAR filename[MAX_PATH];
  LocalPathS(filename, TEXT("dlgTaskCalculator.xml"));
  wf = dlgLoadFromXML(CallBackTable, 
                      filename, 
		      TEXT("IDR_XML_TASKCALCULATOR"));

  if (!wf) return;

  double MACCREADY_enter = MACCREADY;
  double CRUISE_EFFICIENCY_enter = CRUISE_EFFICIENCY;

  emc = EffectiveMacCready(&GPS_INFO, &CALCULATED_INFO);

  cruise_efficiency = CRUISE_EFFICIENCY;

  // find start value for range
  Range = AdjustAATTargets(2.0);

  RefreshCalculator();

  if (!AATEnabled || !ValidTaskPoint(ActiveWayPoint+1)) {
    ((WndButton *)wf->FindByName(TEXT("Optimise")))->SetVisible(false);
  }
  if (!ValidTaskPoint(ActiveWayPoint)) {
    ((WndButton *)wf->FindByName(TEXT("Target")))->SetVisible(false);
  }

  if (wf->ShowModal() == mrCancle) {
    // todo: restore task settings.
    CheckSetMACCREADY(MACCREADY_enter);
    CRUISE_EFFICIENCY = CRUISE_EFFICIENCY_enter;
  }
  delete wf;
  wf = NULL;
}
コード例 #25
0
  bool CheckCondition(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {    
    if (!Calculated->Flying || !ValidTaskPoint(ActiveWayPoint)) {
      return false;
    }

    fgtt = !((Calculated->TerrainWarningLatitude == 0.0) &&
	     (Calculated->TerrainWarningLongitude == 0.0));

    if (!Calculated->FinalGlide || (Calculated->TaskAltitudeDifference<-50)) {
      fgtt_last = false;
    } else if ((fgtt) && (!fgtt_last)) {
      // just reached final glide, previously well below
      return true;
    }
    return false;
  };
コード例 #26
0
ファイル: DrawBestCruiseTrack.cpp プロジェクト: LK8000/LK8000
void MapWindow::DrawBestCruiseTrack(LKSurface& Surface, const POINT& Orig)
{
  if (OvertargetMode>OVT_TASK) return;

  if (!ValidTaskPoint(ActiveTaskPoint)) return;

  if (DerivedDrawInfo.WaypointDistance < 0.010) return;

  // dont draw bestcruise indicator if not needed
  if (fabs(DerivedDrawInfo.BestCruiseTrack-DerivedDrawInfo.WaypointBearing)<2) { // 091202 10 to 2
	return;
  } 


  const auto hpOld = Surface.SelectObject(LKPen_Blue_N1);
  const auto hbOld = Surface.SelectObject(LKBrush_Blue);

  if (Appearance.BestCruiseTrack == ctBestCruiseTrackDefault){

    int dy = (long)(70); 
    POINT Arrow[7] = { {-1,-40}, {1,-40}, {1,0}, {6,8}, {-6,8}, {-1,0}, {-1,-40}};

    Arrow[2].y -= dy;
    Arrow[3].y -= dy;
    Arrow[4].y -= dy;
    Arrow[5].y -= dy;

    PolygonRotateShift(Arrow, 7, Orig.x, Orig.y, 
                       DerivedDrawInfo.BestCruiseTrack-DisplayAngle);

    Surface.Polygon(Arrow,7);

  } else
  if (Appearance.BestCruiseTrack == ctBestCruiseTrackAltA){

    POINT Arrow[] = { {-1,-40}, {-1,-62}, {-6,-62}, {0,-70}, {6,-62}, {1,-62}, {1,-40}, {-1,-40}};

    PolygonRotateShift(Arrow, sizeof(Arrow)/sizeof(Arrow[0]),
                       Orig.x, Orig.y, 
                       DerivedDrawInfo.BestCruiseTrack-DisplayAngle);
    Surface.Polygon(Arrow, (sizeof(Arrow)/sizeof(Arrow[0])));
  }

  Surface.SelectObject(hpOld);
  Surface.SelectObject(hbOld);
}
コード例 #27
0
void dlgAddMultiSelectListDetailsDialog(int Index) {
    int iLastTaskPoint = 0;
    while (ValidTaskPoint(iLastTaskPoint))
        iLastTaskPoint++;
    iLastTaskPoint--;
    if ((Index >= 0) && (Index < iNO_ELEMENTS)) {
        switch (Elements[Index].type) {
        case IM_AIRSPACE:
            wf->SetTimerNotify(0,NULL);
            LKASSERT(Elements[Index].ptr);
            CAirspaceManager::Instance().PopupAirspaceDetail(static_cast<CAirspace*>(Elements[Index].ptr));
            break;

        case IM_WAYPOINT:
            wf->SetTimerNotify(0,NULL);
            LKASSERT(Elements[Index].iIdx < (int)WayPointList.size());
            SelectedWaypoint = Elements[Index].iIdx;
            wf->SetTimerNotify(0,NULL);
            PopupWaypointDetails();
            break;

        case IM_TASK_PT:
            wf->SetTimerNotify(0,NULL);
            LKASSERT(Elements[Index].iIdx <= MAXTASKPOINTS);
            LKASSERT(iLastTaskPoint>=0);
            RealActiveWaypoint = -1;
            if (Elements[Index].iIdx == 0)
                dlgTaskWaypointShowModal(Elements[Index].iIdx, 0, false, true);
            else {
                if (Elements[Index].iIdx == iLastTaskPoint)
                    dlgTaskWaypointShowModal(Elements[Index].iIdx, 2, false, true);
                else {
                    if ((AATEnabled) && (CALCULATED_INFO.Flying) && (!IsMultiMapNoMain())) {
                        wf->SetModalResult(mrOK);
                        wf->SetVisible(false);
                        dlgTarget(Elements[Index].iIdx);
                    } else {
                        dlgTaskWaypointShowModal(Elements[Index].iIdx, 1, false, true);
                    }
                }
            }
            break;
        } // switch
    } // if Index..
}
コード例 #28
0
ファイル: AATDistance.cpp プロジェクト: LK8000/LK8000
double AATDistance::DistanceCovered_internal(double longitude,
                                             double latitude,
                                             bool insector) {
  double achieved;
  if (!ValidTaskPoint(ActiveTaskPoint) || (ActiveTaskPoint==0)) {
    //   max_achieved_distance = 0;
    return 0.0;
  }
  LockTaskData();
  if (insector) {
    achieved = DistanceCovered_inside(longitude, latitude);
  } else {
    achieved = DistanceCovered_outside(longitude, latitude);
  }

  UnlockTaskData();
  //  max_achieved_distance = max(achieved, max_achieved_distance);
  return achieved;
}
コード例 #29
0
ファイル: Statistics.cpp プロジェクト: JanezKolar/LK8000
void Statistics::RenderBarograph(HDC hdc, RECT rc)
{

  ResetScale();
  ScaleXFromData(rc, &flightstats.Altitude);
  ScaleYFromData(rc, &flightstats.Altitude);
  ScaleXFromData(rc, &flightstats.Altitude_Base);
  ScaleYFromData(rc, &flightstats.Altitude_Base);
  ScaleXFromData(rc, &flightstats.Altitude_Ceiling);
  ScaleYFromData(rc, &flightstats.Altitude_Ceiling);

  DrawXGrid(hdc, rc, 
            0.25, flightstats.Altitude.x_min,
            STYLE_THINDASHPAPER);

  DrawYGrid(hdc, rc, 1000/ALTITUDEMODIFY, 0, STYLE_THINDASHPAPER);

  DrawLineGraph(hdc, rc, &flightstats.Altitude,
                STYLE_MEDIUMBLACK);

  LockTaskData();
  for(int j=0;j<MAXTASKPOINTS;j++) {
    if (ValidTaskPoint(j) && (LegStartTime[j]>=0)) {
      double xx = (LegStartTime[j]-Calculated->TakeOffTime)/3600;
      if (xx>=0) {
        DrawLine(hdc, rc,
                 xx, flightstats.Altitude.y_min,
                 xx, flightstats.Altitude.y_max,
                 STYLE_THINDASHPAPER);
      }
    }
  }
  UnlockTaskData();

  DrawTrend(hdc, rc, &flightstats.Altitude_Base, STYLE_BLUETHIN);

  DrawTrend(hdc, rc, &flightstats.Altitude_Ceiling, STYLE_BLUETHIN);

  DrawXLabel(hdc, rc, TEXT("t"));
  DrawYLabel(hdc, rc, TEXT("h"));

}
コード例 #30
0
ファイル: PGTaskMgr.cpp プロジェクト: LK8000/LK8000
void PGTaskMgr::AddEssCircle(int TskIdx) {
    PGCicrcleTaskPt *pTskPt = new PGEssCicrcleTaskPt;

    LatLon2Grid(deg2rad(WayPointList[Task[TskIdx].Index].Latitude),
            deg2rad(WayPointList[Task[TskIdx].Index].Longitude),
            pTskPt->m_Center.m_Y,
            pTskPt->m_Center.m_X);

    if (TskIdx == 0) {
        pTskPt->m_Radius = StartRadius;
    } else if (ValidTaskPoint(TskIdx + 1)) {
        pTskPt->m_Radius = (Task[TskIdx].AATCircleRadius);
    } else {
        pTskPt->m_Radius = FinishRadius;
    }

    pTskPt->m_bExit = ((TskIdx > 0) ? (Task[TskIdx].OutCircle) : !PGStartOut);

    m_Task.push_back(pTskPt);
}