diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index 6a4ce077b..c9b5b7208 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -1,4 +1,4 @@ -// FGAIAircraft - FGAIBase-derived class creates an AI airplane +// // FGAIAircraft - FGAIBase-derived class creates an AI airplane // // Written by David Culp, started October 2003. // @@ -276,6 +276,19 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) { if (! leadPointReached(curr)) { controlHeading(curr); controlSpeed(curr, next); + if (speed < 0) { + cerr << getCallSign() + << ": verifying lead distance to waypoint : " + << fp->getCurrentWaypoint()->name << " " + << fp->getLeadDistance() << ". Distance to go " + << (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)) + << ". Target speed = " + << tgt_speed + << ". Current speed = " + << speed + << ". Minimum Bearing " << minBearing + << endl; + } } else { if (curr->finished) //end of the flight plan { @@ -676,7 +689,15 @@ bool FGAIAircraft::leadPointReached(FGAIFlightPlan::waypoint* curr) { //cerr << "2" << endl; double lead_dist = fp->getLeadDistance(); // experimental: Use fabs, because speed can be negative (I hope) during push_back. - + if ((dist_to_go < fabs(10.0* speed)) && (speed < 0) && (tgt_speed < 0) && fp->getCurrentWaypoint()->name == string("PushBackPoint")) { + tgt_speed = -(dist_to_go / 10.0); + if (tgt_speed > -0.5) { + tgt_speed = -0.5; + } + if (fp->getPreviousWaypoint()->speed < tgt_speed) { + fp->getPreviousWaypoint()->speed = tgt_speed; + } + } if (lead_dist < fabs(2*speed)) { //don't skip over the waypoint lead_dist = fabs(2*speed); @@ -936,8 +957,8 @@ void FGAIAircraft::updateHeading() { bank_sense = 1.0; } //if (trafficRef) - //cerr << trafficRef->getCallSign() << " Heading " - // << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << endl; + // cerr << trafficRef->getCallSign() << " Heading " + // << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << endl; //if (headingDiff > 60) { groundTargetSpeed = tgt_speed; // * cos(headingDiff * SG_DEGREES_TO_RADIANS); //groundTargetSpeed = tgt_speed - tgt_speed * (headingDiff/180); @@ -946,27 +967,34 @@ void FGAIAircraft::updateHeading() { //} if (sign(groundTargetSpeed) != sign(tgt_speed)) groundTargetSpeed = 0.21 * sign(tgt_speed); // to prevent speed getting stuck in 'negative' mode + + // Only update the target values when we're not moving because otherwise we might introduce an enormous target change rate while waiting a the gate, or holding. + if (speed != 0) { + if (headingDiff > 30.0) { + // invert if pushed backward + headingChangeRate += 10.0 * dt * sign(roll); - if (headingDiff > 30.0) { - // invert if pushed backward - headingChangeRate += 10.0 * dt * sign(roll); - - // Clamp the maximum steering rate to 30 degrees per second, - // But only do this when the heading error is decreasing. - if ((headingDiff < headingError)) { - if (headingChangeRate > 30) - headingChangeRate = 30; - else if (headingChangeRate < -30) - headingChangeRate = -30; + // Clamp the maximum steering rate to 30 degrees per second, + // But only do this when the heading error is decreasing. + if ((headingDiff < headingError)) { + if (headingChangeRate > 30) + headingChangeRate = 30; + else if (headingChangeRate < -30) + headingChangeRate = -30; + } + } else { + if (speed != 0) { + if (fabs(headingChangeRate) > headingDiff) + headingChangeRate = headingDiff*sign(roll); + else + headingChangeRate += dt * sign(roll); + } } - } else { - if (fabs(headingChangeRate) > headingDiff) - headingChangeRate = headingDiff*sign(roll); - else - headingChangeRate += dt * sign(roll); } - - hdg += headingChangeRate * dt * (fabs(speed) / 15); + if (trafficRef) + cerr << trafficRef->getCallSign() << " Heading " + << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << "Heading change rate : " << headingChangeRate << " bacnk sence " << bank_sense << endl; + hdg += headingChangeRate * dt * sqrt(fabs(speed) / 15); headingError = headingDiff; } else { if (fabs(speed) > 1.0) { diff --git a/src/AIModel/AIFlightPlan.cxx b/src/AIModel/AIFlightPlan.cxx index 914f5442c..2fa5c3609 100644 --- a/src/AIModel/AIFlightPlan.cxx +++ b/src/AIModel/AIFlightPlan.cxx @@ -1,4 +1,4 @@ -// FGAIFlightPlan - class for loading and storing AI flight plans +// // FGAIFlightPlan - class for loading and storing AI flight plans // Written by David Culp, started May 2004 // - davidculp2@comcast.net // @@ -50,6 +50,7 @@ FGAIFlightPlan::FGAIFlightPlan() { sid = 0; wpt_iterator = waypoints.begin(); + isValid = true; } FGAIFlightPlan::FGAIFlightPlan(const string& filename) @@ -98,6 +99,7 @@ FGAIFlightPlan::FGAIFlightPlan(const string& filename) } wpt_iterator = waypoints.begin(); + isValid = true; //cout << waypoints.size() << " waypoints read." << endl; } @@ -137,7 +139,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac, path.append( p ); SGPropertyNode root; - + isValid = true; // 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 @@ -205,7 +207,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac, SG_LOG(SG_GENERAL, SG_INFO, "Route from " << dep->getId() << " to " << arr->getId() << ". Set leg to : " << leg << " " << ac->getTrafficRef()->getCallSign()); wpt_iterator = waypoints.begin(); bool dist = 0; - create(ac, dep,arr, leg, alt, speed, lat, lon, + isValid = create(ac, dep,arr, leg, alt, speed, lat, lon, firstLeg, radius, fltType, acType, airline, dist); wpt_iterator = waypoints.begin(); //cerr << "after create: " << (*wpt_iterator)->name << endl; diff --git a/src/AIModel/AIFlightPlan.hxx b/src/AIModel/AIFlightPlan.hxx index e9090ce35..44485ae75 100644 --- a/src/AIModel/AIFlightPlan.hxx +++ b/src/AIModel/AIFlightPlan.hxx @@ -87,10 +87,10 @@ public: time_t getStartTime() const { return start_time; } time_t getArrivalTime() const { return arrivalTime; } - void create(FGAIAircraft *, FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon, + bool create(FGAIAircraft *, FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon, bool firstLeg, double radius, const std::string& fltType, const std::string& aircraftType, const std::string& airline, double distance); - void createPushBack(FGAIAircraft *, bool, FGAirport*, double, double, double, const std::string&, const std::string&, const std::string&); - void createTakeOff(FGAIAircraft *, bool, FGAirport *, double, const std::string&); + bool createPushBack(FGAIAircraft *, bool, FGAirport*, double, double, double, const std::string&, const std::string&, const std::string&); + bool createTakeOff(FGAIAircraft *, bool, FGAirport *, double, const std::string&); void setLeg(int val) { leg = val;} void setTime(time_t st) { start_time = st; } @@ -142,20 +142,21 @@ private: std::string activeRunway; FGTaxiRoute *taxiRoute; std::string name; + bool isValid; void createPushBackFallBack(FGAIAircraft *, bool, FGAirport*, double, double, double, const std::string&, const std::string&, const std::string&); - void createClimb(FGAIAircraft *, bool, FGAirport *, double, double, const std::string&); - void createCruise(FGAIAircraft *, bool, FGAirport*, FGAirport*, double, double, double, double, const std::string&); - void createDescent(FGAIAircraft *, FGAirport *, double latitude, double longitude, double speed, double alt,const std::string&, double distance); - void createLanding(FGAIAircraft *, FGAirport *, const std::string&); - void createParking(FGAIAircraft *, FGAirport *, double radius); + bool createClimb(FGAIAircraft *, bool, FGAirport *, 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 resetWaypoints(); - void createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline); + bool createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline); void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport); void createDefaultTakeoffTaxi(FGAIAircraft *, FGAirport* aAirport, FGRunway* aRunway); - void createTakeoffTaxi(FGAIAircraft *, bool firstFlight, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline); + 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); @@ -170,7 +171,7 @@ private: public: wpt_vector_iterator getFirstWayPoint() { return waypoints.begin(); }; wpt_vector_iterator getLastWayPoint() { return waypoints.end(); }; - + bool isValidPlan() { return isValid; }; }; #endif // _FG_AIFLIGHTPLAN_HXX diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx index a0a396d8f..9ba1c4d8b 100644 --- a/src/AIModel/AIFlightPlanCreate.cxx +++ b/src/AIModel/AIFlightPlanCreate.cxx @@ -47,7 +47,7 @@ // Check lat/lon values during initialization; -void FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep, +bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep, FGAirport * arr, int legNr, double alt, double speed, double latitude, double longitude, bool firstFlight, @@ -55,38 +55,39 @@ void FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep, const string & aircraftType, const string & airline, double distance) { + bool retVal = true; int currWpt = wpt_iterator - waypoints.begin(); switch (legNr) { case 1: - createPushBack(ac, firstFlight, dep, latitude, longitude, - radius, fltType, aircraftType, airline); + retVal = createPushBack(ac, firstFlight, dep, latitude, longitude, + radius, fltType, aircraftType, airline); break; case 2: - createTakeoffTaxi(ac, firstFlight, dep, radius, fltType, + retVal = createTakeoffTaxi(ac, firstFlight, dep, radius, fltType, aircraftType, airline); break; case 3: - createTakeOff(ac, firstFlight, dep, speed, fltType); + retVal = createTakeOff(ac, firstFlight, dep, speed, fltType); break; case 4: - createClimb(ac, firstFlight, dep, speed, alt, fltType); + retVal = createClimb(ac, firstFlight, dep, speed, alt, fltType); break; case 5: - createCruise(ac, firstFlight, dep, arr, latitude, longitude, speed, + retVal = createCruise(ac, firstFlight, dep, arr, latitude, longitude, speed, alt, fltType); break; case 6: - createDescent(ac, arr, latitude, longitude, speed, alt, fltType, + retVal = createDescent(ac, arr, latitude, longitude, speed, alt, fltType, distance); break; case 7: - createLanding(ac, arr, fltType); + retVal = createLanding(ac, arr, fltType); break; case 8: - createLandingTaxi(ac, arr, radius, fltType, aircraftType, airline); + retVal = createLandingTaxi(ac, arr, radius, fltType, aircraftType, airline); break; case 9: - createParking(ac, arr, radius); + retVal = createParking(ac, arr, radius); break; default: //exit(1); @@ -96,6 +97,7 @@ void FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep, } wpt_iterator = waypoints.begin() + currWpt; leg++; + return retVal; } FGAIFlightPlan::waypoint * @@ -200,7 +202,7 @@ void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAIAircraft * ac, waypoints.push_back(wpt); } -void FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, +bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, FGAirport * apt, double radius, const string & fltType, @@ -240,7 +242,7 @@ void FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, FGGroundNetwork *gn = apt->getDynamics()->getGroundNetwork(); if (!gn->exists()) { createDefaultTakeoffTaxi(ac, apt, rwy); - return; + return true; } intVec ids; @@ -278,7 +280,7 @@ void FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, if (taxiRoute->empty()) { createDefaultTakeoffTaxi(ac, apt, rwy); - return; + return true; } taxiRoute->first(); @@ -313,6 +315,7 @@ void FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, wpt->routeIndex = route; waypoints.push_back(wpt); } + return true; } void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac, @@ -341,7 +344,7 @@ void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac, waypoints.push_back(wpt); } -void FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, +bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, double radius, const string & fltType, const string & acType, @@ -360,7 +363,7 @@ void FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, // Find a route from runway end to parking/gate. if (!gn->exists()) { createDefaultLandingTaxi(ac, apt); - return; + return true; } intVec ids; @@ -379,7 +382,7 @@ void FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, if (taxiRoute->empty()) { createDefaultLandingTaxi(ac, apt); - return; + return true; } int node; @@ -399,6 +402,7 @@ void FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, wpt->routeIndex = route; waypoints.push_back(wpt); } + return true; } /******************************************************************* @@ -412,7 +416,7 @@ void FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, * more likely however. * ******************************************************************/ -void FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight, +bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight, FGAirport * apt, double speed, const string & fltType) { @@ -487,13 +491,14 @@ void FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight, wpt = cloneWithPos(ac, wpt, "5000 ft", pt); wpt->altitude = airportElev + 5000; waypoints.push_back(wpt); + return true; } /******************************************************************* * CreateClimb * initialize the Aircraft at the parking location ******************************************************************/ -void FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight, +bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight, FGAirport * apt, double speed, double alt, const string & fltType) { @@ -527,6 +532,7 @@ void FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight, wpt->altitude = 18000; waypoints.push_back(wpt); } + return true; } @@ -536,7 +542,7 @@ void FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight, * Generate a flight path from the last waypoint of the cruise to * the permission to land point ******************************************************************/ -void FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt, +bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt, double latitude, double longitude, double speed, double alt, const string & fltType, @@ -823,8 +829,7 @@ void FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt, //cerr << "Repositioning to waypoint " << (*waypoints.begin())->name << endl; ac->resetPositionFromFlightPlan(); } - - + return true; } /******************************************************************* @@ -833,7 +838,7 @@ void FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt, hardcoded at 5000 meters from the threshold) to the threshold, at a standard glide slope angle of 3 degrees. ******************************************************************/ -void FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt, +bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt, const string & fltType) { double vTouchdown = ac->getPerformance()->vTouchdown(); @@ -873,13 +878,14 @@ void FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt, wpt->crossat = apt->getElevation(); waypoints.push_back(wpt); */ + return true; } /******************************************************************* * CreateParking * initialize the Aircraft at the parking location ******************************************************************/ -void FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt, +bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt, double radius) { waypoint *wpt; @@ -914,6 +920,7 @@ void FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt, createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), aptElev, vTaxiReduced); waypoints.push_back(wpt); + return true; } /** diff --git a/src/AIModel/AIFlightPlanCreateCruise.cxx b/src/AIModel/AIFlightPlanCreateCruise.cxx index 1932de9ce..05f80c89a 100644 --- a/src/AIModel/AIFlightPlanCreateCruise.cxx +++ b/src/AIModel/AIFlightPlanCreateCruise.cxx @@ -286,7 +286,7 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep, * Note that this is the original version that does not * do any dynamic route computation. ******************************************************************/ -void FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport *dep, +bool FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport *dep, FGAirport *arr, double latitude, double longitude, double speed, double alt, const string& fltType) diff --git a/src/AIModel/AIFlightPlanCreatePushBack.cxx b/src/AIModel/AIFlightPlanCreatePushBack.cxx index 34f21a1fc..191423ff9 100644 --- a/src/AIModel/AIFlightPlanCreatePushBack.cxx +++ b/src/AIModel/AIFlightPlanCreatePushBack.cxx @@ -37,7 +37,7 @@ // TODO: Use James Turner's createOnGround functions. -void FGAIFlightPlan::createPushBack(FGAIAircraft *ac, +bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep, double latitude, double longitude, @@ -71,6 +71,7 @@ void FGAIFlightPlan::createPushBack(FGAIAircraft *ac, " of flight type " << fltType << " of airline " << airline << " at airport " << dep->getId()); + return false; char buffer[10]; snprintf (buffer, 10, "%d", gateId); //FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node); @@ -104,7 +105,7 @@ void FGAIFlightPlan::createPushBack(FGAIAircraft *ac, if (gateId < 0) { createPushBackFallBack(ac, firstFlight, dep, latitude, longitude, radius, fltType, aircraftType, airline); - return; + return true; } //cerr << "getting parking " << gateId; @@ -231,6 +232,7 @@ void FGAIFlightPlan::createPushBack(FGAIAircraft *ac, } } + return true; } /******************************************************************* * createPushBackFallBack diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx index dace2d26c..a05654cfe 100644 --- a/src/ATC/atc_mgr.cxx +++ b/src/ATC/atc_mgr.cxx @@ -157,9 +157,9 @@ void FGATCManager::init() { //dialog.init(); - osg::Node* node = apt->getDynamics()->getGroundNetwork()->getRenderNode(); - cerr << "Adding groundnetWork to the scenegraph" << endl; - globals->get_scenery()->get_scene_graph()->addChild(node); + //osg::Node* node = apt->getDynamics()->getGroundNetwork()->getRenderNode(); + //cerr << "Adding groundnetWork to the scenegraph::init" << endl; + //globals->get_scenery()->get_scene_graph()->addChild(node); } } @@ -177,7 +177,7 @@ void FGATCManager::update ( double time ) { double speed = fgGetDouble("/velocities/groundspeed-kt"); double altitude = fgGetDouble("/position/altitude-ft"); - cerr << "Running FGATCManager::update()" << endl; + //cerr << "Running FGATCManager::update()" << endl; controller->updateAircraftInformation(ai_ac.getID(), latitude, longitude, @@ -185,10 +185,10 @@ void FGATCManager::update ( double time ) { speed, altitude, time); } - /*string airport = fgGetString("/sim/presets/airport-id"); + string airport = fgGetString("/sim/presets/airport-id"); FGAirport *apt = FGAirport::findByIdent(airport); osg::Node* node = apt->getDynamics()->getGroundNetwork()->getRenderNode(); - cerr << "Adding groundnetWork to the scenegraph" << endl; + //cerr << "Adding groundnetWork to the scenegraph::update" << endl; + globals->get_scenery()->get_scene_graph()->addChild(node); -*/ } diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index c6b14504c..dc7d8c5f3 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -419,6 +419,7 @@ bool FGTrafficRecord::pushBackAllowed() // In essence, we should check whether the pusbback route itself, as well as the associcated // taxiways near the pushback point are free of traffic. // To do so, we need to + return true; } diff --git a/src/ATC/trafficcontrol.hxx b/src/ATC/trafficcontrol.hxx index 66381af52..a60ffd468 100644 --- a/src/ATC/trafficcontrol.hxx +++ b/src/ATC/trafficcontrol.hxx @@ -182,6 +182,8 @@ public: void allowRepeatedTransmissions () { allowTransmission=true; }; void nextFrequency() { frequencyId++; }; int getNextFrequency() { return frequencyId; }; + intVec& getIntentions() { return intentions; }; + int getCurrentPosition() { return currentPos; }; }; typedef vector<FGTrafficRecord> TrafficVector; diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx index a87861fab..2c676d2e4 100644 --- a/src/Airports/groundnetwork.cxx +++ b/src/Airports/groundnetwork.cxx @@ -1,3 +1,4 @@ + // groundnet.cxx - Implimentation of the FlightGear airport ground handling code // // Written by Durk Talsma, started June 2005. @@ -36,6 +37,8 @@ #include <simgear/debug/logstream.hxx> #include <simgear/route/waypoint.hxx> #include <simgear/scene/material/EffectGeode.hxx> +#include <simgear/scene/material/matlib.hxx> +#include <simgear/scene/material/mat.hxx> #include <Airports/simple.hxx> #include <Airports/dynamics.hxx> @@ -43,6 +46,8 @@ #include <AIModel/AIAircraft.hxx> #include <AIModel/AIFlightPlan.hxx> +#include <Scenery/scenery.hxx> + #include "groundnetwork.hxx" /*************************************************************************** @@ -93,7 +98,7 @@ void FGTaxiSegment::setDimensions(double elevation) SGGeodesy::inverse(start->getGeod(), end->getGeod(), heading, az2, length); double coveredDistance = length * 0.5; SGGeodesy::direct(start->getGeod(), heading, coveredDistance, center, az2); - cerr << "Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl; + //cerr << "Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl; } @@ -205,6 +210,7 @@ FGGroundNetwork::FGGroundNetwork() //maxDepth = 1000; count = 0; currTraffic = activeTraffic.begin(); + group = 0; } @@ -1096,34 +1102,107 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat, + osg::Node* FGGroundNetwork::getRenderNode() { - osg::Group* group = new osg::Group; - for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) { - osg::Matrix obj_pos; - osg::MatrixTransform *obj_trans = new osg::MatrixTransform; - obj_trans->setDataVariance(osg::Object::STATIC); - WorldCoordinate( obj_pos, (*i)->getLatitude(), (*i)->getLongitude(), parent->elevation()+10, -((*i)->getHeading()) ); + SGMaterialLib *matlib = globals->get_matlib(); + if (group) { + //int nr = ; + globals->get_scenery()->get_scene_graph()->removeChild(group); + //while (group->getNumChildren()) { + // cerr << "Number of children: " << group->getNumChildren() << endl; + simgear::EffectGeode* geode = (simgear::EffectGeode*) group->getChild(0); + //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0); + //geode->releaseGLObjects(); + //group->removeChild(geode); + //delete geode; + } + group = new osg::Group; + + //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) { + double dx = 0; + for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) { + // Handle start point + int pos = i->getCurrentPosition() - 1; + if (pos >= 0) { + + SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude()))); + SGGeod end (SGGeod::fromDeg(segments[pos]->getEnd()->getLongitude(), segments[pos]->getEnd()->getLatitude())); + + double length = SGGeodesy::distanceM(start, end); + //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod()); + + double az2, heading; //, distanceM; + SGGeodesy::inverse(start, end, heading, az2, length); + double coveredDistance = length * 0.5; + SGGeod center; + SGGeodesy::direct(start, heading, coveredDistance, center, az2); + //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl; + /////////////////////////////////////////////////////////////////////////////// + // Make a helper function out of this + osg::Matrix obj_pos; + osg::MatrixTransform *obj_trans = new osg::MatrixTransform; + obj_trans->setDataVariance(osg::Object::STATIC); + + WorldCoordinate( obj_pos, center.getLatitudeDeg(), center.getLongitudeDeg(), parent->elevation()+8+dx, -(heading) ); obj_trans->setMatrix( obj_pos ); - //osg::Vec3 center(0, 0, 0) + //osg::Vec3 center(0, 0, 0) - float width = (*i)->getLength() /2.0; - osg::Vec3 corner(-width, 0, 0.25f); - osg::Vec3 widthVec(2*width + 1, 0, 0); - osg::Vec3 heightVec(0, 0, 1); - osg::Geometry* geometry; - geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec); - simgear::EffectGeode* geode = new simgear::EffectGeode; - geode->setName("test"); - geode->addDrawable(geometry); - //osg::Node *custom_obj; - - obj_trans->addChild(geode); - // wire as much of the scene graph together as we can - //->addChild( obj_trans ); - group->addChild( obj_trans ); + float width = length /2.0; + osg::Vec3 corner(-width, 0, 0.25f); + osg::Vec3 widthVec(2*width + 1, 0, 0); + osg::Vec3 heightVec(0, 1, 0); + osg::Geometry* geometry; + geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec); + simgear::EffectGeode* geode = new simgear::EffectGeode; + geode->setName("test"); + geode->addDrawable(geometry); + //osg::Node *custom_obj; + SGMaterial *mat = matlib->find("UnidirectionalTaper"); + if (mat) + geode->setEffect(mat->get_effect()); + obj_trans->addChild(geode); + // wire as much of the scene graph together as we can + //->addChild( obj_trans ); + group->addChild( obj_trans ); + ///////////////////////////////////////////////////////////////////// + } else { + cerr << "BIG FAT WARNING: current position is here : " << pos << endl; + } + for(intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) { + osg::Matrix obj_pos; + int k = (*j)-1; + if (k >= 0) { + osg::MatrixTransform *obj_trans = new osg::MatrixTransform; + obj_trans->setDataVariance(osg::Object::STATIC); + + WorldCoordinate( obj_pos, segments[k]->getLatitude(), segments[k]->getLongitude(), parent->elevation()+8+dx, -(segments[k]->getHeading()) ); + + obj_trans->setMatrix( obj_pos ); + //osg::Vec3 center(0, 0, 0) + + float width = segments[k]->getLength() /2.0; + osg::Vec3 corner(-width, 0, 0.25f); + osg::Vec3 widthVec(2*width + 1, 0, 0); + osg::Vec3 heightVec(0, 1, 0); + osg::Geometry* geometry; + geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec); + simgear::EffectGeode* geode = new simgear::EffectGeode; + geode->setName("test"); + geode->addDrawable(geometry); + //osg::Node *custom_obj; + SGMaterial *mat = matlib->find("UnidirectionalTaper"); + if (mat) + geode->setEffect(mat->get_effect()); + obj_trans->addChild(geode); + // wire as much of the scene graph together as we can + //->addChild( obj_trans ); + group->addChild( obj_trans ); + } + } + dx += 0.1; } diff --git a/src/Airports/groundnetwork.hxx b/src/Airports/groundnetwork.hxx index 319d8b2dd..57295c65f 100644 --- a/src/Airports/groundnetwork.hxx +++ b/src/Airports/groundnetwork.hxx @@ -24,6 +24,12 @@ #ifndef _GROUNDNETWORK_HXX_ #define _GROUNDNETWORK_HXX_ +#include <osg/Geode> +#include <osg/Geometry> +#include <osg/MatrixTransform> +#include <osg/Shape> + + #include <simgear/compiler.h> #include <simgear/route/waypoint.hxx> @@ -37,6 +43,7 @@ using std::vector; #include "parking.hxx" #include <ATC/trafficcontrol.hxx> + class FGTaxiSegment; // forward reference class FGAIFlightPlan; // forward reference class FGAirport; // forward reference @@ -242,6 +249,8 @@ private: void checkHoldPosition(int id, double lat, double lon, double heading, double speed, double alt); + osg::Group* group; + public: FGGroundNetwork(); ~FGGroundNetwork(); diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx index 11d8d0abe..3445e0a7a 100644 --- a/src/Traffic/Schedule.cxx +++ b/src/Traffic/Schedule.cxx @@ -68,6 +68,7 @@ FGAISchedule::FGAISchedule() radius = 0; groundOffset = 0; distanceToUser = 0; + valid = true; //score = 0; } @@ -120,6 +121,7 @@ FGAISchedule::FGAISchedule(string model, runCount = 0; hits = 0; initialized = false; + valid = true; } FGAISchedule::FGAISchedule(const FGAISchedule &other) @@ -146,6 +148,7 @@ FGAISchedule::FGAISchedule(const FGAISchedule &other) runCount = other.runCount; hits = other.hits; initialized = other.initialized; + valid = other.valid; } @@ -192,9 +195,12 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart) elapsedTimeEnroute, remainingTimeEnroute, deptime = 0; - + if (!valid) { + return false; + } scheduleFlights(); if (flights.empty()) { // No flights available for this aircraft + valid = false; return false; } @@ -211,7 +217,7 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart) firstRun = false; } - FGScheduledFlight* flight = flights.front(); + FGScheduledFlight* flight = flights.front(); if (!deptime) { deptime = flight->getDepartureTime(); //cerr << "Settiing departure time " << deptime << endl; @@ -329,19 +335,29 @@ bool FGAISchedule::createAIAircraft(FGScheduledFlight* flight, double speedKnots aircraft->setBank(0); courseToDest = SGGeodesy::courseDeg(position, arr->geod()); - aircraft->SetFlightPlan(new FGAIFlightPlan(aircraft, flightPlanName, courseToDest, deptime, - dep, arr, true, radius, - flight->getCruiseAlt()*100, - position.getLatitudeDeg(), - position.getLongitudeDeg(), - speedKnots, flightType, acType, - airline)); - - - FGAIManager* aimgr = (FGAIManager *) globals-> get_subsystem("ai_model"); - aimgr->attach(aircraft); - AIManagerRef = aircraft->getID(); - return true; + FGAIFlightPlan *fp = new FGAIFlightPlan(aircraft, flightPlanName, courseToDest, deptime, + dep, arr, true, radius, + flight->getCruiseAlt()*100, + position.getLatitudeDeg(), + position.getLongitudeDeg(), + speedKnots, flightType, acType, + airline); + if (fp->isValidPlan()) { + aircraft->SetFlightPlan(fp); + FGAIManager* aimgr = (FGAIManager *) globals-> get_subsystem("ai_model"); + aimgr->attach(aircraft); + AIManagerRef = aircraft->getID(); + return true; + } else { + delete aircraft; + delete fp; + //hand back the flights that had already been scheduled + while (!flights.empty()) { + flights.front()->release(); + flights.erase(flights.begin()); + } + return false; + } } // Create an initial heading for user controlled aircraft. diff --git a/src/Traffic/Schedule.hxx b/src/Traffic/Schedule.hxx index 92b7e78aa..1f508271b 100644 --- a/src/Traffic/Schedule.hxx +++ b/src/Traffic/Schedule.hxx @@ -59,6 +59,7 @@ class FGAISchedule bool firstRun; double courseToDest; bool initialized; + bool valid; void scheduleFlights(); @@ -124,6 +125,7 @@ class FGAISchedule // used to sort in decending order of score: I've probably found a better way to // decending order sorting, but still need to test that. bool operator< (const FGAISchedule &other) const { return (score > other.score); }; + void taint() { valid = false; }; //void * getAiRef () { return AIManagerRef; }; //FGAISchedule* getAddress () { return this;}; diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx index 4abbc1a20..9ebf78c1c 100644 --- a/src/Traffic/TrafficMgr.cxx +++ b/src/Traffic/TrafficMgr.cxx @@ -258,6 +258,7 @@ void FGTrafficManager::update(double /*dt */ ) } //cerr << "Processing << " << (*currAircraft)->getRegistration() << " with score " << (*currAircraft)->getScore() << endl; if (!((*currAircraft)->update(now, userCart))) { + (*currAircraft)->taint(); // NOTE: With traffic manager II, this statement below is no longer true // after proper initialization, we shouldnt get here. // But let's make sure