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.
This commit is contained in:
parent
fee003e8cc
commit
8ba9f4e3a4
5 changed files with 252 additions and 14 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
#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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue