Merge branch 'next' of gitorious.org:fg/flightgear into next
This commit is contained in:
commit
777b983094
12 changed files with 220 additions and 155 deletions
|
@ -941,7 +941,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
}*/
|
||||
double rolloutDistance =
|
||||
(vTouchdownMetric * vTouchdownMetric - vTaxiMetric * vTaxiMetric) / (2 * decelMetric);
|
||||
cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
|
||||
//cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
|
||||
int nPoints = 50;
|
||||
for (int i = 1; i < nPoints; i++) {
|
||||
snprintf(buffer, 12, "landing03%d", i);
|
||||
|
@ -983,7 +983,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
pushBackWaypoint(wpt);
|
||||
}
|
||||
}
|
||||
cerr << "Done. " << endl;
|
||||
//cerr << "Done. " << endl;
|
||||
|
||||
/*
|
||||
//Runway Threshold
|
||||
|
|
|
@ -187,12 +187,12 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
|
|||
if ((*i) != pos) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"Error in FGTrafficRecord::setPositionAndIntentions at " << SG_ORIGIN);
|
||||
//cerr << "Pos : " << pos << " Curr " << *(intentions.begin()) << endl;
|
||||
cerr << "Pos : " << pos << " Curr " << *(intentions.begin()) << endl;
|
||||
for (intVecIterator i = intentions.begin();
|
||||
i != intentions.end(); i++) {
|
||||
//cerr << (*i) << " ";
|
||||
cerr << (*i) << " ";
|
||||
}
|
||||
//cerr << endl;
|
||||
cerr << endl;
|
||||
}
|
||||
intentions.erase(i);
|
||||
} else {
|
||||
|
@ -878,11 +878,11 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
|
|||
// already exists here. So, we can simplify the current code.
|
||||
|
||||
ActiveRunwayVecIterator rwy = activeRunways.begin();
|
||||
if (parent->getId() == fgGetString("/sim/presets/airport-id")) {
|
||||
//for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) {
|
||||
// rwy->printDepartureCue();
|
||||
//}
|
||||
}
|
||||
//if (parent->getId() == fgGetString("/sim/presets/airport-id")) {
|
||||
// for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) {
|
||||
// rwy->printDepartureCue();
|
||||
// }
|
||||
//}
|
||||
|
||||
rwy = activeRunways.begin();
|
||||
while (rwy != activeRunways.end()) {
|
||||
|
@ -1318,6 +1318,7 @@ void FGStartupController::render(bool visible)
|
|||
|
||||
//for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
|
||||
double dx = 0;
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
if (i->isActive(300)) {
|
||||
// Handle start point
|
||||
|
@ -1387,7 +1388,7 @@ void FGStartupController::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segment->hasBlock()) {
|
||||
if (segment->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
@ -1464,7 +1465,7 @@ void FGStartupController::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segment->hasBlock()) {
|
||||
if (segment->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <Airports/dynamics.hxx>
|
||||
|
||||
#include <AIModel/AIAircraft.hxx>
|
||||
#include <AIModel/performancedata.hxx>
|
||||
#include <AIModel/AIFlightPlan.hxx>
|
||||
|
||||
#include <ATC/atc_mgr.hxx>
|
||||
|
@ -51,6 +52,7 @@
|
|||
|
||||
#include "groundnetwork.hxx"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FGTaxiSegment
|
||||
**************************************************************************/
|
||||
|
@ -113,6 +115,44 @@ void FGTaxiSegment::setDimensions(double elevation)
|
|||
// headingDiff = fabs(headingDiff - 360);
|
||||
//}
|
||||
|
||||
void FGTaxiSegment::block(int id, time_t blockTime, time_t now)
|
||||
{
|
||||
BlockListIterator i = blockTimes.begin();
|
||||
while (i != blockTimes.end()) {
|
||||
if (i->getId() == id)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i == blockTimes.end()) {
|
||||
blockTimes.push_back(Block(id, blockTime, now));
|
||||
sort(blockTimes.begin(), blockTimes.end());
|
||||
} else {
|
||||
i->updateTimeStamps(blockTime, now);
|
||||
}
|
||||
}
|
||||
|
||||
// The segment has a block if any of the block times listed in the block list is
|
||||
// smaller than the current time.
|
||||
bool FGTaxiSegment::hasBlock(time_t now)
|
||||
{
|
||||
for (BlockListIterator i = blockTimes.begin(); i != blockTimes.end(); i++) {
|
||||
if (i->getBlockTime() < now)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FGTaxiSegment::unblock(time_t now)
|
||||
{
|
||||
if (blockTimes.size()) {
|
||||
BlockListIterator i = blockTimes.begin();
|
||||
if (i->getTimeStamp() < (now - 30)) {
|
||||
blockTimes.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FGTaxiRoute
|
||||
|
@ -651,7 +691,11 @@ void FGGroundNetwork::announcePosition(int id,
|
|||
rec.setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||
rec.setRadius(radius); // only need to do this when creating the record.
|
||||
rec.setAircraft(aircraft);
|
||||
activeTraffic.push_front(rec);
|
||||
if (leg == 2) {
|
||||
activeTraffic.push_front(rec);
|
||||
} else {
|
||||
activeTraffic.push_back(rec);
|
||||
}
|
||||
|
||||
} else {
|
||||
i->setPositionAndIntentions(currentPosition, intendedRoute);
|
||||
|
@ -707,7 +751,7 @@ bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, Traffic
|
|||
trans_num->setIntValue(-1);
|
||||
// PopupCallback(n);
|
||||
//cerr << "Selected transmission message " << n << endl;
|
||||
FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
|
||||
//FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
|
||||
FGATCDialogNew::instance()->removeEntry(1);
|
||||
} else {
|
||||
//cerr << "creating message for " << i->getAircraft()->getCallSign() << endl;
|
||||
|
@ -985,6 +1029,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition at " << SG_ORIGIN);
|
||||
|
@ -996,7 +1041,9 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
return;
|
||||
}
|
||||
if (current->getAircraft()->getTakeOffStatus() == 2) {
|
||||
//cerr << current->getAircraft()->getCallSign() << ". Taxi in position and hold" << endl;
|
||||
current->setHoldPosition(false);
|
||||
current->clearSpeedAdjustment();
|
||||
return;
|
||||
}
|
||||
bool origStatus = current->hasHoldPosition();
|
||||
|
@ -1017,89 +1064,32 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
} else {
|
||||
nx = tx;
|
||||
}
|
||||
if (tx->hasBlock() || nx->hasBlock() ) {
|
||||
//if (tx->hasBlock(now) || nx->hasBlock(now) ) {
|
||||
// current->setHoldPosition(true);
|
||||
//}
|
||||
SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
|
||||
SGGeod end (SGGeod::fromDeg(nx->getStart()->getLongitude(), nx->getStart()->getLatitude()));
|
||||
|
||||
double distance = SGGeodesy::distanceM(start, end);
|
||||
if (nx->hasBlock(now) && (distance < i->getRadius() * 4)) {
|
||||
current->setHoldPosition(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* for (i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
if (i->getId() != current->getId()) {
|
||||
int node = current->crosses(this, *i);
|
||||
if (node != -1) {
|
||||
FGTaxiNode *taxiNode = findNode(node);
|
||||
|
||||
// Determine whether it's save to continue or not.
|
||||
// If we have a crossing route, there are two possibilities:
|
||||
// 1) This is an interestion
|
||||
// 2) This is oncoming two-way traffic, using the same taxiway.
|
||||
//cerr << "Hold check 1 : " << id << " has common node " << node << endl;
|
||||
|
||||
SGGeod other(SGGeod::
|
||||
fromDegM(i->getLongitude(), i->getLatitude(),
|
||||
i->getAltitude()));
|
||||
bool needsToWait;
|
||||
bool opposing;
|
||||
if (current->isOpposing(this, *i, node)) {
|
||||
needsToWait = true;
|
||||
opposing = true;
|
||||
//cerr << "Hold check 2 : " << node << " has opposing segment " << endl;
|
||||
// issue a "Hold Position" as soon as we're close to the offending node
|
||||
// For now, I'm doing this as long as the other aircraft doesn't
|
||||
// have a hold instruction as soon as we're within a reasonable
|
||||
// distance from the offending node.
|
||||
// This may be a bit of a conservative estimate though, as it may
|
||||
// be well possible that both aircraft can both continue to taxi
|
||||
// without crashing into each other.
|
||||
} else {
|
||||
opposing = false;
|
||||
if (SGGeodesy::distanceM(other, taxiNode->getGeod()) > 200) // 2.0*i->getRadius())
|
||||
{
|
||||
needsToWait = false;
|
||||
//cerr << "Hold check 3 : " << id <<" Other aircraft approaching node is still far away. (" << dist << " nm). Can safely continue "
|
||||
// << endl;
|
||||
} else {
|
||||
needsToWait = true;
|
||||
//cerr << "Hold check 4: " << id << " Would need to wait for other aircraft : distance = " << dist << " meters" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
double dist =
|
||||
SGGeodesy::distanceM(curr, taxiNode->getGeod());
|
||||
if (!(i->hasHoldPosition())) {
|
||||
|
||||
if ((dist < 200) && //2.5*current->getRadius()) &&
|
||||
(needsToWait) && (i->onRoute(this, *current)) &&
|
||||
//((i->onRoute(this, *current)) || ((!(i->getSpeedAdjustment())))) &&
|
||||
(!(current->getId() == i->getWaitsForId())))
|
||||
//(!(i->getSpeedAdjustment()))) // &&
|
||||
//(!(current->getSpeedAdjustment())))
|
||||
|
||||
{
|
||||
if (!(isUserAircraft(i->getAircraft()))) { // test code. Don't wait for the user, let the user wait for you.
|
||||
current->setHoldPosition(true);
|
||||
current->setWaitsForId(i->getId());
|
||||
}
|
||||
//cerr << "Hold check 5: " << current->getCallSign() <<" Setting Hold Position: distance to node (" << node << ") "
|
||||
// << dist << " meters. Waiting for " << i->getCallSign();
|
||||
//if (opposing)
|
||||
//cerr <<" [opposing] " << endl;
|
||||
//else
|
||||
// cerr << "[non-opposing] " << endl;
|
||||
//if (i->hasSpeefAdjustment())
|
||||
// {
|
||||
// cerr << " (which in turn waits for ) " << i->
|
||||
} else {
|
||||
//cerr << "Hold check 6: " << id << " No need to hold yet: Distance to node : " << dist << " nm"<< endl;
|
||||
}
|
||||
} else {
|
||||
intVecIterator ivi = i->getIntentions().begin();
|
||||
while (ivi != i->getIntentions().end()) {
|
||||
if ((*ivi) > 0) {
|
||||
distance += segments[(*ivi)-1]->getLength();
|
||||
if ((segments[(*ivi)-1]->hasBlock(now)) && (distance < i->getRadius() * 4)) {
|
||||
current->setHoldPosition(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ivi++;
|
||||
}
|
||||
} */
|
||||
}
|
||||
}
|
||||
bool currStatus = current->hasHoldPosition();
|
||||
current->setHoldPosition(origStatus);
|
||||
// Either a Hold Position or a resume taxi transmission has been issued
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
if ((now - lastTransmission) > 2) {
|
||||
available = true;
|
||||
}
|
||||
|
@ -1348,6 +1338,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
FGScenery * local_scenery = globals->get_scenery();
|
||||
double elevation_meters = 0.0;
|
||||
double elevation_feet = 0.0;
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
//for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
|
||||
double dx = 0;
|
||||
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
|
@ -1417,7 +1408,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segments[pos]->hasBlock()) {
|
||||
if (segments[pos]->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
@ -1491,7 +1482,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segments[k]->hasBlock()) {
|
||||
if (segments[k]->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
@ -1516,8 +1507,9 @@ string FGGroundNetwork::getName() {
|
|||
|
||||
void FGGroundNetwork::update(double dt)
|
||||
{
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
(*tsi)->unblock();
|
||||
(*tsi)->unblock(now);
|
||||
}
|
||||
int priority = 1;
|
||||
//sort(activeTraffic.begin(), activeTraffic.end(), compare_trafficrecords);
|
||||
|
@ -1527,6 +1519,8 @@ void FGGroundNetwork::update(double dt)
|
|||
i != parent->getDynamics()->getStartupController()->getActiveTraffic().end(); i++) {
|
||||
i->allowPushBack();
|
||||
i->setPriority(priority++);
|
||||
// in meters per second;
|
||||
double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
|
||||
if (i->isActive(60)) {
|
||||
|
||||
// Check for all active aircraft whether it's current pos segment is
|
||||
|
@ -1540,7 +1534,7 @@ void FGGroundNetwork::update(double dt)
|
|||
for (intVecIterator k = i->getIntentions().begin(); k != i->getIntentions().end(); k++) {
|
||||
if ((*k) == posReverse) {
|
||||
i->denyPushBack();
|
||||
segments[posReverse-1]->block();
|
||||
segments[posReverse-1]->block(i->getId(), now, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1548,13 +1542,15 @@ void FGGroundNetwork::update(double dt)
|
|||
}
|
||||
// if the current aircraft is still allowed to pushback, we can start reserving a route for if by blocking all the entry taxiways.
|
||||
if (i->pushBackAllowed()) {
|
||||
double length = 0;
|
||||
int pos = i->getCurrentPosition();
|
||||
if (pos > 0) {
|
||||
FGTaxiSegment *seg = segments[pos-1];
|
||||
FGTaxiNode *node = seg->getEnd();
|
||||
length = seg->getLength();
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
|
||||
(*tsi)->block();
|
||||
(*tsi)->block(i->getId(), now, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1563,9 +1559,11 @@ void FGGroundNetwork::update(double dt)
|
|||
if (pos > 0) {
|
||||
FGTaxiSegment *seg = segments[pos-1];
|
||||
FGTaxiNode *node = seg->getEnd();
|
||||
length += seg->getLength();
|
||||
time_t blockTime = now + (length / vTaxi);
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
|
||||
(*tsi)->block();
|
||||
(*tsi)->block(i->getId(), blockTime-30, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1574,10 +1572,13 @@ void FGGroundNetwork::update(double dt)
|
|||
}
|
||||
}
|
||||
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
double length = 0;
|
||||
double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
|
||||
i->setPriority(priority++);
|
||||
int pos = i->getCurrentPosition();
|
||||
if (pos > 0) {
|
||||
if (segments[pos-1]->hasBlock()) {
|
||||
length = segments[pos-1]->getLength();
|
||||
if (segments[pos-1]->hasBlock(now)) {
|
||||
//SG_LOG(SG_GENERAL, SG_ALERT, "Taxiway incursion for AI aircraft" << i->getAircraft()->getCallSign());
|
||||
}
|
||||
|
||||
|
@ -1586,7 +1587,7 @@ void FGGroundNetwork::update(double dt)
|
|||
for (ivi = i->getIntentions().begin(); ivi != i->getIntentions().end(); ivi++) {
|
||||
int segIndex = (*ivi);
|
||||
if (segIndex > 0) {
|
||||
if (segments[segIndex-1]->hasBlock())
|
||||
if (segments[segIndex-1]->hasBlock(now))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1596,9 +1597,11 @@ void FGGroundNetwork::update(double dt)
|
|||
if (pos > 0) {
|
||||
FGTaxiSegment *seg = segments[pos-1];
|
||||
FGTaxiNode *node = seg->getEnd();
|
||||
length += seg->getLength();
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
|
||||
(*tsi)->block();
|
||||
time_t blockTime = now + (length / vTaxi);
|
||||
(*tsi)->block(i->getId(), blockTime - 30, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,12 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
class Block;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::list;
|
||||
|
||||
#include "gnnode.hxx"
|
||||
#include "parking.hxx"
|
||||
|
@ -54,6 +57,25 @@ typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
|
|||
//typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
|
||||
//typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
|
||||
|
||||
class Block
|
||||
{
|
||||
private:
|
||||
int id;
|
||||
time_t blocktime;
|
||||
time_t touch;
|
||||
public:
|
||||
Block(int i, time_t bt, time_t curr) { id = i; blocktime= bt; touch = curr; };
|
||||
~Block() {};
|
||||
int getId() { return id; };
|
||||
void updateTimeStamps(time_t bt, time_t now) { blocktime = (bt < blocktime) ? bt : blocktime; touch = now; };
|
||||
const time_t getBlockTime() const { return blocktime; };
|
||||
time_t getTimeStamp() { return touch; };
|
||||
bool operator< (const Block &other) const { return blocktime < other.blocktime; };
|
||||
};
|
||||
|
||||
typedef vector<Block> BlockList;
|
||||
typedef BlockList::iterator BlockListIterator;
|
||||
|
||||
/***************************************************************************************
|
||||
* class FGTaxiSegment
|
||||
**************************************************************************************/
|
||||
|
@ -67,7 +89,7 @@ private:
|
|||
SGGeod center;
|
||||
bool isActive;
|
||||
bool isPushBackRoute;
|
||||
bool isBlocked;
|
||||
BlockList blockTimes;
|
||||
FGTaxiNode *start;
|
||||
FGTaxiNode *end;
|
||||
int index;
|
||||
|
@ -83,7 +105,6 @@ public:
|
|||
heading(0),
|
||||
isActive(0),
|
||||
isPushBackRoute(0),
|
||||
isBlocked(0),
|
||||
start(0),
|
||||
end(0),
|
||||
index(0),
|
||||
|
@ -99,7 +120,7 @@ public:
|
|||
center (other.center),
|
||||
isActive (other.isActive),
|
||||
isPushBackRoute (other.isPushBackRoute),
|
||||
isBlocked (other.isBlocked),
|
||||
blockTimes (other.blockTimes),
|
||||
start (other.start),
|
||||
end (other.end),
|
||||
index (other.index),
|
||||
|
@ -116,7 +137,7 @@ public:
|
|||
center = other.center;
|
||||
isActive = other.isActive;
|
||||
isPushBackRoute = other.isPushBackRoute;
|
||||
isBlocked = other.isBlocked;
|
||||
blockTimes = other.blockTimes;
|
||||
start = other.start;
|
||||
end = other.end;
|
||||
index = other.index;
|
||||
|
@ -144,15 +165,9 @@ public:
|
|||
isPushBackRoute = val;
|
||||
};
|
||||
void setDimensions(double elevation);
|
||||
void block() {
|
||||
isBlocked = true;
|
||||
}
|
||||
void unblock() {
|
||||
isBlocked = false;
|
||||
};
|
||||
bool hasBlock() {
|
||||
return isBlocked;
|
||||
};
|
||||
void block(int id, time_t blockTime, time_t now);
|
||||
void unblock(time_t now);
|
||||
bool hasBlock(time_t now);
|
||||
|
||||
FGTaxiNode * getEnd() {
|
||||
return end;
|
||||
|
|
|
@ -41,12 +41,25 @@ using std::string;
|
|||
|
||||
using namespace FGXMLAutopilot;
|
||||
|
||||
class ComponentForge : public map<string,FunctorBase<Component> *> {
|
||||
public:
|
||||
virtual ~ ComponentForge();
|
||||
};
|
||||
|
||||
ComponentForge::~ComponentForge()
|
||||
{
|
||||
for( iterator it = begin(); it != end(); ++it )
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
static ComponentForge componentForge;
|
||||
|
||||
Autopilot::Autopilot( SGPropertyNode_ptr rootNode, SGPropertyNode_ptr configNode ) :
|
||||
_name("unnamed autopilot"),
|
||||
_serviceable(true),
|
||||
_rootNode(rootNode)
|
||||
{
|
||||
map<string,FunctorBase<Component> *> componentForge;
|
||||
|
||||
componentForge["pid-controller"] = new CreateAndConfigureFunctor<PIDController,Component>();
|
||||
componentForge["pi-simple-controller"] = new CreateAndConfigureFunctor<PISimpleController,Component>();
|
||||
componentForge["predict-simple"] = new CreateAndConfigureFunctor<Predictor,Component>();
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
bool is_serviceable() const { return _serviceable; }
|
||||
|
||||
std::string get_name() const { return _name; }
|
||||
void set_name( std::string & name ) { _name = name; }
|
||||
void set_name( const std::string & name ) { _name = name; }
|
||||
|
||||
void add_component( Component * component );
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
@ -43,6 +44,8 @@ using simgear::PropertyList;
|
|||
class FGXMLAutopilotGroupImplementation : public FGXMLAutopilotGroup
|
||||
{
|
||||
public:
|
||||
virtual void addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config );
|
||||
virtual void removeAutopilot( const std::string & name );
|
||||
void init();
|
||||
void reinit();
|
||||
void update( double dt );
|
||||
|
@ -52,6 +55,30 @@ private:
|
|||
|
||||
};
|
||||
|
||||
void FGXMLAutopilotGroupImplementation::addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config )
|
||||
{
|
||||
BOOST_FOREACH( std::string & n, _autopilotNames ) {
|
||||
if( n == name ) {
|
||||
SG_LOG(SG_ALL, SG_ALERT, "NOT adding duplicate property rule name " << name );
|
||||
return;
|
||||
}
|
||||
}
|
||||
FGXMLAutopilot::Autopilot * ap = new FGXMLAutopilot::Autopilot( apNode, config );
|
||||
ap->set_name( name );
|
||||
set_subsystem( name, ap );
|
||||
_autopilotNames.push_back( name );
|
||||
}
|
||||
|
||||
void FGXMLAutopilotGroupImplementation::removeAutopilot( const std::string & name )
|
||||
{
|
||||
FGXMLAutopilot::Autopilot * ap = (FGXMLAutopilot::Autopilot*)get_subsystem( name );
|
||||
if( ap == NULL ) return; // ?
|
||||
remove_subsystem( name );
|
||||
delete ap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGXMLAutopilotGroupImplementation::update( double dt )
|
||||
{
|
||||
// update all configured autopilots
|
||||
|
@ -63,10 +90,7 @@ void FGXMLAutopilotGroupImplementation::reinit()
|
|||
SGSubsystemGroup::unbind();
|
||||
|
||||
for( vector<string>::size_type i = 0; i < _autopilotNames.size(); i++ ) {
|
||||
FGXMLAutopilot::Autopilot * ap = (FGXMLAutopilot::Autopilot*)get_subsystem( _autopilotNames[i] );
|
||||
if( ap == NULL ) continue; // ?
|
||||
remove_subsystem( _autopilotNames[i] );
|
||||
delete ap;
|
||||
removeAutopilot( _autopilotNames[i] );
|
||||
}
|
||||
_autopilotNames.clear();
|
||||
init();
|
||||
|
@ -90,21 +114,20 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
|
|||
if( rootNode == NULL )
|
||||
return;
|
||||
|
||||
PropertyList autopilotNodes = rootNode->getChildren(childName);
|
||||
for( PropertyList::size_type i = 0; i < autopilotNodes.size(); i++ ) {
|
||||
SGPropertyNode_ptr pathNode = autopilotNodes[i]->getNode( "path" );
|
||||
BOOST_FOREACH( SGPropertyNode_ptr autopilotNode, rootNode->getChildren(childName) ) {
|
||||
SGPropertyNode_ptr pathNode = autopilotNode->getNode( "path" );
|
||||
if( pathNode == NULL ) {
|
||||
SG_LOG( SG_ALL, SG_WARN, "No configuration file specified for this property-rule!");
|
||||
continue;
|
||||
}
|
||||
|
||||
string apName;
|
||||
SGPropertyNode_ptr nameNode = autopilotNodes[i]->getNode( "name" );
|
||||
SGPropertyNode_ptr nameNode = autopilotNode->getNode( "name" );
|
||||
if( nameNode != NULL ) {
|
||||
apName = nameNode->getStringValue();
|
||||
} else {
|
||||
std::ostringstream buf;
|
||||
buf << "unnamed_autopilot_" << i;
|
||||
buf << "unnamed_autopilot_" << autopilotNode->getIndex();
|
||||
apName = buf.str();
|
||||
}
|
||||
|
||||
|
@ -120,31 +143,31 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
|
|||
SG_LOG( SG_ALL, SG_WARN, "Duplicate property-rule configuration name " << name << ", renamed to " << apName );
|
||||
}
|
||||
|
||||
SGPath config = globals->resolve_maybe_aircraft_path(pathNode->getStringValue());
|
||||
if (config.isNull())
|
||||
{
|
||||
SG_LOG( SG_ALL, SG_ALERT, "Cannot find property-rule configuration file '" << pathNode->getStringValue() << "'." );
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
|
||||
addAutopilotFromFile( apName, autopilotNode, pathNode->getStringValue() );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
SGPropertyNode_ptr root = new SGPropertyNode();
|
||||
readProperties( config.str(), root );
|
||||
void FGXMLAutopilotGroup::addAutopilotFromFile( const std::string & name, SGPropertyNode_ptr apNode, const char * path )
|
||||
{
|
||||
SGPath config = globals->resolve_maybe_aircraft_path(path);
|
||||
if (config.isNull())
|
||||
{
|
||||
SG_LOG( SG_ALL, SG_ALERT, "Cannot find property-rule configuration file '" << path << "'." );
|
||||
return;
|
||||
}
|
||||
SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
|
||||
|
||||
SG_LOG( SG_AUTOPILOT, SG_INFO, "adding property-rule subsystem " << apName );
|
||||
FGXMLAutopilot::Autopilot * ap = new FGXMLAutopilot::Autopilot( autopilotNodes[i], root );
|
||||
ap->set_name( apName );
|
||||
set_subsystem( apName, ap );
|
||||
_autopilotNames.push_back( apName );
|
||||
try {
|
||||
SGPropertyNode_ptr configNode = new SGPropertyNode();
|
||||
readProperties( config.str(), configNode );
|
||||
|
||||
} catch (const sg_exception& e) {
|
||||
SG_LOG( SG_AUTOPILOT, SG_ALERT, "Failed to load property-rule configuration: "
|
||||
<< config.str() << ":" << e.getMessage() );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
SG_LOG( SG_AUTOPILOT, SG_INFO, "adding property-rule subsystem " << name );
|
||||
addAutopilot( name, apNode, configNode );
|
||||
|
||||
} catch (const sg_exception& e) {
|
||||
SG_LOG( SG_AUTOPILOT, SG_ALERT, "Failed to load property-rule configuration: "
|
||||
<< config.str() << ":" << e.getMessage() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#ifndef _XMLAUTO_HXX
|
||||
#define _XMLAUTO_HXX 1
|
||||
|
||||
|
||||
/**
|
||||
* @brief Model an autopilot system by implementing a SGSubsystemGroup
|
||||
*
|
||||
|
@ -33,6 +32,9 @@ class FGXMLAutopilotGroup : public SGSubsystemGroup
|
|||
{
|
||||
public:
|
||||
static FGXMLAutopilotGroup * createInstance();
|
||||
void addAutopilotFromFile( const std::string & name, SGPropertyNode_ptr apNode, const char * path );
|
||||
virtual void addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config ) = 0;
|
||||
virtual void removeAutopilot( const std::string & name ) = 0;
|
||||
protected:
|
||||
FGXMLAutopilotGroup() : SGSubsystemGroup() {}
|
||||
|
||||
|
|
|
@ -35,8 +35,7 @@ public:
|
|||
};
|
||||
|
||||
template <class TClass,class TBase> class CreateAndConfigureFunctor :
|
||||
public FunctorBase<TBase>,
|
||||
SGReferenced {
|
||||
public FunctorBase<TBase> {
|
||||
public:
|
||||
virtual TBase * operator()( SGPropertyNode_ptr configNode ) {
|
||||
TBase * base = new TClass();
|
||||
|
|
|
@ -374,18 +374,24 @@ void FGAISchedule::scheduleFlights(time_t now)
|
|||
if (!flights.empty()) {
|
||||
return;
|
||||
}
|
||||
string startingPort;
|
||||
//string startingPort;
|
||||
string userPort = fgGetString("/sim/presets/airport-id");
|
||||
SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " << registration << " " << homePort);
|
||||
FGScheduledFlight *flight = NULL;
|
||||
do {
|
||||
flight = findAvailableFlight(currentDestination, flightIdentifier);
|
||||
|
||||
if (currentDestination.empty()) {
|
||||
flight = findAvailableFlight(userPort, flightIdentifier, now, (now+6400));
|
||||
if (!flight)
|
||||
flight = findAvailableFlight(currentDestination, flightIdentifier);
|
||||
} else {
|
||||
flight = findAvailableFlight(currentDestination, flightIdentifier);
|
||||
}
|
||||
if (!flight) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//if (startingPort.empty()) {
|
||||
// startingPort = flight->getDepartureAirport()->getId();
|
||||
//}
|
||||
currentDestination = flight->getArrivalAirport()->getId();
|
||||
//cerr << "Current destination " << currentDestination << endl;
|
||||
if (!initialized) {
|
||||
|
@ -393,7 +399,10 @@ void FGAISchedule::scheduleFlights(time_t now)
|
|||
//cerr << "Scheduled " << registration << " " << score << " for Flight "
|
||||
// << flight-> getCallSign() << " from " << departurePort << " to " << currentDestination << endl;
|
||||
if (userPort == departurePort) {
|
||||
lastRun = 1;
|
||||
hits++;
|
||||
} else {
|
||||
lastRun = 0;
|
||||
}
|
||||
//runCount++;
|
||||
initialized = true;
|
||||
|
|
|
@ -128,7 +128,7 @@ class FGAISchedule
|
|||
// decending order sorting, but still need to test that.
|
||||
bool operator< (const FGAISchedule &other) const;
|
||||
void taint() { valid = false; };
|
||||
int getLastUsed() { return (int) valid;};
|
||||
int getLastUsed() { return lastRun; };
|
||||
void setLastUsed(unsigned int val) {lastRun = val; };
|
||||
//void * getAiRef () { return AIManagerRef; };
|
||||
//FGAISchedule* getAddress () { return this;};
|
||||
|
|
|
@ -285,7 +285,7 @@ GLuint FGPanel::getInitDisplayList()
|
|||
void
|
||||
FGPanel::update (double dt)
|
||||
{
|
||||
glCallList(getInitDisplayList());
|
||||
/*glCallList*/(getInitDisplayList());
|
||||
|
||||
// Draw the instruments.
|
||||
// Syd Adams: added instrument clipping
|
||||
|
|
Loading…
Add table
Reference in a new issue