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(); } }
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; };
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(); } } }
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; }
// 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); }
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(); } } }
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; }
// // 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); }
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; } } }
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; }
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_"))); } }
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_"))); } }
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; }
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; } }
/** * @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(); } }
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; } };
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)); };
/** * @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(); } }
// 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(); }
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(); } }
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(); } }
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; }
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); }
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; }
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; };
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); }
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.. }
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; }
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")); }
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); }