From 8ba9f4e3a4fd51e0652e8b73120e3b3a77701d2d Mon Sep 17 00:00:00 2001 From: ehofman Date: Tue, 30 Nov 2004 12:34:11 +0000 Subject: [PATCH] Vivian Meazza: 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 | 27 +++++- src/AIModel/AICarrier.cxx | 186 ++++++++++++++++++++++++++++++++++++- src/AIModel/AICarrier.hxx | 22 +++++ src/AIModel/AIManager.cxx | 7 +- src/AIModel/AIScenario.cxx | 26 ++++-- 5 files changed, 253 insertions(+), 15 deletions(-) diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index bc8b2e48a..fd8d8c85c 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -73,7 +73,9 @@ typedef struct { list wire_objects; // List of wire object names list 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 diff --git a/src/AIModel/AICarrier.cxx b/src/AIModel/AICarrier.cxx index d6e29b746..84775fa58 100644 --- a/src/AIModel/AICarrier.cxx +++ b/src/AIModel/AICarrier.cxx @@ -24,6 +24,12 @@ #include #include +#include +#include +#include +#include
+#include
+ #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(&source)); + props->tie("controls/flols/distance-m", + SGRawValuePointer(&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& 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& 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; diff --git a/src/AIModel/AICarrier.hxx b/src/AIModel/AICarrier.hxx index 32cea5983..15f2bdf45 100644 --- a/src/AIModel/AICarrier.hxx +++ b/src/AIModel/AICarrier.hxx @@ -80,6 +80,9 @@ public: void setCatapultObjects(const list& 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 diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index 2a4b7dde5..25f5425c7 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -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); diff --git a/src/AIModel/AIScenario.cxx b/src/AIModel/AIScenario.cxx index 0e92bc7c1..903a67947 100644 --- a/src/AIModel/AIScenario.cxx +++ b/src/AIModel/AIScenario.cxx @@ -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); -- 2.39.5