]> git.mxchange.org Git - flightgear.git/commitdiff
Vivian Meazza:
authorehofman <ehofman>
Tue, 30 Nov 2004 12:34:11 +0000 (12:34 +0000)
committerehofman <ehofman>
Tue, 30 Nov 2004 12:34:11 +0000 (12:34 +0000)
This is a sub-system which can be added to any carrier.

These files add a functioning Fresnel Lens Optical Landing System (FLOLS).
The orange/red 'source' lights are illuminated according to the position of
the pilot's eye above/below the 3.5 deg glide slope. The apparent position
of the source light relative to the fixed green datum lights allow the pilot
to 'fly the meatball'. The green 'cut' lights flash when the pilot's eye is
below the coverage of the lowest (red) source light.

TODO - add rules for the operation of the wave-off lights.

src/AIModel/AIBase.hxx
src/AIModel/AICarrier.cxx
src/AIModel/AICarrier.hxx
src/AIModel/AIManager.cxx
src/AIModel/AIScenario.cxx

index bc8b2e48a51f2b965966bf6f55a0979063dae8ef..fd8d8c85c254a49f84076123fc9ea733e4e065a6 100644 (file)
@@ -73,7 +73,9 @@ typedef struct {
    list<string> wire_objects;     // List of wire object names
    list<string> catapult_objects; // List of catapult object names
    double radius;             // used by ship ojects, in feet
-    
+   double x_offset;           // used by ship ojects, in meters
+   double y_offset;           // used by ship ojects, in meters
+   double z_offset;           // used by ship ojects, in meters    
 } FGAIModelEntity;
 
 
@@ -102,6 +104,10 @@ public:
     void setLongitude( double longitude );
     void setBank( double bank );
     void setRadius ( double radius );
+    void setXoffset( double x_offset );
+    void setYoffset( double y_offset );
+    void setZoffset( double z_offset );
+
 
     void* getID();
     void setDie( bool die );
@@ -122,6 +128,12 @@ protected:
     double vs;          // vertical speed, feet per minute  
     double turn_radius_ft; // turn radius ft at 15 kts rudder angle 15 degrees
 
+    // these describe the flols 
+    Point3D flolspos; // WGS84 lat & lon in degrees, elev above sea-level in meters
+    double flols_x_offset;     // longitudinal distance, in meters
+    double flols_y_offset;     // lateral distance, in meters
+    double flols_z_offset;     // height, in meters
+    
     double ft_per_deg_lon;
     double ft_per_deg_lat;
 
@@ -223,6 +235,17 @@ inline void FGAIBase::setRadius( double radius ) {
   turn_radius_ft = radius;
 }
 
+inline void FGAIBase::setXoffset( double x_offset ) {
+  flols_x_offset = x_offset;
+}
+
+inline void FGAIBase::setYoffset( double y_offset ) {
+  flols_y_offset = y_offset;
+}
+
+inline void FGAIBase::setZoffset( double z_offset ) {
+  flols_z_offset = z_offset;
+}
 inline void FGAIBase::setHeading( double heading ) {
   hdg = tgt_heading = heading;
 }
@@ -251,5 +274,7 @@ inline FGAIBase::object_type FGAIBase::getType() { return _otype; }
 
 inline void* FGAIBase::getID() { return this; }
 
+
+
 #endif // _FG_AIBASE_HXX
 
index d6e29b746ba2ae884988cb064168b0940c9bbb7d..84775fa58e3cb463c3025e137b88eeb22d7de0ca 100644 (file)
 #include <string>
 #include <vector>
 
+#include <simgear/math/point3d.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+#include <math.h>
+#include <Main/util.hxx>
+#include <Main/viewer.hxx>
+
 #include "AICarrier.hxx"
 
 
