示例#1
0
BOOL PBB50(TCHAR *String, NMEA_INFO *pGPS) {
  // $PBB50,100,0,10,1,10000,0,1,0,20*4A..
  // $PBB50,0,.0,.0,0,0,1.07,0,-228*58
  // $PBB50,14,-.2,.0,196,0,.92,0,-228*71

  double vtas, vias, wnet;
  TCHAR ctemp[80];

  NMEAParser::ExtractParameter(String,ctemp,0);
  vtas = StrToDouble(ctemp,NULL)/TOKNOTS;

  NMEAParser::ExtractParameter(String,ctemp,1);
  wnet = StrToDouble(ctemp,NULL)/TOKNOTS;

  NMEAParser::ExtractParameter(String,ctemp,2);
  pGPS->MacReady = StrToDouble(ctemp,NULL)/TOKNOTS;
  CheckSetMACCREADY(pGPS->MacReady);

  NMEAParser::ExtractParameter(String,ctemp,3);
  vias = sqrt(StrToDouble(ctemp,NULL))/TOKNOTS;

  // inclimb/incruise 1=cruise,0=climb, OAT
  NMEAParser::ExtractParameter(String,ctemp,6);


  #if USESWITCHES
  int climb = iround(StrToDouble(ctemp,NULL));
  pGPS->SwitchState.VarioCircling = (climb==1);
  #endif

  #if 0 // UNUSED EnableExternalTriggerCruise
  if (EnableExternalTriggerCruise) {
    if (climb) {
      ExternalTriggerCruise = false;
      ExternalTriggerCircling = true;
    } else {
      ExternalTriggerCruise = true;
      ExternalTriggerCircling = false;
    }
  } else {
    ExternalTriggerCruise = false;
  }
  #endif

  NMEAParser::ExtractParameter(String,ctemp,7);
  pGPS->OutsideAirTemperature = StrToDouble(ctemp,NULL);
  pGPS->TemperatureAvailable = true;

  pGPS->AirspeedAvailable = TRUE;
  pGPS->IndicatedAirspeed = vias;
  pGPS->TrueAirspeed = vtas;
  pGPS->VarioAvailable = TRUE;
  pGPS->Vario = wnet;

  TriggerVarioUpdate();

  return FALSE;
}
示例#2
0
static void OnMacCreadyData(DataField *Sender, 
			    DataField::DataAccessKind_t Mode){
  switch(Mode){
  case DataField::daSpecial:
    if (CALCULATED_INFO.timeCircling>0) {
      CheckSetMACCREADY(CALCULATED_INFO.TotalHeightClimb /CALCULATED_INFO.timeCircling);
      Sender->Set(MACCREADY*LIFTMODIFY);
      RefreshCalculator();
    }
    break;
  case DataField::daGet:
    Sender->Set(MACCREADY*LIFTMODIFY);
    break;
  case DataField::daPut: 
  case DataField::daChange:
    CheckSetMACCREADY(Sender->GetAsFloat()/LIFTMODIFY);
    RefreshCalculator();
    break;
  case DataField::daInc:
  case DataField::daDec:
    break;
  }
}
示例#3
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Parses LXWP2 sentence.
///
/// @param d         device descriptor
/// @param sentence  received NMEA sentence
/// @param info      GPS info to be updated
///
/// @retval true if the sentence has been parsed
///
//static
bool DevLX::LXWP2(PDeviceDescriptor_t, const TCHAR* sentence, NMEA_INFO* info)
{
  // $LXWP2,mccready,ballast,bugs,polar_a,polar_b,polar_c, audio volume
  //   *CS<CR><LF>
  //
  // Mccready: float in m/s
  // Ballast: float 1.0 ... 1.5
  // Bugs: 0 - 100%
  // polar_a: float polar_a=a/10000 w=a*v2+b*v+c
  // polar_b: float polar_b=b/100 v=(km/h/100) w=(m/s)
  // polar_c: float polar_c=c
  // audio volume 0 - 100%

  ParToDouble(sentence, 0, &info->MacReady);
  CheckSetMACCREADY(info->MacReady);


  return(true);
} // LXWP2()
示例#4
0
void dlgTaskCalculatorShowModal(void){

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

  if (!wf) return;

  double MACCREADY_enter = MACCREADY;
  double CRUISE_EFFICIENCY_enter = CRUISE_EFFICIENCY;

  emc = EffectiveMacCready(&GPS_INFO, &CALCULATED_INFO);

  cruise_efficiency = CRUISE_EFFICIENCY;

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

  RefreshCalculator();

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

  if (wf->ShowModal() == mrCancle) {
    // todo: restore task settings.
    CheckSetMACCREADY(MACCREADY_enter);
    CRUISE_EFFICIENCY = CRUISE_EFFICIENCY_enter;
  }
  delete wf;
  wf = NULL;
}
示例#5
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();

}
示例#6
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Parses LXWP2 sentence.
///
/// @param d         device descriptor
/// @param sentence  received NMEA sentence
/// @param info      GPS info to be updated
///
/// @retval true if the sentence has been parsed
///
//static
bool DevLXV7_EXP::LXWP2(PDeviceDescriptor_t, const TCHAR* sentence, NMEA_INFO*)
{
  // $LXWP2,mccready,ballast,bugs,polar_a,polar_b,polar_c, audio volume
  //   *CS<CR><LF>
  //
  // Mccready: float in m/s
  // Ballast: float 1.0 ... 1.5
  // Bugs: 0 - 100%
  // polar_a: float polar_a=a/10000 w=a*v2+b*v+c
  // polar_b: float polar_b=b/100 v=(km/h/100) w=(m/s)
  // polar_c: float polar_c=c
  // audio volume 0 - 100%
//float fBallast,fBugs, polar_a, polar_b, polar_c, fVolume;


double fTmp;
int iTmp;
if(LXV7_EXP_MacCreadyUpdateTimeout > 0)
{
	LXV7_EXP_MacCreadyUpdateTimeout--;
}
else
  if (ParToDouble(sentence, 0, &fTmp))
  {
	iTmp =(int) (fTmp*100.0+0.5f);
	fTmp = (double)(iTmp)/100.0;
	LXV7_EXP_bValid = true;
	if(fabs(MACCREADY - fTmp)> 0.001)
	{
	  CheckSetMACCREADY(fTmp);
	  iLXV7_EXP_RxUpdateTime =5;
	}
  }


if(LXV7_EXP_BallastUpdateTimeout > 0)
{
	LXV7_EXP_BallastUpdateTimeout--;
}
else
  if (ParToDouble(sentence, 1, &fTmp))
  {
	fTmp -= 1.0;
	if(  fabs(fTmp -BALLAST) >= 0.05)
    {
      CheckSetBallast(fTmp);
      iLXV7_EXP_RxUpdateTime = 5;
    }
  }

if(LXV7_EXP_BugsUpdateTimeout > 0)
{
  LXV7_EXP_BugsUpdateTimeout--;
}
else
  if(ParToDouble(sentence, 2, &fTmp))
  {
	int iTmp2 = 100-(int)(fTmp+0.5);
	fTmp =  (double)iTmp2/100.0;
	if(  fabs(fTmp -BUGS) >= 0.03)
    {
      CheckSetBugs(fTmp);
      iLXV7_EXP_RxUpdateTime = 5;
    }
  }
/*
  if (ParToDouble(sentence, 3, &fTmp))
    fPolar_a = fTmp;
  if (ParToDouble(sentence, 4, &fTmp))
    fPolar_b = fTmp;
  if (ParToDouble(sentence, 5, &fTmp))
    fPolar_c = fTmp;
  if (ParToDouble(sentence, 6, &fTmp))
  {
    fVolume = fTmp;
  }
*/
  return(true);
} // LXWP2()
示例#7
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Parses LXWP2 sentence.
///
/// @param d         device descriptor
/// @param sentence  received NMEA sentence
/// @param info      GPS info to be updated
///
/// @retval true if the sentence has been parsed
///
//static
bool DevLX16xx::LXWP2(PDeviceDescriptor_t, const TCHAR* sentence, NMEA_INFO*)
{
  // $LXWP2,mccready,ballast,bugs,polar_a,polar_b,polar_c, audio volume
  //   *CS<CR><LF>
  //
  // Mccready: float in m/s
  // Ballast: float 1.0 ... 1.5
  // Bugs: 0 - 100%
  // polar_a: float polar_a=a/10000 w=a*v2+b*v+c
  // polar_b: float polar_b=b/100 v=(km/h/100) w=(m/s)
  // polar_c: float polar_c=c
  // audio volume 0 - 100%
//float fBallast,fBugs, polar_a, polar_b, polar_c, fVolume;


double fTmp;
int iTmp;
if(MacCreadyUpdateTimeout > 0)
{
	MacCreadyUpdateTimeout--;
}
else
  if (ParToDouble(sentence, 0, &fTmp))
  {
	iTmp =(int) (fTmp*100.0+0.5f);
	fTmp = (double)(iTmp)/100.0;
	bValid = true;
	if(fabs(MACCREADY - fTmp)> 0.001)
	{
	  CheckSetMACCREADY(fTmp);
	  iLX16xx_RxUpdateTime =5;
	}
  }


if(BallastUpdateTimeout > 0)
{
  BallastUpdateTimeout--;
}
else
  if (ParToDouble(sentence, 1, &fTmp))
  {
    double newBallast = CalculateBalastFromLX(fTmp);
    if(fabs(newBallast- BALLAST) > 0.01 )
    {
      CheckSetBallast(newBallast);
      iLX16xx_RxUpdateTime = 5;
    }
  }

if(BugsUpdateTimeout > 0)
{
  BugsUpdateTimeout--;
}
else {
  if(ParToDouble(sentence, 2, &fTmp))
  {
    double newBug = CalculateBugsFromLX(fTmp);
	if(  fabs(newBug -BUGS) >= 0.03)
    {
      CheckSetBugs(newBug);
      iLX16xx_RxUpdateTime = 5;
    }
  }
}
  if (ParToDouble(sentence, 3, &fTmp))
    fPolar_a = fTmp;
  if (ParToDouble(sentence, 4, &fTmp))
    fPolar_b = fTmp;
  if (ParToDouble(sentence, 5, &fTmp))
    fPolar_c = fTmp;
  if (ParToDouble(sentence, 6, &fTmp))
  {
    fVolume = fTmp;
  }
  return(true);
} // LXWP2()
示例#8
0
bool DevLXMiniMap::LXWP2(PDeviceDescriptor_t, const TCHAR* sentence, NMEA_INFO* info)
{
  // $LXWP2,mccready,ballast,bugs,polar_a,polar_b,polar_c, audio volume
  //   *CS<CR><LF>
  //
  // Mccready: float in m/s
  // Ballast: float 1.0 ... 1.5
  // Bugs: 0 - 100%
  // polar_a: float polar_a=a/10000 w=a*v2+b*v+c
  // polar_b: float polar_b=b/100 v=(km/h/100) w=(m/s)
  // polar_c: float polar_c=c
  // audio volume 0 - 100%

	if(McReadyTimeout>0)
	{
		McReadyTimeout--;
	}
	else
	{
		ParToDouble(sentence, 0, &info->MacReady);
		CheckSetMACCREADY(info->MacReady);
	}

	if(BallastTimeout>0)
	{
		BallastTimeout--;
	}
	else
	{
		double tempBallastFactor;

		ParToDouble(sentence, 1, &tempBallastFactor);

		double newBallast = CalculateBalast(tempBallastFactor);

		if(fabs(newBallast- BALLAST) > 0.01 )
		{
			CheckSetBallast(newBallast);
		}

	}


	if(BugsTimeout>0)
	{
		BugsTimeout--;
	}
	else
	{

		double tempBugs;
		ParToDouble(sentence, 2, &tempBugs);

		tempBugs = (100.0 - tempBugs)/100;

		if(fabs(tempBugs -BUGS) > 0.01)
		{
			CheckSetBugs(tempBugs);
		}

	}



  return(true);
} // LXWP2()