7b824755ee
I have prepared a patch that: - Introduces a FGTileMgr::scenery_available method which asks the tilemanager if scenery for a given range around a lat/lon pair is already loaded and make use of that method at some -9999 meter checks. - Introduces a FGScenery::get_elevation_m method which queries the altitude at a given position. In constrast to the groundcache functions this is the best choice if you ask for one *single* altitude value. Make use of that thing in AI/ATC classes and for the current views ground level. At the current views part the groundcache is reused if possible. - The computation of the 'current groundlevel' is no longer done on the tilemanagers update since the required functions are now better seperated. Alltogether it eliminates somehow redundant terrain level computations which are now superseeded by that more finegrained functions and the existence of the groundcache. Additionally it introduces an api to commonly required functions which was very complex to do prevously.
331 lines
10 KiB
C++
331 lines
10 KiB
C++
// ADA.cxx -- interface to the "External"-ly driven ADA flight model
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful, but
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
//
|
|
// $Id$
|
|
|
|
// Modified by Cdr. VS Renganthan <vsranga@ada.ernet.in>, 12 Oct 2K
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <simgear/io/iochannel.hxx>
|
|
#include <simgear/io/sg_socket.hxx>
|
|
#include <simgear/constants.h>
|
|
|
|
#include <Controls/controls.hxx>
|
|
#include <Main/globals.hxx>
|
|
|
|
#include <Main/fg_props.hxx> //to get ID of window (left/right or center)
|
|
#include <Scenery/scenery.hxx> //to pass ground elevation to FDM
|
|
|
|
#include "ADA.hxx"
|
|
|
|
#define numberofbytes 472 // from FDM to visuals
|
|
#define nbytes 8 //from visuals to FDM
|
|
|
|
struct {
|
|
double number_of_bytes;
|
|
double lat_geoc;
|
|
double lon_geoc;
|
|
double altitude;
|
|
double psirad;
|
|
double thetrad;
|
|
double phirad;
|
|
double earth_posn_angle;
|
|
double radius_to_vehicle;
|
|
double sea_level_radius;
|
|
double latitude;
|
|
double longitude;
|
|
double Vnorth;
|
|
double Veast;
|
|
double Vdown;
|
|
double Vcas_kts;
|
|
double prad;
|
|
double qrad;
|
|
double rrad;
|
|
double alpharad;
|
|
double betarad;
|
|
double latitude_dot;
|
|
double longitude_dot;
|
|
double radius_dot;
|
|
double Gamma_vert_rad;
|
|
double Runway_altitude;
|
|
double throttle;
|
|
double pstick;
|
|
double rstick;
|
|
double rpedal;
|
|
double U_local;
|
|
double V_local;
|
|
double W_local;
|
|
double U_dot_local;
|
|
double V_dot_local;
|
|
double W_dot_local;
|
|
double Machno;
|
|
double anxg;
|
|
double anyg;
|
|
double anzg;
|
|
double aux1;
|
|
double aux2;
|
|
double aux3;
|
|
double aux4;
|
|
double aux5;
|
|
double aux6;
|
|
double aux7;
|
|
double aux8;
|
|
int iaux1;
|
|
int iaux2;
|
|
int iaux3;
|
|
int iaux4;
|
|
int iaux5;
|
|
int iaux6;
|
|
int iaux7;
|
|
int iaux8;
|
|
int iaux9;
|
|
int iaux10;
|
|
int iaux11;
|
|
int iaux12;
|
|
float aux9;
|
|
float aux10;
|
|
float aux11;
|
|
float aux12;
|
|
float aux13;
|
|
float aux14;
|
|
float aux15;
|
|
float aux16;
|
|
float aux17;
|
|
float aux18;
|
|
} sixdof_to_visuals;
|
|
|
|
double view_offset; //if this zero, means center window
|
|
|
|
struct {
|
|
double ground_elevation;
|
|
} visuals_to_sixdof;
|
|
|
|
#define ground_elevation visuals_to_sixdof.ground_elevation
|
|
|
|
#define number_of_bytes sixdof_to_visuals.number_of_bytes
|
|
#define U_dot_local sixdof_to_visuals.U_dot_local
|
|
#define V_dot_local sixdof_to_visuals.V_dot_local
|
|
#define W_dot_local sixdof_to_visuals.W_dot_local
|
|
#define U_local sixdof_to_visuals.U_local
|
|
#define V_local sixdof_to_visuals.V_local
|
|
#define W_local sixdof_to_visuals.W_local
|
|
#define throttle sixdof_to_visuals.throttle
|
|
#define pstick sixdof_to_visuals.pstick
|
|
#define rstick sixdof_to_visuals.rstick
|
|
#define rpedal sixdof_to_visuals.rpedal
|
|
#define V_north sixdof_to_visuals.Vnorth
|
|
#define V_east sixdof_to_visuals.Veast
|
|
#define V_down sixdof_to_visuals.Vdown
|
|
#define V_calibrated_kts sixdof_to_visuals.Vcas_kts
|
|
#define P_body sixdof_to_visuals.prad
|
|
#define Q_body sixdof_to_visuals.qrad
|
|
#define R_body sixdof_to_visuals.rrad
|
|
#define Latitude_dot sixdof_to_visuals.latitude_dot
|
|
#define Longitude_dot sixdof_to_visuals.longitude_dot
|
|
#define Radius_dot sixdof_to_visuals.radius_dot
|
|
#define Latitude sixdof_to_visuals.latitude
|
|
#define Longitude sixdof_to_visuals.longitude
|
|
#define Lat_geocentric sixdof_to_visuals.lat_geoc
|
|
#define Lon_geocentric sixdof_to_visuals.lon_geoc
|
|
#define Radius_to_vehicle sixdof_to_visuals.radius_to_vehicle
|
|
#define Altitude sixdof_to_visuals.altitude
|
|
#define Phi sixdof_to_visuals.phirad
|
|
#define Theta sixdof_to_visuals.thetrad
|
|
#define Psi sixdof_to_visuals.psirad
|
|
#define Alpha sixdof_to_visuals.alpharad
|
|
#define Beta sixdof_to_visuals.betarad
|
|
#define Sea_level_radius sixdof_to_visuals.sea_level_radius
|
|
#define Earth_position_angle sixdof_to_visuals.earth_posn_angle
|
|
#define Runway_altitude sixdof_to_visuals.Runway_altitude
|
|
#define Gamma_vert_rad sixdof_to_visuals.Gamma_vert_rad
|
|
#define Machno sixdof_to_visuals.Machno
|
|
#define anxg sixdof_to_visuals.anxg
|
|
#define anyg sixdof_to_visuals.anyg
|
|
#define anzg sixdof_to_visuals.anzg
|
|
|
|
|
|
FGADA::FGADA( double dt ) {
|
|
// set_delta_t( dt );
|
|
}
|
|
|
|
|
|
FGADA::~FGADA() {
|
|
}
|
|
|
|
|
|
// Initialize the ADA flight model, dt is the time increment
|
|
// for each subsequent iteration through the EOM
|
|
void FGADA::init() {
|
|
|
|
//do init common to all FDM"s
|
|
common_init();
|
|
|
|
//now do ADA-specific init.
|
|
|
|
// cout << "FGADA::init()" << endl;
|
|
|
|
char OutBuffer[nbytes];
|
|
copy_to_FGADA();
|
|
|
|
printf("\nInitialising UDP sockets\n");
|
|
// initialise a "udp" socket
|
|
fdmsock = new SGSocket( "fdm_pc", "5001", "udp" );
|
|
|
|
// open as a client
|
|
bool result = fdmsock->open(SG_IO_OUT);
|
|
if (result == false) {
|
|
printf ("Socket Open Error\n");
|
|
} else {
|
|
copy_to_FGADA();
|
|
// Write FGExternal structure from socket to establish connection
|
|
int result = fdmsock->write(OutBuffer, nbytes);
|
|
printf("Connection established = %d.\n", result);
|
|
}
|
|
}
|
|
|
|
|
|
// Run an iteration of the EOM. This is essentially a NOP here
|
|
// because these values are getting filled in elsewhere based on
|
|
// external input.
|
|
void FGADA::update( double dt ) {
|
|
// cout << "FGADA::update()" << endl;
|
|
|
|
if (is_suspended())
|
|
return;
|
|
|
|
char Buffer[numberofbytes];
|
|
char OutBuffer[nbytes];
|
|
|
|
// Read FGExternal structure from socket
|
|
while (1) {
|
|
int result = fdmsock->read(Buffer, numberofbytes);
|
|
if (result == numberofbytes) {
|
|
// Copy buffer into FGExternal structure
|
|
memcpy (&sixdof_to_visuals, &Buffer, sizeof (Buffer));
|
|
// Convert from the FGExternal struct to the FGInterface struct (input)
|
|
copy_from_FGADA();
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
copy_to_FGADA();
|
|
fgGetDouble("/sim/view/offset",view_offset);
|
|
if ( view_offset == 0.0) {
|
|
memcpy (&OutBuffer, &visuals_to_sixdof, sizeof (OutBuffer));
|
|
fdmsock->write(OutBuffer, nbytes);
|
|
}
|
|
}
|
|
|
|
// Convert from the FGInterface struct to the FGADA struct (output)
|
|
bool FGADA::copy_to_FGADA () {
|
|
ground_elevation = get_Runway_altitude_m();
|
|
return true;
|
|
}
|
|
|
|
|
|
// Convert from the FGADA struct to the FGInterface struct (input)
|
|
bool FGADA::copy_from_FGADA() {
|
|
|
|
//Positions and attitudes for The Rendering engine
|
|
_set_Geodetic_Position( Latitude, Longitude, Altitude );
|
|
_set_Euler_Angles( Phi, Theta, Psi );
|
|
_set_Geocentric_Position( Lat_geocentric, Lon_geocentric,
|
|
Radius_to_vehicle );
|
|
_set_Sea_level_radius( Sea_level_radius );
|
|
|
|
_set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
|
|
_set_Earth_position_angle( Earth_position_angle );
|
|
_set_sin_lat_geocentric(Lat_geocentric);
|
|
_set_cos_lat_geocentric(Lat_geocentric);
|
|
_set_sin_cos_longitude(Longitude);
|
|
_set_sin_cos_latitude(Latitude);
|
|
|
|
// Velocities and accelerations for the pitch ladder and velocity vector
|
|
_set_Accels_Local( U_dot_local, V_dot_local, W_dot_local );
|
|
_set_Velocities_Ground( U_local, V_local, W_local );//same as V_NED in mps
|
|
_set_Velocities_Local( V_north, V_east, V_down ); //same as UVW_local in fps
|
|
|
|
//Positions and attitude for ship
|
|
_set_daux(1,sixdof_to_visuals.aux1);//ship lat
|
|
_set_daux(2,sixdof_to_visuals.aux2);//ship lon
|
|
_set_daux(3,sixdof_to_visuals.aux3);//ship alt+heave
|
|
_set_daux(4,sixdof_to_visuals.aux4);//distance of a/c from ski-jump exit
|
|
_set_faux(1,sixdof_to_visuals.aux9);//ship pitch
|
|
_set_faux(2,sixdof_to_visuals.aux10);//ship roll
|
|
_set_faux(3,sixdof_to_visuals.aux11);//ship yaw
|
|
_set_iaux(1,sixdof_to_visuals.iaux1);//flag for drawing ship
|
|
|
|
// controls
|
|
globals->get_controls()->set_throttle(0,throttle/131.0);
|
|
globals->get_controls()->set_elevator(pstick);
|
|
globals->get_controls()->set_aileron(rstick);
|
|
globals->get_controls()->set_rudder(rpedal);
|
|
|
|
// auxilliary parameters for HUD
|
|
_set_V_calibrated_kts( V_calibrated_kts );
|
|
_set_Alpha( Alpha );
|
|
_set_Beta( Beta );
|
|
_set_Accels_CG_Body_N( anxg,anyg,anzg);
|
|
_set_Mach_number( Machno);
|
|
_set_Climb_Rate( W_local*SG_METER_TO_FEET ); //pressure alt in feet for lca(navy)
|
|
|
|
_set_iaux(2,sixdof_to_visuals.iaux2);//control law mode switch posn
|
|
_set_iaux(3,sixdof_to_visuals.iaux3);//ldg gear posn
|
|
_set_iaux(4,sixdof_to_visuals.iaux4);// wow nose status
|
|
_set_iaux(5,sixdof_to_visuals.iaux5);// wow main status
|
|
_set_iaux(6,sixdof_to_visuals.iaux6);// arrester hook posn
|
|
_set_iaux(7,sixdof_to_visuals.iaux7);
|
|
_set_iaux(8,sixdof_to_visuals.iaux8);
|
|
_set_iaux(9,sixdof_to_visuals.iaux9);
|
|
_set_iaux(10,sixdof_to_visuals.iaux10);
|
|
_set_iaux(11,sixdof_to_visuals.iaux11);
|
|
_set_iaux(12,sixdof_to_visuals.iaux12);
|
|
|
|
_set_daux(5,sixdof_to_visuals.aux5);
|
|
_set_daux(6,sixdof_to_visuals.aux6);
|
|
_set_daux(7,sixdof_to_visuals.aux7);
|
|
_set_daux(8,sixdof_to_visuals.aux8);
|
|
|
|
_set_faux(4,sixdof_to_visuals.aux12);
|
|
_set_faux(5,sixdof_to_visuals.aux13);
|
|
_set_faux(6,sixdof_to_visuals.aux14);
|
|
_set_faux(7,sixdof_to_visuals.aux15);
|
|
_set_faux(8,sixdof_to_visuals.aux16);
|
|
_set_faux(9,sixdof_to_visuals.aux17);
|
|
_set_faux(10,sixdof_to_visuals.aux18);
|
|
|
|
// Angular rates
|
|
_set_Omega_Body( P_body, Q_body, R_body );
|
|
|
|
// Miscellaneous quantities
|
|
_set_Gamma_vert_rad( Gamma_vert_rad );
|
|
_set_Runway_altitude( Runway_altitude );
|
|
|
|
// SG_LOG( SG_FLIGHT, SG_DEBUG, "lon = " << Longitude
|
|
// << " lat_geoc = " << Lat_geocentric << " lat_geod = " << Latitude
|
|
// << " alt = " << Altitude << " sl_radius = " << Sea_level_radius
|
|
// << " radius_to_vehicle = " << Radius_to_vehicle );
|
|
|
|
|
|
// printf("sr=%f\n",Sea_level_radius);
|
|
// printf("psi = %f %f\n",Psi,Psi*SGD_RADIANS_TO_DEGREES);
|
|
|
|
return true;
|
|
}
|