@@ -50,6 +56,7 @@ void FGAICarrier::getVelocityWrtEarth(sgVec3 v) {
 }
 
 void FGAICarrier::update(double dt) {
+   UpdateFlols(dt);
    FGAIShip::update(dt);
 
    // Update the velocity information stored in those nodes.
@@ -89,7 +96,23 @@ bool FGAICarrier::init() {
 
    return true;
 }
-
+void FGAICarrier::bind() {
+   FGAIBase::bind();
+
+   props->tie("controls/flols/source-lights",
+                SGRawValuePointer<int>(&source));
+   props->tie("controls/flols/distance-m",
+                SGRawValuePointer<double>(&dist));                            
+   props->setBoolValue("controls/flols/cut-lights", false);
+   props->setBoolValue("controls/flols/wave-off-lights", false);
+   props->setBoolValue("controls/flols/cond-datum-lights", true);  
+   }
+
+void FGAICarrier::unbind() {
+    FGAIBase::unbind();
+    props->untie("controls/flols/source-lights");
+}
+   
 void FGAICarrier::mark_nohot(ssgEntity* e) {
   if (e->isAKindOf(ssgTypeBranch())) {
     ssgBranch* br = (ssgBranch*)e;
@@ -183,7 +206,7 @@ bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects) {
           SG_LOG(SG_GENERAL, SG_ALERT,
                  "AICarrier: Found a cat not modelled with exactly one line!");
         }
-        // Now some special code to make shure the cat points in the right
+        // Now some special code to make sure the cat points in the right
         // direction. The 0 index must be the backward end, the 1 index
         // the forward end.
         // Forward is positive x-direction in our 3D model, also the model
@@ -208,4 +231,163 @@ bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects) {
   return found;
 }
 
+void FGAICarrier::UpdateFlols( double dt) {
+/*    cout << "x_offset " << flols_x_offset 
+          << " y_offset " << flols_y_offset 
+          << " z_offset " << flols_z_offset << endl;
+        
+     cout << "roll " << roll 
+          << " heading " << hdg
+          << " pitch " << pitch << endl;
+        
+     cout << "carrier lon " << pos[0] 
+          << " lat " <<  pos[1]
+          << " alt " << pos[2] << endl;*/
+        
+// set the Flols intitial position to the carrier position
+  flolspos = pos;
+  
+/*  cout << "flols lon " << flolspos[0] 
+          << " lat " <<  flolspos[1]
+          << " alt " << flolspos[2] << endl;*/
+          
+// set the offsets in metres
+
+/*  cout << "flols_x_offset " << flols_x_offset << endl
+       << "flols_y_offset " << flols_y_offset << endl
+       << "flols_z_offset " << flols_z_offset << endl;*/
+     
+  in[0] = flols_x_offset;  
+  in[1] = flols_y_offset;
+  in[2] = flols_z_offset;    
+
+// pre-process the trig functions
+
+    cosRx = cos(roll * SG_DEGREES_TO_RADIANS);
+    sinRx = sin(roll * SG_DEGREES_TO_RADIANS);
+    cosRy = cos(pitch * SG_DEGREES_TO_RADIANS);
+    sinRy = sin(pitch * SG_DEGREES_TO_RADIANS);
+    cosRz = cos(hdg * SG_DEGREES_TO_RADIANS);
+    sinRz = sin(hdg * SG_DEGREES_TO_RADIANS);
+
+// set up the transform matrix
+
+    trans[0][0] =  cosRy * cosRz;
+    trans[0][1] =  -1 * cosRx * sinRz + sinRx * sinRy * cosRz ;
+    trans[0][2] =  sinRx * sinRz + cosRx * sinRy * cosRz;
+
+    trans[1][0] =  cosRy * sinRz;
+    trans[1][1] =  cosRx * cosRz + sinRx * sinRy * sinRz;
+    trans[1][2] =  -1 * sinRx * cosRx + cosRx * sinRy * sinRz;
+
+    trans[2][0] =  -1 * sinRy;
+    trans[2][1] =  sinRx * cosRy;
+    trans[2][2] =  cosRx * cosRy;
+
+// multiply the input and transform matrices
+
+   out[0] = in[0] * trans[0][0] + in[1] * trans[0][1] + in[2] * trans[0][2];
+   out[1] = in[0] * trans[1][0] + in[1] * trans[1][1] + in[2] * trans[1][2];
+   out[2] = in[0] * trans[2][0] + in[1] * trans[2][1] + in[2] * trans[2][2];
+// convert meters to ft to degrees of latitude
+   out[0] = (out[0] * 3.28083989501) /(366468.96 - 3717.12 * cos(flolspos[0] * SG_DEGREES_TO_RADIANS));
+
+// convert meters to ft to degrees of longitude
+   out[1] = (out[1] * 3.28083989501)/(365228.16 * cos(flolspos[1] * SG_DEGREES_TO_RADIANS));
+
+//print out the result
+/*   cout  << "lat adjust deg" << out[0] 
+        << " lon adjust deg " << out[1] 
+        << " alt adjust m " << out[2]  << endl;*/
+
+// adjust Flols position    
+   flolspos[0] += out[0];
+   flolspos[1] += out[1];
+   flolspos[2] += out[2];   
+
+// convert flols position to cartesian co-ordinates 
+
+  sgGeodToCart(flolspos[1] * SG_DEGREES_TO_RADIANS,
+               flolspos[0] * SG_DEGREES_TO_RADIANS,
+               flolspos[2] , flolsXYZ );
+
+
+/*  cout << "flols X " << flolsXYZ[0] 
+       << " Y " <<  flolsXYZ[1]
+       << " Z " << flolsXYZ[2] << endl; 
+
+// check the conversion
+         
+  sgCartToGeod(flolsXYZ, &lat, &lon, &alt);
+  cout << "flols check lon " << lon   
+        << " lat " << lat 
+        << " alt " << alt << endl;      */
+               
+//get the current position of the pilot's eyepoint (cartesian cordinates)
+
+  sgdCopyVec3( eyeXYZ, globals->get_current_view()->get_absolute_view_pos() );
+  
+ /* cout  << "Eye_X "  << eyeXYZ[0] 
+        << " Eye_Y " << eyeXYZ[1] 
+        << " Eye_Z " << eyeXYZ[2]  << endl; */
+        
+  sgCartToGeod(eyeXYZ, &lat, &lon, &alt);
+  
+  eyepos[0] = lon * SG_RADIANS_TO_DEGREES;
+  eyepos[1] = lat * SG_RADIANS_TO_DEGREES;
+  eyepos[2] = alt;
+  
+/*  cout << "eye lon " << eyepos[0]
+        << " eye lat " << eyepos[1] 
+        << " eye alt " << eyepos[2] << endl; */
+
+//calculate the ditance from eye to flols
+      
+  dist = sgdDistanceVec3( flolsXYZ, eyeXYZ );
+  
+  //cout << "distance " << dist << endl; 
+  
+  if ( dist < 5000 ) {
+       // calculate height above FLOLS 
+       double y = eyepos[2] - flolspos[2];
+       
+       // calculate the angle from the flols to eye
+       // above the horizontal
+       double angle;
+       if ( dist != 0 ) {
+           angle = asin( y / dist );
+         } else {
+           angle = 0.0;
+         }
+        
+       angle *= SG_RADIANS_TO_DEGREES;
+        
+      
+  // cout << " height " << y << " angle " << angle ;
+
+// set the value of source  
+        
+       if ( angle <= 4.35 && angle > 4.01 )
+         { source = 1; }
+         else if ( angle <= 4.01 && angle > 3.670 )
+         { source = 2; }
+         else if ( angle <= 3.670 && angle > 3.330 )
+         { source = 3; }
+         else if ( angle <= 3.330 && angle > 2.990 )
+         { source = 4; }
+         else if ( angle <= 2.990 && angle > 2.650 )
+         { source = 5; }
+         else if ( angle <= 2.650  )
+         { source = 6; }
+         else
+         { source = 0; }
+         
+//         cout << " source " << source << endl;
+                     
+   }   
+} // end updateflols
+
 int FGAICarrierHardware::unique_id = 1;
index 32cea59835dc09beb4e233ec597b44a57252c5e5..15f2bdf452711027028644d85db11075037e986b 100644 (file)
@@ -80,6 +80,9 @@ public:
         void setCatapultObjects(const list<string>& catapult_objects);
 
        void getVelocityWrtEarth(sgVec3 v);
+       virtual void bind();
+    virtual void unbind();
+    void UpdateFlols ( double dt );
        
        bool init();
 
@@ -97,6 +100,25 @@ private:
 
        // Velocity wrt earth.
        sgVec3 vel_wrt_earth;
+    
+    float trans[3][3];
+    float in[3];
+    float out[3];
+
+    double Rx, Ry, Rz;
+    double Sx, Sy, Sz;
+    double Tx, Ty, Tz;
+
+    float cosRx, sinRx;
+    float cosRy, sinRy;
+    float cosRz, sinRz;
+        
+    double flolsXYZ[3], eyeXYZ[3]; 
+    double lat, lon, alt;
+    double dist;
+    int source;
+    Point3D eyepos;
+    Point3D flolspos;  
 };
 
 #endif  // _FG_AICARRIER_HXX
