1
0
Fork 0

More work on AI/ATC integration:

- Fixed a bug in AI aircraft ground steering code: When aircraft were not moving, the value of headingchangeRate kept increasing to insane levels. Although this was clamped to a maximum of 30 degrees per second, the initial rate could still push the aircraft in the wrong direction. In practice, this bug would be visible when an AI aicraft would be pushed back, when it tended to veer to the right.
 - Make sure that the aircraft slows down well ahead of the pushback point. This change ensures that the AC will actually reach the pushback point. It also ensures a slightly tighter steering range.
 - AI ground steering rate is tuned to 30 degrees per second at a nominal taxispeed of 15. I now modulate the heading adjustment rate by manipulating the adjustment using a non-linear function (the sqrt). This allows for a slightly tighter turn radius at speeds < 15 and slightly looser turns at speeds > 15.
 - The AI Flightplan generation code can return false. This can be used to determine whether any additional AI aircraft may be created. Currently, the function returns false when no more parkings are available. This should limit the build-up of huge AIAircraft tower stacks.
 - The ground network can now graphically display all aircraft actitivy on the ground network by using a virtual marker system.
This commit is contained in:
Durk Talsma 2011-04-19 18:01:24 +02:00
parent ee9a5cf73d
commit a7ccae9fca
14 changed files with 258 additions and 108 deletions

View file

@ -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) {

View file

@ -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;

View file

@ -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

View file

@ -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;
}
/**

View file

@ -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)

View file

@ -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

View file

@ -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);
*/
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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();

View file

@ -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.

View file

@ -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;};

View file

@ -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