Exemple #1
0
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();
}
Exemple #2
0
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();

  }
}
Exemple #3
0
/** 
 * @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();
     }
}
Exemple #4
0
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);
    }
  }
}
Exemple #5
0
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();
  };
}
Exemple #6
0
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;

}
Exemple #7
0
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();
  };
}
Exemple #8
0
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;
}
Exemple #9
0
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"));

}
Exemple #10
0
/*
 * 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);
}
Exemple #11
0
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();
        }
    }
}
Exemple #13
0
// 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;
}
Exemple #14
0
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();
  };
}
Exemple #15
0
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();
}
Exemple #17
0
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();
}
Exemple #19
0
/** 
 * @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;

}
Exemple #21
0
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();

}
Exemple #22
0
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();

}
Exemple #23
0
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
Exemple #24
0
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;
}
Exemple #25
0
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();

}
Exemple #26
0
//
// 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);
}
Exemple #27
0
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;
}
Exemple #29
0
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();
  }
}
Exemple #30
0
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();

}