index 2a4b7dde591b8514d4cf6b2f75154c4d7a724e0a..25f5425c7793cc5e0e9e9370084f7681e6c8bb6a 100644 (file)
@@ -176,7 +176,7 @@ FGAIManager::createAircraft( FGAIModelEntity *entity,   FGAISchedule *ref) {
 void*
 FGAIManager::createShip( FGAIModelEntity *entity ) {
     
-     //cout << "creating ship" << endl;    
+     // cout << "creating ship" << endl;    
 
         FGAIShip* ai_ship = new FGAIShip(this);
         ai_list.push_back(ai_ship);
@@ -202,7 +202,7 @@ FGAIManager::createShip( FGAIModelEntity *entity ) {
 void*
 FGAIManager::createCarrier( FGAIModelEntity *entity ) {
     
-    //cout << "creating carrier" << endl;
+    // cout << "creating carrier" << endl;
 
         FGAICarrier* ai_carrier = new FGAICarrier(this);
         ai_list.push_back(ai_carrier);
@@ -219,6 +219,9 @@ FGAIManager::createCarrier( FGAIModelEntity *entity ) {
         ai_carrier->setWireObjects(entity->wire_objects);
         ai_carrier->setCatapultObjects(entity->catapult_objects);
         ai_carrier->setRadius(entity->radius);
+        ai_carrier->setXoffset(entity->x_offset);
+        ai_carrier->setYoffset(entity->y_offset);
+        ai_carrier->setZoffset(entity->z_offset);
 
         if ( entity->fp ) {
            ai_carrier->setFlightPlan(entity->fp);
index 0e92bc7c1efd04a152a43b3efaf490bfbcc7d878..903a679475bd0d567545673c1aa9d0153d4953be 100644 (file)
@@ -40,24 +40,32 @@ FGAIScenario::FGAIScenario(string &filename)
 {
   int i;
   SGPath path( globals->get_fg_root() );
-  //cout << "/Data/AI/" << filename << endl;
+  
+  cout << "/Data/AI/" << filename << endl;
+  
   path.append( ("/Data/AI/" + filename + ".xml").c_str() );
   SGPropertyNode root;
   readProperties(path.str(), &root);
-  //cout <<"path " << path.str() << endl;
+  
+  cout <<"path " << path.str() << endl;
+  
   try {
       readProperties(path.str(), &root);
   } catch (const sg_exception &e) {
       SG_LOG(SG_GENERAL, SG_ALERT,
        "Incorrect path specified for AI scenario: ");
-       //cout << path.str() << endl;
+       
+       cout << path.str() << endl;
+      
       return;
   }
 
   entries.clear();
   SGPropertyNode * node = root.getNode("scenario");
   for (i = 0; i < node->nChildren(); i++) { 
-     //cout << "Reading entity data entry " << i << endl;        
+     
+     cout << "Reading entity data entry " << i << endl;        
+     
      SGPropertyNode * entry_node = node->getChild(i);
 
      FGAIModelEntity* en = new FGAIModelEntity;
@@ -88,12 +96,10 @@ FGAIScenario::FGAIScenario(string &filename)
      en->cd              = entry_node->getDoubleValue("cd", 0.029); 
      en->mass            = entry_node->getDoubleValue("mass", 0.007); 
      en->radius          = entry_node->getDoubleValue("turn-radius-ft", 2000);
-
- /*    en->name            = entry_node->getStringValue("name", "");
-    en->x_pivot         = entry_node->getDoubleValue("x-pivot", 0.0); 
-     en->y_pivot         = entry_node->getDoubleValue("y-pivot", 0.0); 
-     en->z_pivot         = entry_node->getDoubleValue("z-pivot", 0.0); */
-     
+     en->x_offset        = entry_node->getDoubleValue("x-offset-m", 5.5); 
+     en->y_offset        = entry_node->getDoubleValue("y-offset-m", 1.0); 
+     en->z_offset        = entry_node->getDoubleValue("z-offset-m", 1.0); 
+ /*  en->name            = entry_node->getStringValue("name", "");*/
      en->wire_objects     = getAllNodeVals("wire", entry_node);
      en->catapult_objects = getAllNodeVals("catapult", entry_node);
      en->solid_objects    = getAllNodeVals("solid", entry_node);