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; }
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; } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// 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()
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; }
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(); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// 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()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// 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()
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()