Durk Talsma:
Okay, here's the latest update to the tarffic manager/AI Manager. AITraffic can now fly multiple routes and be initialized while sitting statically at airports.
This commit is contained in:
parent
ffafb573b2
commit
c537267f96
13 changed files with 284 additions and 42 deletions
|
@ -51,7 +51,8 @@ const FGAIAircraft::PERF_STRUCT FGAIAircraft::settings[] = {
|
|||
};
|
||||
|
||||
|
||||
FGAIAircraft::FGAIAircraft(FGAIManager* mgr) {
|
||||
FGAIAircraft::FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref) {
|
||||
trafficRef = ref;
|
||||
manager = mgr;
|
||||
_type_str = "aircraft";
|
||||
_otype = otAircraft;
|
||||
|
@ -114,7 +115,14 @@ void FGAIAircraft::Run(double dt) {
|
|||
|
||||
FGAIAircraft::dt = dt;
|
||||
|
||||
if (fp) ProcessFlightPlan(dt);
|
||||
if (fp)
|
||||
{
|
||||
ProcessFlightPlan(dt);
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
if (now < fp->getStartTime())
|
||||
return;
|
||||
//ProcessFlightPlan(dt);
|
||||
}
|
||||
|
||||
double turn_radius_ft;
|
||||
double turn_circum_ft;
|
||||
|
@ -295,6 +303,8 @@ void FGAIAircraft::SetFlightPlan(FGAIFlightPlan *f) {
|
|||
}
|
||||
|
||||
void FGAIAircraft::ProcessFlightPlan( double dt ) {
|
||||
|
||||
|
||||
FGAIFlightPlan::waypoint* prev = 0; // the one behind you
|
||||
FGAIFlightPlan::waypoint* curr = 0; // the one ahead
|
||||
FGAIFlightPlan::waypoint* next = 0; // the next plus 1
|
||||
|
@ -348,10 +358,35 @@ void FGAIAircraft::ProcessFlightPlan( double dt ) {
|
|||
|
||||
if ( dist_to_go < lead_dist ) {
|
||||
if (curr->finished) { //end of the flight plan, so terminate
|
||||
setDie(true);
|
||||
return;
|
||||
if (trafficRef)
|
||||
{
|
||||
delete fp;
|
||||
//time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
trafficRef->next();
|
||||
|
||||
FGAIModelEntity entity;
|
||||
entity.m_class = "jet_transport";
|
||||
//entity.path = modelPath.c_str();
|
||||
entity.flightplan = "none";
|
||||
entity.latitude = _getLatitude();
|
||||
entity.longitude = _getLongitude();
|
||||
entity.altitude = trafficRef->getCruiseAlt() * 100; // convert from FL to feet
|
||||
entity.speed = 450;
|
||||
//entity.fp = new FGAIFlightPlan(&entity, courseToDest, i->getDepartureTime(), dep, arr);
|
||||
entity.fp = new FGAIFlightPlan(&entity,
|
||||
999, // A hack
|
||||
trafficRef->getDepartureTime(),
|
||||
trafficRef->getDepartureAirport(),
|
||||
trafficRef->getArrivalAirport());
|
||||
SetFlightPlan(entity.fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
setDie(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// we've reached the lead-point for the waypoint ahead
|
||||
// we've reached the lead-point for the waypoint ahead
|
||||
if (next) tgt_heading = fp->getBearing(curr, next);
|
||||
fp->IncrementWaypoint();
|
||||
prev = fp->getPreviousWaypoint();
|
||||
|
@ -386,6 +421,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt ) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
bool FGAIAircraft::_getGearDown() const {
|
||||
return ((props->getFloatValue("position/altitude-agl-ft") < 900.0)
|
||||
&& (props->getFloatValue("velocities/airspeed-kt")
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include "AIManager.hxx"
|
||||
#include "AIBase.hxx"
|
||||
|
||||
#include <Traffic/SchedFlight.hxx>
|
||||
#include <Traffic/Schedule.hxx>
|
||||
|
||||
#include <string>
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
@ -49,7 +52,7 @@ public:
|
|||
enum aircraft_e {LIGHT=0, WW2_FIGHTER, JET_TRANSPORT, JET_FIGHTER, TANKER};
|
||||
static const PERF_STRUCT settings[];
|
||||
|
||||
FGAIAircraft(FGAIManager* mgr);
|
||||
FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref=0);
|
||||
~FGAIAircraft();
|
||||
|
||||
bool init();
|
||||
|
@ -70,7 +73,8 @@ public:
|
|||
inline void SetTanker(bool setting) { isTanker = setting; };
|
||||
|
||||
private:
|
||||
|
||||
FGAISchedule *trafficRef;
|
||||
|
||||
bool hdg_lock;
|
||||
bool alt_lock;
|
||||
double dt_count;
|
||||
|
|
|
@ -136,7 +136,7 @@ bool FGAIBase::init() {
|
|||
props = root->getNode(_type_str.c_str(), index, true);
|
||||
|
||||
if (model_path != "") {
|
||||
model = sgLoad3DModel( globals->get_fg_root(),
|
||||
model = load3DModel( globals->get_fg_root(),
|
||||
model_path.c_str(),
|
||||
props,
|
||||
globals->get_sim_time_sec() );
|
||||
|
@ -157,6 +157,36 @@ bool FGAIBase::init() {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
ssgBranch * FGAIBase::load3DModel(const string& fg_root,
|
||||
const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec)
|
||||
{
|
||||
// some more code here to check whether a model with this name has already been loaded
|
||||
// if not load it, otherwise, get the memory pointer and do something like
|
||||
// SetModel as in ATC/AIEntity.cxx
|
||||
//SSGBranch *model;
|
||||
model = manager->getModel(path);
|
||||
if (!(model))
|
||||
{
|
||||
model = sgLoad3DModel(fg_root,
|
||||
path,
|
||||
prop_root,
|
||||
sim_time_sec);
|
||||
manager->setModel(path, model);
|
||||
model->ref();
|
||||
}
|
||||
//else
|
||||
// {
|
||||
// model->ref();
|
||||
// aip.init(model);
|
||||
// aip.setVisible(false);
|
||||
// globals->get_scenery()->get_scene_graph()->addKid(aip.getSceneGraph());
|
||||
// do some setModel stuff.
|
||||
return model;
|
||||
}
|
||||
|
||||
bool FGAIBase::isa( object_type otype ) {
|
||||
if ( otype == _otype ) { return true; }
|
||||
else { return false; }
|
||||
|
|
|
@ -202,6 +202,10 @@ public:
|
|||
int _getID() const;
|
||||
|
||||
inline double _getRange() { return range; };
|
||||
ssgBranch * load3DModel(const string& fg_root,
|
||||
const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec);
|
||||
|
||||
static bool _isNight();
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
FGAIFlightPlan::FGAIFlightPlan(string filename)
|
||||
{
|
||||
int i;
|
||||
start_time = 0;
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( ("/Data/AI/FlightPlans/" + filename).c_str() );
|
||||
SGPropertyNode root;
|
||||
|
@ -90,16 +91,30 @@ FGAIFlightPlan::FGAIFlightPlan(string filename)
|
|||
// as setting speeds and altitude computed by the
|
||||
// traffic manager.
|
||||
FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
|
||||
double course,
|
||||
double course,
|
||||
time_t start,
|
||||
FGAirport *dep,
|
||||
FGAirport *arr)
|
||||
{
|
||||
start_time = start;
|
||||
bool useInitialWayPoint = true;
|
||||
bool useCurrentWayPoint = false;
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "/Data/AI/FlightPlans" );
|
||||
path.append( entity->path );
|
||||
SGPropertyNode root;
|
||||
|
||||
// This is a bit of a hack:
|
||||
// Normally the value of course will be used to evaluate whether
|
||||
// or not a waypoint will be used for midair initialization of
|
||||
// an AI aircraft. However, if a course value of 999 will be passed
|
||||
// when an update request is received, which will by definition always be
|
||||
// on the ground and should include all waypoints.
|
||||
if (course == 999)
|
||||
{
|
||||
useInitialWayPoint = false;
|
||||
useCurrentWayPoint = true;
|
||||
}
|
||||
|
||||
try {
|
||||
readProperties(path.str(), &root);
|
||||
|
@ -160,7 +175,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
|
|||
(*i)->altitude);
|
||||
double crse, crsDiff;
|
||||
double dist;
|
||||
first.CourseAndDistance(curr, &crse, &dist);
|
||||
curr.CourseAndDistance(first, &crse, &dist);
|
||||
|
||||
dist *= SG_METER_TO_NM;
|
||||
|
||||
|
@ -182,8 +197,8 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
|
|||
// so once is the useWpt flag is set to true, we cannot reset it to false.
|
||||
//cerr << "Discarding waypoint: " << (*i)->name
|
||||
// << ": Course difference = " << crsDiff
|
||||
// << "Course = " << course
|
||||
// << "crse = " << crse << endl;
|
||||
// << "Course = " << course
|
||||
// << "crse = " << crse << endl;
|
||||
}
|
||||
else
|
||||
useCurrentWayPoint = true;
|
||||
|
@ -192,10 +207,14 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
|
|||
{
|
||||
if ((dist > 100.0) && (useInitialWayPoint))
|
||||
{
|
||||
//waypoints.push_back(init_waypoint);
|
||||
//waypoints.push_back(init_waypoint);;
|
||||
waypoints.insert(i, init_waypoint);
|
||||
//cerr << "Using waypoint : " << init_waypoint->name << endl;
|
||||
}
|
||||
//if (useInitialWayPoint)
|
||||
// {
|
||||
// (*i)->speed = dist; // A hack
|
||||
// }
|
||||
//waypoints.push_back( wpt );
|
||||
//cerr << "Using waypoint : " << (*i)->name
|
||||
// << ": course diff : " << crsDiff
|
||||
|
@ -342,26 +361,35 @@ double FGAIFlightPlan::getBearing(double lat, double lon, waypoint* wp){
|
|||
*/
|
||||
void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double speed)
|
||||
{
|
||||
double wind_speed;
|
||||
double wind_speed;
|
||||
double wind_heading;
|
||||
FGRunway rwy;
|
||||
double lat, lon, az;
|
||||
double lat2, lon2, az2;
|
||||
int direction;
|
||||
|
||||
//waypoints.push_back(wpt);
|
||||
// Create the outbound taxi leg, for now simplified as a
|
||||
// Direct route from the airport center point to the start
|
||||
// of the runway.
|
||||
///////////////////////////////////////////////////////////
|
||||
//cerr << "Cruise Alt << " << alt << endl;
|
||||
//cerr << "Cruise Alt << " << alt << endl;
|
||||
// Temporary code to add some small random variation to aircraft parking positions;
|
||||
direction = (rand() % 360);
|
||||
geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction,
|
||||
100,
|
||||
&lat2, &lon2, &az2 );
|
||||
waypoint *wpt = new waypoint;
|
||||
wpt->name = dep->id; //wpt_node->getStringValue("name", "END");
|
||||
wpt->latitude = dep->latitude;
|
||||
wpt->longitude = dep->longitude;
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = dep->elevation + 19; // probably need to add some model height to it
|
||||
wpt->speed = 15;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
// Get the current active runway, based on code from David Luff
|
||||
|
@ -384,8 +412,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
|
|||
exit(1);
|
||||
}
|
||||
|
||||
double lat, lon, az;
|
||||
double lat2, lon2, az2;
|
||||
|
||||
double heading = rwy.heading;
|
||||
double azimuth = heading + 180.0;
|
||||
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
|
||||
|
@ -546,7 +573,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
|
|||
waypoints.push_back(wpt);
|
||||
//Runway Threshold
|
||||
geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
|
||||
rwy.length*0.45,
|
||||
rwy.length*0.45 * SG_FEET_TO_METER,
|
||||
&lat2, &lon2, &az2 );
|
||||
wpt = new waypoint;
|
||||
wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
|
||||
|
@ -575,28 +602,33 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
|
|||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = false;
|
||||
wpt->on_ground = true;
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
direction = (rand() % 360);
|
||||
geo_direct_wgs_84 ( 0, arr->latitude, arr->longitude, direction,
|
||||
100,
|
||||
&lat2, &lon2, &az2 );
|
||||
|
||||
// Add the final destination waypoint
|
||||
wpt = new waypoint;
|
||||
wpt->name = arr->id; //wpt_node->getStringValue("name", "END");
|
||||
wpt->latitude = arr->latitude;
|
||||
wpt->longitude = arr->longitude;
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = arr->elevation+19;
|
||||
wpt->speed = 15;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = false;
|
||||
wpt->on_ground = true;
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
// And finally one more named "END"
|
||||
wpt = new waypoint;
|
||||
wpt->name = "END"; //wpt_node->getStringValue("name", "END");
|
||||
wpt->latitude = arr->latitude;
|
||||
wpt->longitude = arr->longitude;
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = 19;
|
||||
wpt->speed = 15;
|
||||
wpt->crossat = -10000;
|
||||
|
@ -609,14 +641,14 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
|
|||
// And finally one more named "EOF"
|
||||
wpt = new waypoint;
|
||||
wpt->name = "EOF"; //wpt_node->getStringValue("name", "END");
|
||||
wpt->latitude = arr->latitude;
|
||||
wpt->longitude = arr->longitude;
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = 19;
|
||||
wpt->speed = 15;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = true;
|
||||
wpt->finished = true;
|
||||
wpt->on_ground = true;
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
FGAIFlightPlan(string filename);
|
||||
FGAIFlightPlan(FGAIModelEntity *entity,
|
||||
double course,
|
||||
time_t start,
|
||||
FGAirport *dep,
|
||||
FGAirport *arr);
|
||||
~FGAIFlightPlan();
|
||||
|
@ -66,6 +67,7 @@ public:
|
|||
double getLeadDistance( void ) const {return lead_distance;}
|
||||
double getBearing(waypoint* previous, waypoint* next);
|
||||
double getBearing(double lat, double lon, waypoint* next);
|
||||
time_t getStartTime() { return start_time; };
|
||||
|
||||
void create(FGAirport *dep, FGAirport *arr, double alt, double speed);
|
||||
|
||||
|
@ -79,6 +81,7 @@ private:
|
|||
|
||||
double distance_to_go;
|
||||
double lead_distance;
|
||||
time_t start_time;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#include <Main/fg_props.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
|
||||
#include <Airports/simple.hxx>
|
||||
#include <Traffic/SchedFlight.hxx>
|
||||
#include <Traffic/Schedule.hxx>
|
||||
#include <Traffic/TrafficMgr.hxx>
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "AIManager.hxx"
|
||||
|
@ -53,6 +58,11 @@ FGAIManager::~FGAIManager() {
|
|||
++ai_list_itr;
|
||||
}
|
||||
ai_list.clear();
|
||||
ModelVecIterator i = loadedModels.begin();
|
||||
while (i != loadedModels.end())
|
||||
{
|
||||
i->getModelId()->deRef();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,6 +98,7 @@ void FGAIManager::update(double dt) {
|
|||
// initialize these for finding nearest thermals
|
||||
range_nearest = 10000.0;
|
||||
strength = 0.0;
|
||||
FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("Traffic Manager");
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
|
@ -97,6 +108,7 @@ void FGAIManager::update(double dt) {
|
|||
ai_list_itr = ai_list.begin();
|
||||
while(ai_list_itr != ai_list.end()) {
|
||||
if ((*ai_list_itr)->getDie()) {
|
||||
tmgr->release((*ai_list_itr)->getID());
|
||||
--numObjects[(*ai_list_itr)->getType()];
|
||||
--numObjects[0];
|
||||
(*ai_list_itr)->unbind();
|
||||
|
@ -124,9 +136,9 @@ void FGAIManager::update(double dt) {
|
|||
|
||||
|
||||
void*
|
||||
FGAIManager::createAircraft( FGAIModelEntity *entity ) {
|
||||
FGAIManager::createAircraft( FGAIModelEntity *entity, FGAISchedule *ref) {
|
||||
|
||||
FGAIAircraft* ai_plane = new FGAIAircraft(this);
|
||||
FGAIAircraft* ai_plane = new FGAIAircraft(this, ref);
|
||||
ai_list.push_back(ai_plane);
|
||||
++numObjects[0];
|
||||
++numObjects[FGAIBase::otAircraft];
|
||||
|
@ -352,4 +364,25 @@ void FGAIManager::processScenario( string &filename ) {
|
|||
delete s;
|
||||
}
|
||||
|
||||
// This code keeps track of models that have already been loaded
|
||||
// Eventually we'd prbably need to find a way to keep track of models
|
||||
// that are unloaded again
|
||||
ssgBranch * FGAIManager::getModel(const string& path)
|
||||
{
|
||||
ModelVecIterator i = loadedModels.begin();
|
||||
while (i != loadedModels.end())
|
||||
{
|
||||
if (i->getPath() == path)
|
||||
return i->getModelId();
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FGAIManager::setModel(const string& path, ssgBranch *model)
|
||||
{
|
||||
loadedModels.push_back(FGModelID(path,model));
|
||||
}
|
||||
|
||||
|
||||
//end AIManager.cxx
|
||||
|
|
|
@ -33,7 +33,26 @@
|
|||
#include <AIModel/AIScenario.hxx>
|
||||
#include <AIModel/AIFlightPlan.hxx>
|
||||
|
||||
#include <Traffic/SchedFlight.hxx>
|
||||
#include <Traffic/Schedule.hxx>
|
||||
|
||||
SG_USING_STD(list);
|
||||
SG_USING_STD(vector);
|
||||
|
||||
class FGModelID
|
||||
{
|
||||
private:
|
||||
ssgBranch * model;
|
||||
string path;
|
||||
public:
|
||||
FGModelID(const string& pth, ssgBranch * mdl) { path =pth; model=mdl;};
|
||||
ssgBranch *getModelId() { return model;};
|
||||
const string & getPath() { return path;};
|
||||
};
|
||||
|
||||
typedef vector<FGModelID> ModelVec;
|
||||
typedef vector<FGModelID>::iterator ModelVecIterator;
|
||||
|
||||
class FGAIThermal;
|
||||
|
||||
|
||||
|
@ -51,6 +70,7 @@ private:
|
|||
// on the heap and ***DELETED WHEN REMOVED!!!!!***
|
||||
ai_list_type ai_list;
|
||||
ai_list_iterator ai_list_itr;
|
||||
ModelVec loadedModels;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -63,7 +83,7 @@ public:
|
|||
void update(double dt);
|
||||
|
||||
void* createBallistic( FGAIModelEntity *entity );
|
||||
void* createAircraft( FGAIModelEntity *entity );
|
||||
void* createAircraft( FGAIModelEntity *entity, FGAISchedule *ref=0 );
|
||||
void* createThermal( FGAIModelEntity *entity );
|
||||
void* createStorm( FGAIModelEntity *entity );
|
||||
void* createShip( FGAIModelEntity *entity );
|
||||
|
@ -85,6 +105,9 @@ public:
|
|||
|
||||
void processScenario( string &filename );
|
||||
|
||||
ssgBranch * getModel(const string& path);
|
||||
void setModel(const string& path, ssgBranch *model);
|
||||
|
||||
private:
|
||||
|
||||
bool initDone;
|
||||
|
|
|
@ -167,7 +167,6 @@ bool FGRunwayList::search( const string& aptid, const string& rwyno,
|
|||
}
|
||||
revrwyno = GetReverseRunwayNo(runwayno);
|
||||
}
|
||||
|
||||
runway_map_iterator pos;
|
||||
for ( pos = runways.lower_bound( aptid );
|
||||
pos != runways.upper_bound( aptid ); ++pos)
|
||||
|
|
|
@ -155,6 +155,14 @@ void FGAISchedule::update(time_t now)
|
|||
// of the first listed flight.
|
||||
sort(flights.begin(), flights.end());
|
||||
FGScheduledFlightVecIterator i = flights.begin();
|
||||
if (AIManagerRef)
|
||||
{
|
||||
// Check if this aircraft has been released.
|
||||
FGTrafficManager *tmgr = (FGTrafficManager *) globals->get_subsystem("Traffic Manager");
|
||||
if (tmgr->isReleased(AIManagerRef))
|
||||
AIManagerRef = 0;
|
||||
}
|
||||
|
||||
if (!AIManagerRef)
|
||||
{
|
||||
userLatitude = fgGetDouble("/position/latitude-deg");
|
||||
|
@ -173,7 +181,11 @@ void FGAISchedule::update(time_t now)
|
|||
// This flight is in progress, so we need to calculate it's
|
||||
// approximate position and -if in range- create an AIAircraft
|
||||
// object for it.
|
||||
if ((i->getDepartureTime() < now) && (i->getArrivalTime() > now))
|
||||
//if ((i->getDepartureTime() < now) && (i->getArrivalTime() > now))
|
||||
|
||||
|
||||
// Part of this flight is in the future.
|
||||
if (i->getArrivalTime() > now)
|
||||
{
|
||||
dep = i->getDepartureAirport();
|
||||
arr = i->getArrivalAirport ();
|
||||
|
@ -205,6 +217,7 @@ void FGAISchedule::update(time_t now)
|
|||
// arrival airport, in degrees. From here we can interpolate the
|
||||
// position of the aircraft by calculating the ratio between
|
||||
// total time enroute and elapsed time enroute.
|
||||
|
||||
totalTimeEnroute = i->getArrivalTime() - i->getDepartureTime();
|
||||
elapsedTimeEnroute = now - i->getDepartureTime();
|
||||
remainingTimeEnroute = i->getArrivalTime() - now;
|
||||
|
@ -226,8 +239,20 @@ void FGAISchedule::update(time_t now)
|
|||
|
||||
temp = sgCartToPolar3d(Point3D(newPos[0], newPos[1],newPos[2]));
|
||||
|
||||
lat = temp.lat() * SG_RADIANS_TO_DEGREES;
|
||||
lon = temp.lon() * SG_RADIANS_TO_DEGREES;
|
||||
if (now > i->getDepartureTime())
|
||||
{
|
||||
//cerr << "Lat = " << lat << ", lon = " << lon << endl;
|
||||
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
|
||||
lat = temp.lat() * SG_RADIANS_TO_DEGREES;
|
||||
lon = temp.lon() * SG_RADIANS_TO_DEGREES;
|
||||
//err << "Lat = " << lat << ", lon = " << lon << endl;
|
||||
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
lat = dep->latitude;
|
||||
lon = dep->longitude;
|
||||
}
|
||||
|
||||
SGWayPoint current (lon,
|
||||
lat,
|
||||
|
@ -240,8 +265,8 @@ void FGAISchedule::update(time_t now)
|
|||
i->getCruiseAlt());
|
||||
// We really only need distance to user
|
||||
// and course to destination
|
||||
current.CourseAndDistance(user, &courseToUser, &distanceToUser);
|
||||
current.CourseAndDistance(dest, &courseToDest, &distanceToDest);
|
||||
user.CourseAndDistance(current, &courseToUser, &distanceToUser);
|
||||
dest.CourseAndDistance(current, &courseToDest, &distanceToDest);
|
||||
speed = (distanceToDest*SG_METER_TO_NM) /
|
||||
((double) remainingTimeEnroute/3600.0);
|
||||
|
||||
|
@ -257,6 +282,15 @@ void FGAISchedule::update(time_t now)
|
|||
{
|
||||
string flightPlanName = dep->id + string("-") + arr->id +
|
||||
string(".xml");
|
||||
int alt;
|
||||
//if ((i->getDepartureTime() < now))
|
||||
//{
|
||||
// alt = i->getCruiseAlt() *100;
|
||||
// }
|
||||
//else
|
||||
//{
|
||||
// alt = dep->elevation+19;
|
||||
// }
|
||||
|
||||
FGAIModelEntity entity;
|
||||
|
||||
|
@ -265,13 +299,13 @@ void FGAISchedule::update(time_t now)
|
|||
entity.flightplan = flightPlanName.c_str();
|
||||
entity.latitude = lat;
|
||||
entity.longitude = lon;
|
||||
entity.altitude = i->getCruiseAlt() * 100; // convert from FL to feet
|
||||
entity.altitude = i->getCruiseAlt() *100; // convert from FL to feet
|
||||
entity.speed = 450;
|
||||
entity.fp = new FGAIFlightPlan(&entity, courseToDest, dep, arr);
|
||||
entity.fp = new FGAIFlightPlan(&entity, courseToDest, i->getDepartureTime(), dep, arr);
|
||||
|
||||
// Fixme: A non-existent model path results in an
|
||||
// abort, due to an unhandled exeption, in fg main loop.
|
||||
AIManagerRef = aimgr->createAircraft( &entity );
|
||||
AIManagerRef = aimgr->createAircraft( &entity, this);
|
||||
//cerr << "Created: " << AIManagerRef << endl;
|
||||
}
|
||||
return;
|
||||
|
@ -279,7 +313,7 @@ void FGAISchedule::update(time_t now)
|
|||
|
||||
// Both departure and arrival time are in the future, so this
|
||||
// the aircraft is parked at the departure airport.
|
||||
// Currently this status is mostly ignored, but in furture
|
||||
// Currently this status is mostly ignored, but in future
|
||||
// versions, code should go here that -if within user range-
|
||||
// positions these aircraft at parking locations at the airport.
|
||||
if ((i->getDepartureTime() > now) && (i->getArrivalTime() > now))
|
||||
|
@ -289,3 +323,11 @@ void FGAISchedule::update(time_t now)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGAISchedule::next()
|
||||
{
|
||||
flights.begin()->update();
|
||||
sort(flights.begin(), flights.end());
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define _FGSCHEDULE_HXX_
|
||||
|
||||
|
||||
|
||||
class FGAISchedule
|
||||
{
|
||||
private:
|
||||
|
@ -43,6 +44,7 @@ class FGAISchedule
|
|||
void* AIManagerRef;
|
||||
bool firstRun;
|
||||
|
||||
|
||||
public:
|
||||
FGAISchedule(); // constructor
|
||||
FGAISchedule(string, string, string, bool, FGScheduledFlightVec); // construct & init
|
||||
|
@ -51,6 +53,12 @@ class FGAISchedule
|
|||
~FGAISchedule(); //destructor
|
||||
|
||||
void update(time_t now);
|
||||
void next(); // forces the schedule to move on to the next flight.
|
||||
|
||||
time_t getDepartureTime () { return flights.begin()->getDepartureTime (); };
|
||||
FGAirport * getDepartureAirport () { return flights.begin()->getDepartureAirport(); };
|
||||
FGAirport * getArrivalAirport () { return flights.begin()->getArrivalAirport (); };
|
||||
int getCruiseAlt () { return flights.begin()->getCruiseAlt (); };
|
||||
// More member functions follow later
|
||||
|
||||
};
|
||||
|
|
|
@ -89,6 +89,26 @@ void FGTrafficManager::update(double something)
|
|||
currAircraft++;
|
||||
}
|
||||
|
||||
void FGTrafficManager::release(void *id)
|
||||
{
|
||||
releaseList.push_back(id);
|
||||
}
|
||||
|
||||
bool FGTrafficManager::isReleased(void *id)
|
||||
{
|
||||
IdListIterator i = releaseList.begin();
|
||||
while (i != releaseList.end())
|
||||
{
|
||||
if ((*i) == id)
|
||||
{
|
||||
releaseList.erase(i);
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FGTrafficManager::startXML () {
|
||||
//cout << "Start XML" << endl;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#include "Schedule.hxx"
|
||||
|
||||
|
||||
typedef vector<void *> IdList;
|
||||
typedef vector<void *>::iterator IdListIterator;
|
||||
|
||||
|
||||
class FGTrafficManager : public SGSubsystem, public XMLVisitor
|
||||
{
|
||||
private:
|
||||
|
@ -46,6 +50,8 @@ private:
|
|||
repeat;
|
||||
int cruiseAlt;
|
||||
bool heavy;
|
||||
|
||||
IdList releaseList;
|
||||
|
||||
FGScheduledFlightVec flights;
|
||||
|
||||
|
@ -54,6 +60,8 @@ public:
|
|||
|
||||
void init();
|
||||
void update(double time);
|
||||
void release(void *ref);
|
||||
bool isReleased(void *id);
|
||||
|
||||
// Some overloaded virtual XMLVisitor members
|
||||
virtual void startXML ();
|
||||
|
|
Loading…
Add table
Reference in a new issue