X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FInstrumentation%2Fdclgps.cxx;h=42157d7a1836ffcde8db0f510c4b7c97977b24eb;hb=15724a6a446317f83d429670ebb0e2204c72bdb5;hp=92dcb21325bb442152701d02cf6d311005f281ed;hpb=ca7f9dec76e37537f253e14599d6e0367877f41a;p=flightgear.git diff --git a/src/Instrumentation/dclgps.cxx b/src/Instrumentation/dclgps.cxx index 92dcb2132..42157d7a1 100644 --- a/src/Instrumentation/dclgps.cxx +++ b/src/Instrumentation/dclgps.cxx @@ -152,12 +152,6 @@ DCLGPS::DCLGPS(RenderArea2D* instrument) { _instrument = instrument; _nFields = 1; _maxFields = 2; - - // Units - lets default to US units - FG can set them to other units from config during startup if desired. - _altUnits = GPS_ALT_UNITS_FT; - _baroUnits = GPS_PRES_UNITS_IN; - _velUnits = GPS_VEL_UNITS_KT; - _distUnits = GPS_DIST_UNITS_NM; _lon_node = fgGetNode("/instrumentation/gps/indicated-longitude-deg", true); _lat_node = fgGetNode("/instrumentation/gps/indicated-latitude-deg", true); @@ -211,8 +205,6 @@ DCLGPS::DCLGPS(RenderArea2D* instrument) { // Configuration Initialisation // Should this be in kln89.cxx ? _turnAnticipationEnabled = false; - _suaAlertEnabled = false; - _altAlertEnabled = false; _time = new SGTime; @@ -247,22 +239,18 @@ void DCLGPS::init() { } void DCLGPS::bind() { - fgTie("/instrumentation/gps/waypoint-alert", this, &DCLGPS::GetWaypointAlert); - fgTie("/instrumentation/gps/leg-mode", this, &DCLGPS::GetLegMode); - fgTie("/instrumentation/gps/obs-mode", this, &DCLGPS::GetOBSMode); - fgTie("/instrumentation/gps/approach-arm", this, &DCLGPS::GetApproachArm); - fgTie("/instrumentation/gps/approach-active", this, &DCLGPS::GetApproachActive); - fgTie("/instrumentation/gps/cdi-deflection", this, &DCLGPS::GetCDIDeflection); - fgTie("/instrumentation/gps/to-flag", this, &DCLGPS::GetToFlag); + _tiedProperties.setRoot(fgGetNode("/instrumentation/gps", true)); + _tiedProperties.Tie("waypoint-alert", this, &DCLGPS::GetWaypointAlert); + _tiedProperties.Tie("leg-mode", this, &DCLGPS::GetLegMode); + _tiedProperties.Tie("obs-mode", this, &DCLGPS::GetOBSMode); + _tiedProperties.Tie("approach-arm", this, &DCLGPS::GetApproachArm); + _tiedProperties.Tie("approach-active", this, &DCLGPS::GetApproachActive); + _tiedProperties.Tie("cdi-deflection", this, &DCLGPS::GetCDIDeflection); + _tiedProperties.Tie("to-flag", this, &DCLGPS::GetToFlag); } void DCLGPS::unbind() { - fgUntie("/instrumentation/gps/waypoint-alert"); - fgUntie("/instrumentation/gps/leg-mode"); - fgUntie("/instrumentation/gps/obs-mode"); - fgUntie("/instrumentation/gps/approach-arm"); - fgUntie("/instrumentation/gps/approach-active"); - fgUntie("/instrumentation/gps/cdi-deflection"); + _tiedProperties.Untie(); } void DCLGPS::update(double dt) { @@ -491,8 +479,7 @@ void DCLGPS::update(double dt) { _fromWaypoint = _activeWaypoint; _activeWaypoint = *_activeFP->waypoints[idx + 1]; _dto = false; - // TODO - course alteration message format is dependent on whether we are slaved HSI/CDI indicator or not. - // For now assume we are not. + // Course alteration message format is dependent on whether we are slaved HSI/CDI indicator or not. string s; if(fgGetBool("/instrumentation/nav[0]/slaved-to-gps")) { // TODO - avoid the hardwiring on nav[0] @@ -601,7 +588,8 @@ string DCLGPS::ExpandSIAPIdent(const string& ident) { } /* - Load instrument approaches from an ARINC 424-18 file. + Load instrument approaches from an ARINC 424 file. + Tested on ARINC 424-18. Known / current best guess at the format: Col 1: Always 'S'. If it isn't, ditch it. Col 2-4: "Customer area" code, eg "USA", "CAN". I think that CAN is used for Alaska. @@ -662,7 +650,7 @@ string DCLGPS::ExpandSIAPIdent(const string& ident) { Col 107-111 MSA center fix. We can ignore this. */ void DCLGPS::LoadApproachData() { - FGNPIAP* iap; + FGNPIAP* iap = NULL; GPSWaypoint* wp; GPSFlightPlan* fp; const GPSWaypoint* cwp; @@ -672,10 +660,10 @@ void DCLGPS::LoadApproachData() { path.append("Navaids/rnav.dat"); fin.open(path.c_str(), ios::in); if(!fin) { - cout << "Unable to open input file " << path.c_str() << '\n'; + //cout << "Unable to open input file " << path.c_str() << '\n'; return; } else { - cout << "Opened " << path.c_str() << " for reading\n"; + //cout << "Opened " << path.c_str() << " for reading\n"; } char tmp[256]; string s; @@ -726,7 +714,7 @@ void DCLGPS::LoadApproachData() { if(last_apt_ident != apt_ident) { if(iap_in_progress) { if(iap_error) { - cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; + //cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; nErrors++; } else { _np_iap[iap->_aptIdent].push_back(iap); @@ -756,7 +744,7 @@ void DCLGPS::LoadApproachData() { // This is a new approach - store the last one and trigger // starting afresh by setting the in progress flag to false. if(iap_error) { - cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; + //cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; nErrors++; } else { _np_iap[iap->_aptIdent].push_back(iap); @@ -803,13 +791,21 @@ void DCLGPS::LoadApproachData() { // Note: Currently fgFindAirportID returns NULL on error, but getRunwayByIdent throws an exception. const FGAirport* apt = fgFindAirportID(iap->_aptIdent); if(apt) { + string rwystr; try { - // TODO - sanity check the waypoint ID to ensure we have a double digit number - FGRunway* rwy = apt->getRunwayByIdent(w.id.substr(2, 2)); + rwystr = w.id.substr(2, 2); + // TODO - sanity check the rwystr at this point to ensure we have a double digit number + if(w.id.size() > 4) { + if(w.id[4] == 'L' || w.id[4] == 'C' || w.id[4] == 'R') { + rwystr += w.id[4]; + } + } + FGRunway* rwy = apt->getRunwayByIdent(rwystr); w.lat = rwy->begin().getLatitudeRad(); w.lon = rwy->begin().getLongitudeRad(); } catch(const sg_exception&) { - SG_LOG(SG_GENERAL, SG_WARN, "Unable to find runway " << w.id.substr(2, 2) << " at airport " << iap->_aptIdent); + SG_LOG(SG_INSTR, SG_WARN, "Unable to find runway " << w.id.substr(2, 2) << " at airport " << iap->_aptIdent); + //cout << "Unable to find runway " << w.id.substr(2, 2) << " at airport " << iap->_aptIdent << " ( w.id = " << w.id << ", rwystr = " << rwystr << " )\n"; wp_error = true; } } else { @@ -850,7 +846,7 @@ void DCLGPS::LoadApproachData() { if(iap->_IAP[iap->_IAP.size() - 1]->appType == GPS_APP_NONE) { iap->_IAP[iap->_IAP.size() - 1]->appType = GPS_MAHP; } else { - cout << "Waypoint is MAHP and another type! " << w.id << " [" << apt_ident << ", " << iap_ident << "]\n"; + //cout << "Waypoint is MAHP and another type! " << w.id << " [" << apt_ident << ", " << iap_ident << "]\n"; } } } @@ -922,7 +918,7 @@ void DCLGPS::LoadApproachData() { // This is a new approach - store the last one and trigger // starting afresh by setting the in progress flag to false. if(iap_error) { - cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; + //cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; nErrors++; } else { _np_iap[iap->_aptIdent].push_back(iap); @@ -940,7 +936,7 @@ void DCLGPS::LoadApproachData() { // TODO - sanity check that the approach has all the required elements if(iap_in_progress) { if(iap_error) { - cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; + //cout << "ERROR: Unable to load approach " << iap->_ident << " at " << iap->_aptIdent << '\n'; nErrors++; } else { _np_iap[iap->_aptIdent].push_back(iap); @@ -949,9 +945,9 @@ void DCLGPS::LoadApproachData() { } } - cout << "Done loading approach database\n"; - cout << "Loaded: " << nLoaded << '\n'; - cout << "Failed: " << nErrors << '\n'; + //cout << "Done loading approach database\n"; + //cout << "Loaded: " << nLoaded << '\n'; + //cout << "Failed: " << nErrors << '\n'; fin.close(); } @@ -1003,7 +999,7 @@ void DCLGPS::DtoInitiate(const string& s) { _fromWaypoint.lat = _gpsLat; _fromWaypoint.lon = _gpsLon; _fromWaypoint.type = GPS_WP_VIRT; - _fromWaypoint.id = "DTOWP"; + _fromWaypoint.id = "_DTOWP_"; delete wp; } else { // TODO - Should bring up the user waypoint page. @@ -1023,9 +1019,37 @@ void DCLGPS::DtoCancel() { void DCLGPS::ToggleOBSMode() { _obsMode = !_obsMode; if(_obsMode) { - if(!_activeWaypoint.id.empty()) { - _obsHeading = static_cast(_dtkMag); + // We need to set the OBS heading. The rules for this are: + // + // If the KLN89 is connected to an external HSI or CDI, then the OBS heading must be set + // to the OBS radial on the external indicator, and cannot be changed in the KLN89. + // + // If the KLN89 is not connected to an external indicator, then: + // If there is an active waypoint, the OBS heading is set such that the + // deviation indicator remains at the same deviation (i.e. set to DTK, + // although there may be some small difference). + // + // If there is not an active waypoint, I am not sure what value should be + // set. + // + if(fgGetBool("/instrumentation/nav/slaved-to-gps")) { + _obsHeading = static_cast(fgGetDouble("/instrumentation/nav/radials/selected-deg") + 0.5); + } else if(!_activeWaypoint.id.empty()) { + // NOTE: I am not sure if this is completely correct. There are sometimes small differences + // between DTK and default OBS heading in the simulator (~ 1 or 2 degrees). It might also + // be that OBS heading should be stored as float and only displayed as int, in order to maintain + // the initial bar deviation? + _obsHeading = static_cast(_dtkMag + 0.5); + //cout << "_dtkMag = " << _dtkMag << ", _dtkTrue = " << _dtkTrue << ", _obsHeading = " << _obsHeading << '\n'; + } else { + // TODO - what should we really do here? + _obsHeading = 0; } + + // Valid OBS heading values are 0 -> 359 degrees inclusive (from kln89 simulator). + if(_obsHeading > 359) _obsHeading -= 360; + if(_obsHeading < 0) _obsHeading += 360; + // TODO - the _fromWaypoint location will change as the OBS heading changes. // Might need to store the OBS initiation position somewhere in case it is needed again. SetOBSFromWaypoint(); @@ -1039,7 +1063,8 @@ void DCLGPS::SetOBSFromWaypoint() { // TODO - base the 180 deg correction on the to/from flag. _fromWaypoint = GetPositionOnMagRadial(_activeWaypoint, 10, _obsHeading + 180.0); - _fromWaypoint.id = "OBSWP"; + _fromWaypoint.type = GPS_WP_VIRT; + _fromWaypoint.id = "_OBSWP_"; } void DCLGPS::CDIFSDIncrease() { @@ -1063,16 +1088,6 @@ void DCLGPS::DrawChar(char c, int field, int px, int py, bool bold) { void DCLGPS::DrawText(const string& s, int field, int px, int py, bool bold) { } -void DCLGPS::SetBaroUnits(int n, bool wrap) { - if(n < 1) { - _baroUnits = (GPSPressureUnits)(wrap ? 3 : 1); - } else if(n > 3) { - _baroUnits = (GPSPressureUnits)(wrap ? 1 : 3); - } else { - _baroUnits = (GPSPressureUnits)n; - } -} - void DCLGPS::CreateDefaultFlightPlans() {} // Get the time to the active waypoint in seconds.