From: curt Date: Mon, 4 Feb 2002 22:54:02 +0000 (+0000) Subject: Updates from "Jonathan Polley" to convert from/to 'net' X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=847b9688168fb4f5f5460f3c3551edb2cc26d3aa;p=flightgear.git Updates from "Jonathan Polley" 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. --- diff --git a/src/Network/native_fdm.cxx b/src/Network/native_fdm.cxx index 7d5ac289e..137bf398f 100644 --- a/src/Network/native_fdm.cxx +++ b/src/Network/native_fdm.cxx @@ -21,14 +21,45 @@ // $Id$ +#include // htonl() ntohl() + #include +#include // endian tests #include #include +#include
#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() { } @@ -58,40 +89,73 @@ bool FGNativeFDM::open() { } -static void global2raw( const FGInterface *global, FGRawFDM *raw ) { - raw->version = FG_RAW_FDM_VERSION; +static void global2net( const FGInterface *global, FGNetFDM *net ) { + net->version = FG_NET_FDM_VERSION; // positions - raw->longitude = cur_fdm_state->get_Longitude(); - raw->latitude = cur_fdm_state->get_Latitude(); - raw->altitude = cur_fdm_state->get_Altitude() * SG_FEET_TO_METER; - raw->phi = cur_fdm_state->get_Phi(); - raw->theta = cur_fdm_state->get_Theta(); - raw->psi = cur_fdm_state->get_Psi(); + net->longitude = cur_fdm_state->get_Longitude(); + net->latitude = cur_fdm_state->get_Latitude(); + net->altitude = cur_fdm_state->get_Altitude() * SG_FEET_TO_METER; + net->phi = cur_fdm_state->get_Phi(); + net->theta = cur_fdm_state->get_Theta(); + net->psi = cur_fdm_state->get_Psi(); // velocities - raw->vcas = cur_fdm_state->get_V_calibrated_kts(); - raw->climb_rate = cur_fdm_state->get_Climb_Rate(); + net->vcas = cur_fdm_state->get_V_calibrated_kts(); + 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 ) { - if ( raw->version == FG_RAW_FDM_VERSION ) { - // cout << "pos = " << raw->longitude << " " << raw->latitude << endl; +static void net2global( FGNetFDM *net, FGInterface *global ) { + + // 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; - cur_fdm_state->_updateGeodeticPosition( raw->latitude, - raw->longitude, - raw->altitude + cur_fdm_state->_updateGeodeticPosition( net->latitude, + net->longitude, + net->altitude * SG_METER_TO_FEET ); - cur_fdm_state->_set_Euler_Angles( raw->phi, - raw->theta, - raw->psi ); - cur_fdm_state->_set_V_calibrated_kts( raw->vcas ); - cur_fdm_state->_set_Climb_Rate( raw->climb_rate ); + cur_fdm_state->_set_Euler_Angles( net->phi, + net->theta, + net->psi ); + cur_fdm_state->_set_V_calibrated_kts( net->vcas ); + cur_fdm_state->_set_Climb_Rate( net->climb_rate ); + + globals->set_warp( net->warp ); } 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, - "\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 ) { // cout << "size of cur_fdm_state = " << length << endl; - global2raw( cur_fdm_state, &buf ); + global2net( cur_fdm_state, &buf ); if ( ! io->write( (char *)(& buf), length ) ) { SG_LOG( SG_IO, SG_ALERT, "Error writing data." ); return false; @@ -112,12 +176,12 @@ bool FGNativeFDM::process() { if ( io->get_type() == sgFileType ) { if ( io->read( (char *)(& buf), length ) == length ) { SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); - raw2global( &buf, cur_fdm_state ); + net2global( &buf, cur_fdm_state ); } } else { while ( io->read( (char *)(& buf), length ) == length ) { SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); - raw2global( &buf, cur_fdm_state ); + net2global( &buf, cur_fdm_state ); } } } diff --git a/src/Network/native_fdm.hxx b/src/Network/native_fdm.hxx index 1820b3f2a..dba123766 100644 --- a/src/Network/native_fdm.hxx +++ b/src/Network/native_fdm.hxx @@ -30,12 +30,12 @@ #include #include "protocol.hxx" -#include "raw_fdm.hxx" +#include "net_fdm.hxx" class FGNativeFDM : public FGProtocol, public FGInterface { - FGRawFDM buf; + FGNetFDM buf; int length; public: diff --git a/src/Network/net_fdm.hxx b/src/Network/net_fdm.hxx new file mode 100644 index 000000000..693256ef8 --- /dev/null +++ b/src/Network/net_fdm.hxx @@ -0,0 +1,67 @@ +// net_fdm.hxx -- defines a common net I/O interface to the flight +// dynamics model +// +// Written by Curtis Olson, started September 2001. +// +// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.com +// +// 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$ + + +#ifndef _NET_FDM_HXX +#define _NET_FDM_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + +const int FG_NET_FDM_VERSION = 0x0104; + +// Define a structure containing the top level flight dynamics model +// parameters + +class FGNetFDM { + +public: + + 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 + double longitude; // geodetic (radians) + double latitude; // geodetic (radians) + double altitude; // above sea level (meters) + double agl; // above ground level (meters) + double phi; // roll (radians) + double theta; // pitch (radians) + double psi; // yaw or true heading (radians) + + // Velocities + double vcas; // calibrated airspeed + double climb_rate; // feet per second + + // Time + time_t cur_time; // current unix time + long int warp; // offset in seconds to unix time +}; + + +#endif // _NET_FDM_HXX diff --git a/src/Network/raw_fdm.hxx b/src/Network/raw_fdm.hxx deleted file mode 100644 index d635458f4..000000000 --- a/src/Network/raw_fdm.hxx +++ /dev/null @@ -1,61 +0,0 @@ -// raw_fdm.hxx -- defines a common raw I/O interface to the flight -// dynamics model -// -// Written by Curtis Olson, started September 2001. -// -// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.com -// -// 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$ - - -#ifndef _RAW_FDM_HXX -#define _RAW_FDM_HXX - - -#ifndef __cplusplus -# error This library requires C++ -#endif - -const int FG_RAW_FDM_VERSION = 3; - -// Define a structure containing the top level flight dynamics model -// parameters - -class FGRawFDM { - -public: - - int version; // increment when data values change - - // Positions - double longitude; // geodetic (radians) - double latitude; // geodetic (radians) - double altitude; // above sea level (meters) - double agl; // above ground level (meters) - double phi; // roll (radians) - double theta; // pitch (radians) - double psi; // yaw or true heading (radians) - - // Velocities - double vcas; // calibrated airspeed - double climb_rate; // feet per second -}; - - -#endif // _RAW_FDM_HXX - -