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(); }
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()); } if (changed) { TaskModified = true; } UnlockTaskData(); } }
/** * @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; }
static void OnSelectClicked(WndButton* pWnd){ int res; res = dlgWayPointSelect(); if (res != -1){ SelectedWaypoint = res; LKASSERT(twItemIndex>=0); if (Task[twItemIndex].Index != res) { if (CheckDeclaration()) { LockTaskData(); ResetTaskWaypoint(twItemIndex); Task[twItemIndex].Index = res; Task[twItemIndex].PGConeBase = WayPointList[res].Altitude; TaskModified = true; UnlockTaskData(); } } UpdateCaption(); }; }
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")); }
/* * Currently even if set for FIVV, colors are not used. */ TCHAR *FormatterAlternate::Render(int *color) { //int active=ActiveAlternate; REMOVE LockTaskData(); if(Valid && ValidWayPoint(ActiveAlternate)) { switch (WayPointCalc[ActiveAlternate].VGR ) { case 0: // impossible, give a magenta debug color; *color = 5; break; case 1: #ifdef FIVV *color = 0; // green #else *color = 0; // blue #endif break; case 2: #ifdef FIVV *color = 0; // yellow 4 #else *color = 0; // normale white #endif break; case 3: *color = 1; // red break; default: // even more impossible, give debug color magenta *color = 5; break; } // Value=WayPointCalc[ActiveAlternate].GR; BUGFIX 090918 _stprintf(Text,Format,Value); } else { Valid = false; RenderInvalid(color); } UnlockTaskData(); return(Text); }
void FlyDirectTo(int index) { if (!CheckDeclaration()) return; LockTaskData(); TaskModified = true; TargetModified = true; ActiveWayPoint = -1; AATEnabled = FALSE; InsertRecentList(index); Task[0].Index = index; for (int i=1; i<=MAXTASKPOINTS; i++) { Task[i].Index = -1; } ActiveWayPoint = 0; RefreshTask(); UnlockTaskData(); }
static void OnStartPointListEnter(WindowControl * Sender, WndListFrame::ListInfo_t *ListInfo) { (void)Sender; ItemIndex = ListInfo->ItemIndex + ListInfo->ScrollIndex; if (ItemIndex>=MAXSTARTPOINTS) { ItemIndex = -1; while(ValidStartPoint(ItemIndex++)) { } } if (ItemIndex>=0) { int res; res = dlgWayPointSelect(); if (res>=0) { // TODO bug: don't add it if it's already present! LockTaskData(); StartPoints[ItemIndex].Index = res; StartPoints[ItemIndex].Active = true; UnlockTaskData(); changed = true; UpdateList(); } } }
// 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 if (ActiveWayPoint==0 && PGStartOut && CALCULATED_INFO.IsInSector) return false; if (ActiveWayPoint==0 && !PGStartOut && !CALCULATED_INFO.IsInSector) return false; LockTaskData(); bool ExitWpt = Task[ActiveWayPoint].OutCircle; UnlockTaskData(); if (ExitWpt==0 && PGStartOut && CALCULATED_INFO.IsInSector) return false; if (ExitWpt==0 && !PGStartOut && !CALCULATED_INFO.IsInSector) return false; return true; }
static void OnSelectClicked(WindowControl * Sender){ (void)Sender; int res; res = dlgWayPointSelect(); if (res != -1){ SelectedWaypoint = res; if (Task[twItemIndex].Index != res) { if (CheckDeclaration()) { LockTaskData(); Task[twItemIndex].Index = res; Task[twItemIndex].AATTargetOffsetRadius = 0.0; Task[twItemIndex].AATTargetOffsetRadial = 0.0; Task[twItemIndex].AATSectorRadius = SectorRadius; Task[twItemIndex].AATCircleRadius = SectorRadius; Task[twItemIndex].AATTargetLocked = false; TaskModified = true; UnlockTaskData(); } } UpdateCaption(); }; }
static void OnSelectClicked(WindowControl * Sender) { (void)Sender; if (s_selected<0 || s_selected>=MAXTHISTORY) { StartupStore(_T("... Invalid thermal selected to multitarget, out of range:%d %s"),s_selected,NEWLINE); DoStatusMessage(_T("ERR-126 invalid thermal")); return; } if (!ThermalHistory[s_selected].Valid) { DoStatusMessage(gettext(TEXT("ERR-127 invalid thermal selection"))); return; } #if TESTBENCH StartupStore(_T("... Selected thermal n.%d <%s>\n"),s_selected,ThermalHistory[s_selected].Name); #endif SetThermalMultitarget(s_selected); // update selected multitarget LockTaskData(); // now select the new one WayPointList[RESWP_LASTTHERMAL].Latitude = ThermalHistory[s_selected].Latitude; WayPointList[RESWP_LASTTHERMAL].Longitude = ThermalHistory[s_selected].Longitude; WayPointList[RESWP_LASTTHERMAL].Altitude = ThermalHistory[s_selected].HBase; wcscpy(WayPointList[RESWP_LASTTHERMAL].Name, ThermalHistory[s_selected].Name); UnlockTaskData(); // switch to L> multitarget, and force moving map mode OvertargetMode=OVT_THER; SetModeType(LKMODE_MAP,MP_MOVING); wf->SetModalResult(mrOK); }
void CalculateOptimizedTargetPos(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { if (!DoOptimizeRoute()) return; LockTaskData(); gPGTask.Optimize(Basic, Calculated); for(size_t i=0; i<gPGTask.Count(); ++i) { gPGTask.UpdateTaskPoint(i, Task[i]); } int stdwp=Task[ActiveTaskPoint].Index; WayPointList[RESWP_OPTIMIZED].Latitude = Task[ActiveTaskPoint].AATTargetLat; WayPointList[RESWP_OPTIMIZED].Longitude = Task[ActiveTaskPoint].AATTargetLon; WayPointList[RESWP_OPTIMIZED].Altitude = Task[ActiveTaskPoint].AATTargetAltitude; _stprintf(WayPointList[RESWP_OPTIMIZED].Name, _T("!%s"),WayPointList[stdwp].Name); UnlockTaskData(); }
TCHAR *FormatterWaypoint::Render(int *color) { int thewaypoint = ActiveWayPoint; LockTaskData(); if(ValidTaskPoint(thewaypoint)) { int index = Task[thewaypoint].Index; if ((index>=0) && (WayPointList[index].Reachable)) { *color = 2; // blue text } else { *color = 0; // black text } if ( DisplayTextType == DISPLAYFIRSTTHREE) { _tcsncpy(Text,WayPointList[index].Name,3); Text[3] = '\0'; } else if( DisplayTextType == DISPLAYNUMBER) { _stprintf(Text,TEXT("%d"), WayPointList[index].Number ); } else { _tcsncpy(Text,WayPointList[index].Name, (sizeof(Text)/sizeof(TCHAR))-1); Text[(sizeof(Text)/sizeof(TCHAR))-1] = '\0'; } } else { Valid = false; RenderInvalid(color); } UnlockTaskData(); return(Text); }
// Clear PG void ClearOptimizedTargetPos() { if (!DoOptimizeRoute()) return; LockTaskData(); WayPointList[RESWP_OPTIMIZED].Latitude=RESWP_INVALIDNUMBER; WayPointList[RESWP_OPTIMIZED].Longitude=RESWP_INVALIDNUMBER; WayPointList[RESWP_OPTIMIZED].Altitude=RESWP_INVALIDNUMBER; // name will be assigned by function dynamically _tcscpy(WayPointList[RESWP_OPTIMIZED].Name, _T("OPTIMIZED") ); for(int i = 0; ValidWayPoint(Task[i].Index); ++i) { Task[i].AATTargetLat = WayPointList[Task[i].Index].Latitude; Task[i].AATTargetLon = WayPointList[Task[i].Index].Longitude; Task[i].AATTargetAltitude = WayPointList[Task[i].Index].Altitude; Task[i].AATTargetLocked = false; } gPGTask.Initialize(); UnlockTaskData(); }
/** * @brief Returns task file name * * Function obtains task file path and strips the directory part and file * extension from it. * * @param bufferLen The length of the buffer * @param buffer Buffer for the task file name * * @return Buffer with filled data */ const TCHAR *TaskFileName(unsigned bufferLen, TCHAR buffer[]) { TCHAR name[MAX_PATH] = { _T('\0') }; #if BUGSTOP LKASSERT(buffer!=NULL); #endif if (buffer==NULL) return NULL; LockTaskData(); int len = _tcslen(LastTaskFileName); if(len > 0) { int index = 0; TCHAR *src = LastTaskFileName; while ((*src != _T('\0')) && (*src != _T('.'))) { if ((*src == _T('\\')) || (*src == _T('/'))) { index = 0; } else { name[index] = *src; index++; } src++; } name[index] = _T('\0'); } UnlockTaskData(); _tcsncpy(buffer, name, bufferLen); #if BUGSTOP LKASSERT(bufferLen>0); #endif if (bufferLen>0) buffer[bufferLen - 1] = _T('\0'); return buffer; }
void dlgStartPointShowModal(void) { ItemIndex = -1; if (!ScreenLandscape) { TCHAR filename[MAX_PATH]; LocalPathS(filename, TEXT("dlgStartPoint_L.xml")); wf = dlgLoadFromXML(CallBackTable, filename, TEXT("IDR_XML_STARTPOINT_L")); } else { TCHAR filename[MAX_PATH]; LocalPathS(filename, TEXT("dlgStartPoint.xml")); wf = dlgLoadFromXML(CallBackTable, filename, TEXT("IDR_XML_STARTPOINT")); } if (!wf) return; //ASSERT(wf!=NULL); CheckStartPointInTask(); wStartPointList = (WndListFrame*)wf->FindByName(TEXT("frmStartPointList")); //ASSERT(wStartPointList!=NULL); wStartPointList->SetBorderKind(BORDERLEFT); wStartPointList->SetEnterCallback(OnStartPointListEnter); wStartPointList->SetWidth(wf->GetWidth() - wStartPointList->GetLeft()-2); wStartPointListEntry = (WndOwnerDrawFrame*)wf->FindByName(TEXT("frmStartPointListEntry")); if ( wStartPointList->ScrollbarWidth == -1) { #if defined (PNA) #define SHRINKSBFACTOR 1.0 // shrink width factor. Range .1 to 1 where 1 is very "fat" #else #define SHRINKSBFACTOR 0.75 // shrink width factor. Range .1 to 1 where 1 is very "fat" #endif wStartPointList->ScrollbarWidth = (int) (SCROLLBARWIDTH_INITIAL * ScreenDScale * SHRINKSBFACTOR); } wStartPointListEntry->SetWidth(wStartPointList->GetWidth() - wStartPointList->ScrollbarWidth - 5); //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; }
static void ReadValues(void) { WndProperty* wp; bool changed = false; LockTaskData(); wp = (WndProperty*)wf->FindByName(TEXT("prpEnableMultipleStartPoints")); if (wp) { CHECK_CHANGED(EnableMultipleStartPoints, wp->GetDataField()->GetAsBoolean()); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATEnabled")); if (wp) { CHECK_CHANGED(AATEnabled, wp->GetDataField()->GetAsInteger()); if (DoOptimizeRoute()) AATEnabled=true; // force it on } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskFinishLine")); if (wp) { CHECK_CHANGED(FinishLine, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskFinishRadius")); if (wp) { CHECK_CHANGED(FinishRadius, (DWORD)iround(wp->GetDataField()->GetAsFloat() /DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskStartLine")); if (wp) { CHECK_CHANGED(StartLine, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskStartRadius")); if (wp) { CHECK_CHANGED(StartRadius, (DWORD)iround(wp->GetDataField()->GetAsFloat() /DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskFAISector")); if (wp) { CHECK_CHANGED(SectorType, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskSectorRadius")); if (wp) { CHECK_CHANGED(SectorRadius, (DWORD)iround(wp->GetDataField()->GetAsFloat() /DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpAutoAdvance")); if (wp) { CHECK_CHANGED(AutoAdvance, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpMinTime")); if (wp) { CHECK_CHANGED(AATTaskLength, wp->GetDataField()->GetAsInteger()); if (changed) CALCULATED_INFO.AATTimeToGo=AATTaskLength*60; } if (changed) { TaskModified = true; } UnlockTaskData(); }
static void OnTaskPaintListItem(WindowControl * Sender, LKSurface& Surface){ int n = UpLimit - LowLimit; TCHAR sTmp[120]; TCHAR wpName[120]; TCHAR landableStr[5] = TEXT(" [X]"); // LKTOKEN _@M1238_ "L" landableStr[2] = MsgToken(1238)[0]; LockTaskData(); const PixelRect rcClient(Sender->GetClientRect()); const int w0 = rcClient.GetSize().cx - DLGSCALE(1); const int w1 = Surface.GetTextWidth(TEXT(" 000km")); _stprintf(sTmp, _T(" 000%s"), MsgToken(2179)); const int w2 = Surface.GetTextWidth(sTmp); const int TextMargin = (rcClient.GetSize().cy - Surface.GetTextHeight(TEXT("A"))) / 2; const int p1 = w0-w1-w2- rcClient.GetSize().cy - DLGSCALE(2); const int p2 = w0-w2- rcClient.GetSize().cy - DLGSCALE(2); const PixelRect rc = { 0, 0, rcClient.GetSize().cy, rcClient.GetSize().cy }; if (DrawListIndex < n){ int i = LowLimit + DrawListIndex; // if ((WayPointList[Task[i].Index].Flags & LANDPOINT) >0) // MapWindow::DrawRunway(hDC, &WayPointList[Task[i].Index], rc, 3000,true); MapWindow::DrawTaskPicto(Surface, DrawListIndex, rc, 2500); if (Task[i].Index>=0) { _stprintf(wpName, TEXT("%s%s"), WayPointList[Task[i].Index].Name, (WayPointList[Task[i].Index].Flags & LANDPOINT) ? landableStr : TEXT("")); if (AATEnabled && ValidTaskPoint(i+1) && (i>0)) { if (Task[i].AATType==0 || Task[i].AATType==3) { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATCircleRadius*DISTANCEMODIFY); } else { if(Task[i].AATType==2 && DoOptimizeRoute()) { _stprintf(sTmp, TEXT("%s %.1f/1"), wpName, Task[i].PGConeSlope); } else { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATSectorRadius*DISTANCEMODIFY); } } } else { _stprintf(sTmp, TEXT("%s"), wpName); } Surface.SetBackgroundTransparent(); Surface.SetTextColor(RGB_BLACK); Surface.DrawTextClip(rc.right + DLGSCALE(2), TextMargin, sTmp, p1-DLGSCALE(4)); _stprintf(sTmp, TEXT("%.0f %s"),Task[i].Leg*DISTANCEMODIFY,Units::GetDistanceName()); Surface.DrawText(rc.right+p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp); _stprintf(sTmp, TEXT("%d%s"), iround(Task[i].InBound),MsgToken(2179)); Surface.DrawText(rc.right +p2+w2-Surface.GetTextWidth(sTmp), TextMargin, sTmp); } } else { Surface.SetTextColor(RGB_BLACK); // if (DrawListIndex==n) { // patchout 091126 if (DrawListIndex==n && UpLimit < MAXTASKPOINTS) { // patch 091126 // LKTOKEN _@M832_ = "add waypoint" _stprintf(sTmp, TEXT(" (%s)"), MsgToken(832)); Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, sTmp); } else if ((DrawListIndex==n+1) && ValidTaskPoint(0)) { if (!AATEnabled || ISPARAGLIDER) { // LKTOKEN _@M735_ = "Total:" Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, MsgToken(735)); _stprintf(sTmp, TEXT("%.0f %s%s"), lengthtotal*DISTANCEMODIFY, Units::GetDistanceName(), fai_ok?_T(" FAI"):_T("")); Surface.DrawText(rc.right +p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp); } else { double d1 = CALCULATED_INFO.TaskDistanceToGo; if ((CALCULATED_INFO.TaskStartTime>0.0) && (CALCULATED_INFO.Flying) && (ActiveTaskPoint>0)) { d1 += CALCULATED_INFO.TaskDistanceCovered; } if (d1==0.0) { d1 = CALCULATED_INFO.AATTargetDistance; } _stprintf(sTmp, TEXT("%s %.0f min %.0f (%.0f) %s"), // LKTOKEN _@M735_ = "Total:" MsgToken(735), AATTaskLength*1.0, DISTANCEMODIFY*lengthtotal, DISTANCEMODIFY*d1, Units::GetDistanceName()); Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, sTmp); } } } UnlockTaskData(); }
static void OnTaskListEnter(WindowControl * Sender, WndListFrame::ListInfo_t *ListInfo) { (void)Sender; bool isfinish = false; ItemIndex = ListInfo->ItemIndex+ListInfo->ScrollIndex; // If we are clicking on Add Waypoint if ((ItemIndex>=0) && (ItemIndex == UpLimit) && (UpLimit<MAXTASKPOINTS)) { // add new waypoint if (CheckDeclaration()) { if (ItemIndex>0) { #ifdef LAST_TASKPOINT_QUESTION if (MessageBoxX( // LKTOKEN _@M817_ = "Will this be the finish?" MsgToken(817), // LKTOKEN _@M54_ = "Add Waypoint" MsgToken(54), mbYesNo) == IdYes) #else if(0) #endif { isfinish = true; // Set initial wp as the finish by default, or home if nonex LockTaskData(); // ItemIndex is already checked for > 0 no need to test twice Task[ItemIndex].Index = Task[0].Index; UnlockTaskData(); } else { isfinish = false; } } int res; res = dlgWayPointSelect(); if (ValidWayPoint(res)){ LockTaskData(); ResetTaskWaypoint(ItemIndex); Task[ItemIndex].Index = res; Task[ItemIndex].PGConeBase = WayPointList[res].Altitude; UnlockTaskData(); if (ItemIndex==0) { dlgTaskWaypointShowModal(ItemIndex, 0, true); // start waypoint } else if (isfinish) { dlgTaskWaypointShowModal(ItemIndex, 2, true); // finish waypoint } else { if (AATEnabled || DoOptimizeRoute()) { // only need to set properties for finish dlgTaskWaypointShowModal(ItemIndex, 1, true); // normal waypoint } } } // ValidWaypoint OverviewRefreshTask(); } // CheckDeclaration return; } // Index==UpLimit, clicking on Add Waypoint if (ItemIndex<UpLimit) { if (ItemIndex==0) { dlgTaskWaypointShowModal(ItemIndex, 0); // start waypoint } else { if (ItemIndex==UpLimit-1) { dlgTaskWaypointShowModal(ItemIndex, 2); // finish waypoint } else { dlgTaskWaypointShowModal(ItemIndex, 1); // turnpoint } } OverviewRefreshTask(); } } // OnTaskListEnter
bool LoadGpxTask(LPCTSTR szFileName) { LockTaskData(); StartupStore(_T(". LoadGpxTask : <%s>%s"), szFileName, NEWLINE); ClearTask(); FILE* stream = _tfopen(szFileName, TEXT("rb")); if(stream) { fseek(stream, 0, SEEK_END); // seek to end of file long size = ftell(stream); // get current file pointer fseek(stream, 0, SEEK_SET); // seek back to beginning of file char * buff = (char*) calloc(size + 1, sizeof (char)); long nRead = fread(buff, sizeof (char), size, stream); fclose(stream); if(nRead != size) { free(buff); UnlockTaskData(); return false; } TCHAR * szXML = (TCHAR*) calloc(size + 1, sizeof (TCHAR)); utf2TCHAR(buff, szXML, size + 1); free(buff); XMLNode rootNode = XMLNode::parseString(szXML, _T("gpx")); free(szXML); if(rootNode) { if(rootNode.isEmpty()) { UnlockTaskData(); return false; } //TODO: here we load just the first route may be there are others routes in the GPX file... XMLNode routeNode=rootNode.getChildNode(TEXT("rte")); if(routeNode.isEmpty()) { //ERROR no route found in GPX file UnlockTaskData(); return false; } int numWPnodes=routeNode.nChildNode(); //count number of XML nodes inside <rte> </rte> int numOfWPs=routeNode.nChildNode(TEXT("rtept")); //count number of WPs in the route if(numOfWPs<1 || numOfWPs>MAXTASKPOINTS) { //ERROR: no WPs at all or too many WPs found in route in GPX file UnlockTaskData(); return false; } LPCTSTR dataStr=NULL; double lat; XMLNode WPnode,detailNode; WAYPOINT newPoint; for(int i=0,idx=0;i<numWPnodes;i++) { memset(&newPoint, 0, sizeof (newPoint)); WPnode=routeNode.getChildNode(i); if(_tcscmp(WPnode.getName(),TEXT("rtept"))==0) { dataStr=WPnode.getAttribute(TEXT("lat")); if(!dataStr) { //ERROR: WP without latitude ClearTask(); UnlockTaskData(); return false; } lat=_tcstod(dataStr,NULL); dataStr=WPnode.getAttribute(TEXT("lon")); if(!dataStr) { //ERROR: WP without longitude ClearTask(); UnlockTaskData(); return false; } memset(&newPoint, 0, sizeof (newPoint)); newPoint.Latitude=lat; newPoint.Longitude=_tcstod(dataStr,NULL); detailNode=WPnode.getChildNode(TEXT("ele"),0); if(detailNode) { dataStr=detailNode.getText(0); if(dataStr) newPoint.Altitude=_tcstod(dataStr,NULL); } detailNode=WPnode.getChildNode(TEXT("name"),0); if(detailNode) { dataStr=detailNode.getText(0); if(dataStr) _tcscpy(newPoint.Name, dataStr); } detailNode=WPnode.getChildNode(TEXT("cmt"),0); if(detailNode) { dataStr=detailNode.getText(0); if(dataStr) { newPoint.Comment = (TCHAR*) malloc((_tcslen(dataStr)+1)*sizeof(TCHAR)); if(newPoint.Comment) _tcscpy(newPoint.Comment, dataStr); } } #ifdef TASK_DETAILS detailNode=WPnode.getChildNode(TEXT("desc"),0); if(detailNode) { dataStr=detailNode.getText(0); if(dataStr) { newPoint.Details = (TCHAR*) malloc((_tcslen(dataStr)+1)*sizeof(TCHAR)); if(newPoint.Details) _tcscpy(newPoint.Details, dataStr); } } #else newPoint.Details=nullptr; #endif newPoint.Format=LKW_GPX; newPoint.Style=STYLE_NORMAL; if (idx==0) newPoint.Flags = START; else if (idx==numOfWPs-1) newPoint.Flags = FINISH; else newPoint.Flags = TURNPOINT + WAYPOINTFLAG; int ix =FindOrAddWaypoint(&newPoint,ISGAAIRCRAFT && (idx==0 || idx==numOfWPs-1)); //if GA check widely if we have already depart and dest airports if (ix>=0) Task[idx++].Index=ix; #ifdef TASK_DETAILS if (newPoint.Details) { free(newPoint.Details); } #endif if (newPoint.Comment) { free(newPoint.Comment); } } //if(rtept) } //for(each node in rtept) } //if(rootNode) } //if(stream) if(ISGAAIRCRAFT) { //Set task options for GA aircraft StartLine=1; //Line StartRadius=1000; SectorType=LINE; SectorRadius=1000; FinishLine=0; //Circle FinishRadius=500; } else { //otherwise set default task options for other categories StartLine=2; //Sector StartRadius=1500; SectorType=CIRCLE; SectorRadius=2000; FinishLine=0; //Circle FinishRadius=3000; } AutoAdvance=1; //Auto AATEnabled=false; PGOptimizeRoute=false; StartHeightRef=1; //ASL RefreshTask(); TaskModified = false; TargetModified = false; _tcscpy(LastTaskFileName, szFileName); UnlockTaskData(); return true; }
void TaskStatistics(NMEA_INFO *Basic, DERIVED_INFO *Calculated, const double this_maccready) { if (!ValidTaskPoint(ActiveWayPoint) || ((ActiveWayPoint>0) && !ValidTaskPoint(ActiveWayPoint-1))) { Calculated->LegSpeed = 0; Calculated->LegDistanceToGo = 0; Calculated->LegDistanceCovered = 0; Calculated->LegTimeToGo = 0; if (!AATEnabled) { Calculated->AATTimeToGo = 0; } // Calculated->TaskSpeed = 0; Calculated->TaskDistanceToGo = 0; Calculated->TaskDistanceCovered = 0; Calculated->TaskTimeToGo = 0; Calculated->LKTaskETE = 0; Calculated->TaskTimeToGoTurningNow = -1; Calculated->TaskAltitudeRequired = 0; Calculated->TaskAltitudeDifference = 0; Calculated->TaskAltitudeDifference0 = 0; Calculated->TaskAltitudeArrival = 0; Calculated->TerrainWarningLatitude = 0.0; Calculated->TerrainWarningLongitude = 0.0; Calculated->GRFinish = INVALID_GR; Calculated->FinalGlide = false; CheckGlideThroughTerrain(Basic, Calculated); // BUGFIX 091123 // no task selected, so work things out at current heading GlidePolar::MacCreadyAltitude(this_maccready, 100.0, Basic->TrackBearing, Calculated->WindSpeed, Calculated->WindBearing, &(Calculated->BestCruiseTrack), &(Calculated->VMacCready), (Calculated->FinalGlide==true), NULL, 1.0e6, CRUISE_EFFICIENCY); return; } // LockFlightData(); LockTaskData(); // Calculate Task Distances // First calculate distances for this waypoint double LegCovered, LegToGo=0, LegXTD=0, LegCurrentCourse; double LegDistance, LegBearing=0; bool calc_turning_now; double w1lat; double w1lon; double w0lat; double w0lon; if (AATEnabled && (ActiveWayPoint>0) && (ValidTaskPoint(ActiveWayPoint))) { w1lat = Task[ActiveWayPoint].AATTargetLat; w1lon = Task[ActiveWayPoint].AATTargetLon; } else { w1lat = WayPointList[TASKINDEX].Latitude; w1lon = WayPointList[TASKINDEX].Longitude; } DistanceBearing(Basic->Latitude, Basic->Longitude, w1lat, w1lon, &LegToGo, &LegBearing); if (AATEnabled && (ActiveWayPoint>0) && ValidTaskPoint(ActiveWayPoint+1) && Calculated->IsInSector && (this_maccready>0.1) ) { calc_turning_now = true; } else { calc_turning_now = false; } if (ActiveWayPoint<1) { LegCovered = 0; LegCurrentCourse=LegBearing; if (ValidTaskPoint(ActiveWayPoint+1)) { // BUGFIX 091221 LegToGo=0; } } else { if (AATEnabled) { LKASSERT((ActiveWayPoint-1)>=0); // TODO accuracy: Get best range point to here... w0lat = Task[ActiveWayPoint-1].AATTargetLat; w0lon = Task[ActiveWayPoint-1].AATTargetLon; } else { LKASSERT((ActiveWayPoint-1)>=0); LKASSERT(ValidTaskPoint(ActiveWayPoint-1)); w0lat = WayPointList[Task[ActiveWayPoint-1].Index].Latitude; w0lon = WayPointList[Task[ActiveWayPoint-1].Index].Longitude; } DistanceBearing(w1lat, w1lon, w0lat, w0lon, &LegDistance, NULL); LegCovered = ProjectedDistance(w0lon, w0lat, w1lon, w1lat, Basic->Longitude, Basic->Latitude, &LegXTD, &LegCurrentCourse); if ((StartLine==0) && (ActiveWayPoint==1)) { // Correct speed calculations for radius // JMW TODO accuracy: legcovered replace this with more accurate version // LegDistance -= StartRadius; LegCovered = max(0.0, LegCovered-StartRadius); } } Calculated->LegDistanceToGo = LegToGo; Calculated->LegDistanceCovered = LegCovered; Calculated->LegCrossTrackError = LegXTD; Calculated->LegActualTrueCourse = LegCurrentCourse; Calculated->TaskDistanceCovered = LegCovered; if (Basic->Time > Calculated->LegStartTime) { if (flightstats.LegStartTime[ActiveWayPoint]<0) { flightstats.LegStartTime[ActiveWayPoint] = Basic->Time; } Calculated->LegSpeed = Calculated->LegDistanceCovered / (Basic->Time - Calculated->LegStartTime); } // Now add distances for start to previous waypoint if (!AATEnabled) { for(int i=0;i< ActiveWayPoint-1; i++) { if (!ValidTaskPoint(i) || !ValidTaskPoint(i+1)) continue; w1lat = WayPointList[Task[i].Index].Latitude; w1lon = WayPointList[Task[i].Index].Longitude; w0lat = WayPointList[Task[i+1].Index].Latitude; w0lon = WayPointList[Task[i+1].Index].Longitude; DistanceBearing(w1lat, w1lon, w0lat, w0lon, &LegDistance, NULL); Calculated->TaskDistanceCovered += LegDistance; } } else if (ActiveWayPoint>0) { // JMW added correction for distance covered Calculated->TaskDistanceCovered = aatdistance.DistanceCovered(Basic->Longitude, Basic->Latitude, ActiveWayPoint); } CheckTransitionFinalGlide(Basic, Calculated); // accumulators double TaskAltitudeRequired = 0; double TaskAltitudeRequired0 = 0; Calculated->TaskDistanceToGo = 0; Calculated->TaskTimeToGo = 0; Calculated->LKTaskETE = 0; Calculated->TaskTimeToGoTurningNow = 0; Calculated->TaskAltitudeArrival = 0; double LegTime0; // Calculate Final Glide To Finish int FinalWayPoint = getFinalWaypoint(); double final_height = FAIFinishHeight(Basic, Calculated, -1); double total_energy_height = Calculated->NavAltitude + Calculated->EnergyHeight; double height_above_finish = total_energy_height - final_height; if (ISPARAGLIDER) { TaskAltitudeRequired = final_height; TaskAltitudeRequired0 = final_height; } // Now add it for remaining waypoints int task_index= FinalWayPoint; double StartBestCruiseTrack = -1; while ((task_index>ActiveWayPoint) && (ValidTaskPoint(task_index))) { double this_LegTimeToGo; bool this_is_final = (task_index==FinalWayPoint) || ForceFinalGlide; this_is_final = true; // JMW CHECK FGAMT if (AATEnabled) { w1lat = Task[task_index].AATTargetLat; w1lon = Task[task_index].AATTargetLon; w0lat = Task[task_index-1].AATTargetLat; w0lon = Task[task_index-1].AATTargetLon; } else { w1lat = WayPointList[Task[task_index].Index].Latitude; w1lon = WayPointList[Task[task_index].Index].Longitude; w0lat = WayPointList[Task[task_index-1].Index].Latitude; w0lon = WayPointList[Task[task_index-1].Index].Longitude; } double NextLegDistance, NextLegBearing; DistanceBearing(w0lat, w0lon, w1lat, w1lon, &NextLegDistance, &NextLegBearing); double LegAltitude = GlidePolar:: MacCreadyAltitude(this_maccready, NextLegDistance, NextLegBearing, Calculated->WindSpeed, Calculated->WindBearing, 0, 0, this_is_final, &this_LegTimeToGo, height_above_finish, CRUISE_EFFICIENCY); double LegAltitude0 = GlidePolar:: MacCreadyAltitude(0, NextLegDistance, NextLegBearing, Calculated->WindSpeed, Calculated->WindBearing, 0, 0, true, &LegTime0, 1.0e6, CRUISE_EFFICIENCY ); if (LegTime0>=0.9*ERROR_TIME) { // can't make it, so assume flying at current mc LegAltitude0 = LegAltitude; } TaskAltitudeRequired += LegAltitude; TaskAltitudeRequired0 += LegAltitude0; if(ISPARAGLIDER) { // if required altitude is less than previous turpoint altitude, // use previous turn point altitude double w0Alt = FAIFinishHeight(Basic, Calculated, task_index-1); if(TaskAltitudeRequired < w0Alt) { Calculated->TaskAltitudeArrival += w0Alt - TaskAltitudeRequired; TaskAltitudeRequired = w0Alt; } if(TaskAltitudeRequired0 < w0Alt) { TaskAltitudeRequired0 = w0Alt; } } Calculated->TaskDistanceToGo += NextLegDistance; Calculated->TaskTimeToGo += this_LegTimeToGo; if (task_index==1) { StartBestCruiseTrack = NextLegBearing; } if (calc_turning_now) { if (task_index == ActiveWayPoint+1) { double NextLegDistanceTurningNow, NextLegBearingTurningNow; double this_LegTimeToGo_turningnow=0; DistanceBearing(Basic->Latitude, Basic->Longitude, w1lat, w1lon, &NextLegDistanceTurningNow, &NextLegBearingTurningNow); GlidePolar:: MacCreadyAltitude(this_maccready, NextLegDistanceTurningNow, NextLegBearingTurningNow, Calculated->WindSpeed, Calculated->WindBearing, 0, 0, this_is_final, &this_LegTimeToGo_turningnow, height_above_finish, CRUISE_EFFICIENCY); Calculated->TaskTimeToGoTurningNow += this_LegTimeToGo_turningnow; } else { Calculated->TaskTimeToGoTurningNow += this_LegTimeToGo; } } height_above_finish-= LegAltitude; task_index--; } // current waypoint, do this last! if (AATEnabled && (ActiveWayPoint>0) && ValidTaskPoint(ActiveWayPoint+1) && Calculated->IsInSector) { if (Calculated->WaypointDistance<AATCloseDistance()*3.0) { LegBearing = AATCloseBearing(Basic, Calculated); } } #ifdef BCT_ALT_FIX // Don't calculate BCT yet. LegAltitude will be used to calculate // task altitude difference, which will then be used to calculate BCT. #endif double LegAltitude = GlidePolar::MacCreadyAltitude(this_maccready, LegToGo, LegBearing, Calculated->WindSpeed, Calculated->WindBearing, #ifdef BCT_ALT_FIX 0, #else &(Calculated->BestCruiseTrack), #endif &(Calculated->VMacCready), // (Calculated->FinalGlide==1), true, // JMW CHECK FGAMT &(Calculated->LegTimeToGo), height_above_finish, CRUISE_EFFICIENCY); double LegAltitude0 = GlidePolar::MacCreadyAltitude(0, LegToGo, LegBearing, Calculated->WindSpeed, Calculated->WindBearing, 0, 0, true, &LegTime0, 1.0e6, CRUISE_EFFICIENCY ); #ifndef BCT_ALT_FIX // fix problem of blue arrow wrong in task sector if (StartBestCruiseTrack>=0) // use it only if assigned, workaround if (Calculated->IsInSector && (ActiveWayPoint==0)) { // set best cruise track to first leg bearing when in start sector Calculated->BestCruiseTrack = StartBestCruiseTrack; } #endif // JMW TODO accuracy: Use safetymc where appropriate if (LegTime0>= 0.9*ERROR_TIME) { // can't make it, so assume flying at current mc LegAltitude0 = LegAltitude; } TaskAltitudeRequired += LegAltitude; TaskAltitudeRequired0 += LegAltitude0; Calculated->TaskDistanceToGo += LegToGo; Calculated->TaskTimeToGo += Calculated->LegTimeToGo; #ifndef BCT_ALT_FIX height_above_finish-= LegAltitude; #endif if (calc_turning_now) { Calculated->TaskTimeToGoTurningNow += Basic->Time-Calculated->TaskStartTime; } else { Calculated->TaskTimeToGoTurningNow = -1; } if (ISPARAGLIDER) { Calculated->TaskAltitudeRequired = TaskAltitudeRequired; } else { Calculated->TaskAltitudeRequired = TaskAltitudeRequired + final_height; TaskAltitudeRequired0 += final_height; } Calculated->TaskAltitudeDifference = total_energy_height - Calculated->TaskAltitudeRequired; Calculated->TaskAltitudeDifference0 = total_energy_height - TaskAltitudeRequired0; Calculated->NextAltitudeDifference0 = total_energy_height - Calculated->NextAltitudeRequired0; Calculated->TaskAltitudeArrival += Calculated->TaskAltitudeDifference; Calculated->GRFinish= CalculateGlideRatio(Calculated->TaskDistanceToGo, Calculated->NavAltitude - final_height); if (Calculated->TaskSpeedAchieved >0) Calculated->LKTaskETE = Calculated->TaskDistanceToGo/Calculated->TaskSpeedAchieved; else Calculated->LKTaskETE=0; #ifdef BCT_ALT_FIX // This MCA call's only purpose is to update BestCruiseTrack (BCT). // It must occur after TaskAltitudeDifference (TAD) is updated, // since BCT depends on TAD. GlidePolar::MacCreadyAltitude(this_maccready, LegToGo, LegBearing, Calculated->WindSpeed, Calculated->WindBearing, &(Calculated->BestCruiseTrack), 0, true, 0, height_above_finish, CRUISE_EFFICIENCY, Calculated->TaskAltitudeDifference); // fix problem of blue arrow wrong in task sector if (StartBestCruiseTrack>=0) // use it only if assigned, workaround if (Calculated->IsInSector && (ActiveWayPoint==0)) { // set best cruise track to first leg bearing when in start sector Calculated->BestCruiseTrack = StartBestCruiseTrack; } height_above_finish-= LegAltitude; #endif CheckGlideThroughTerrain(Basic, Calculated); CheckForceFinalGlide(Basic, Calculated); UnlockTaskData(); }
// // THIS FUNCTION IS THREAD SAFE, but not using optimized clipping // void MapWindow::DrawTaskPicto(HDC hdc,int TaskIdx, RECT rc, double fScaleFact) { int center_x = (rc.right-rc.left)/2; int center_y = (rc.bottom-rc.top)/2; int SecType = SectorType; int width = center_x-2; HPEN oldpen = 0; HBRUSH oldbrush = 0; if(AATEnabled) oldbrush = (HBRUSH) SelectObject(hdc, LKBrush_LightGrey); else oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)); oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick); int finish=0; while( ValidTaskPoint(finish)) finish++; finish--; if(center_y < width) width = center_y-2; POINT startfinishline[2] = {{0,-width/ScreenScale}, {0,width/ScreenScale}}; POINT track[3] = {{0,-width/5/ScreenScale}, {width/2/ScreenScale,0}, {0,width/5/ScreenScale}}; if(TaskIdx == finish) { track[0].x = -width/2/ScreenScale; track[0].y= -width/5/ScreenScale; track[1].x = 0 ; track[1].y= 0; track[2].x = -width/2/ScreenScale ; track[2].y= width/5/ScreenScale; } LockTaskData(); // protect from external task changes double StartRadial = Task[TaskIdx].AATStartRadial; double FinishRadial = Task[TaskIdx].AATFinishRadial; if(TaskIdx==0) { FinishRadial = Task[TaskIdx].AATStartRadial; StartRadial = Task[TaskIdx].AATFinishRadial; } double LineBrg; double SecRadius; GetTaskSectorParameter( TaskIdx, &SecType,&SecRadius); switch (SecType) { case CIRCLE: CircleNoCliping(hdc, center_x, center_y, width-2, rc, true); break; case SECTOR: Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); break; case DAe: if (!AATEnabled) { // this Type exist only if not AAT task // JMW added german rules CircleNoCliping(hdc, center_x, center_y, width/8, rc, true); Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); } break; default: case LINE: if (TaskIdx == 0) { LineBrg = Task[TaskIdx].OutBound-90; } else if (TaskIdx == finish) { LineBrg = Task[TaskIdx].InBound-90; } else { LineBrg = Task[TaskIdx].Bisector; } threadsafePolygonRotateShift(startfinishline, 2, center_x, center_y, LineBrg); Polygon(hdc, startfinishline, 2); if ((TaskIdx == 0) || (TaskIdx == finish)) { threadsafePolygonRotateShift(track, 3, center_x, center_y, LineBrg); Polygon(hdc, track, 3); } break; case CONE: if (DoOptimizeRoute()) { int radius = width-2; CircleNoCliping(hdc, center_x, center_y, radius, rc, true); HPEN prevPen = (HPEN)::SelectObject(hdc, hpTerrainLine); for( int i = 1; i < 4 && radius > (width/5); ++i) { CircleNoCliping(hdc, center_x, center_y, radius -= width/5, rc, true); } ::SelectObject(hdc, prevPen); } break; } UnlockTaskData(); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); }
static void UpdateValuesRules(void) { WndProperty *wp; TCHAR Temp[80]; wp = (WndProperty*)wf->FindByName(TEXT("prpValidStart")); if (wp) { if (CALCULATED_INFO.ValidStart) { // LKTOKEN _@M677_ = "TRUE" wp->SetText(gettext(TEXT("_@M677_"))); } else { // LKTOKEN _@M278_ = "FALSE" wp->SetText(gettext(TEXT("_@M278_"))); } } wp = (WndProperty*)wf->FindByName(TEXT("prpValidFinish")); if (wp) { if (CALCULATED_INFO.ValidFinish) { // LKTOKEN _@M677_ = "TRUE" wp->SetText(gettext(TEXT("_@M677_"))); } else { // LKTOKEN _@M278_ = "FALSE" wp->SetText(gettext(TEXT("_@M278_"))); } } wp = (WndProperty*)wf->FindByName(TEXT("prpStartTime")); if (wp) { if (CALCULATED_INFO.TaskStartTime>0) { Units::TimeToText(Temp, (int)TimeLocal((int)(CALCULATED_INFO.TaskStartTime))); wp->SetText(Temp); } else { wp->SetText(TEXT("")); } } wp = (WndProperty*)wf->FindByName(TEXT("prpStartSpeed")); if (wp) { if (CALCULATED_INFO.TaskStartTime>0) { _stprintf(Temp, TEXT("%.0f %s"), TASKSPEEDMODIFY*CALCULATED_INFO.TaskStartSpeed, Units::GetTaskSpeedName()); wp->SetText(Temp); } else { wp->SetText(TEXT("")); } } // StartMaxHeight, StartMaxSpeed; // double start_h; LockTaskData(); wp = (WndProperty*)wf->FindByName(TEXT("prpStartPoint")); if (ValidTaskPoint(0)) { // start_h = WayPointList[Task[0].Index].Altitude; if (wp) { wp->SetText(WayPointList[Task[0].Index].Name); } } else { // start_h = 0; if (wp) { wp->SetText(TEXT("")); } } wp = (WndProperty*)wf->FindByName(TEXT("prpStartHeight")); if (wp) { if (CALCULATED_INFO.TaskStartTime>0) { _stprintf(Temp, TEXT("%.0f %s"), (CALCULATED_INFO.TaskStartAltitude)*ALTITUDEMODIFY, Units::GetAltitudeName()); wp->SetText(Temp); } else { wp->SetText(TEXT("")); } } wp = (WndProperty*)wf->FindByName(TEXT("prpFinishAlt")); if (wp) { double finish_min = FAIFinishHeight(&GPS_INFO, &CALCULATED_INFO, -1); _stprintf(Temp, TEXT("%.0f %s"), finish_min*ALTITUDEMODIFY, Units::GetAltitudeName()); wp->SetText(Temp); } UnlockTaskData(); }
bool TaskAltitudeRequired(NMEA_INFO *Basic, DERIVED_INFO *Calculated, double this_maccready, double *Vfinal, double *TotalTime, double *TotalDistance, int *ifinal) { int i; double w1lat; double w1lon; double w0lat; double w0lon; double LegTime, LegDistance, LegBearing, LegAltitude; bool retval = false; // Calculate altitude required from start of task bool isfinal=true; LegAltitude = 0; double TotalAltitude = 0; *TotalTime = 0; *TotalDistance = 0; *ifinal = 0; LockTaskData(); double heightFinal = FAIFinishHeight(Basic, Calculated, -1); double height_above_finish = FAIFinishHeight(Basic, Calculated, 0) - heightFinal; for(i=MAXTASKPOINTS-2;i>=0;i--) { if (!ValidTaskPoint(i) || !ValidTaskPoint(i+1)) continue; w1lat = WayPointList[Task[i].Index].Latitude; w1lon = WayPointList[Task[i].Index].Longitude; w0lat = WayPointList[Task[i+1].Index].Latitude; w0lon = WayPointList[Task[i+1].Index].Longitude; if (AATEnabled) { w1lat = Task[i].AATTargetLat; w1lon = Task[i].AATTargetLon; // also use optimized finish point for PG optimized task. if (!isfinal || DoOptimizeRoute()) { w0lat = Task[i+1].AATTargetLat; w0lon = Task[i+1].AATTargetLon; } } DistanceBearing(w1lat, w1lon, w0lat, w0lon, &LegDistance, &LegBearing); *TotalDistance += LegDistance; LegAltitude = GlidePolar::MacCreadyAltitude(this_maccready, LegDistance, LegBearing, Calculated->WindSpeed, Calculated->WindBearing, 0, 0, true, &LegTime, height_above_finish, CRUISE_EFFICIENCY ); // JMW CHECK FGAMT height_above_finish-= LegAltitude; TotalAltitude += LegAltitude; if( ISPARAGLIDER ) { // if required altitude is less than previous turpoint altitude, // use previous turn point altitude double w1Alt = FAIFinishHeight(Basic, Calculated, i); if( (TotalAltitude+heightFinal) < w1Alt ) { TotalAltitude = w1Alt; } } if (LegTime<0) { retval = false; goto OnExit; } else { *TotalTime += LegTime; } if (isfinal) { *ifinal = i+1; if (LegTime>0) { *Vfinal = LegDistance/LegTime; } } isfinal = false; } if (*ifinal==0) { retval = false; goto OnExit; } TotalAltitude += FAIFinishHeight(Basic, Calculated, -1); if (!ValidTaskPoint(*ifinal)) { Calculated->TaskAltitudeRequiredFromStart = TotalAltitude; retval = false; } else { Calculated->TaskAltitudeRequiredFromStart = TotalAltitude; retval = true; } OnExit: UnlockTaskData(); return retval; }
void MapWindow::DrawBearing(HDC hdc, const RECT rc) { int overindex=GetOvertargetIndex(); if (overindex<0) return; double startLat = DrawInfo.Latitude; double startLon = DrawInfo.Longitude; double targetLat; double targetLon; if (OvertargetMode>OVT_TASK) { LockTaskData(); targetLat = WayPointList[overindex].Latitude; targetLon = WayPointList[overindex].Longitude; UnlockTaskData(); DrawGreatCircle(hdc, startLon, startLat, targetLon, targetLat, rc); } else { if (!ValidTaskPoint(ActiveWayPoint)) { return; } LockTaskData(); if (AATEnabled && ( DoOptimizeRoute() || ((ActiveWayPoint>0) && ValidTaskPoint(ActiveWayPoint+1))) ) { targetLat = Task[ActiveWayPoint].AATTargetLat; targetLon = Task[ActiveWayPoint].AATTargetLon; } else { targetLat = WayPointList[Task[ActiveWayPoint].Index].Latitude; targetLon = WayPointList[Task[ActiveWayPoint].Index].Longitude; } UnlockTaskData(); DrawGreatCircle(hdc, startLon, startLat, targetLon, targetLat, rc); if (mode.Is(Mode::MODE_TARGET_PAN)) { // Draw all of task if in target pan mode startLat = targetLat; startLon = targetLon; LockTaskData(); for (int i=ActiveWayPoint+1; i<MAXTASKPOINTS; i++) { if (ValidTaskPoint(i)) { if (AATEnabled && ValidTaskPoint(i+1)) { targetLat = Task[i].AATTargetLat; targetLon = Task[i].AATTargetLon; } else { targetLat = WayPointList[Task[i].Index].Latitude; targetLon = WayPointList[Task[i].Index].Longitude; } DrawGreatCircle(hdc, startLon, startLat, targetLon, targetLat, rc); startLat = targetLat; startLon = targetLon; } } UnlockTaskData(); } } if (AATEnabled) { // draw symbol at target, makes it easier to see LockTaskData(); if(mode.Is(Mode::MODE_TARGET_PAN)) { for(int i=ActiveWayPoint+1; i<MAXTASKPOINTS; i++) { if(ValidTaskPoint(i) && ValidTaskPoint(i+1)) { if(i>= ActiveWayPoint) { POINT sct; LatLon2Screen(Task[i].AATTargetLon, Task[i].AATTargetLat, sct); DrawBitmapIn(hdc, sct, hBmpTarget,true); } } } } if(ValidTaskPoint(ActiveWayPoint+1) && (DoOptimizeRoute() || (ActiveWayPoint>0)) ) { POINT sct; LatLon2Screen(Task[ActiveWayPoint].AATTargetLon, Task[ActiveWayPoint].AATTargetLat, sct); DrawBitmapIn(hdc, sct, hBmpTarget,true); } UnlockTaskData(); } }
void DoAutoMacCready(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { if (!Calculated->AutoMacCready) return; bool is_final_glide = false; bool is_conical_ess = false; double ConeSlope = 0.0; // LockFlightData(); LockTaskData(); double mc_new = MACCREADY; static bool first_mc = true; if (AutoMcMode == amcEquivalent) { if ((!Calculated->Circling) && (!Calculated->OnGround)) { if (Calculated->EqMc >= 0) { // MACCREADY = LowPassFilter(MACCREADY,Calculated->EqMc,0.8); CheckSetMACCREADY(Calculated->EqMc); } else { // -1.0 is used as an invalid flag. Normally flying at -1 MC means almost flying // at stall speed, which is pretty unusual. Maybe in wave conditions? if (Calculated->EqMc >-1) { CheckSetMACCREADY(Calculated->EqMc*-1); } } } UnlockTaskData(); return; } // otherwise, if AutoMc for finalglide or "both", return if no goto if (ValidTaskPoint(ActiveWayPoint)) { if (Calculated->FinalGlide && ActiveIsFinalWaypoint()) { is_final_glide = true; } else { first_mc = true; } if (DoOptimizeRoute() && Calculated->NextAltitude > 0.) { // Special case for Conical end of Speed section int Type = -1; GetTaskSectorParameter(ActiveWayPoint, &Type, NULL); ConeSlope = Task[ActiveWayPoint].PGConeSlope; if (Type == CONE && ConeSlope > 0.0) { is_final_glide = true; is_conical_ess = true; } } } double av_thermal = -1; if (flightstats.ThermalAverage.y_ave > 0) { if (Calculated->Circling && (Calculated->AverageThermal > 0)) { #if BUGSTOP LKASSERT((flightstats.ThermalAverage.sum_n + 1) != 0); #endif if (flightstats.ThermalAverage.sum_n == -1) { flightstats.ThermalAverage.sum_n = -0.99; } av_thermal = (flightstats.ThermalAverage.y_ave * flightstats.ThermalAverage.sum_n + Calculated->AverageThermal) / (flightstats.ThermalAverage.sum_n + 1); } else { av_thermal = flightstats.ThermalAverage.y_ave; } } else if (Calculated->Circling && (Calculated->AverageThermal > 0)) { // insufficient stats, so use this/last thermal's average av_thermal = Calculated->AverageThermal; } if (!ValidTaskPoint(ActiveWayPoint)) { if (av_thermal > 0) { mc_new = av_thermal; } else { mc_new = 0; } } else if (((AutoMcMode == amcFinalGlide) || (AutoMcMode == amcFinalAndClimb)) && is_final_glide) { if (Calculated->TaskAltitudeDifference0 > 0) { // only change if above final glide with zero Mc // otherwise when we are well below, it will wind Mc back to // zero #if BUGSTOP LKASSERT((Calculated->WaypointDistance + 1) != 0); #endif if (Calculated->WaypointDistance < 0) Calculated->WaypointDistance = 0; // temporary but ok double slope = (Calculated->NavAltitude + Calculated->EnergyHeight - FAIFinishHeight(Basic, Calculated, ActiveWayPoint)) / (Calculated->WaypointDistance + 1); double mc_pirker = PirkerAnalysis(Basic, Calculated, Calculated->WaypointBearing, slope); mc_pirker = max(0.0, mc_pirker); if (first_mc) { // don't allow Mc to wind down to zero when first achieving // final glide; but do allow it to wind down after that if (mc_pirker >= mc_new) { mc_new = mc_pirker; first_mc = false; } else if (AutoMcMode == amcFinalAndClimb) { // revert to averager based auto Mc if (av_thermal > 0) { mc_new = av_thermal; } } } else { mc_new = mc_pirker; } if (is_conical_ess) { const double VOpt = GlidePolar::FindSpeedForSlope(ConeSlope); const double eqMC = GlidePolar::EquMC(VOpt); if(mc_new > eqMC) { mc_new = eqMC; } } } else { // below final glide at zero Mc, never achieved final glide if (first_mc && (AutoMcMode == amcFinalAndClimb)) { // revert to averager based auto Mc if (av_thermal > 0) { mc_new = av_thermal; } } } } else if ((AutoMcMode == amcAverageClimb) || ((AutoMcMode == amcFinalAndClimb)&& !is_final_glide)) { if (av_thermal > 0) { mc_new = av_thermal; } } CheckSetMACCREADY(LowPassFilter(MACCREADY, mc_new, 0.6)); UnlockTaskData(); // UnlockFlightData(); }