static void OnAltitudeData(DataField *Sender, DataField::DataAccessKind_t Mode){ static double newalt=0; WndProperty* wp; switch(Mode){ case DataField::daGet: break; case DataField::daPut: case DataField::daChange: newalt = Sender->GetAsFloat(); QNH=FindQNH(GPS_INFO.BaroAltitude,Units::ToSysAltitude(newalt)); // 100411 wp = (WndProperty*)wf->FindByName(TEXT("prpQNH")); if (wp) { if (PressureHg) { INHg=QNH/TOHPA; wp->GetDataField()-> SetAsFloat(INHg); } else { wp->GetDataField()-> SetAsFloat(QNH); } wp->RefreshDisplay(); } break; case DataField::daInc: case DataField::daDec: case DataField::daSpecial: break; } }
void NMEAParser::TestRoutine(NMEA_INFO *GPS_INFO) { #ifdef DEBUG #ifndef GNAV static int i=90; static TCHAR t1[] = TEXT("1,1,1,1"); static TCHAR t2[] = TEXT("1,300,500,220,2,DD927B,0,-4.5,30,-1.4,1"); static TCHAR t3[] = TEXT("0,0,1200,50,2,DD9146,270,-4.5,30,-1.4,1"); // static TCHAR b50[] = TEXT("0,.1,.0,0,0,1.06,0,-222"); // static TCHAR t4[] = TEXT("-3,500,1024,50"); // nmeaParser1.ParseNMEAString_Internal(TEXT("$PTAS1,201,200,02583,000*2A"), GPS_INFO); // nmeaParser1.ParseNMEAString_Internal(TEXT("$GPRMC,082430.00,A,3744.09096,S,14426.16069,E,0.520294.90,301207,,,A*77"), GPS_INFO); // nmeaParser1.ParseNMEAString_Internal(TEXT("$GPGGA,082430.00,3744.09096,S,1426.16069,E,1,08,1.37,157.6,M,-4.9,M,,*5B"), GPS_INFO); QNH=1013.25; double h; double altraw= 5.0; h = AltitudeToQNHAltitude(altraw); QNH = FindQNH(altraw, 50.0); h = AltitudeToQNHAltitude(altraw); i++; if (i>100) { i=0; } if (i<50) { GPS_INFO->FLARM_Available = true; TCHAR ctemp[MAX_NMEA_LEN]; TCHAR *params[MAX_NMEA_PARAMS]; size_t nr; nr = nmeaParser1.ExtractParameters(t1, ctemp, params, MAX_NMEA_PARAMS); nmeaParser1.PFLAU(t1, params, nr, GPS_INFO); nr = nmeaParser1.ExtractParameters(t2, ctemp, params, MAX_NMEA_PARAMS); nmeaParser1.PFLAA(t2, params, nr, GPS_INFO); nr = nmeaParser1.ExtractParameters(t3, ctemp, params, MAX_NMEA_PARAMS); nmeaParser1.PFLAA(t3, params, nr, GPS_INFO); } #endif #endif }
static BOOL PDGFTL1(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS) { /* $PDGFTL1 field example QNE 1013.25 altitude 0 2025 meters QNH altitude 1 2000 meters vario cm/s 2 250 2.5m/s netto vario 3 -14 dm/s IAS 4 45 kmh ground efficiency 5 134 13:4 GR Wind speed 6 28 kmh Wind direction 7 65 degrees Main lithium battery 3,82 v 8 382 0.01v Backup AA battery 1,53 v 9 153 0.01v 100209 Paolo Ventafridda netto and ias optionals */ TCHAR ctemp[80]; double vtas, vias; double altqne, altqnh; static bool initqnh=true; NMEAParser::ExtractParameter(String,ctemp,0); altqne = StrToDouble(ctemp,NULL); NMEAParser::ExtractParameter(String,ctemp,1); altqnh = StrToDouble(ctemp,NULL); // AutoQNH will take care of setting an average QNH if nobody does it for a while if (initqnh) { // if digifly has qnh set by user qne and qnh are of course different if (altqne != altqnh) { UpdateQNH(FindQNH(altqne,altqnh)); StartupStore(_T(". Using Digifly QNH %f%s"),QNH,NEWLINE); initqnh=false; } else { // if locally QNH was set, either by user of by AutoQNH, stop processing QNH from digifly if ( (QNH <= 1012) || (QNH>=1014)) initqnh=false; // else continue entering initqnh until somebody changes qnh in either digifly or lk8000 } } UpdateBaroSource( pGPS,0, d, AltitudeToQNHAltitude(altqne)); NMEAParser::ExtractParameter(String,ctemp,2); #if 1 pGPS->Vario = StrToDouble(ctemp,NULL)/100; #else double newVario = StrToDouble(ctemp,NULL)/100; pGPS->Vario = LowPassFilter(pGPS->Vario,newVario,0.1); #endif pGPS->VarioAvailable = TRUE; NMEAParser::ExtractParameter(String,ctemp,3); if (ctemp[0] != '\0') { pGPS->NettoVario = StrToDouble(ctemp,NULL)/10; // dm/s pGPS->NettoVarioAvailable = TRUE; } else pGPS->NettoVarioAvailable = FALSE; NMEAParser::ExtractParameter(String,ctemp,4); if (ctemp[0] != '\0') { // we store m/s , so we convert it from kmh vias = StrToDouble(ctemp,NULL)/3.6; if (vias >1) { vtas = vias*AirDensityRatio(altqne); pGPS->TrueAirspeed = vtas; pGPS->IndicatedAirspeed = vias; pGPS->AirspeedAvailable = TRUE; } } else { pGPS->AirspeedAvailable = FALSE; } NMEAParser::ExtractParameter(String,ctemp,8); pGPS->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)/100; NMEAParser::ExtractParameter(String,ctemp,9); pGPS->ExtBatt2_Voltage = StrToDouble(ctemp,NULL)/100; TriggerVarioUpdate(); return TRUE; }
// // Support for new 2011 Digifly TOURTELL protocol // (Subset of TL1, pending upgrade in june 2011 for all devices) // static BOOL PDGFTTL(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS) { /* $PDGFTTL field example QNE 1013.25 altitude 0 2025 meters QNH altitude 1 2000 meters vario cm/s 2 250 2.5m/s IAS 4 45 kmh netto vario 3 -14 dm/s */ TCHAR ctemp[80]; double vtas, vias; double altqne, altqnh; static bool initqnh=true; NMEAParser::ExtractParameter(String,ctemp,0); altqne = StrToDouble(ctemp,NULL); NMEAParser::ExtractParameter(String,ctemp,1); altqnh = StrToDouble(ctemp,NULL); // AutoQNH will take care of setting an average QNH if nobody does it for a while if (initqnh) { // if digifly has qnh set by user qne and qnh are of course different if (altqne != altqnh) { QNH=FindQNH(altqne,altqnh); CAirspaceManager::Instance().QnhChangeNotify(QNH); StartupStore(_T(". Using Digifly QNH %f%s"),QNH,NEWLINE); initqnh=false; } else { // if locally QNH was set, either by user of by AutoQNH, stop processing QNH from digifly if ( (QNH <= 1012) || (QNH>=1014)) initqnh=false; // else continue entering initqnh until somebody changes qnh in either digifly or lk8000 } } UpdateBaroSource( pGPS, 0,d, AltitudeToQNHAltitude(altqne)); NMEAParser::ExtractParameter(String,ctemp,2); #if 1 pGPS->Vario = StrToDouble(ctemp,NULL)/100; #else double newVario = StrToDouble(ctemp,NULL)/100; pGPS->Vario = LowPassFilter(pGPS->Vario,newVario,0.1); #endif pGPS->VarioAvailable = TRUE; NMEAParser::ExtractParameter(String,ctemp,4); if (ctemp[0] != '\0') { pGPS->NettoVario = StrToDouble(ctemp,NULL)/10; // dm/s pGPS->NettoVarioAvailable = TRUE; } else pGPS->NettoVarioAvailable = FALSE; NMEAParser::ExtractParameter(String,ctemp,4); if (ctemp[0] != '\0') { // we store m/s , so we convert it from kmh vias = StrToDouble(ctemp,NULL)/3.6; if (vias >1) { vtas = vias*AirDensityRatio(pGPS->BaroAltitude); pGPS->TrueAirspeed = vtas; pGPS->IndicatedAirspeed = vias; pGPS->AirspeedAvailable = TRUE; } } else { pGPS->AirspeedAvailable = FALSE; } TriggerVarioUpdate(); return TRUE; }
void DoAutoQNH(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { static int done_autoqnh = 0; if (DoInit[MDI_DOAUTOQNH]) { done_autoqnh=0; DoInit[MDI_DOAUTOQNH]=false; } // Reject if already done if (done_autoqnh==10) return; // Reject if in IGC logger mode if (ReplayLogger::IsEnabled()) return; // Reject if no valid GPS fix if (Basic->NAVWarning) return; // Reject if no baro altitude if (!Basic->BaroAltitudeAvailable) return; // Reject if terrain height is invalid if (!Calculated->TerrainValid) return; if (QNH != 1013.25) return; if (Basic->Speed<TakeOffSpeedThreshold) { done_autoqnh++; } else { done_autoqnh= 0; // restart... } if (done_autoqnh==10) { double fixaltitude = Calculated->TerrainAlt; // if we have a valid fix, and a valid home waypoint, then if we are close to it assume we are at home // and use known altitude, instead of presumed terrain altitude which is always approximated double hdist=0; if (ValidWayPoint(HomeWaypoint)) { DistanceBearing(Basic->Latitude, Basic->Longitude, WayPointList[HomeWaypoint].Latitude, WayPointList[HomeWaypoint].Longitude,&hdist,NULL); if (hdist <2000) { fixaltitude=WayPointList[HomeWaypoint].Altitude; StartupStore(_T(". AutoQNH: setting QNH to HOME waypoint altitude=%.0f m%s"),fixaltitude,NEWLINE); } else { if (fixaltitude!=0) StartupStore(_T(". AutoQNH: setting QNH to average terrain altitude=%.0f m%s"),fixaltitude,NEWLINE); else StartupStore(_T(". AutoQNH: cannot set QNH, impossible terrain altitude%s"),NEWLINE); } } else { // 101121 extend search for nearest wp int i=FindNearestWayPoint(Basic->Longitude, Basic->Latitude, 2000); if ( (i>RESWP_END) && (WayPointList[i].Altitude>0) ) { // avoid using TAKEOFF wp fixaltitude=WayPointList[i].Altitude; #if ALPHADEBUG StartupStore(_T(". AutoQNH: setting QNH to nearest <%s> waypoint altitude=%.0f m%s"), WayPointList[i].Name,fixaltitude,NEWLINE); #endif } else { #if ALPHADEBUG if (fixaltitude!=0) StartupStore(_T(". AutoQNH: setting QNH to average terrain altitude=%.0f m%s"),fixaltitude,NEWLINE); else StartupStore(_T(". AutoQNH: cannot set QNH, impossible terrain altitude%s"),NEWLINE); #endif } } if (fixaltitude!=0) { QNH = FindQNH(Basic->BaroAltitude, fixaltitude); TCHAR qmes[80]; if (PressureHg) _stprintf(qmes,_T("QNH set to %.2f, Altitude %.0f%s"),QNH/TOHPA,fixaltitude, Units::GetUnitName(Units::GetUserAltitudeUnit())); else _stprintf(qmes,_T("QNH set to %.2f, Altitude %.0f%s"),QNH,fixaltitude, Units::GetUnitName(Units::GetUserAltitudeUnit())); DoStatusMessage(qmes); CAirspaceManager::Instance().QnhChangeNotify(QNH); } } }
static BOOL PWES0(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS) { /* Sent by Westerboer VW1150 combining data stream from Flarm and VW1020. RMZ is being sent too, which is a problem. $PWES0,22,10,8,18,17,6,1767,1804,1073,1073,116,106 A B C D E F G H I J K L A Device 21 = VW1000, 21 = VW 1010, 22 = VW1020, 23 = VW1030 B vario *10 = 2.2 m/s C average vario *10 = 1.0 m/s D netto vario *10 = 1.8 m/s E average netto vario *10 = 1.7 m/s F stf = -999.. 999 (neg faster.. slower) G baro altitude = 1767 m H baro altitude calibrated by user? I IAS kmh *10 = 107.3 kmh J TAS kmh *10 ? K battery V *10 = 11.6 V L OAT * 10 = 10.6 C */ TCHAR ctemp[180]; double vtas, vias; double altqne, altqnh; static bool initqnh=true; #ifdef DEVICE_SERIAL static int NoMsg =0; // static int HardwareId = 0; if(_tcslen(String) < 180) if(((pGPS->SerialNumber == 0) || (oldSerial != SerialNumber)) && (NoMsg < 5)) { NoMsg++ ; NMEAParser::ExtractParameter(String,ctemp,0); pGPS->HardwareId= (int)StrToDouble(ctemp,NULL); switch (pGPS->HardwareId) { case 21: _tcscpy(d->Name, TEXT("VW1010")); break; case 22: _tcscpy(d->Name, TEXT("VW1020")); break; case 23: _tcscpy(d->Name, TEXT("VW1030")); break; default: _tcscpy(d->Name, TEXT("Westerboer")); break; } StartupStore(_T(". %s\n"),ctemp); _stprintf(ctemp, _T("%s DETECTED"), d->Name); oldSerial = pGPS->SerialNumber; DoStatusMessage(ctemp); StartupStore(_T(". %s\n"),ctemp); } #endif // instant vario NMEAParser::ExtractParameter(String,ctemp,1); pGPS->Vario = StrToDouble(ctemp,NULL)/10; pGPS->VarioAvailable = TRUE; // netto vario NMEAParser::ExtractParameter(String,ctemp,3); if (ctemp[0] != '\0') { pGPS->NettoVario = StrToDouble(ctemp,NULL)/10; pGPS->NettoVarioAvailable = TRUE; } else pGPS->NettoVarioAvailable = FALSE; // Baro altitudes. To be verified, because I have no docs from Westerboer of any kind. NMEAParser::ExtractParameter(String,ctemp,6); altqne = StrToDouble(ctemp,NULL); NMEAParser::ExtractParameter(String,ctemp,7); altqnh = StrToDouble(ctemp,NULL); // AutoQNH will take care of setting an average QNH if nobody does it for a while if (initqnh) { // if wester has qnh set by user qne and qnh are of course different if (altqne != altqnh) { QNH=FindQNH(altqne,altqnh); CAirspaceManager::Instance().QnhChangeNotify(QNH); StartupStore(_T(". Using WESTERBOER QNH %f%s"),QNH,NEWLINE); initqnh=false; } else { // if locally QNH was set, either by user of by AutoQNH, stop processing QNH from Wester if ( (QNH <= 1012) || (QNH>=1014)) initqnh=false; // else continue entering initqnh until somebody changes qnh in either Wester or lk8000 } } UpdateBaroSource( pGPS, 0,d, AltitudeToQNHAltitude(altqne)); // IAS and TAS NMEAParser::ExtractParameter(String,ctemp,8); vias = StrToDouble(ctemp,NULL)/36; NMEAParser::ExtractParameter(String,ctemp,9); vtas = StrToDouble(ctemp,NULL)/36; if (vias >1) { pGPS->TrueAirspeed = vtas; pGPS->IndicatedAirspeed = vias; pGPS->AirspeedAvailable = TRUE; } else pGPS->AirspeedAvailable = FALSE; // external battery voltage NMEAParser::ExtractParameter(String,ctemp,10); pGPS->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)/10; // OAT NMEAParser::ExtractParameter(String,ctemp,11); pGPS->OutsideAirTemperature = StrToDouble(ctemp,NULL)/10; pGPS->TemperatureAvailable=TRUE; TriggerVarioUpdate(); return TRUE; }