1
0
Fork 0

Updates from "Jonathan Polley" <jwpolley@home.com> to convert from/to 'net'

format before reading/writing data from/to remote machine.  This allows
different endian machines to talk to each other.  Also added support for
passing time and time offset (warp) in the data packet.
This commit is contained in:
curt 2002-02-04 22:54:02 +00:00
parent 4453bec3de
commit 847b968816
3 changed files with 106 additions and 36 deletions

View file

@ -21,14 +21,45 @@
// $Id$ // $Id$
#include <netinet/in.h> // htonl() ntohl()
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/io/lowlevel.hxx> // endian tests
#include <simgear/io/iochannel.hxx> #include <simgear/io/iochannel.hxx>
#include <FDM/flight.hxx> #include <FDM/flight.hxx>
#include <Main/globals.hxx>
#include "native_fdm.hxx" #include "native_fdm.hxx"
// The function htond is defined this way due to the way some
// processors and OSes treat floating point values. Some will raise
// an exception whenever a "bad" floating point value is loaded into a
// floating point register. Solaris is notorious for this, but then
// so is LynxOS on the PowerPC. By translating the data in place,
// there is no need to load a FP register with the "corruped" floating
// point value. By doing the BIG_ENDIAN test, I can optimize the
// routine for big-endian processors so it can be as efficient as
// possible
static void htond (double &x)
{
if ( sgIsLittleEndian() ) {
int *Double_Overlay;
int Holding_Buffer;
Double_Overlay = (int *) &x;
Holding_Buffer = Double_Overlay [0];
Double_Overlay [0] = htonl (Double_Overlay [1]);
Double_Overlay [1] = htonl (Holding_Buffer);
} else {
return;
}
}
FGNativeFDM::FGNativeFDM() { FGNativeFDM::FGNativeFDM() {
} }
@ -58,40 +89,73 @@ bool FGNativeFDM::open() {
} }
static void global2raw( const FGInterface *global, FGRawFDM *raw ) { static void global2net( const FGInterface *global, FGNetFDM *net ) {
raw->version = FG_RAW_FDM_VERSION; net->version = FG_NET_FDM_VERSION;
// positions // positions
raw->longitude = cur_fdm_state->get_Longitude(); net->longitude = cur_fdm_state->get_Longitude();
raw->latitude = cur_fdm_state->get_Latitude(); net->latitude = cur_fdm_state->get_Latitude();
raw->altitude = cur_fdm_state->get_Altitude() * SG_FEET_TO_METER; net->altitude = cur_fdm_state->get_Altitude() * SG_FEET_TO_METER;
raw->phi = cur_fdm_state->get_Phi(); net->phi = cur_fdm_state->get_Phi();
raw->theta = cur_fdm_state->get_Theta(); net->theta = cur_fdm_state->get_Theta();
raw->psi = cur_fdm_state->get_Psi(); net->psi = cur_fdm_state->get_Psi();
// velocities // velocities
raw->vcas = cur_fdm_state->get_V_calibrated_kts(); net->vcas = cur_fdm_state->get_V_calibrated_kts();
raw->climb_rate = cur_fdm_state->get_Climb_Rate(); net->climb_rate = cur_fdm_state->get_Climb_Rate();
// time
net->cur_time = globals->get_time_params()->get_cur_time();
net->warp = globals->get_warp();
// Convert the net buffer to network format
net->version = htonl(net->version);
htond(net->longitude);
htond(net->latitude);
htond(net->altitude);
htond(net->phi);
htond(net->theta);
htond(net->psi);
htond(net->vcas);
htond(net->climb_rate);
net->cur_time = htonl( net->cur_time );
net->warp = htonl( net->warp );
} }
static void raw2global( const FGRawFDM *raw, FGInterface *global ) { static void net2global( FGNetFDM *net, FGInterface *global ) {
if ( raw->version == FG_RAW_FDM_VERSION ) {
// cout << "pos = " << raw->longitude << " " << raw->latitude << endl; // Convert to the net buffer from network format
net->version = htonl(net->version);
htond(net->longitude);
htond(net->latitude);
htond(net->altitude);
htond(net->phi);
htond(net->theta);
htond(net->psi);
htond(net->vcas);
htond(net->climb_rate);
net->cur_time = htonl(net->cur_time);
net->warp = htonl(net->warp);
if ( net->version == FG_NET_FDM_VERSION ) {
// cout << "pos = " << net->longitude << " " << net->latitude << endl;
// cout << "sea level rad = " << cur_fdm_state->get_Sea_level_radius() << endl; // cout << "sea level rad = " << cur_fdm_state->get_Sea_level_radius() << endl;
cur_fdm_state->_updateGeodeticPosition( raw->latitude, cur_fdm_state->_updateGeodeticPosition( net->latitude,
raw->longitude, net->longitude,
raw->altitude net->altitude
* SG_METER_TO_FEET ); * SG_METER_TO_FEET );
cur_fdm_state->_set_Euler_Angles( raw->phi, cur_fdm_state->_set_Euler_Angles( net->phi,
raw->theta, net->theta,
raw->psi ); net->psi );
cur_fdm_state->_set_V_calibrated_kts( raw->vcas ); cur_fdm_state->_set_V_calibrated_kts( net->vcas );
cur_fdm_state->_set_Climb_Rate( raw->climb_rate ); cur_fdm_state->_set_Climb_Rate( net->climb_rate );
globals->set_warp( net->warp );
} else { } else {
SG_LOG( SG_IO, SG_ALERT, "Error: version mismatch in raw2global()" ); SG_LOG( SG_IO, SG_ALERT, "Error: version mismatch in net2global()" );
SG_LOG( SG_IO, SG_ALERT, SG_LOG( SG_IO, SG_ALERT,
"\tsomeone needs to upgrade raw_fdm.hxx and recompile." ); "\tsomeone needs to upgrade net_fdm.hxx and recompile." );
} }
} }
@ -103,7 +167,7 @@ bool FGNativeFDM::process() {
if ( get_direction() == SG_IO_OUT ) { if ( get_direction() == SG_IO_OUT ) {
// cout << "size of cur_fdm_state = " << length << endl; // cout << "size of cur_fdm_state = " << length << endl;
global2raw( cur_fdm_state, &buf ); global2net( cur_fdm_state, &buf );
if ( ! io->write( (char *)(& buf), length ) ) { if ( ! io->write( (char *)(& buf), length ) ) {
SG_LOG( SG_IO, SG_ALERT, "Error writing data." ); SG_LOG( SG_IO, SG_ALERT, "Error writing data." );
return false; return false;
@ -112,12 +176,12 @@ bool FGNativeFDM::process() {
if ( io->get_type() == sgFileType ) { if ( io->get_type() == sgFileType ) {
if ( io->read( (char *)(& buf), length ) == length ) { if ( io->read( (char *)(& buf), length ) == length ) {
SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); SG_LOG( SG_IO, SG_DEBUG, "Success reading data." );
raw2global( &buf, cur_fdm_state ); net2global( &buf, cur_fdm_state );
} }
} else { } else {
while ( io->read( (char *)(& buf), length ) == length ) { while ( io->read( (char *)(& buf), length ) == length ) {
SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); SG_LOG( SG_IO, SG_DEBUG, "Success reading data." );
raw2global( &buf, cur_fdm_state ); net2global( &buf, cur_fdm_state );
} }
} }
} }

View file

@ -30,12 +30,12 @@
#include <FDM/flight.hxx> #include <FDM/flight.hxx>
#include "protocol.hxx" #include "protocol.hxx"
#include "raw_fdm.hxx" #include "net_fdm.hxx"
class FGNativeFDM : public FGProtocol, public FGInterface { class FGNativeFDM : public FGProtocol, public FGInterface {
FGRawFDM buf; FGNetFDM buf;
int length; int length;
public: public:

View file

@ -1,4 +1,4 @@
// raw_fdm.hxx -- defines a common raw I/O interface to the flight // net_fdm.hxx -- defines a common net I/O interface to the flight
// dynamics model // dynamics model
// //
// Written by Curtis Olson, started September 2001. // Written by Curtis Olson, started September 2001.
@ -22,24 +22,28 @@
// $Id$ // $Id$
#ifndef _RAW_FDM_HXX #ifndef _NET_FDM_HXX
#define _RAW_FDM_HXX #define _NET_FDM_HXX
#ifndef __cplusplus #ifndef __cplusplus
# error This library requires C++ # error This library requires C++
#endif #endif
const int FG_RAW_FDM_VERSION = 3; const int FG_NET_FDM_VERSION = 0x0104;
// Define a structure containing the top level flight dynamics model // Define a structure containing the top level flight dynamics model
// parameters // parameters
class FGRawFDM { class FGNetFDM {
public: public:
int version; // increment when data values change int version; // increment when data values change
int pad; // keep doubles 64-bit aligned for some
// hardware platforms, such as the Sun
// SPARC, which don't like misaligned
// data
// Positions // Positions
double longitude; // geodetic (radians) double longitude; // geodetic (radians)
@ -53,9 +57,11 @@ public:
// Velocities // Velocities
double vcas; // calibrated airspeed double vcas; // calibrated airspeed
double climb_rate; // feet per second double climb_rate; // feet per second
// Time
time_t cur_time; // current unix time
long int warp; // offset in seconds to unix time
}; };
#endif // _RAW_FDM_HXX #endif // _NET_FDM_HXX