GPS::GPS ( SGPropertyNode *node) :
_selectedCourse(0.0),
+ _desiredCourse(0.0),
_dataValid(false),
_lastPosValid(false),
_mode("init"),
_trip_odometer_node = _gpsNode->getChild("trip-odometer", 0, true);
_true_bug_error_node = _gpsNode->getChild("true-bug-error-deg", 0, true);
_magnetic_bug_error_node = _gpsNode->getChild("magnetic-bug-error-deg", 0, true);
+ _eastWestVelocity = _gpsNode->getChild("ew-velocity-msec", 0, true);
+ _northSouthVelocity = _gpsNode->getChild("ns-velocity-msec", 0, true);
// waypoints
SGPropertyNode *wp_node = _gpsNode->getChild("wp", 0, true);
fromFlag->alias(wp1_node->getChild("from-flag"));
// autopilot drive properties
+ _apDrivingFlag = fgGetNode("/autopilot/settings/gps-driving-true-heading", true);
_apTrueHeading = fgGetNode("/autopilot/settings/true-heading-deg",true);
_apTargetAltitudeFt = fgGetNode("/autopilot/settings/target-altitude-ft", true);
_apAltitudeLock = fgGetNode("/autopilot/locks/altitude", true);
_indicated_pos = SGGeod();
_last_vertical_speed = 0.0;
_last_true_track = 0.0;
+ _lastEWVelocity = _lastNSVelocity = 0.0;
_raim_node->setDoubleValue(0.0);
_indicated_pos = SGGeod();
_tracking_bug_node->setDoubleValue(0);
_true_bug_error_node->setDoubleValue(0);
_magnetic_bug_error_node->setDoubleValue(0);
+ _northSouthVelocity->setDoubleValue(0.0);
+ _eastWestVelocity->setDoubleValue(0.0);
}
void
double vertical_speed_mpm = ((_indicated_pos.getElevationM() - _last_pos.getElevationM()) * 60 / dt);
_last_vertical_speed = vertical_speed_mpm * SG_METER_TO_FEET;
- speed_kt = fgGetLowPass(_last_speed_kts, speed_kt, dt/20.0);
+ speed_kt = fgGetLowPass(_last_speed_kts, speed_kt, dt/10.0);
_last_speed_kts = speed_kt;
+ SGGeod g = _indicated_pos;
+ g.setLongitudeDeg(_last_pos.getLongitudeDeg());
+ double northSouthM = SGGeodesy::distanceM(_last_pos, g);
+ northSouthM = copysign(northSouthM, _indicated_pos.getLatitudeDeg() - _last_pos.getLatitudeDeg());
+
+ double nsMSec = fgGetLowPass(_lastNSVelocity, northSouthM / dt, dt/2.0);
+ _lastNSVelocity = nsMSec;
+ _northSouthVelocity->setDoubleValue(nsMSec);
+
+
+ g = _indicated_pos;
+ g.setLatitudeDeg(_last_pos.getLatitudeDeg());
+ double eastWestM = SGGeodesy::distanceM(_last_pos, g);
+ eastWestM = copysign(eastWestM, _indicated_pos.getLongitudeDeg() - _last_pos.getLongitudeDeg());
+
+ double ewMSec = fgGetLowPass(_lastEWVelocity, eastWestM / dt, dt/2.0);
+ _lastEWVelocity = ewMSec;
+ _eastWestVelocity->setDoubleValue(ewMSec);
+
double odometer = _odometer_node->getDoubleValue();
_odometer_node->setDoubleValue(odometer + distance_m * SG_METER_TO_NM);
odometer = _trip_odometer_node->getDoubleValue();
void GPS::driveAutopilot()
{
if (!_config.driveAutopilot() || !_realismSimpleGps->getBoolValue()) {
+ _apDrivingFlag->setBoolValue(false);
return;
}
// compatability feature - allow the route-manager / GPS to drive the
// generic autopilot heading hold *in leg mode only*
- if (_mode == "leg") {
+
+ bool drive = _mode == "leg";
+ _apDrivingFlag->setBoolValue(drive);
+
+ if (drive) {
// FIXME: we want to set desired track, not heading, here
_apTrueHeading->setDoubleValue(getWP1Bearing());
}
void GPS::directTo()
{
- if (!isScratchPositionValid()) {
- SG_LOG(SG_INSTR, SG_WARN, "invalid DTO lat/lon");
- return;
+ _wp0_position = _indicated_pos;
+
+ if (isScratchPositionValid()) {
+ _wp1Ident = _scratchNode->getStringValue("ident");
+ _wp1Name = _scratchNode->getStringValue("name");
+ _wp1_position = _scratchPos;
}
- _wp0_position = _indicated_pos;
- _wp1Ident = _scratchNode->getStringValue("ident");
- _wp1Name = _scratchNode->getStringValue("name");
- _wp1_position = _scratchPos;
-
_mode = "dto";
_desiredCourse = getLegMagCourse();
_desiredCourseNode->fireValueChanged();
clearScratch();
-
wp1Changed();
}
void GPS::selectOBSMode()
{
- if (!isScratchPositionValid()) {
- SG_LOG(SG_INSTR, SG_WARN, "invalid OBS lat/lon");
- return;
+ if (isScratchPositionValid()) {
+ _wp1Ident = _scratchNode->getStringValue("ident");
+ _wp1Name = _scratchNode->getStringValue("name");
+ _wp1_position = _scratchPos;
}
SG_LOG(SG_INSTR, SG_INFO, "GPS switching to OBS mode");
_mode = "obs";
-
- _wp1Ident = _scratchNode->getStringValue("ident");
- _wp1Name = _scratchNode->getStringValue("name");
- _wp1_position = _scratchPos;
_wp0_position = _indicated_pos;
wp1Changed();
}