static void OnMoveBeforeClicked(WindowControl * Sender){ (void)Sender; LockTaskData(); SwapWaypoint(twItemIndex-1); SetWaypointValues(); UnlockTaskData(); wf->SetModalResult(mrOK); }
static void OverviewRefreshTask(void) { LockTaskData(); RefreshTask(); int i; // Only need to refresh info where the removal happened // as the order of other taskpoints hasn't changed UpLimit = 0; lengthtotal = 0; for (i=0; i<MAXTASKPOINTS; i++) { if (Task[i].Index != -1) { lengthtotal += Task[i].Leg; UpLimit = i+1; } } // Simple FAI 2004 triangle rules fai_ok = true; if (lengthtotal>0) { for (i=0; i<MAXTASKPOINTS; i++) { if (Task[i].Index != -1) { double lrat = Task[i].Leg/lengthtotal; if ((lrat>0.45)||(lrat<0.10)) { fai_ok = false; } } } } else { fai_ok = false; } RefreshTaskStatistics(); WndProperty* wp; wp = (WndProperty*)wf->FindByName(TEXT("prpAATEst")); if (wp) { double dd = CALCULATED_INFO.TaskTimeToGo; // if ((CALCULATED_INFO.TaskStartTime>0.0)&&(CALCULATED_INFO.Flying)) { patchout 091126 if ( (CALCULATED_INFO.TaskStartTime>0.0)&&(CALCULATED_INFO.Flying) &&(ActiveTaskPoint>0)) { // patch 091126 dd += GPS_INFO.Time-CALCULATED_INFO.TaskStartTime; } dd= min(24.0*60.0,dd/60.0); wp->GetDataField()->SetAsFloat(dd); wp->RefreshDisplay(); } LowLimit =0; wTaskList->ResetList(); wTaskList->Redraw(); UpdateCaption(); UnlockTaskData(); }
bool MapWindow::WaypointInTask(int ind) { bool retval = false; LockTaskData(); if ((ind<0)||(ind>=(int)WayPointList.size())) { retval = WayPointList[ind].InTask; } UnlockTaskData(); return retval; }
void SaveDefaultTask(void) { LockTaskData(); TCHAR buffer[MAX_PATH]; LocalPath(buffer,TEXT(LKD_TASKS)); _tcscat(buffer,TEXT("\\")); _tcscat(buffer,_T(LKF_DEFAULTASK)); // 091101 SaveTask(buffer); UnlockTaskData(); }
// A waypoint is valid here only if a list exists, it is within range and it is not reserved bool ValidNotResWayPoint(int i) { // 091213 bool retval = true; LockTaskData(); if ((i<=RESWP_END)||(i>=(int)WayPointList.size())) { retval = false; } UnlockTaskData(); return retval; }
bool ValidStartPoint(size_t i) { bool retVal=false; LockTaskData(); if(i<MAXSTARTPOINTS) { retVal = ValidWayPointFast(StartPoints[i].Index); } UnlockTaskData(); return retVal; }
static void DoOptimise(void) { double myrange= Range; double RangeLast= Range; double deltaTlast = 0; int steps = 0; if (!AATEnabled) return; LockFlightData(); LockTaskData(); TargetDialogOpen = true; do { myrange = Range; AdjustAATTargets(Range); RefreshTask(); RefreshTaskStatistics(); double deltaT = CALCULATED_INFO.TaskTimeToGo; if ((CALCULATED_INFO.TaskStartTime>0.0)&&(CALCULATED_INFO.Flying)) { deltaT += GPS_INFO.Time-CALCULATED_INFO.TaskStartTime; } deltaT= min(24.0*60.0,deltaT/60.0)-AATTaskLength-5; double dRdT = 0.001; if (steps>0) { if (fabs(deltaT-deltaTlast)>0.01) { dRdT = min(0.5,(Range-RangeLast)/(deltaT-deltaTlast)); if (dRdT<=0.0) { // error, time decreases with increasing range! // or, no effect on time possible break; } } else { // minimal change for whatever reason // or, no effect on time possible, e.g. targets locked break; } } RangeLast = Range; deltaTlast = deltaT; if (fabs(deltaT)>0.25) { // more than 15 seconds error Range -= dRdT*deltaT; Range = max(-1.0, min(Range,1.0)); } else { break; } } while (steps++<25); Range = myrange; AdjustAATTargets(Range); RefreshCalculator(); TargetDialogOpen = false; UnlockTaskData(); UnlockFlightData(); }
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; }
// 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(); }
static void OnSetAlt2Clicked(WndButton* pWnd){ LockTaskData(); Alternate2 = SelectedWaypoint; RefreshTask(); UnlockTaskData(); if (ValidWayPoint(Alternate2)) DoStatusMessage(_T("Altern.2="),WayPointList[Alternate2].Name); retStatus=4; wf->SetModalResult(mrOK); }
double AATDistance::DistanceCovered(double longitude, double latitude, int taskwaypoint) { (void)taskwaypoint; // unused double retval; LockTaskData(); retval= DistanceCovered_internal(longitude, latitude, false); UnlockTaskData(); return retval; }
// 100929 A waypoint is valid here only if it is virtual, and with a valid content bool ValidResWayPoint(int i) { // 091213 bool retval = true; LockTaskData(); if ( (i<0) || (i>RESWP_END) ) retval = false; else { if (WayPointList[i].Latitude == RESWP_INVALIDNUMBER) retval=false; } UnlockTaskData(); return retval; }
static void GetWaypointValues(void) { WndProperty* wp; bool changed = false; if (!AATEnabled) { return; } if ((twItemIndex<MAXTASKPOINTS)&&(twItemIndex>=0)) { LockTaskData(); wp = (WndProperty*)wf->FindByName(TEXT("prpAATType")); if (wp) { CHECK_CHANGED(Task[twItemIndex].AATType, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATCircleRadius")); if (wp) { CHECK_CHANGED(Task[twItemIndex].AATCircleRadius, iround(wp->GetDataField()->GetAsFloat()/DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATSectorRadius")); if (wp) { CHECK_CHANGED(Task[twItemIndex].AATSectorRadius, iround(wp->GetDataField()->GetAsFloat()/DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATStartRadial")); if (wp) { CHECK_CHANGED(Task[twItemIndex].AATStartRadial, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATFinishRadial")); if (wp) { CHECK_CHANGED(Task[twItemIndex].AATFinishRadial, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpOutCircle")); if (wp) { CHECK_CHANGED(Task[twItemIndex].OutCircle, wp->GetDataField()->GetAsInteger()); } if (changed) { TaskModified = true; } UnlockTaskData(); } }
bool MapWindow::TargetMoved(double &longitude, double &latitude) { bool retval = false; LockTaskData(); if (targetMoved) { longitude = targetMovedLon; latitude = targetMovedLat; targetMoved = false; retval = true; } UnlockTaskData(); return retval; }
static void OnReplaceClicked(WindowControl * Sender){ (void)Sender; LockTaskData(); ReplaceWaypoint(SelectedWaypoint); RealActiveWaypoint = SelectedWaypoint; RefreshTask(); UnlockTaskData(); MapWindow::RefreshMap(); wf->SetModalResult(mrOK); }
static void OnMoveBeforeClicked(WndButton* pWnd){ LockTaskData(); SwapWaypoint(twItemIndex-1); SetWaypointValues(); UnlockTaskData(); if(pWnd) { WndForm * pForm = pWnd->GetParentWndForm(); if(pForm) { pForm->SetModalResult(mrOK); } } }
static void OnClearClicked(WndButton* pWnd) { LockTaskData(); for (int i=0; i<MAXSTARTPOINTS; i++) { StartPoints[i].Index = -1; StartPoints[i].Active = false; } StartPoints[0].Index = Task[0].Index; StartPoints[0].Active = true; changed = true; UnlockTaskData(); UpdateList(); }
// // 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 AATDistance::ThinData(int taskwaypoint) { double contractfactor = 0.8; static bool do_delete[MAXNUM_AATDISTANCE]; LockTaskData(); int i; for (i=0; i<MAXNUM_AATDISTANCE; i++) { do_delete[i]= false; } while (num_points[taskwaypoint]> MAXNUM_AATDISTANCE*contractfactor) { distancethreshold[taskwaypoint] /= contractfactor; for (i= num_points[taskwaypoint]-1; i>0; i--) { double d; DistanceBearing(lat_points[taskwaypoint][i], lon_points[taskwaypoint][i], lat_points[taskwaypoint][i-1], lon_points[taskwaypoint][i-1], &d, NULL); if ((d<distancethreshold[taskwaypoint]) && (best[taskwaypoint]!=i)) { do_delete[i] = true; // mark it for deletion } } // now shuffle points along int j; i = 0; j = i; int pnts_in_new=0; while (j< num_points[taskwaypoint]) { if (!do_delete[j]) { lat_points[taskwaypoint][i] = lat_points[taskwaypoint][j]; lon_points[taskwaypoint][i] = lon_points[taskwaypoint][j]; i++; pnts_in_new = i; } j++; } if (pnts_in_new) { num_points[taskwaypoint] = pnts_in_new; } } if (num_points[taskwaypoint]>=MAXNUM_AATDISTANCE) { // error! num_points[taskwaypoint]=MAXNUM_AATDISTANCE-1; } UnlockTaskData(); }
static void OnRemoveClicked(WindowControl * Sender) { (void)Sender; LockTaskData(); RemoveTaskPoint(twItemIndex); SetWaypointValues(); if (ActiveWayPoint>=twItemIndex) { ActiveWayPoint--; } if (ActiveWayPoint<0) { ActiveWayPoint= -1; } UnlockTaskData(); wf->SetModalResult(mrOK); }
static void OnPaintWaypointPicto(WindowControl * Sender, LKSurface& Surface) { if (Sender) { const RECT rc = Sender->GetClientRect(); MapWindow::DrawWaypointPictoBg(Surface, rc); LockTaskData(); LKASSERT(ValidWayPointFast(SelectedWaypoint)); if (WayPointCalc[SelectedWaypoint].IsLandable) { MapWindow::DrawRunway(Surface, &WayPointList[SelectedWaypoint], rc, 4000, true); } else { MapWindow::DrawWaypointPicto(Surface, rc, &WayPointList[SelectedWaypoint]); } UnlockTaskData(); } }
void FlyDirectTo(int index) { if (!CheckDeclaration()) return; LockTaskData(); AATEnabled = FALSE; InsertRecentList(index); ClearTask(); Task[0].Index = index; ActiveWayPoint = 0; RefreshTask(); UnlockTaskData(); }
void ClearTask(void) { LockTaskData(); TaskModified = true; TargetModified = true; LastTaskFileName[0] = _T('\0'); ActiveWayPoint = -1; EnableMultipleStartPoints = false; std::for_each(begin(Task), end(Task), ResetTaskWpt); std::for_each(begin(TaskStats), end(TaskStats), ResetTaskStat); std::for_each(begin(StartPoints), end(StartPoints), ResetStartPoint); UnlockTaskData(); }
/** * @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(); } }
void ClearTask(void) { LockTaskData(); TaskModified = true; TargetModified = true; if (ISPARAGLIDER) PGOptimizeRoute = PGOptimizeRoute_Config; LastTaskFileName[0] = _T('\0'); ActiveWayPoint = -1; EnableMultipleStartPoints = false; std::for_each(std::begin(Task), std::end(Task), ResetTaskWpt); std::for_each(std::begin(TaskStats), std::end(TaskStats), ResetTaskStat); std::for_each(std::begin(StartPoints), std::end(StartPoints), ResetStartPoint); UnlockTaskData(); }
// Are we on the correct side of start cylinder? bool CorrectSide() { // Remember that IsInSector works reversed... #if DEBUGTGATES StartupStore(_T("CorrectSide: PGstartout=%d InSector=%d\n"),PGStartOut,CALCULATED_INFO.IsInSector); #endif LockTaskData(); bool ExitWpt = ((ActiveTaskPoint > 0) ? (Task[ActiveTaskPoint].OutCircle) : !PGStartOut); UnlockTaskData(); if (!ExitWpt && CALCULATED_INFO.IsInSector) return false; if (ExitWpt && !CALCULATED_INFO.IsInSector) return false; return true; }
/** * @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(); } }
static void OnRemoveClicked(WndButton* pWnd) { LockTaskData(); RemoveTaskPoint(twItemIndex); SetWaypointValues(); if (ActiveTaskPoint>=twItemIndex) { ActiveTaskPoint--; } if (ActiveTaskPoint<0) { ActiveTaskPoint= -1; } UnlockTaskData(); if(pWnd) { WndForm * pForm = pWnd->GetParentWndForm(); if(pForm) { pForm->SetModalResult(mrOK); } } }
static void OnSelectClicked(WindowControl * Sender){ (void)Sender; int res; res = dlgWayPointSelect(); if (res != -1){ SelectedWaypoint = res; if (Task[twItemIndex].Index != res) { if (CheckDeclaration()) { LockTaskData(); ResetTaskWaypoint(twItemIndex); Task[twItemIndex].Index = res; TaskModified = true; UnlockTaskData(); } } UpdateCaption(); }; }
void dlgStartPointShowModal(void) { ItemIndex = -1; wf = dlgLoadFromXML(CallBackTable, ScreenLandscape ? TEXT("dlgStartPoint_L.xml") : TEXT("dlgStartPoint_P.xml"), ScreenLandscape ? IDR_XML_STARTPOINT_L : IDR_XML_STARTPOINT_P); if (!wf) return; //ASSERT(wf!=NULL); CheckStartPointInTask(); wStartPointList = (WndListFrame*)wf->FindByName(TEXT("frmStartPointList")); //ASSERT(wStartPointList!=NULL); wStartPointList->SetBorderKind(BORDERLEFT); wStartPointList->SetEnterCallback(OnStartPointListEnter); wStartPointListEntry = (WndOwnerDrawFrame*)wf->FindByName(TEXT("frmStartPointListEntry")); //ASSERT(wStartPointListEntry!=NULL); wStartPointListEntry->SetCanFocus(true); UpdateList(); changed = false; wf->ShowModal(); // now retrieve back the properties... if (changed) { LockTaskData(); TaskModified = true; RefreshTask(); UnlockTaskData(); }; delete wf; wf = NULL; }