wpn->getChild("eta", 0, true);
_route->clear();
+ _route->set_current(0);
update_mirror();
_pathNode = fgGetNode(RM "file-path", 0, true);
aProp->setStringValue( eta_str );
}
-void FGRouteMgr::add_waypoint( const SGWayPoint& wp, int n ) {
+void FGRouteMgr::add_waypoint( const SGWayPoint& wp, int n )
+{
_route->add_waypoint( wp, n );
- if (_route->current_index() > n) {
+ if ((n >= 0) && (_route->current_index() > n)) {
_route->set_current(_route->current_index() + 1);
}
+ waypointsChanged();
+}
+
+void FGRouteMgr::waypointsChanged()
+{
+ double routeDistanceNm = _route->total_distance() * SG_METER_TO_NM;
+ totalDistance->setDoubleValue(routeDistanceNm);
+ double cruiseSpeedKts = cruise->getDoubleValue("speed", 0.0);
+ if (cruiseSpeedKts > 1.0) {
+ // very very crude approximation, doesn't allow for climb / descent
+ // performance or anything else at all
+ ete->setDoubleValue(routeDistanceNm / cruiseSpeedKts * (60.0 * 60.0));
+ }
+
update_mirror();
_edited->fireValueChanged();
+ checkFinished();
}
-
SGWayPoint FGRouteMgr::pop_waypoint( int n ) {
if ( _route->size() <= 0 ) {
return SGWayPoint();
SGWayPoint wp = _route->get_waypoint(n);
_route->delete_waypoint(n);
- update_mirror();
- _edited->fireValueChanged();
- checkFinished();
-
+ waypointsChanged();
return wp;
}
SGWayPoint* FGRouteMgr::make_waypoint(const string& tgt ) {
string target(boost::to_upper_copy(tgt));
- // extract altitude
- double alt = cruise->getDoubleValue("altitude-ft") * SG_FEET_TO_METER;
+ double alt = -9999.0;
+ // extract altitude
size_t pos = target.find( '@' );
if ( pos != string::npos ) {
alt = atof( target.c_str() + pos + 1 );
void FGRouteMgr::InputListener::valueChanged(SGPropertyNode *prop)
{
const char *s = prop->getStringValue();
+ if (strlen(s) == 0) {
+ return;
+ }
+
if (!strcmp(s, "@CLEAR"))
mgr->init();
else if (!strcmp(s, "@ACTIVATE"))
mgr->loadRoute();
} else if (!strcmp(s, "@SAVE")) {
mgr->saveRoute();
- } else if (!strcmp(s, "@POP"))
- mgr->pop_waypoint(0);
- else if (!strncmp(s, "@DELETE", 7))
+ } else if (!strcmp(s, "@POP")) {
+ SG_LOG(SG_AUTOPILOT, SG_WARN, "route-manager @POP command is deprecated");
+ } else if (!strcmp(s, "@NEXT")) {
+ mgr->jumpToIndex(mgr->currentWaypoint() + 1);
+ } else if (!strcmp(s, "@PREVIOUS")) {
+ mgr->jumpToIndex(mgr->currentWaypoint() - 1);
+ } else if (!strncmp(s, "@JUMP", 5)) {
+ mgr->jumpToIndex(atoi(s + 5));
+ } else if (!strncmp(s, "@DELETE", 7))
mgr->pop_waypoint(atoi(s + 7));
else if (!strncmp(s, "@INSERT", 7)) {
char *r;
bool FGRouteMgr::activate()
{
- if (_departure) {
+ if (isRouteActive()) {
+ SG_LOG(SG_AUTOPILOT, SG_WARN, "duplicate route-activation, no-op");
+ return false;
+ }
+
+ // only add departure waypoint if we're not airborne, so that
+ // in-air route activation doesn't confuse matters.
+ if (weightOnWheels->getBoolValue() && _departure) {
string runwayId(departure->getStringValue("runway"));
FGRunway* runway = NULL;
if (_departure->hasRunwayWithIdent(runwayId)) {
}
_route->set_current(0);
-
- double routeDistanceNm = _route->total_distance() * SG_METER_TO_NM;
- totalDistance->setDoubleValue(routeDistanceNm);
- double cruiseSpeedKts = cruise->getDoubleValue("speed", 0.0);
- if (cruiseSpeedKts > 1.0) {
- // very very crude approximation, doesn't allow for climb / descent
- // performance or anything else at all
- ete->setDoubleValue(routeDistanceNm / cruiseSpeedKts * (60.0 * 60.0));
- }
-
active->setBoolValue(true);
SG_LOG(SG_AUTOPILOT, SG_INFO, "route-manager, activate route ok");
return true;
void FGRouteMgr::jumpToIndex(int index)
{
- if (!active->getBoolValue()) {
- SG_LOG(SG_AUTOPILOT, SG_ALERT, "trying to sequence waypoints with no active route");
- return;
- }
-
if ((index < 0) || (index >= _route->size())) {
SG_LOG(SG_AUTOPILOT, SG_ALERT, "passed invalid index (" <<
index << ") to FGRouteMgr::jumpToIndex");
return _route->current_index();
}
+void FGRouteMgr::setWaypointTargetAltitudeFt(unsigned int index, int altFt)
+{
+ SGWayPoint wp = _route->get_waypoint(index);
+ wp.setTargetAltFt(altFt);
+ // simplest way to update a waypoint is to remove and re-add it
+ _route->delete_waypoint(index);
+ _route->add_waypoint(wp, index);
+ waypointsChanged();
+}
+
void FGRouteMgr::saveRoute()
{
SGPath path(_pathNode->getStringValue());
}
SGPropertyNode_ptr altProp = aWP->getChild("altitude-ft");
- double alt = cruise->getDoubleValue("altitude-ft") * SG_FEET_TO_METER;
+ double altM = cruise->getDoubleValue("altitude-ft") * SG_FEET_TO_METER;
if (altProp) {
- alt = altProp->getDoubleValue();
+ altM = altProp->getDoubleValue() * SG_FEET_TO_METER;
}
string ident(aWP->getStringValue("ident"));
if (aWP->hasChild("longitude-deg")) {
// explicit longitude/latitude
SGWayPoint swp(aWP->getDoubleValue("longitude-deg"),
- aWP->getDoubleValue("latitude-deg"), alt,
+ aWP->getDoubleValue("latitude-deg"), altM,
SGWayPoint::WGS84, ident, aWP->getStringValue("name"));
add_waypoint(swp);
} else if (aWP->hasChild("navid")) {
SGGeodesy::direct(p->geod(), radialDeg, offsetNm * SG_NM_TO_METER, pos, az2);
}
- SGWayPoint swp(pos.getLongitudeDeg(), pos.getLatitudeDeg(), alt,
+ SGWayPoint swp(pos.getLongitudeDeg(), pos.getLatitudeDeg(), altM,
SGWayPoint::WGS84, ident, "");
add_waypoint(swp);
} else {
throw sg_io_exception("bad route file, unknown waypoint:" + ident);
}
- SGWayPoint swp(p->longitude(), p->latitude(), alt,
+ SGWayPoint swp(p->longitude(), p->latitude(), altM,
SGWayPoint::WGS84, p->ident(), p->name());
add_waypoint(swp);
}
void FGRouteMgr::setDepartureICAO(const char* aIdent)
{
- _departure = FGAirport::findByIdent(aIdent);
+ if ((aIdent == NULL) || (strlen(aIdent) < 4)) {
+ _departure = NULL;
+ } else {
+ _departure = FGAirport::findByIdent(aIdent);
+ }
}
const char* FGRouteMgr::getDestinationICAO() const
void FGRouteMgr::setDestinationICAO(const char* aIdent)
{
- _destination = FGAirport::findByIdent(aIdent);
+ if ((aIdent == NULL) || (strlen(aIdent) < 4)) {
+ _destination = NULL;
+ } else {
+ _destination = FGAirport::findByIdent(aIdent);
+ }
}