#include "route_mgr.hxx"
+#include <boost/algorithm/string/case_conv.hpp>
+
#include <simgear/misc/strutils.hxx>
#include <simgear/structure/exception.hxx>
FGRouteMgr::FGRouteMgr() :
_route( new SGRoute ),
- _autoSequence(true),
- _driveAutopilot(true),
input(fgGetNode( RM "input", true )),
- mirror(fgGetNode( RM "route", true )),
- altitude_set( false )
+ mirror(fgGetNode( RM "route", true ))
{
listener = new InputListener(this);
input->setStringValue("");
lat = fgGetNode( "/position/latitude-deg", true );
alt = fgGetNode( "/position/altitude-ft", true );
magvar = fgGetNode("/environment/magnetic-variation-deg", true);
-
-// autopilot drive properties
- _apTargetAltitudeFt = fgGetNode( "/autopilot/settings/target-altitude-ft", true );
- _apAltitudeLock = fgGetNode( "/autopilot/locks/altitude", true );
- _apTrueHeading = fgGetNode( "/autopilot/settings/true-heading-deg", true );
- rm->tie("drive-autopilot", SGRawValuePointer<bool>(&_driveAutopilot));
- _driveAutopilot = false;
-
+
departure = fgGetNode(RM "departure", true);
// init departure information from current location
SGGeod pos = SGGeod::fromDegFt(lon->getDoubleValue(), lat->getDoubleValue(), alt->getDoubleValue());
alternate->getChild("runway", 0, true);
cruise = fgGetNode(RM "cruise", true);
- cruise->getChild("altitude", 0, true);
+ cruise->getChild("altitude-ft", 0, true);
+ cruise->setDoubleValue("altitude-ft", 10000.0);
cruise->getChild("flight-level", 0, true);
- cruise->getChild("speed", 0, true);
-
+ cruise->getChild("speed-kts", 0, true);
+ cruise->setDoubleValue("speed-kts", 160.0);
+
totalDistance = fgGetNode(RM "total-distance", true);
totalDistance->setDoubleValue(0.0);
airborne = fgGetNode(RM "airborne", true);
airborne->setBoolValue(false);
-
- rm->tie("auto-sequence", SGRawValuePointer<bool>(&_autoSequence));
-
+
currentWp = fgGetNode(RM "current-wp", true);
currentWp->setIntValue(_route->current_index());
void FGRouteMgr::bind() { }
void FGRouteMgr::unbind() { }
-void FGRouteMgr::updateTargetAltitude() {
- if (_route->current_index() == _route->size()) {
- altitude_set = false;
- return;
- }
-
- SGWayPoint wp = _route->get_current();
- if (wp.get_target().getElevationM() < -9990.0) {
- altitude_set = false;
- return;
- }
-
- altitude_set = true;
-
- if (!_driveAutopilot) {
- return;
- }
-
- _apTargetAltitudeFt->setDoubleValue(wp.get_target().getElevationFt());
-
- if ( !near_ground() ) {
- _apAltitudeLock->setStringValue( "altitude-hold" );
- }
-}
-
bool FGRouteMgr::isRouteActive() const
{
return active->getBoolValue();
wp.CourseAndDistance( lon->getDoubleValue(), lat->getDoubleValue(),
alt->getDoubleValue(), &wp_course, &wp_distance );
- if (_autoSequence && (wp_distance < 2000.0)) {
- double courseDeviation = inboundCourse - wp_course;
- SG_NORMALIZE_RANGE(courseDeviation, -180.0, 180.0);
- if (fabs(courseDeviation) < 90.0) {
- SG_LOG( SG_AUTOPILOT, SG_INFO, "route manager doing sequencing");
- sequence();
- }
- }
-
- if (_driveAutopilot) {
- _apTrueHeading->setDoubleValue(wp_course);
- }
-
// update wp0 / wp1 / wp-last for legacy users
wp0->setDoubleValue("dist", wp_distance * SG_METER_TO_NM);
wp_course -= magvar->getDoubleValue(); // expose magnetic bearing
void FGRouteMgr::add_waypoint( const SGWayPoint& wp, int n ) {
_route->add_waypoint( wp, n );
update_mirror();
- if ((n==0) || (_route->size() == 1)) {
- updateTargetAltitude();
- }
}
_route->delete_waypoint(n);
}
- updateTargetAltitude();
update_mirror();
return wp;
}
SGWayPoint* FGRouteMgr::make_waypoint(const string& tgt ) {
- string target = tgt;
+ string target(boost::to_upper_copy(tgt));
- // make upper case
- for (unsigned int i = 0; i < target.size(); i++) {
- target[i] = toupper(target[i]);
- }
-
// extract altitude
- double alt = -9999.0;
+ double alt = cruise->getDoubleValue("altitude-ft") * SG_FEET_TO_METER;
+
size_t pos = target.find( '@' );
if ( pos != string::npos ) {
alt = atof( target.c_str() + pos + 1 );
return NULL;
}
+ SGGeod geod = SGGeod::fromGeodM(p->geod(), alt);
if (pieces.size() == 1) {
// simple case
- return new SGWayPoint(p->geod(), target, p->name());
+ return new SGWayPoint(geod, target, p->name());
}
if (pieces.size() == 3) {
az2;
radial += magvar->getDoubleValue(); // convert to true bearing
SGGeod offsetPos;
- SGGeodesy::direct(p->geod(), radial, distanceNm * SG_NM_TO_METER, offsetPos, az2);
+ SGGeodesy::direct(geod, radial, distanceNm * SG_NM_TO_METER, offsetPos, az2);
+ offsetPos.setElevationM(alt);
SG_LOG(SG_AUTOPILOT, SG_INFO, "final offset radial is " << radial);
-
- if (alt > -9990) {
- offsetPos.setElevationM(alt);
- } // otherwise use the elevation of navid
return new SGWayPoint(offsetPos, p->ident() + pieces[2], target);
}
}
currentWp->setIntValue(_route->current_index());
- updateTargetAltitude();
SG_LOG(SG_AUTOPILOT, SG_INFO, "route manager, current-wp is now " << _route->current_index());
}