]> git.mxchange.org Git - flightgear.git/commitdiff
Added some code to visualize the ground networks.
authorDurk Talsma <durk@localhost.(none)>
Sun, 17 Apr 2011 08:19:58 +0000 (10:19 +0200)
committerDurk Talsma <durk@localhost.(none)>
Sun, 17 Apr 2011 08:19:58 +0000 (10:19 +0200)
src/ATC/atc_mgr.cxx
src/ATC/atcdialog.cxx
src/ATC/atcdialog.hxx
src/ATC/trafficcontrol.cxx
src/Airports/dynamics.cxx
src/Airports/dynamics.hxx
src/Airports/gnnode.cxx
src/Airports/gnnode.hxx
src/Airports/groundnetwork.cxx
src/Airports/groundnetwork.hxx
src/Scenery/tilemgr.cxx

index 88f527f32347d9b261578bb3efdb46b2d31856e2..dace2d26caa9526572c20e749f0a22bbaca9f95a 100644 (file)
@@ -29,6 +29,7 @@
 #include <simgear/math/SGMath.hxx>
 #include <Airports/dynamics.hxx>
 #include <Airports/simple.hxx>
+#include <Scenery/scenery.hxx>
 #include "atc_mgr.hxx"
 
 
@@ -155,6 +156,10 @@ void FGATCManager::init() {
                                       aircraftRadius, leg, &ai_ac);
 
     //dialog.init();
+
+   osg::Node* node = apt->getDynamics()->getGroundNetwork()->getRenderNode();
+   cerr << "Adding groundnetWork to the scenegraph" << endl;
+   globals->get_scenery()->get_scene_graph()->addChild(node);
    }
 }
 
@@ -180,4 +185,10 @@ void FGATCManager::update ( double time ) {
                                               speed,
                                               altitude, time);
     }
+   /*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;
+   globals->get_scenery()->get_scene_graph()->addChild(node);
+*/
 }
index a4c75a6113ebd89323af00ac7c7308447e6d84e7..c59bf959b6b40a07e0764cbd1ba1e83230fa6763 100644 (file)
@@ -91,9 +91,62 @@ void FGATCDialogNew::addEntry(int nr, string txt) {
     commands.push_back(txt);
 }
 
