Additional AI Aircraft properties for animation
Add a number of properties set by both AI Traffic and Swift aircraft: gear/gear[0..5]/position-norm surface-positions/flap-pos-norm surface-positions/spoiler-pos-norm surface-positions/speedbrake-pos-norm controls/lighting/beacon controls/lighting/cabin-lights controls/lighting/landing-lights controls/lighting/nav-lights controls/lighting/strobe controls/lighting/taxi-lights Also improve take-off behaviour
This commit is contained in:
parent
06e6883396
commit
51173f32ff
12 changed files with 478 additions and 170 deletions
|
@ -56,7 +56,7 @@ using std::endl;
|
|||
FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
|
||||
/* HOT must be disabled for AI Aircraft,
|
||||
* otherwise traffic detection isn't working as expected.*/
|
||||
FGAIBase(otAircraft, false),
|
||||
FGAIBaseAircraft(),
|
||||
_performance(0)
|
||||
{
|
||||
trafficRef = ref;
|
||||
|
@ -134,7 +134,7 @@ void FGAIAircraft::readFromScenario(SGPropertyNode* scFileNode) {
|
|||
|
||||
|
||||
void FGAIAircraft::bind() {
|
||||
FGAIBase::bind();
|
||||
FGAIBaseAircraft::bind();
|
||||
|
||||
tie("transponder-id",
|
||||
SGRawValueMethods<FGAIAircraft,const char*>(*this,
|
||||
|
@ -169,8 +169,8 @@ void FGAIAircraft::setPerformance(const std::string& acType, const std::string&
|
|||
|
||||
void FGAIAircraft::Run(double dt)
|
||||
{
|
||||
bool outOfSight = false,
|
||||
flightplanActive = true;
|
||||
bool outOfSight = false,
|
||||
flightplanActive = true;
|
||||
updatePrimaryTargetValues(dt, flightplanActive, outOfSight); // target hdg, alt, speed
|
||||
if (outOfSight) {
|
||||
return;
|
||||
|
@ -183,11 +183,8 @@ void FGAIAircraft::setPerformance(const std::string& acType, const std::string&
|
|||
handleATCRequests(dt); // ATC also has a word to say
|
||||
updateSecondaryTargetValues(dt); // target roll, vertical speed, pitch
|
||||
updateActualState(dt);
|
||||
#if 0
|
||||
// 25/11/12 - added but disabled, since setting properties isn't
|
||||
// affecting the AI-model as expected.
|
||||
|
||||
updateModelProperties(dt);
|
||||
#endif
|
||||
|
||||
// We currently have one situation in which an AIAircraft object is used that is not attached to the
|
||||
// AI manager. In this particular case, the AIAircraft is used to shadow the user's aircraft's behavior in the AI world.
|
||||
|
@ -195,7 +192,7 @@ void FGAIAircraft::setPerformance(const std::string& acType, const std::string&
|
|||
// enough
|
||||
if (manager){
|
||||
UpdateRadar(manager);
|
||||
invisible = !manager->isVisible(pos);
|
||||
invisible = !manager->isVisible(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,27 +369,52 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
|||
fp->setLeadDistance(tgt_speed, tgt_heading, curr, next);
|
||||
}
|
||||
|
||||
// Calculate a target altitude for any leg in which at least one waypoint is in the air.
|
||||
|
||||
if (!(prev->getOn_ground())) // only update the tgt altitude from flightplan if not on the ground
|
||||
{
|
||||
tgt_altitude_ft = prev->getAltitude();
|
||||
if (prev->getInAir() && curr->getInAir()) {
|
||||
// Completely in-air leg, so calculate the target altitude and VS.
|
||||
if (curr->getCrossat() > -1000.0) {
|
||||
use_perf_vs = false;
|
||||
// Distance to go in meters
|
||||
double vert_dist_ft = curr->getCrossat() - altitude_ft;
|
||||
double err_dist = prev->getCrossat() - altitude_ft;
|
||||
double dist_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
double vert_dist_ft = curr->getCrossat() - altitude_ft;
|
||||
double err_dist = prev->getCrossat() - altitude_ft;
|
||||
tgt_vs = calcVerticalSpeed(vert_dist_ft, dist_m, speed, err_dist);
|
||||
|
||||
tgt_altitude_ft = curr->getCrossat();
|
||||
checkTcas();
|
||||
tgt_altitude_ft = curr->getCrossat();
|
||||
} else {
|
||||
use_perf_vs = true;
|
||||
tgt_altitude_ft = prev->getCrossat();
|
||||
}
|
||||
} else if (curr->getInAir()) {
|
||||
// Take-off leg (prev is on ground)
|
||||
if (curr->getCrossat() > -1000.0) {
|
||||
// Altitude restriction
|
||||
use_perf_vs = false;
|
||||
double dist_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
double vert_dist_ft = curr->getCrossat() - altitude_ft;
|
||||
double err_dist = - altitude_ft;
|
||||
tgt_vs = calcVerticalSpeed(vert_dist_ft, dist_m, speed, err_dist);
|
||||
tgt_altitude_ft = curr->getCrossat();
|
||||
} else {
|
||||
// no cross-at, so assume same as previous
|
||||
use_perf_vs = true;
|
||||
tgt_altitude_ft = prev->getCrossat();
|
||||
}
|
||||
} else if (prev->getInAir()) {
|
||||
// Landing Leg (curr is on ground).
|
||||
|
||||
// Assume we want to touch down on the point, and not early!
|
||||
use_perf_vs = false;
|
||||
double dist_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
double vert_dist_ft = curr->getAltitude() - altitude_ft;
|
||||
double err_dist = - altitude_ft;
|
||||
tgt_vs = calcVerticalSpeed(vert_dist_ft, dist_m, speed, err_dist);
|
||||
tgt_altitude_ft = curr->getAltitude();
|
||||
}
|
||||
|
||||
AccelTo(prev->getSpeed());
|
||||
hdg_lock = alt_lock = true;
|
||||
no_roll = prev->getOn_ground();
|
||||
no_roll = (prev->getOn_ground() && curr->getOn_ground());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,6 +839,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
|||
fp->getPreviousWaypoint()->setSpeed(tgt_speed);
|
||||
}
|
||||
}
|
||||
|
||||
if (lead_dist < fabs(2*speed)) {
|
||||
//don't skip over the waypoint
|
||||
lead_dist = fabs(2*speed);
|
||||
|
@ -1417,34 +1440,50 @@ double limitRateOfChange(double cur, double target, double maxDeltaSec, double d
|
|||
return (fabs(delta) < maxDelta) ? delta : copysign(maxDelta, delta);
|
||||
}
|
||||
|
||||
// drive various properties in a semi-realistic fashion.
|
||||
// Drive various properties in a semi-realistic fashion.
|
||||
// Note that we assume that the properties are set at
|
||||
// a waypoint rather than in the leg before. So we need
|
||||
// to use the previous waypoint (i.e. the one just passed)
|
||||
// rather than the current one (i.e. the next one on the route)
|
||||
void FGAIAircraft::updateModelProperties(double dt)
|
||||
{
|
||||
if (!props) {
|
||||
if ((!fp) || (!fp->getPreviousWaypoint())) {
|
||||
return;
|
||||
}
|
||||
|
||||
SGPropertyNode* gear = props->getChild("gear", 0, true);
|
||||
double targetGearPos = fp->getCurrentWaypoint()->getGear_down() ? 1.0 : 0.0;
|
||||
if (!gear->hasValue("gear/position-norm")) {
|
||||
gear->setDoubleValue("gear/position-norm", targetGearPos);
|
||||
}
|
||||
double targetGearPos = fp->getPreviousWaypoint()->getGear_down() ? 1.0 : 0.0;
|
||||
double gearPos = getGearPos();
|
||||
|
||||
double gearPosNorm = gear->getDoubleValue("gear/position-norm");
|
||||
if (gearPosNorm != targetGearPos) {
|
||||
gearPosNorm += limitRateOfChange(gearPosNorm, targetGearPos, 0.1, dt);
|
||||
if (gearPosNorm < 0.001) {
|
||||
gearPosNorm = 0.0;
|
||||
} else if (gearPosNorm > 0.999) {
|
||||
gearPosNorm = 1.0;
|
||||
if (gearPos != targetGearPos) {
|
||||
gearPos = gearPos + limitRateOfChange(gearPos, targetGearPos, 0.1, dt);
|
||||
if (gearPos < 0.001) {
|
||||
gearPos = 0.0;
|
||||
} else if (gearPos > 0.999) {
|
||||
gearPos = 1.0;
|
||||
}
|
||||
|
||||
for (int i=0; i<6; ++i) {
|
||||
SGPropertyNode* g = gear->getChild("gear", i, true);
|
||||
g->setDoubleValue("position-norm", gearPosNorm);
|
||||
} // of gear setting loop
|
||||
} // of gear in-transit
|
||||
|
||||
// double flapPosNorm = props->getDoubleValue();
|
||||
setGearPos(gearPos);
|
||||
}
|
||||
|
||||
double targetFlapsPos = fp->getPreviousWaypoint()->getFlaps();
|
||||
double flapsPos = getFlapsPos();
|
||||
|
||||
if (flapsPos != targetFlapsPos) {
|
||||
flapsPos = flapsPos + limitRateOfChange(flapsPos, targetFlapsPos, 0.05, dt);
|
||||
if (flapsPos < 0.001) {
|
||||
flapsPos = 0.0;
|
||||
} else if (flapsPos > 0.999) {
|
||||
flapsPos = 1.0;
|
||||
}
|
||||
setFlapsPos(flapsPos);
|
||||
}
|
||||
|
||||
setSpeedBrakePos(fp->getPreviousWaypoint()->getSpeedBrakes());
|
||||
setSpoilerPos(fp->getPreviousWaypoint()->getSpoilers());
|
||||
setCabinLight(fp->getPreviousWaypoint()->getCabinLight());
|
||||
setBeaconLight(fp->getPreviousWaypoint()->getBeaconLight());
|
||||
setLandingLight(fp->getPreviousWaypoint()->getLandingLight());
|
||||
setNavLight(fp->getPreviousWaypoint()->getNavLight());
|
||||
setStrobeLight(fp->getPreviousWaypoint()->getStrobeLight());
|
||||
setTaxiLight(fp->getPreviousWaypoint()->getTaxiLight());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef _FG_AIAircraft_HXX
|
||||
#define _FG_AIAircraft_HXX
|
||||
|
||||
#include "AIBase.hxx"
|
||||
#include "AIBaseAircraft.hxx"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -32,7 +32,7 @@ class FGATCController;
|
|||
class FGATCInstruction;
|
||||
class FGAIWaypoint;
|
||||
|
||||
class FGAIAircraft : public FGAIBase {
|
||||
class FGAIAircraft : public FGAIBaseAircraft {
|
||||
|
||||
public:
|
||||
FGAIAircraft(FGAISchedule *ref=0);
|
||||
|
|
|
@ -664,7 +664,6 @@ bool FGAIBase::isa( object_type otype ) {
|
|||
return otype == _otype;
|
||||
}
|
||||
|
||||
|
||||
void FGAIBase::bind() {
|
||||
_tiedProperties.setRoot(props);
|
||||
tie("id", SGRawValueMethods<FGAIBase,int>(*this,
|
||||
|
@ -723,11 +722,9 @@ void FGAIBase::bind() {
|
|||
tie("radar/rotation", SGRawValuePointer<double>(&rotation));
|
||||
tie("radar/ht-diff-ft", SGRawValuePointer<double>(&ht_diff));
|
||||
tie("subID", SGRawValuePointer<int>(&_subID));
|
||||
tie("controls/lighting/nav-lights", SGRawValueFunctions<bool>(_isNight));
|
||||
|
||||
props->setStringValue("sim/model/path", model_path);
|
||||
|
||||
props->setBoolValue("controls/lighting/beacon", true);
|
||||
props->setBoolValue("controls/lighting/strobe", true);
|
||||
props->setBoolValue("controls/glide-path", true);
|
||||
|
||||
props->setStringValue("controls/flight/lateral-mode", "roll");
|
||||
|
|
93
src/AIModel/AIBaseAircraft.cxx
Normal file
93
src/AIModel/AIBaseAircraft.cxx
Normal file
|
@ -0,0 +1,93 @@
|
|||
// FGAIBaseAircraft - abstract base class for AI aircraft
|
||||
// Written by Stuart Buchanan, started August 2002
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "AIBaseAircraft.hxx"
|
||||
#include <src/Main/globals.hxx>
|
||||
|
||||
FGAIBaseAircraft::FGAIBaseAircraft() : FGAIBase(otStatic, false)
|
||||
{
|
||||
m_gearPos = 0.0f;
|
||||
m_flapsPos = 0.0f;
|
||||
m_spoilerPos = 0.0f;
|
||||
m_speedbrakePos = 0.0f;
|
||||
|
||||
// Light properties.
|
||||
m_beaconLight = false;
|
||||
m_cabinLight = false;
|
||||
m_landingLight = false;
|
||||
m_navLight = false;
|
||||
m_strobeLight = false;
|
||||
m_taxiLight = false;
|
||||
}
|
||||
|
||||
void FGAIBaseAircraft::bind() {
|
||||
FGAIBase::bind();
|
||||
|
||||
// All gear positions are linked for simplicity
|
||||
tie("gear/gear[0]/position-norm", SGRawValuePointer<double>(&m_gearPos));
|
||||
tie("gear/gear[1]/position-norm", SGRawValuePointer<double>(&m_gearPos));
|
||||
tie("gear/gear[2]/position-norm", SGRawValuePointer<double>(&m_gearPos));
|
||||
tie("gear/gear[3]/position-norm", SGRawValuePointer<double>(&m_gearPos));
|
||||
tie("gear/gear[4]/position-norm", SGRawValuePointer<double>(&m_gearPos));
|
||||
tie("gear/gear[5]/position-norm", SGRawValuePointer<double>(&m_gearPos));
|
||||
|
||||
tie("surface-positions/flap-pos-norm",
|
||||
SGRawValueMethods<FGAIBaseAircraft,double>(*this,
|
||||
&FGAIBaseAircraft::getFlapsPos,
|
||||
&FGAIBaseAircraft::setFlapsPos));
|
||||
|
||||
tie("surface-positions/spoiler-pos-norm",
|
||||
SGRawValueMethods<FGAIBaseAircraft,double>(*this,
|
||||
&FGAIBaseAircraft::getSpoilerPos,
|
||||
&FGAIBaseAircraft::setSpoilerPos));
|
||||
|
||||
tie("surface-positions/speedbrake-pos-norm",
|
||||
SGRawValueMethods<FGAIBaseAircraft,double>(*this,
|
||||
&FGAIBaseAircraft::getSpeedBrakePos,
|
||||
&FGAIBaseAircraft::setSpeedBrakePos));
|
||||
|
||||
tie("controls/lighting/beacon",
|
||||
SGRawValueMethods<FGAIBaseAircraft,bool>(*this,
|
||||
&FGAIBaseAircraft::getBeaconLight,
|
||||
&FGAIBaseAircraft::setBeaconLight));
|
||||
|
||||
tie("controls/lighting/cabin-lights",
|
||||
SGRawValueMethods<FGAIBaseAircraft,bool>(*this,
|
||||
&FGAIBaseAircraft::getCabinLight,
|
||||
&FGAIBaseAircraft::setCabinLight));
|
||||
|
||||
tie("controls/lighting/landing-lights",
|
||||
SGRawValueMethods<FGAIBaseAircraft,bool>(*this,
|
||||
&FGAIBaseAircraft::getLandingLight,
|
||||
&FGAIBaseAircraft::setLandingLight));
|
||||
|
||||
tie("controls/lighting/nav-lights",
|
||||
SGRawValueMethods<FGAIBaseAircraft,bool>(*this,
|
||||
&FGAIBaseAircraft::getNavLight,
|
||||
&FGAIBaseAircraft::setNavLight));
|
||||
|
||||
tie("controls/lighting/strobe",
|
||||
SGRawValueMethods<FGAIBaseAircraft,bool>(*this,
|
||||
&FGAIBaseAircraft::getStrobeLight,
|
||||
&FGAIBaseAircraft::setStrobeLight));
|
||||
|
||||
tie("controls/lighting/taxi-lights",
|
||||
SGRawValueMethods<FGAIBaseAircraft,bool>(*this,
|
||||
&FGAIBaseAircraft::getTaxiLight,
|
||||
&FGAIBaseAircraft::setTaxiLight));
|
||||
|
||||
}
|
73
src/AIModel/AIBaseAircraft.hxx
Normal file
73
src/AIModel/AIBaseAircraft.hxx
Normal file
|
@ -0,0 +1,73 @@
|
|||
// FGAIBaseAircraft - abstract base class for AI aircraft
|
||||
// Written by Stuart Buchanan, started August 2002
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef _FG_AIBaseAircraft_HXX
|
||||
#define _FG_AIBaseAircraft_HXX
|
||||
|
||||
#include "AIBase.hxx"
|
||||
|
||||
#include <string>
|
||||
|
||||
class FGAIBaseAircraft : public FGAIBase {
|
||||
|
||||
public:
|
||||
FGAIBaseAircraft();
|
||||
|
||||
void bind();
|
||||
|
||||
// Note that this is mapped to all 6 gear indices gear/gear[0..5]
|
||||
void setGearPos(double pos) { m_gearPos = pos; };
|
||||
void setFlapsPos(double pos) { m_flapsPos = pos; };
|
||||
void setSpoilerPos(double pos) { m_spoilerPos = pos; };
|
||||
void setSpeedBrakePos(double pos) { m_speedbrakePos = pos; };
|
||||
void setBeaconLight(bool light) { m_beaconLight = light; };
|
||||
void setLandingLight(bool light) { m_landingLight = light; };
|
||||
void setNavLight(bool light) { m_navLight = light; };
|
||||
void setStrobeLight(bool light) { m_strobeLight = light; };
|
||||
void setTaxiLight(bool light) { m_taxiLight = light; };
|
||||
void setCabinLight(bool light) { m_cabinLight = light; };
|
||||
|
||||
double getGearPos() const { return m_gearPos; };
|
||||
double getFlapsPos() const { return m_flapsPos; };
|
||||
double getSpoilerPos() const { return m_spoilerPos; };
|
||||
double getSpeedBrakePos() const { return m_speedbrakePos; };
|
||||
bool getBeaconLight() const { return m_beaconLight; };
|
||||
bool getLandingLight() const { return m_landingLight; };
|
||||
bool getNavLight() const { return m_navLight; };
|
||||
bool getStrobeLight() const { return m_strobeLight; };
|
||||
bool getTaxiLight() const { return m_taxiLight; };
|
||||
bool getCabinLight() const { return m_cabinLight; };
|
||||
|
||||
protected:
|
||||
|
||||
// Aircraft properties.
|
||||
double m_gearPos;
|
||||
double m_flapsPos;
|
||||
double m_spoilerPos;
|
||||
double m_speedbrakePos;
|
||||
|
||||
// Light properties.
|
||||
bool m_beaconLight;
|
||||
bool m_cabinLight;
|
||||
bool m_landingLight;
|
||||
bool m_navLight;
|
||||
bool m_strobeLight;
|
||||
bool m_taxiLight;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -52,7 +52,7 @@ FGAIWaypoint::FGAIWaypoint() {
|
|||
crossat = 0;
|
||||
finished = 0;
|
||||
gear_down = 0;
|
||||
flaps_down = 0;
|
||||
flaps = 0;
|
||||
on_ground = 0;
|
||||
routeIndex = 0;
|
||||
time_sec = 0;
|
||||
|
@ -240,18 +240,51 @@ bool FGAIFlightPlan::parseProperties(const std::string& filename)
|
|||
for (int i = 0; i < node->nChildren(); i++) {
|
||||
FGAIWaypoint* wpt = new FGAIWaypoint;
|
||||
SGPropertyNode * wpt_node = node->getChild(i);
|
||||
wpt->setName (wpt_node->getStringValue("name", "END" ));
|
||||
wpt->setLatitude (wpt_node->getDoubleValue("lat", 0 ));
|
||||
wpt->setLongitude (wpt_node->getDoubleValue("lon", 0 ));
|
||||
wpt->setAltitude (wpt_node->getDoubleValue("alt", 0 ));
|
||||
wpt->setSpeed (wpt_node->getDoubleValue("ktas", 0 ));
|
||||
wpt->setCrossat (wpt_node->getDoubleValue("crossat", -10000 ));
|
||||
wpt->setGear_down (wpt_node->getBoolValue("gear-down", false ));
|
||||
wpt->setFlaps_down (wpt_node->getBoolValue("flaps-down", false ));
|
||||
wpt->setOn_ground (wpt_node->getBoolValue("on-ground", false ));
|
||||
wpt->setTime_sec (wpt_node->getDoubleValue("time-sec", 0 ));
|
||||
wpt->setTime (wpt_node->getStringValue("time", "" ));
|
||||
wpt->setFinished ((wpt->getName() == "END"));
|
||||
|
||||
bool gear, flaps;
|
||||
|
||||
// Calculate some default values if they are not set explicitly in the flightplan
|
||||
if (wpt_node->getDoubleValue("ktas", 0) < 1.0f ) {
|
||||
// Not moving so assume shut down.
|
||||
wpt->setPowerDownLights();
|
||||
flaps = false;
|
||||
gear = true;
|
||||
} else if (wpt_node->getDoubleValue("alt", 0) > 10000.0f ) {
|
||||
// Cruise flight;
|
||||
wpt->setCruiseLights();
|
||||
flaps = false;
|
||||
gear = false;
|
||||
} else if (wpt_node->getBoolValue("on-ground", false)) {
|
||||
// On ground
|
||||
wpt->setGroundLights();
|
||||
flaps = true;
|
||||
gear = true;
|
||||
} else if (wpt_node->getDoubleValue("alt", 0) < 3000.0f ) {
|
||||
// In the air below 3000 ft, so flaps and gear down.
|
||||
wpt->setApproachLights();
|
||||
flaps = true;
|
||||
gear = true;
|
||||
} else {
|
||||
// In the air 3000-10000 ft
|
||||
wpt->setApproachLights();
|
||||
flaps = false;
|
||||
gear = false;
|
||||
}
|
||||
|
||||
wpt->setName (wpt_node->getStringValue("name", "END" ));
|
||||
wpt->setLatitude (wpt_node->getDoubleValue("lat", 0 ));
|
||||
wpt->setLongitude (wpt_node->getDoubleValue("lon", 0 ));
|
||||
wpt->setAltitude (wpt_node->getDoubleValue("alt", 0 ));
|
||||
wpt->setSpeed (wpt_node->getDoubleValue("ktas", 0 ));
|
||||
wpt->setCrossat (wpt_node->getDoubleValue("crossat", -10000 ));
|
||||
wpt->setGear_down (wpt_node->getBoolValue("gear-down", gear ));
|
||||
wpt->setFlaps (wpt_node->getBoolValue("flaps-down", flaps ) ? 1.0 : 0.0);
|
||||
wpt->setSpoilers (wpt_node->getBoolValue("spoilers", false ) ? 1.0 : 0.0);
|
||||
wpt->setSpeedBrakes (wpt_node->getBoolValue("speedbrakes", false ) ? 1.0 : 0.0);
|
||||
wpt->setOn_ground (wpt_node->getBoolValue("on-ground", false ));
|
||||
wpt->setTime_sec (wpt_node->getDoubleValue("time-sec", 0 ));
|
||||
wpt->setTime (wpt_node->getStringValue("time", "" ));
|
||||
wpt->setFinished ((wpt->getName() == "END"));
|
||||
pushBackWaypoint( wpt );
|
||||
}
|
||||
if( getLastWaypoint()->getName().compare("END") != 0 ) {
|
||||
|
@ -356,16 +389,17 @@ void FGAIFlightPlan::setLeadDistance(double speed, double bearing,
|
|||
lead_distance = 0.5;
|
||||
return;
|
||||
}
|
||||
|
||||
if (speed < 25) {
|
||||
turn_radius = ((360/30)*fabs(speed)) / (2*M_PI);
|
||||
} else
|
||||
turn_radius = ((360/30)*fabs(speed)) / (2*M_PI);
|
||||
} else {
|
||||
turn_radius = 0.1911 * speed * speed; // an estimate for 25 degrees bank
|
||||
}
|
||||
|
||||
double inbound = bearing;
|
||||
double outbound = getBearing(current, next);
|
||||
leadInAngle = fabs(inbound - outbound);
|
||||
if (leadInAngle > 180.0)
|
||||
leadInAngle = 360.0 - leadInAngle;
|
||||
if (leadInAngle > 180.0) leadInAngle = 360.0 - leadInAngle;
|
||||
//if (leadInAngle < 30.0) // To prevent lead_dist from getting so small it is skipped
|
||||
// leadInAngle = 30.0;
|
||||
|
||||
|
@ -422,7 +456,14 @@ void FGAIFlightPlan::resetWaypoints()
|
|||
wpt->setPos ( (*i)->getPos() );
|
||||
wpt->setCrossat ( (*i)->getCrossat() );
|
||||
wpt->setGear_down ( (*i)->getGear_down() );
|
||||
wpt->setFlaps_down ( (*i)->getFlaps_down() );
|
||||
wpt->setFlaps ( (*i)->getFlaps() );
|
||||
wpt->setSpoilers ( (*i)->getSpoilers() );
|
||||
wpt->setSpeedBrakes ( (*i)->getSpeedBrakes());
|
||||
wpt->setBeaconLight ( (*i)->getBeaconLight() );
|
||||
wpt->setLandingLight( (*i)->getLandingLight() );
|
||||
wpt->setNavLight ( (*i)->getNavLight() );
|
||||
wpt->setStrobeLight ( (*i)->getStrobeLight());
|
||||
wpt->setTaxiLight ( (*i)->getTaxiLight() );
|
||||
wpt->setFinished ( false );
|
||||
wpt->setOn_ground ( (*i)->getOn_ground() );
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Recycling waypoint " << wpt->getName());
|
||||
|
|
|
@ -36,12 +36,20 @@ private:
|
|||
double crossat;
|
||||
bool finished;
|
||||
bool gear_down;
|
||||
bool flaps_down;
|
||||
double flaps;
|
||||
double spoilers;
|
||||
double speedbrakes;
|
||||
bool on_ground;
|
||||
int routeIndex; // For AI/ATC purposes;
|
||||
double time_sec;
|
||||
double trackLength; // distance from previous FGAIWaypoint (for AI purposes);
|
||||
std::string time;
|
||||
bool beacon_light;
|
||||
bool landing_light;
|
||||
bool nav_light;
|
||||
bool strobe_light;
|
||||
bool taxi_light;
|
||||
bool cabin_light;
|
||||
|
||||
public:
|
||||
FGAIWaypoint();
|
||||
|
@ -55,12 +63,33 @@ public:
|
|||
void setCrossat (double val) { crossat = val; };
|
||||
void setFinished (bool fin) { finished = fin; };
|
||||
void setGear_down (bool grd) { gear_down = grd; };
|
||||
void setFlaps_down (bool fld) { flaps_down = fld; };
|
||||
void setFlaps (double val) { flaps = val; };
|
||||
void setSpoilers (double val) { spoilers = val; };
|
||||
void setSpeedBrakes (double val) { speedbrakes = val; };
|
||||
void setOn_ground (bool grn) { on_ground = grn; };
|
||||
void setRouteIndex (int rte) { routeIndex = rte; };
|
||||
void setTime_sec (double ts ) { time_sec = ts; };
|
||||
void setTrackLength (double tl ) { trackLength = tl; };
|
||||
void setTime (const std::string& tme) { time = tme; };
|
||||
void setLights (bool beacon, bool cabin, bool ldg, bool nav, bool strobe, bool taxi) {
|
||||
beacon_light = beacon;
|
||||
cabin_light = cabin;
|
||||
landing_light = ldg;
|
||||
nav_light = nav;
|
||||
strobe_light = strobe;
|
||||
taxi_light = taxi; };
|
||||
// beacon cabin ldg nav strobe taxi
|
||||
void setPowerDownLights() { setLights(false, true, false, false, false, false); };
|
||||
void setGroundLights() { setLights(true, true, false, true, false, true ); };
|
||||
void setCruiseLights() { setLights(true, true, false, true, true, false); };
|
||||
void setTakeOffLights() { setLights(true, false, true, true, true, false); };
|
||||
void setApproachLights() { setLights(true, false, true, true, true, false); };
|
||||
void setBeaconLight (bool beacon) { beacon_light = beacon; };
|
||||
void setCabinLight (bool cabin) { cabin_light = cabin; };
|
||||
void setLandingLight (bool ldg) { landing_light = ldg; };
|
||||
void setNavLight (bool nav) { nav_light = nav; };
|
||||
void setStrobeLight (bool strobe) { strobe_light = strobe; };
|
||||
void setTaxiLight (bool taxi) { taxi_light = taxi; };
|
||||
|
||||
bool contains(const std::string& name);
|
||||
|
||||
|
@ -73,13 +102,22 @@ public:
|
|||
|
||||
double getCrossat () { return crossat; };
|
||||
bool getGear_down () { return gear_down; };
|
||||
bool getFlaps_down () { return flaps_down; };
|
||||
double getFlaps () { return flaps; };
|
||||
double getSpoilers () { return spoilers; };
|
||||
double getSpeedBrakes() { return speedbrakes; };
|
||||
bool getOn_ground () { return on_ground; };
|
||||
bool getInAir () { return ! on_ground; };
|
||||
int getRouteIndex () { return routeIndex; };
|
||||
bool isFinished () { return finished; };
|
||||
double getTime_sec () { return time_sec; };
|
||||
double getTrackLength() { return trackLength; };
|
||||
const std::string& getTime () { return time; };
|
||||
bool getBeaconLight() { return beacon_light; };
|
||||
bool getCabinLight() { return cabin_light; };
|
||||
bool getLandingLight() { return landing_light; };
|
||||
bool getNavLight() { return nav_light; };
|
||||
bool getStrobeLight() { return strobe_light;};
|
||||
bool getTaxiLight() { return taxi_light; };
|
||||
|
||||
};
|
||||
|
||||
|
@ -115,13 +153,13 @@ public:
|
|||
|
||||
double getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const;
|
||||
int getLeg () const { return leg;};
|
||||
|
||||
|
||||
void setLeadDistance(double speed, double bearing, FGAIWaypoint* current, FGAIWaypoint* next);
|
||||
void setLeadDistance(double distance_ft);
|
||||
double getLeadDistance( void ) const {return lead_distance;}
|
||||
double getBearing(FGAIWaypoint* previous, FGAIWaypoint* next) const;
|
||||
double getBearing(const SGGeod& aPos, FGAIWaypoint* next) const;
|
||||
|
||||
|
||||
double checkTrackLength(const std::string& wptName) const;
|
||||
time_t getStartTime() const { return start_time; }
|
||||
time_t getArrivalTime() const { return arrivalTime; }
|
||||
|
@ -137,7 +175,7 @@ public:
|
|||
|
||||
double getLeadInAngle() const { return leadInAngle; }
|
||||
const std::string& getRunway() const;
|
||||
|
||||
|
||||
void setRepeat(bool r) { repeat = r; }
|
||||
bool getRepeat(void) const { return repeat; }
|
||||
void restart(void);
|
||||
|
@ -162,7 +200,7 @@ public:
|
|||
FGAIFlightPlan* getSID() { return sid; };
|
||||
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
|
||||
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
|
||||
|
||||
|
||||
void shortenToFirst(unsigned int number, std::string name);
|
||||
|
||||
void setGate(const ParkingAssignment& pka);
|
||||
|
@ -192,14 +230,14 @@ private:
|
|||
std::string name;
|
||||
bool isValid;
|
||||
FGAirportRef departure, arrival;
|
||||
|
||||
|
||||
void createPushBackFallBack(FGAIAircraft *, bool, FGAirport*, double radius, const std::string&, const std::string&, const std::string&);
|
||||
bool createClimb(FGAIAircraft *, bool, FGAirport *, FGAirport* arrival, double, double, const std::string&);
|
||||
bool createCruise(FGAIAircraft *, bool, FGAirport*, FGAirport*, double, double, double, double, const std::string&);
|
||||
bool createDescent(FGAIAircraft *, FGAirport *, double latitude, double longitude, double speed, double alt,const std::string&, double distance);
|
||||
bool createLanding(FGAIAircraft *, FGAirport *, const std::string&);
|
||||
bool createParking(FGAIAircraft *, FGAirport *, double radius);
|
||||
void deleteWaypoints();
|
||||
void deleteWaypoints();
|
||||
void resetWaypoints();
|
||||
void eraseLastWaypoint();
|
||||
void pushBackWaypoint(FGAIWaypoint *wpt);
|
||||
|
@ -210,22 +248,23 @@ private:
|
|||
bool createTakeoffTaxi(FGAIAircraft *, bool firstFlight, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline);
|
||||
|
||||
double getTurnRadius(double, bool);
|
||||
|
||||
|
||||
FGAIWaypoint* createOnGround(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
|
||||
FGAIWaypoint* createOnRunway(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
|
||||
FGAIWaypoint* createInAir(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
|
||||
FGAIWaypoint* cloneWithPos(FGAIAircraft *, FGAIWaypoint* aWpt, const std::string& aName, const SGGeod& aPos);
|
||||
FGAIWaypoint* clone(FGAIWaypoint* aWpt);
|
||||
|
||||
|
||||
|
||||
//void createCruiseFallback(bool, FGAirport*, FGAirport*, double, double, double, double);
|
||||
void evaluateRoutePart(double deplat, double deplon, double arrlat, double arrlon);
|
||||
|
||||
|
||||
/**
|
||||
* look for and parse an PropertyList flight-plan file - essentially
|
||||
* a flat list waypoint objects, encoded to properties
|
||||
*/
|
||||
bool parseProperties(const std::string& filename);
|
||||
|
||||
|
||||
void createWaypoints(FGAIAircraft *ac,
|
||||
double course,
|
||||
time_t start,
|
||||
|
@ -240,7 +279,7 @@ private:
|
|||
const std::string& fltType,
|
||||
const std::string& acType,
|
||||
const std::string& airline);
|
||||
|
||||
|
||||
public:
|
||||
wpt_vector_iterator getFirstWayPoint() { return waypoints.begin(); };
|
||||
wpt_vector_iterator getLastWayPoint() { return waypoints.end(); };
|
||||
|
|
|
@ -52,7 +52,7 @@ using std::string;
|
|||
|
||||
/* FGAIFlightPlan::create()
|
||||
* dynamically create a flight plan for AI traffic, based on data provided by the
|
||||
* Traffic Manager, when reading a filed flightplan failes. (DT, 2004/07/10)
|
||||
* Traffic Manager, when reading a filed flightplan fails. (DT, 2004/07/10)
|
||||
*
|
||||
* This is the top-level function, and the only one that is publicly available.
|
||||
*
|
||||
|
@ -133,17 +133,34 @@ FGAIWaypoint * FGAIFlightPlan::createOnGround(FGAIAircraft * ac,
|
|||
double aSpeed)
|
||||
{
|
||||
FGAIWaypoint *wpt = new FGAIWaypoint;
|
||||
wpt->setName (aName );
|
||||
wpt->setLongitude (aPos.getLongitudeDeg() );
|
||||
wpt->setLatitude (aPos.getLatitudeDeg() );
|
||||
wpt->setAltitude (aElev );
|
||||
wpt->setSpeed (aSpeed );
|
||||
wpt->setCrossat (-10000.1 );
|
||||
wpt->setGear_down (true );
|
||||
wpt->setFlaps_down (true );
|
||||
wpt->setFinished (false );
|
||||
wpt->setOn_ground (true );
|
||||
wpt->setRouteIndex (0 );
|
||||
wpt->setName (aName );
|
||||
wpt->setLongitude (aPos.getLongitudeDeg() );
|
||||
wpt->setLatitude (aPos.getLatitudeDeg() );
|
||||
wpt->setAltitude (aElev );
|
||||
wpt->setSpeed (aSpeed );
|
||||
wpt->setCrossat (-10000.1 );
|
||||
wpt->setGear_down (true );
|
||||
wpt->setFlaps (0.0f );
|
||||
wpt->setSpoilers (0.0f );
|
||||
wpt->setSpeedBrakes (0.0f );
|
||||
wpt->setFinished (false );
|
||||
wpt->setOn_ground (true );
|
||||
wpt->setRouteIndex (0 );
|
||||
if (aSpeed > 0.0f) {
|
||||
wpt->setGroundLights();
|
||||
} else {
|
||||
wpt->setPowerDownLights();
|
||||
}
|
||||
return wpt;
|
||||
}
|
||||
|
||||
FGAIWaypoint * FGAIFlightPlan::createOnRunway(FGAIAircraft * ac,
|
||||
const std::string & aName,
|
||||
const SGGeod & aPos, double aElev,
|
||||
double aSpeed)
|
||||
{
|
||||
FGAIWaypoint * wpt = createOnGround(ac, aName, aPos, aElev, aSpeed);
|
||||
wpt->setTakeOffLights();
|
||||
return wpt;
|
||||
}
|
||||
|
||||
|
@ -154,9 +171,17 @@ FGAIWaypoint * FGAIFlightPlan::createInAir(FGAIAircraft * ac,
|
|||
{
|
||||
FGAIWaypoint * wpt = createOnGround(ac, aName, aPos, aElev, aSpeed);
|
||||
wpt->setGear_down (false );
|
||||
wpt->setFlaps_down (false );
|
||||
wpt->setFlaps (0.0f );
|
||||
wpt->setSpoilers (0.0f );
|
||||
wpt->setSpeedBrakes(0.0f );
|
||||
wpt->setOn_ground (false );
|
||||
wpt->setCrossat (aElev );
|
||||
|
||||
if (aPos.getElevationFt() < 10000.0f) {
|
||||
wpt->setApproachLights();
|
||||
} else {
|
||||
wpt->setCruiseLights();
|
||||
}
|
||||
return wpt;
|
||||
}
|
||||
|
||||
|
@ -170,9 +195,13 @@ FGAIWaypoint * FGAIFlightPlan::clone(FGAIWaypoint * aWpt)
|
|||
wpt->setSpeed ( aWpt->getSpeed() );
|
||||
wpt->setCrossat ( aWpt->getCrossat() );
|
||||
wpt->setGear_down ( aWpt->getGear_down() );
|
||||
wpt->setFlaps_down ( aWpt->getFlaps_down() );
|
||||
wpt->setFlaps ( aWpt->getFlaps() );
|
||||
wpt->setFinished ( aWpt->isFinished() );
|
||||
wpt->setOn_ground ( aWpt->getOn_ground() );
|
||||
wpt->setLandingLight (aWpt->getLandingLight() );
|
||||
wpt->setNavLight (aWpt->getNavLight() );
|
||||
wpt->setStrobeLight (aWpt->getStrobeLight() );
|
||||
wpt->setTaxiLight (aWpt->getTaxiLight() );
|
||||
wpt->setRouteIndex ( 0 );
|
||||
|
||||
return wpt;
|
||||
|
@ -206,14 +235,14 @@ void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAIAircraft * ac,
|
|||
ac->getPerformance()->vTaxi());
|
||||
pushBackWaypoint(wpt);
|
||||
wpt =
|
||||
createOnGround(ac, "Runway Takeoff", runwayTakeoff, airportElev,
|
||||
createOnRunway(ac, "Runway Takeoff", runwayTakeoff, airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
|
||||
wpt->setFlaps(0.5f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
// Acceleration point, 105 meters into the runway,
|
||||
SGGeod accelPoint = aRunway->pointOnCenterline(105.0);
|
||||
wpt = createOnGround(ac, "Accel", accelPoint, airportElev,
|
||||
wpt = createOnRunway(ac, "Accel", accelPoint, airportElev,
|
||||
ac->getPerformance()->vRotate());
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
|
@ -341,15 +370,20 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
|||
// Note that we actually have hold points in the ground network, but this is just an initial test.
|
||||
//cerr << "Setting departurehold point: " << endl;
|
||||
wpt->setName( wpt->getName() + string("DepartureHold"));
|
||||
wpt->setFlaps(0.5f);
|
||||
wpt->setTakeOffLights();
|
||||
}
|
||||
if (taxiRoute.nodesLeft() == 0) {
|
||||
wpt->setName(wpt->getName() + string("Accel"));
|
||||
wpt->setTakeOffLights();
|
||||
wpt->setFlaps(0.5f);
|
||||
}
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
// Acceleration point, 105 meters into the runway,
|
||||
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, "Accel", accelPoint, apt->getElevation(), ac->getPerformance()->vRotate());
|
||||
FGAIWaypoint *wpt = createOnRunway(ac, "Accel", accelPoint, apt->getElevation(), ac->getPerformance()->vRotate());
|
||||
wpt->setFlaps(0.5f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
//cerr << "[done]" << endl;
|
||||
|
@ -483,6 +517,7 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
double accelMetric = accel * SG_KT_TO_MPS;
|
||||
double vTaxiMetric = vTaxi * SG_KT_TO_MPS;
|
||||
double vRotateMetric = vRotate * SG_KT_TO_MPS;
|
||||
double vTakeoffMetric = vTakeoff * SG_KT_TO_MPS;
|
||||
|
||||
FGAIWaypoint *wpt;
|
||||
// Get the current active runway, based on code from David Luff
|
||||
|
@ -503,38 +538,47 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
|
||||
double airportElev = apt->getElevation();
|
||||
|
||||
// distance from the runway threshold to accelerate to rotation speed.
|
||||
double d = accelDistance(vTaxiMetric, vRotateMetric, accelMetric) + ACCEL_POINT;
|
||||
|
||||
SGGeod accelPoint = rwy->pointOnCenterline(d);
|
||||
wpt = createOnGround(ac, "rotate", accelPoint, airportElev, vTakeoff);
|
||||
SGGeod rotatePoint = rwy->pointOnCenterline(d);
|
||||
wpt = createOnRunway(ac, "rotate", rotatePoint, airportElev, vRotate);
|
||||
wpt->setFlaps(0.5f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
// After rotation, we still need to accelerate to the take-off speed.
|
||||
double t = d + accelDistance(vRotateMetric, vTakeoffMetric, accelMetric);
|
||||
SGGeod takeoffPoint = rwy->pointOnCenterline(t);
|
||||
wpt = createOnRunway(ac, "takeoff", takeoffPoint, airportElev, vTakeoff);
|
||||
wpt->setGear_down(true);
|
||||
wpt->setFlaps(0.5f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
double vRef = vTakeoff + 20; // climb-out at v2 + 20kts
|
||||
|
||||
double gearUpDist = d + pitchDistance(INITIAL_PITCH_ANGLE, 400 * SG_FEET_TO_METER);
|
||||
accelPoint = rwy->pointOnCenterline(gearUpDist);
|
||||
|
||||
wpt = cloneWithPos(ac, wpt, "gear-up", accelPoint);
|
||||
wpt->setSpeed(vRef);
|
||||
wpt->setCrossat(airportElev + 400);
|
||||
wpt->setOn_ground(false);
|
||||
wpt->setGear_down(false);
|
||||
|
||||
// We want gear-up to take place at ~400ft AGL. However, the flightplan
|
||||
// will move onto the next leg once it gets within 2xspeed of the next waypoint.
|
||||
// With closely spaced waypoints on climb-out this can occur almost immediately,
|
||||
// so we put the waypoint further away.
|
||||
double gearUpDist = t + 2*vRef*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 400 * SG_FEET_TO_METER);
|
||||
SGGeod gearUpPoint = rwy->pointOnCenterline(gearUpDist);
|
||||
wpt = createInAir(ac, "gear-up", gearUpPoint, airportElev + 400, vRef);
|
||||
wpt->setFlaps(0.5f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
// limit climbout speed to 240kts below 10000'
|
||||
// limit climbout speed to 240kts below 10000'
|
||||
double vClimbBelow10000 = std::min(240.0, ac->getPerformance()->vClimb());
|
||||
|
||||
// create two climb-out points. This is important becuase the first climb point will
|
||||
// be a (sometimes large) turn towards the destination, and we don't want to
|
||||
// commence that turn below 2000'
|
||||
double climbOut = d + pitchDistance(INITIAL_PITCH_ANGLE, 2000 * SG_FEET_TO_METER);
|
||||
accelPoint = rwy->pointOnCenterline(climbOut);
|
||||
wpt = createInAir(ac, "2000'", accelPoint, airportElev + 2000, vClimbBelow10000);
|
||||
// create two climb-out points. This is important becuase the first climb point will
|
||||
// be a (sometimes large) turn towards the destination, and we don't want to
|
||||
// commence that turn below 2000'
|
||||
double climbOut = t + 2*vClimbBelow10000*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 2000 * SG_FEET_TO_METER);
|
||||
SGGeod climbOutPoint = rwy->pointOnCenterline(climbOut);
|
||||
wpt = createInAir(ac, "2000'", climbOutPoint, airportElev + 2000, vClimbBelow10000);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
climbOut = d + pitchDistance(INITIAL_PITCH_ANGLE, 2500 * SG_FEET_TO_METER);
|
||||
accelPoint = rwy->pointOnCenterline(climbOut);
|
||||
wpt = createInAir(ac, "2500'", accelPoint, airportElev + 2500, vClimbBelow10000);
|
||||
climbOut = t + 2*vClimbBelow10000*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 2500 * SG_FEET_TO_METER);
|
||||
SGGeod climbOutPoint2 = rwy->pointOnCenterline(climbOut);
|
||||
wpt = createInAir(ac, "2500'", climbOutPoint2, airportElev + 2500, vClimbBelow10000);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
return true;
|
||||
|
@ -542,7 +586,7 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
|
||||
/*******************************************************************
|
||||
* CreateClimb
|
||||
* initialize the Aircraft at the parking location
|
||||
* initialize the Aircraft in a climb.
|
||||
******************************************************************/
|
||||
bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
||||
FGAirport * apt, FGAirport* arrival,
|
||||
|
@ -580,8 +624,6 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
|||
|
||||
SGGeod climb1 = SGGeodesy::direct(cur, course, 10 * SG_NM_TO_METER);
|
||||
wpt = createInAir(ac, "10000ft climb", climb1, 10000, vClimb);
|
||||
wpt->setGear_down(true);
|
||||
wpt->setFlaps_down(true);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
SGGeod climb2 = SGGeodesy::direct(cur, course, 20 * SG_NM_TO_METER);
|
||||
|
@ -591,8 +633,6 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* CreateDescent
|
||||
* Generate a flight path from the last waypoint of the cruise to
|
||||
|
@ -948,13 +988,19 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
double glideslopeEntry = -((2000 * SG_FEET_TO_METER) / tan(3.0)) + touchdownDistance;
|
||||
FGAIWaypoint *wpt = createInAir(ac, "Glideslope begin", rwy->pointOnCenterline(glideslopeEntry),
|
||||
currElev + 2000, vApproach);
|
||||
wpt->setGear_down(true);
|
||||
wpt->setFlaps(1.0f);
|
||||
wpt->setSpeedBrakes(1.0f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
// deceleration point, 500' above touchdown elevation - slow from approach speed
|
||||
// to touchdown speed
|
||||
double decelPoint = -((500 * SG_FEET_TO_METER) / tan(3.0)) + touchdownDistance;
|
||||
wpt = createInAir(ac, "500' decel", rwy->pointOnCenterline(decelPoint),
|
||||
currElev + 2000, vTouchdown);
|
||||
currElev + 500, vTouchdown);
|
||||
wpt->setGear_down(true);
|
||||
wpt->setFlaps(1.0f);
|
||||
wpt->setSpeedBrakes(1.0f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
// compute elevation above the runway start, based on a 3-degree glideslope
|
||||
|
@ -962,6 +1008,9 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
tan(3.0 * SG_DEGREES_TO_RADIANS) * SG_METER_TO_FEET;
|
||||
wpt = createInAir(ac, "CrossThreshold", rwy->begin(),
|
||||
heightAboveRunwayStart + currElev, vTouchdown);
|
||||
wpt->setGear_down(true);
|
||||
wpt->setFlaps(1.0f);
|
||||
wpt->setSpeedBrakes(1.0f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
double rolloutDistance = accelDistance(vTouchdownMetric, vTaxiMetric, decelMetric);
|
||||
|
@ -972,7 +1021,10 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
double t = ((double) i) / nPoints;
|
||||
coord = rwy->pointOnCenterline(touchdownDistance + (rolloutDistance * t));
|
||||
double vel = (vTouchdownMetric * (1.0 - t)) + (vTaxiMetric * t);
|
||||
wpt = createOnGround(ac, buffer, coord, currElev, vel);
|
||||
wpt = createOnRunway(ac, buffer, coord, currElev, vel);
|
||||
wpt->setFlaps(1.0f);
|
||||
wpt->setSpeedBrakes(1.0f);
|
||||
wpt->setSpoilers(1.0f);
|
||||
wpt->setCrossat(currElev);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
|
@ -994,7 +1046,10 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
}
|
||||
|
||||
if (tn) {
|
||||
wpt = createOnGround(ac, buffer, tn->geod(), currElev, vTaxi);
|
||||
wpt = createOnRunway(ac, buffer, tn->geod(), currElev, vTaxi);
|
||||
wpt->setFlaps(1.0f);
|
||||
wpt->setSpeedBrakes(1.0f);
|
||||
wpt->setSpoilers(0.0f);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <src/Main/globals.hxx>
|
||||
|
||||
|
||||
FGAISwiftAircraft::FGAISwiftAircraft(const std::string& callsign, const std::string& modelString) : FGAIBase(otStatic, false)
|
||||
FGAISwiftAircraft::FGAISwiftAircraft(const std::string& callsign, const std::string& modelString) : FGAIBaseAircraft()
|
||||
{
|
||||
std::size_t pos = modelString.find("/Aircraft/"); // Only supporting AI models from FGDATA/AI/Aircraft for now
|
||||
if(pos != std::string::npos)
|
||||
|
@ -67,15 +67,15 @@ double FGAISwiftAircraft::getGroundElevation(const SGGeod& pos) const
|
|||
|
||||
void FGAISwiftAircraft::setPlaneSurface(const AircraftSurfaces& surfaces)
|
||||
{
|
||||
m_gearNode->setDoubleValue(surfaces.gear);
|
||||
m_flapsIdentNode->setDoubleValue(surfaces.flaps);
|
||||
m_spoilerNode->setDoubleValue(surfaces.spoilers);
|
||||
m_speedBrakeNode->setDoubleValue(surfaces.spoilers);
|
||||
m_landLightNode->setBoolValue(surfaces.landingLight);
|
||||
m_taxiLightNode->setBoolValue(surfaces.taxiLight);
|
||||
m_beaconLightNode->setBoolValue(surfaces.beaconLight);
|
||||
m_strobeLightNode->setBoolValue(surfaces.strobeLight);
|
||||
m_navLightNode->setBoolValue(surfaces.navLight);
|
||||
setGearPos(surfaces.gear);
|
||||
setFlapsPos(surfaces.flaps);
|
||||
setSpoilerPos(surfaces.spoilers);
|
||||
setSpeedBrakePos(surfaces.spoilers);
|
||||
setBeaconLight(surfaces.beaconLight);
|
||||
setLandingLight(surfaces.landingLight);
|
||||
setNavLight(surfaces.navLight);
|
||||
setStrobeLight(surfaces.strobeLight);
|
||||
setTaxiLight(surfaces.taxiLight);
|
||||
}
|
||||
|
||||
void FGAISwiftAircraft::setPlaneTransponder(const AircraftTransponder& transponder)
|
||||
|
@ -91,17 +91,6 @@ void FGAISwiftAircraft::initProps()
|
|||
m_transponderCodeNode = _getProps()->getNode("swift/transponder/code", true);
|
||||
m_transponderCModeNode = _getProps()->getNode("swift/transponder/c-mode", true);
|
||||
m_transponderIdentNode = _getProps()->getNode("swift/transponder/ident", true);
|
||||
|
||||
m_gearNode = _getProps()->getNode("swift/gear/gear-down", true);
|
||||
m_flapsIdentNode = _getProps()->getNode("swift/flight/flaps", true);
|
||||
m_spoilerNode = _getProps()->getNode("swift/flight/spoilers", true);
|
||||
m_speedBrakeNode = _getProps()->getNode("swift/flight/speedbrake", true);
|
||||
|
||||
m_landLightNode = _getProps()->getNode("swift/lighting/landing-lights", true);
|
||||
m_navLightNode = _getProps()->getNode("swift/lighting/nav-lights", true);
|
||||
m_taxiLightNode = _getProps()->getNode("swift/lighting/taxi-light", true);
|
||||
m_beaconLightNode = _getProps()->getNode("swift/lighting/beacon", true);
|
||||
m_strobeLightNode = _getProps()->getNode("swift/lighting/strobe", true);
|
||||
}
|
||||
|
||||
FGAISwiftAircraft::~FGAISwiftAircraft() = default;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define FLIGHTGEAR_AISWIFTAIRCRAFT_H
|
||||
|
||||
|
||||
#include "AIBase.hxx"
|
||||
#include "AIBaseAircraft.hxx"
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
|
@ -67,9 +67,7 @@ struct AircraftSurfaces
|
|||
int lightPattern;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class FGAISwiftAircraft : public FGAIBase
|
||||
class FGAISwiftAircraft : public FGAIBaseAircraft
|
||||
{
|
||||
public:
|
||||
FGAISwiftAircraft(const std::string& callsign, const std::string& modelString);
|
||||
|
@ -89,24 +87,6 @@ private:
|
|||
SGPropertyNode_ptr m_transponderCodeNode;
|
||||
SGPropertyNode_ptr m_transponderCModeNode;
|
||||
SGPropertyNode_ptr m_transponderIdentNode;
|
||||
|
||||
SGPropertyNode_ptr m_gearNode;
|
||||
SGPropertyNode_ptr m_flapsIdentNode;
|
||||
SGPropertyNode_ptr m_spoilerNode;
|
||||
SGPropertyNode_ptr m_speedBrakeNode;
|
||||
//SGPropertyNode_ptr m_slatsNode;
|
||||
//SGPropertyNode_ptr m_wingSweepNode;
|
||||
//SGPropertyNode_ptr m_thrustNode;
|
||||
//SGPropertyNode_ptr m_elevatorNode;
|
||||
//SGPropertyNode_ptr m_rudderNode;
|
||||
//SGPropertyNode_ptr m_aileronNode;
|
||||
SGPropertyNode_ptr m_landLightNode;
|
||||
SGPropertyNode_ptr m_taxiLightNode;
|
||||
SGPropertyNode_ptr m_beaconLightNode;
|
||||
SGPropertyNode_ptr m_strobeLightNode;
|
||||
SGPropertyNode_ptr m_navLightNode;
|
||||
//SGPropertyNode_ptr m_lightPatternNode;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ set(SOURCES
|
|||
AIAircraft.cxx
|
||||
AIBallistic.cxx
|
||||
AIBase.cxx
|
||||
AIBaseAircraft.cxx
|
||||
AICarrier.cxx
|
||||
AIEscort.cxx
|
||||
AIFlightPlan.cxx
|
||||
|
@ -28,6 +29,7 @@ set(HEADERS
|
|||
AIAircraft.hxx
|
||||
AIBallistic.hxx
|
||||
AIBase.hxx
|
||||
AIBaseAircraft.hxx
|
||||
AICarrier.hxx
|
||||
AIEscort.hxx
|
||||
AIFlightPlan.hxx
|
||||
|
|
|
@ -81,7 +81,7 @@ void FGSidStar::load(SGPath filename) {
|
|||
wpt->setSpeed (wpt_node->getDoubleValue("ktas", 0));
|
||||
wpt->setCrossat (wpt_node->getDoubleValue("crossat", -10000));
|
||||
wpt->setGear_down (wpt_node->getBoolValue("gear-down", false));
|
||||
wpt->setFlaps_down (wpt_node->getBoolValue("flaps-down", false));
|
||||
wpt->setFlaps (wpt_node->getBoolValue("flaps-down", false) ? 0.5 : 0.0); // We'll assume all SIDS only require half flaps
|
||||
wpt->setOn_ground (wpt_node->getBoolValue("on-ground", false));
|
||||
wpt->setTime_sec (wpt_node->getDoubleValue("time-sec", 0));
|
||||
wpt->setTime (wpt_node->getStringValue("time", ""));
|
||||
|
|
Loading…
Add table
Reference in a new issue