+void FGATCDialogNew::removeEntry(int nr) {
+    commands.clear();
+}
+
+
 
 void FGATCDialogNew::PopupDialog() {
-    double onBoardRadioFreq0 =
+    /*double onBoardRadioFreq0 =
+        fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz");
+    double onBoardRadioFreq1 =
+        fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz");
+
+    const char *dialog_name = "atc-dialog";
+    _gui = (NewGUI *)globals->get_subsystem("gui");
+    SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name);
+    if (!dlg)
+        return;
+
+    _gui->closeDialog(dialog_name);
+    SGPropertyNode_ptr button_group = getNamedNode(dlg, "transmission-choice");
+    button_group->removeChildren("button", false);
+
+    const int bufsize = 32;
+    char buf[bufsize];
+    int commandNr = 0;
+    // loop over all entries that should fill up the dialog; use 10 items for now...
+    for (StringVecIterator i = commands.begin(); i != commands.end(); i++) {
+        snprintf(buf, bufsize, "/sim/atc/opt[%d]", commandNr);
+            fgSetBool(buf, false);
+        SGPropertyNode *entry = button_group->getNode("button", commandNr, true);
+        copyProperties(button_group->getNode("button-template", true), entry);
+       entry->removeChildren("enabled", true);
+       entry->setStringValue("property", buf);
+       entry->setIntValue("keynum", '1' + commandNr);
+       if (commandNr == 0)
+           entry->setBoolValue("default", true);
+
+       snprintf(buf, bufsize, "%d", 1 + commandNr);
+       string legend = string(buf) + (*i); //"; // + current->menuentry;
+       entry->setStringValue("legend", legend.c_str());
+       entry->setIntValue("binding/value", commandNr);
+        commandNr++;
+       //current++;
+    }
+*/
+    //if (dialogVisible) {
+    //    _gui->closeDialog(dialog_name);
+    //} else {
+    //    _gui->showDialog(dialog_name);
+    //}
+    dialogVisible = !dialogVisible;
+    return;
+}
+
+void FGATCDialogNew::update(double dt) {
+ double onBoardRadioFreq0 =
         fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz");
     double onBoardRadioFreq1 =
         fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz");
@@ -136,11 +189,8 @@ void FGATCDialogNew::PopupDialog() {
     } else {
         _gui->showDialog(dialog_name);
     }
-    dialogVisible = !dialogVisible;
+    //dialogVisible = !dialogVisible;
     return;
-}
-
-void FGATCDialogNew::update(double dt) {
     /*
     static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
     int n = trans_num->getIntValue();
index f667b87dc3f5f640f451117ebe6a15cf23d23c95..f52b5b4f1852e0f7c20a8b2abdf6add13ea4c9f0 100644 (file)
@@ -60,6 +60,7 @@ public:
     void update(double dt);
     void PopupDialog();
     void addEntry(int, string);
+    void removeEntry(int);
 };
 
 extern FGATCDialogNew *currentATCDialog;
index b0adba5412816aae54071083d07e4361272bd393..c6b14504c7be977be7958506c238c70d5d8f226d 100644 (file)
@@ -399,6 +399,10 @@ void FGTrafficRecord::setHeadingAdjustment(double heading)
 
 bool FGTrafficRecord::pushBackAllowed()
 {
+    // With the user ATC / AI integration, checking whether the user's aircraft is near no longer works, because
+    // this will effectively block the user's aircraft itself from receiving pushback clearance. 
+    // So, what can we do?
+    /*
     double course, az2, dist;
     SGGeod curr(SGGeod::fromDegM(getLongitude(),
                                  getLatitude(), getAltitude()));
@@ -409,7 +413,12 @@ bool FGTrafficRecord::pushBackAllowed()
     SGGeodesy::inverse(curr, user, course, az2, dist);
     //cerr << "Distance to user : " << dist << endl;
     return (dist > 250);
+    */
 
+
+    // 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 
 }
 
 
@@ -1023,6 +1032,8 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star
                 trans_num->setIntValue(-1);
                  // PopupCallback(n);
                  cerr << "Selected transmission message" << n << endl;
+                 FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
+                 atc->getATCDialog()->removeEntry(1);
             } else {
                 cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
                 transmit(&(*i), msgId, msgDir, false);
@@ -1092,6 +1103,7 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
     }
     checkTransmissionState(5, now, (startTime + 140), i, MSG_INITIATE_CONTACT,                          ATC_AIR_TO_GROUND);
     checkTransmissionState(6, now, (startTime + 150), i, MSG_ACKNOWLEDGE_INITIATE_CONTACT,              ATC_GROUND_TO_AIR);
+    checkTransmissionState(7, now, (startTime + 180), i, MSG_REQUEST_PUSHBACK_CLEARANCE,                ATC_AIR_TO_GROUND);
 
 
    
index d608043b478bee48b05c9e6c6dc56b8f2e33f056..fd5025a38fba26e6db3f981f3841c82eed528993 100644 (file)
@@ -96,10 +96,11 @@ void FGAirportDynamics::init()
     random_shuffle(parkings.begin(), parkings.end());
     sort(parkings.begin(), parkings.end());
     // add the gate positions to the ground network. 
+    groundNetwork.setParent(_ap);
     groundNetwork.addNodes(&parkings);
     groundNetwork.init();
     groundNetwork.setTowerController(&towerController);
-    groundNetwork.setParent(_ap);
+    
 }
 
 bool FGAirportDynamics::getAvailableParking(double *lat, double *lon,
index ecadb9d62205b91fcfc8f538fe1c37a3a5703d85..1aa61fe6fcc4cc5695f7b7d4d478bcf445b32752 100644 (file)
@@ -72,6 +72,9 @@ private:
   string chooseRunwayFallback();
   bool innerGetActiveRunway(const string &trafficType, int action, string &runway, double heading);
   string chooseRwyByHeading(stringVec rwys, double heading);
+
+    double elevation;
+
 public:
   FGAirportDynamics(FGAirport* ap);
   FGAirportDynamics(const FGAirportDynamics &other);
index c9883d812edda287d5fa6dd8b27f7b2fbe20f943..ae37d59594a03b65fc86847563820028659507ba 100644 (file)
@@ -31,9 +31,9 @@ double processPosition(const string &pos)
   return value;
 }
 
-bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b) {
-  return a->hasSmallerHeadingDiff(*b);
-}
+//bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b) {
+//  return a->hasSmallerHeadingDiff(*b);
+//}
 
 bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) {
   return a->getLength() > b->getLength();
@@ -42,7 +42,10 @@ bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) {
 /**************************************************************************
  * FGTaxiNode
  *************************************************************************/
-
+void FGTaxiNode::setElevation(double val)
+{
+    geod.setElevationM(val);
+}
 
 void FGTaxiNode::setLatitude (double val)
 {
@@ -64,10 +67,10 @@ void FGTaxiNode::setLongitude(const string& val)
   geod.setLongitudeDeg(processPosition(val));
 }
   
-void FGTaxiNode::sortEndSegments(bool byLength)
-{
-  if (byLength)
-    sort(next.begin(), next.end(), sortByLength);
-  else
-    sort(next.begin(), next.end(), sortByHeadingDiff);
-}
+//void FGTaxiNode::sortEndSegments(bool byLength)
+//{
+//  if (byLength)
+//    sort(next.begin(), next.end(), sortByLength);
+//  else
+//    sort(next.begin(), next.end(), sortByHeadingDiff);
+//}
index 3358ea51e6e891a87adebad77adef2958bb3ec80..a7627715e8e55190add131526e69edc09bcda447 100644 (file)
@@ -83,6 +83,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
   void setIndex(int idx)                  { index = idx;                 };
   void setLatitude (double val);
   void setLongitude(double val);
+  void setElevation(double val);
   void setLatitude (const std::string& val);
   void setLongitude(const std::string& val);
   void addSegment(FGTaxiSegment *segment) { next.push_back(segment);     };
@@ -99,6 +100,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
   double getPathScore() { return pathScore; };
   double getLatitude() { return geod.getLatitudeDeg();};
   double getLongitude(){ return geod.getLongitudeDeg();};
+  double getElevation() { return geod.getElevationM();};
 
   const SGGeod& getGeod() const { return geod; }
 
@@ -111,7 +113,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
   FGTaxiSegmentVectorIterator getEndRoute()   { return next.end();   }; 
   bool operator<(const FGTaxiNode &other) const { return index < other.index; };
 
-  void sortEndSegments(bool);
+  //void sortEndSegments(bool);
 
 };
 
index 37e9946bfc912f18a437fb17ef4a63b2bd5f3264..a87861fabac16a25f6314b17764cb4a4cbd49542 100644 (file)
 #include <math.h>
 #include <algorithm>
 
+
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/MatrixTransform>
+#include <osg/Shape>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/route/waypoint.hxx>
+#include <simgear/scene/material/EffectGeode.hxx>
 
 #include <Airports/simple.hxx>
 #include <Airports/dynamics.hxx>
@@ -77,19 +84,26 @@ void FGTaxiSegment::setEnd(FGTaxiNodeVector * nodes)
 
 // There is probably a computationally cheaper way of 
 // doing this.
-void FGTaxiSegment::setTrackDistance()
+void FGTaxiSegment::setDimensions(double elevation)
 {
     length = SGGeodesy::distanceM(start->getGeod(), end->getGeod());
+    //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
+
+    double az2; //, distanceM;
+    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;
 }
 
 
-void FGTaxiSegment::setCourseDiff(double crse)
-{
-    headingDiff = fabs(course - crse);
+//void FGTaxiSegment::setCourseDiff(double crse)
+//{
+//    headingDiff = fabs(course - crse);
 
-    if (headingDiff > 180)
-        headingDiff = fabs(headingDiff - 360);
-}
+//    if (headingDiff > 180)
+//        headingDiff = fabs(headingDiff - 360);
+//}
 
 
 /***************************************************************************
@@ -227,6 +241,7 @@ void FGGroundNetwork::addNodes(FGParkingVec * parkings)
         n.setIndex(i->getIndex());
         n.setLatitude(i->getLatitude());
         n.setLongitude(i->getLongitude());
+        n.setElevation(parent->getElevation());
         nodes.push_back(new FGTaxiNode(n));
 
         i++;
@@ -245,7 +260,7 @@ void FGGroundNetwork::init()
     while (i != segments.end()) {
         (*i)->setStart(&nodes);
         (*i)->setEnd(&nodes);
-        (*i)->setTrackDistance();
+        (*i)->setDimensions(parent->getElevation());
         (*i)->setIndex(index);
         if ((*i)->isPushBack()) {
             pushBackNodes.push_back((*i)->getEnd());
@@ -511,6 +526,36 @@ void FGGroundNetwork::signOff(int id)
     }
 }
 
+bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
+                               AtcMsgDir msgDir)
+{
+    int state = i->getState();
+    if ((state >= minState) && (state <= maxState) && available) {
+        if ((msgDir == ATC_AIR_TO_GROUND) && isUserAircraft(i->getAircraft())) {
+            
+            cerr << "Checking state " << state << " for " << i->getAircraft()->getCallSign() << endl;
+            static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
+            int n = trans_num->getIntValue();
+            if (n >= 0) {
+                trans_num->setIntValue(-1);
+                 // PopupCallback(n);
+                 cerr << "Selected transmission message" << n << endl;
+            } else {
+                cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
+                transmit(&(*i), msgId, msgDir, false);
+                return false;
+            }
+        }
+        //cerr << "Transmitting startup msg" << endl;
+        transmit(&(*i), msgId, msgDir, true);
+        i->updateState();
+        lastTransmission = now;
+        available = false;
+        return true;
+    }
+    return false;
+}
+
 void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
                                                 double heading, double speed, double alt,
                                                 double dt)
@@ -568,23 +613,14 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
         if ((now - lastTransmission) > 15) {
             available = true;
         }
-        if ((state < 3) && available) {
-             transmit(&(*current), MSG_REQUEST_TAXI_CLEARANCE, ATC_AIR_TO_GROUND, true);
-             current->setState(3);
-             lastTransmission = now;
-             available = false;
+        if (checkTransmissionState(0,2, current, now, MSG_REQUEST_TAXI_CLEARANCE, ATC_AIR_TO_GROUND)) {
+            current->setState(3);
         }
-        if ((state == 3) && available) {
-            transmit(&(*current), MSG_ISSUE_TAXI_CLEARANCE, ATC_GROUND_TO_AIR, true);
+        if (checkTransmissionState(3,3, current, now, MSG_ISSUE_TAXI_CLEARANCE, ATC_GROUND_TO_AIR)) {
             current->setState(4);
-            lastTransmission = now;
-            available = false;
         }
-        if ((state == 4) && available) {
-            transmit(&(*current), MSG_ACKNOWLEDGE_TAXI_CLEARANCE, ATC_AIR_TO_GROUND, true);
+        if (checkTransmissionState(4,4, current, now, MSG_ACKNOWLEDGE_TAXI_CLEARANCE, ATC_AIR_TO_GROUND)) {
             current->setState(5);
-            lastTransmission = now;
-            available = false;
         }
         if ((state == 5) && available) {
             current->setState(0);
@@ -862,8 +898,17 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
         //cerr << "Current state " << current->getState() << endl;
     } else {
     }
-    int state = current->getState();
-    if ((state == 1) && (available)) {
+    //int state = current->getState();
+    if (checkTransmissionState(1,1, current, now, MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND)) {
+            current->setState(0);
+            current->setHoldPosition(true);
+    }
+    if (checkTransmissionState(2,2, current, now, MSG_ACKNOWLEDGE_RESUME_TAXI, ATC_AIR_TO_GROUND)) {
+            current->setState(0);
+            current->setHoldPosition(false);
+    }
+
+    /*if ((state == 1) && (available)) {
         //cerr << "ACKNOWLEDGE HOLD" << endl;
         transmit(&(*current), MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND, true);
         current->setState(0);
@@ -879,8 +924,8 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
         current->setHoldPosition(false);
         lastTransmission = now;
         available = false;
-    }
-}
+    }*/
+} 
 
 /**
  * Check whether situations occur where the current aircraft is waiting for itself
@@ -1036,3 +1081,51 @@ FGATCInstruction FGGroundNetwork::getInstruction(int id)
     }
     return FGATCInstruction();
 }
+
+// Note that this function is copied from simgear. for maintanance purposes, it's probabtl better to make a general function out of that.
+static void WorldCoordinate(osg::Matrix& obj_pos, double lat,
+                            double lon, double elev, double hdg)
+{
+    SGGeod geod = SGGeod::fromDegM(lon, lat, elev);
+    obj_pos = geod.makeZUpFrame();
+    // hdg is not a compass heading, but a counter-clockwise rotation
+    // around the Z axis
+    obj_pos.preMult(osg::Matrix::rotate(hdg * SGD_DEGREES_TO_RADIANS,
+                                        0.0, 0.0, 1.0));
+}
+
+
+
+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()) );
+
+                obj_trans->setMatrix( obj_pos );
+        //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 );
+    }
+
+
+    return group;
+}
\ No newline at end of file
index 06ed98b12710f1f92aa1137a2a60cb78ca129d2f..319d8b2dd540b069b427a94300f4a75585f7cd6e 100644 (file)
@@ -56,8 +56,8 @@ private:
   int startNode;
   int endNode;
   double length;
-  double course;
-  double headingDiff;
+  double heading;
+  SGGeod center;
   bool isActive;
   bool isPushBackRoute;
   FGTaxiNode *start;
@@ -72,8 +72,7 @@ public:
       startNode(0),
       endNode(0),
       length(0),
-      course(0),
-      headingDiff(0),
+      heading(0),
       isActive(0),
       isPushBackRoute(0),
       start(0),
@@ -87,8 +86,8 @@ public:
       startNode         (other.startNode),
       endNode           (other.endNode),
       length            (other.length),
-      course            (other.course),
-      headingDiff       (other.headingDiff),
+      heading           (other.heading),
+      center            (other.center),
       isActive          (other.isActive),
       isPushBackRoute   (other.isPushBackRoute),
       start             (other.start),
@@ -103,8 +102,8 @@ public:
       startNode          = other.startNode;
       endNode            = other.endNode;
       length             = other.length;
-      course             = other.course;
-      headingDiff        = other.headingDiff;
+      heading            = other.heading;
+      center             = other.center;
       isActive           = other.isActive;
       isPushBackRoute    = other.isPushBackRoute;
       start              = other.start;
@@ -123,13 +122,15 @@ public:
   void setStart(FGTaxiNodeVector *nodes);
   void setEnd  (FGTaxiNodeVector *nodes);
   void setPushBackType(bool val) { isPushBackRoute = val; };
-  void setTrackDistance();
+  void setDimensions(double elevation);
 
   FGTaxiNode * getEnd() { return end;};
   FGTaxiNode * getStart() { return start; };
   double getLength() { return length; };
   int getIndex() { return index; };
-  
+  double getLatitude()  { return center.getLatitudeDeg();  };
+  double getLongitude() { return center.getLongitudeDeg(); };
+  double getHeading()   { return heading; }; 
   bool isPushBack() { return isPushBackRoute; };
 
   int getPenalty(int nGates);
@@ -137,7 +138,7 @@ public:
   FGTaxiSegment *getAddress() { return this;};
 
   bool operator<(const FGTaxiSegment &other) const { return index < other.index; };
-  bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
+  //bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
   FGTaxiSegment *opposite() { return oppositeDirection; };
   void setCourseDiff(double crse);
 
@@ -273,7 +274,10 @@ public:
   virtual bool hasInstruction(int id);
   virtual FGATCInstruction getInstruction(int id);
 
+  bool checkTransmissionState(int minState, int MaxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
+                               AtcMsgDir msgDir);
   bool checkForCircularWaits(int id);
+  osg::Node* getRenderNode();
 };
 
 
index 6c19ec5c0e25a94dd6d03ccfc53d963f61027791..53f1f346db2510902219b36833b319df62defeae 100644 (file)
@@ -152,6 +152,7 @@ bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_vie
         if ( tile_cache.insert_tile( t ) )
         {
             // Attach to scene graph
+
             t->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
         } else
         {