Merge all Net/DDS FDM, GUI and Ctrls struct handling into one source file and make it FlightGear agnostic which means that they can be used by, for instance, fgviewer.
This commit is contained in:
parent
8f5dc3e764
commit
875713efad
12 changed files with 1863 additions and 1793 deletions
|
@ -31,6 +31,7 @@
|
|||
#include <simgear/io/sg_netBuffer.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Network/native_structs.hxx>
|
||||
#include <Network/native_ctrls.hxx>
|
||||
#include <Network/native_fdm.hxx>
|
||||
|
||||
|
@ -221,7 +222,7 @@ void FGExternalNet::update(double dt)
|
|||
|
||||
// Send control positions to remote fdm
|
||||
length = sizeof(ctrls);
|
||||
FGProps2Ctrls<FGNetCtrls>(&ctrls, true, true);
|
||||
FGProps2Ctrls<FGNetCtrls>( globals->get_props(), &ctrls, true, true);
|
||||
if (data_client.send((char*)(&ctrls), length, 0) != length) {
|
||||
SG_LOG(SG_IO, SG_DEBUG, "Error writing data.");
|
||||
} else {
|
||||
|
@ -232,7 +233,7 @@ void FGExternalNet::update(double dt)
|
|||
length = sizeof(fdm);
|
||||
while ((result = data_server.recv((char*)(&fdm), length, 0)) >= 0) {
|
||||
SG_LOG(SG_IO, SG_DEBUG, "Success reading data.");
|
||||
FGFDM2Props<FGNetFDM>(&fdm);
|
||||
FGFDM2Props<FGNetFDM>( globals->get_props(), &fdm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <simgear/misc/strutils.hxx> // split()
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Network/native_structs.hxx>
|
||||
#include <Network/native_ctrls.hxx>
|
||||
#include <Network/native_fdm.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
@ -405,12 +406,12 @@ void FGExternalPipe::update_binary( double dt ) {
|
|||
|
||||
// Send control positions to remote fdm
|
||||
length = sizeof(ctrls);
|
||||
FGProps2Ctrls<FGNetCtrls>( &ctrls, true, false );
|
||||
FGProps2Ctrls<FGNetCtrls>( globals->get_props(), &ctrls, true, false );
|
||||
char *ptr = buf;
|
||||
*((int *)ptr) = iterations;
|
||||
// cout << "iterations = " << iterations << endl;
|
||||
ptr += sizeof(int);
|
||||
memcpy( ptr, (char *)(&ctrls), length );
|
||||
memcpy( ptr, (char *)( globals->get_props(),&ctrls), length );
|
||||
// cout << "writing control structure, size = "
|
||||
// << length + sizeof(int) << endl;
|
||||
|
||||
|
@ -426,7 +427,7 @@ void FGExternalPipe::update_binary( double dt ) {
|
|||
<< fifo_name_2 << " expected 1 item, but got " << result );
|
||||
} else {
|
||||
// cout << " read successful." << endl;
|
||||
FGFDM2Props<FGNetFDM>( &fdm, false );
|
||||
FGFDM2Props<FGNetFDM>( globals->get_props(), &fdm, false );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ set(SOURCES
|
|||
jsclient.cxx
|
||||
lfsglass.cxx
|
||||
native.cxx
|
||||
native_structs.cxx
|
||||
native_ctrls.cxx
|
||||
native_fdm.cxx
|
||||
native_gui.cxx
|
||||
|
@ -48,6 +49,7 @@ set(HEADERS
|
|||
jsclient.hxx
|
||||
lfsglass.hxx
|
||||
native.hxx
|
||||
native_ctrls.hxx
|
||||
native_ctrls.hxx
|
||||
native_fdm.hxx
|
||||
native_gui.hxx
|
||||
|
|
|
@ -93,9 +93,21 @@ int main()
|
|||
* the buffer array to a valid sample memory location. */
|
||||
samples[0] = FG_DDS_FDM__alloc ();
|
||||
|
||||
/* Poll until a keys is pressed */
|
||||
// wait set
|
||||
dds_entity_t waitset = dds_create_waitset(participant);
|
||||
dds_entity_t rdcond = dds_create_readcondition(reader,
|
||||
DDS_NOT_READ_SAMPLE_STATE);
|
||||
int status = dds_waitset_attach(waitset, rdcond, reader);
|
||||
if (status < 0)
|
||||
DDS_FATAL("ds_waitset_attach: %s\n", dds_strretcode(-status));
|
||||
|
||||
/* Wait for a new packet. */
|
||||
set_mode(1);
|
||||
while( !get_key() )
|
||||
|
||||
size_t num = 1;
|
||||
dds_attach_t results[num];
|
||||
dds_duration_t timeout = DDS_MSECS(500);
|
||||
while(dds_waitset_wait(waitset, results, num, timeout) >= 0)
|
||||
{
|
||||
/* Do the actual read.
|
||||
* The return value contains the number of read samples. */
|
||||
|
@ -117,11 +129,8 @@ int main()
|
|||
fflush(stdout);
|
||||
// break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Polling sleep. */
|
||||
dds_sleepfor(DDS_MSECS(20));
|
||||
}
|
||||
|
||||
if (get_key()) break;
|
||||
}
|
||||
set_mode(0);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <Main/fg_props.hxx>
|
||||
#include <Scenery/scenery.hxx> // ground elevation
|
||||
|
||||
#include "native_structs.hxx"
|
||||
#include "native_ctrls.hxx"
|
||||
|
||||
// FreeBSD works better with this included last ... (?)
|
||||
|
@ -47,645 +48,6 @@
|
|||
# include <netinet/in.h> // htonl() ntohl()
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Populate the FGNetCtrls structure from the property tree.
|
||||
template<>
|
||||
void FGProps2Ctrls<FGNetCtrls>( FGNetCtrls *net, bool honor_freezes,
|
||||
bool net_byte_order )
|
||||
{
|
||||
int i;
|
||||
SGPropertyNode *node;
|
||||
SGPropertyNode *fuelpump;
|
||||
SGPropertyNode *tempnode;
|
||||
|
||||
// fill in values
|
||||
node = fgGetNode("/controls/flight", true);
|
||||
net->version = FG_NET_CTRLS_VERSION;
|
||||
net->aileron = node->getDoubleValue( "aileron" );
|
||||
net->elevator = node->getDoubleValue( "elevator" );
|
||||
net->rudder = node->getDoubleValue( "rudder" );
|
||||
net->aileron_trim = node->getDoubleValue( "aileron-trim" );
|
||||
net->elevator_trim = node->getDoubleValue( "elevator-trim" );
|
||||
net->rudder_trim = node->getDoubleValue( "rudder-trim" );
|
||||
net->flaps = node->getDoubleValue( "flaps" );
|
||||
net->speedbrake = node->getDoubleValue( "speedbrake" );
|
||||
net->spoilers = node->getDoubleValue( "spoilers" );
|
||||
net->flaps_power
|
||||
= fgGetDouble( "/systems/electrical/outputs/flaps", 1.0 ) >= 1.0;
|
||||
net->flap_motor_ok = node->getBoolValue( "flaps-serviceable" );
|
||||
|
||||
net->num_engines = FGNetCtrls::FG_MAX_ENGINES;
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
|
||||
// Controls
|
||||
node = fgGetNode("/controls/engines/engine", i );
|
||||
fuelpump = fgGetNode("/systems/electrical/outputs/fuel-pump", i );
|
||||
|
||||
tempnode = node->getChild("starter");
|
||||
if ( tempnode != NULL ) {
|
||||
net->starter_power[i] = ( tempnode->getDoubleValue() >= 1.0 );
|
||||
}
|
||||
tempnode = node->getChild("master-bat");
|
||||
if ( tempnode != NULL ) {
|
||||
net->master_bat[i] = tempnode->getBoolValue();
|
||||
}
|
||||
tempnode = node->getChild("master-alt");
|
||||
if ( tempnode != NULL ) {
|
||||
net->master_alt[i] = tempnode->getBoolValue();
|
||||
}
|
||||
|
||||
net->throttle[i] = node->getDoubleValue( "throttle", 0.0 );
|
||||
net->mixture[i] = node->getDoubleValue( "mixture", 0.0 );
|
||||
net->prop_advance[i] = node->getDoubleValue( "propeller-pitch", 0.0 );
|
||||
net->condition[i] = node->getDoubleValue( "condition", 0.0 );
|
||||
net->magnetos[i] = node->getIntValue( "magnetos", 0 );
|
||||
if ( i == 0 ) {
|
||||
// cout << "Magnetos -> " << node->getIntValue( "magnetos", 0 );
|
||||
}
|
||||
if ( i == 0 ) {
|
||||
// cout << "Starter -> " << node->getIntValue( "starter", false )
|
||||
// << endl;
|
||||
}
|
||||
|
||||
if ( fuelpump != NULL ) {
|
||||
net->fuel_pump_power[i] = ( fuelpump->getDoubleValue() >= 1.0 );
|
||||
} else {
|
||||
net->fuel_pump_power[i] = 0;
|
||||
}
|
||||
|
||||
// Faults
|
||||
SGPropertyNode *faults = node->getChild( "faults", 0, true );
|
||||
net->engine_ok[i] = faults->getBoolValue( "serviceable", true );
|
||||
net->mag_left_ok[i]
|
||||
= faults->getBoolValue( "left-magneto-serviceable", true );
|
||||
net->mag_right_ok[i]
|
||||
= faults->getBoolValue( "right-magneto-serviceable", true);
|
||||
net->spark_plugs_ok[i]
|
||||
= faults->getBoolValue( "spark-plugs-serviceable", true );
|
||||
net->oil_press_status[i]
|
||||
= faults->getIntValue( "oil-pressure-status", 0 );
|
||||
net->fuel_pump_ok[i]
|
||||
= faults->getBoolValue( "fuel-pump-serviceable", true );
|
||||
}
|
||||
net->num_tanks = FGNetCtrls::FG_MAX_TANKS;
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
|
||||
node = fgGetNode("/controls/fuel/tank", i);
|
||||
if ( node->getChild("fuel_selector") != 0 ) {
|
||||
net->fuel_selector[i]
|
||||
= node->getChild("fuel_selector")->getBoolValue();
|
||||
} else {
|
||||
net->fuel_selector[i] = false;
|
||||
}
|
||||
}
|
||||
node = fgGetNode("/controls/gear", true);
|
||||
net->brake_left = node->getChild("brake-left")->getDoubleValue();
|
||||
net->brake_right = node->getChild("brake-right")->getDoubleValue();
|
||||
net->copilot_brake_left
|
||||
= node->getChild("copilot-brake-left")->getDoubleValue();
|
||||
net->copilot_brake_right
|
||||
= node->getChild("copilot-brake-right")->getDoubleValue();
|
||||
net->brake_parking = node->getChild("brake-parking")->getDoubleValue();
|
||||
|
||||
net->gear_handle = fgGetBool( "/controls/gear/gear-down" );
|
||||
|
||||
net->master_avionics = fgGetBool("/controls/switches/master-avionics");
|
||||
|
||||
net->wind_speed_kt = fgGetDouble("/environment/wind-speed-kt");
|
||||
net->wind_dir_deg = fgGetDouble("/environment/wind-from-heading-deg");
|
||||
net->turbulence_norm =
|
||||
fgGetDouble("/environment/turbulence/magnitude-norm");
|
||||
|
||||
net->temp_c = fgGetDouble("/environment/temperature-degc");
|
||||
net->press_inhg = fgGetDouble("/environment/pressure-sea-level-inhg");
|
||||
|
||||
net->hground = fgGetDouble("/position/ground-elev-m");
|
||||
net->magvar = fgGetDouble("/environment/magnetic-variation-deg");
|
||||
|
||||
net->icing = fgGetBool("/hazards/icing/wing");
|
||||
|
||||
net->speedup = fgGetInt("/sim/speed-up");
|
||||
net->freeze = 0;
|
||||
if ( honor_freezes ) {
|
||||
if ( fgGetBool("/sim/freeze/master") ) {
|
||||
net->freeze |= 0x01;
|
||||
}
|
||||
if ( fgGetBool("/sim/freeze/position") ) {
|
||||
net->freeze |= 0x02;
|
||||
}
|
||||
if ( fgGetBool("/sim/freeze/fuel") ) {
|
||||
net->freeze |= 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
if ( net_byte_order ) {
|
||||
// convert to network byte order
|
||||
net->version = htonl(net->version);
|
||||
htond(net->aileron);
|
||||
htond(net->elevator);
|
||||
htond(net->rudder);
|
||||
htond(net->aileron_trim);
|
||||
htond(net->elevator_trim);
|
||||
htond(net->rudder_trim);
|
||||
htond(net->flaps);
|
||||
htond(net->speedbrake);
|
||||
htond(net->spoilers);
|
||||
net->flaps_power = htonl(net->flaps_power);
|
||||
net->flap_motor_ok = htonl(net->flap_motor_ok);
|
||||
|
||||
net->num_engines = htonl(net->num_engines);
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
|
||||
net->master_bat[i] = htonl(net->master_bat[i]);
|
||||
net->master_alt[i] = htonl(net->master_alt[i]);
|
||||
net->magnetos[i] = htonl(net->magnetos[i]);
|
||||
net->starter_power[i] = htonl(net->starter_power[i]);
|
||||
htond(net->throttle[i]);
|
||||
htond(net->mixture[i]);
|
||||
net->fuel_pump_power[i] = htonl(net->fuel_pump_power[i]);
|
||||
htond(net->prop_advance[i]);
|
||||
htond(net->condition[i]);
|
||||
net->engine_ok[i] = htonl(net->engine_ok[i]);
|
||||
net->mag_left_ok[i] = htonl(net->mag_left_ok[i]);
|
||||
net->mag_right_ok[i] = htonl(net->mag_right_ok[i]);
|
||||
net->spark_plugs_ok[i] = htonl(net->spark_plugs_ok[i]);
|
||||
net->oil_press_status[i] = htonl(net->oil_press_status[i]);
|
||||
net->fuel_pump_ok[i] = htonl(net->fuel_pump_ok[i]);
|
||||
}
|
||||
|
||||
net->num_tanks = htonl(net->num_tanks);
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
|
||||
net->fuel_selector[i] = htonl(net->fuel_selector[i]);
|
||||
}
|
||||
|
||||
net->cross_feed = htonl(net->cross_feed);
|
||||
htond(net->brake_left);
|
||||
htond(net->brake_right);
|
||||
htond(net->copilot_brake_left);
|
||||
htond(net->copilot_brake_right);
|
||||
htond(net->brake_parking);
|
||||
net->gear_handle = htonl(net->gear_handle);
|
||||
net->master_avionics = htonl(net->master_avionics);
|
||||
htond(net->wind_speed_kt);
|
||||
htond(net->wind_dir_deg);
|
||||
htond(net->turbulence_norm);
|
||||
htond(net->temp_c);
|
||||
htond(net->press_inhg);
|
||||
htond(net->hground);
|
||||
htond(net->magvar);
|
||||
net->icing = htonl(net->icing);
|
||||
net->speedup = htonl(net->speedup);
|
||||
net->freeze = htonl(net->freeze);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update the property tree from the FGNetCtrls structure.
|
||||
template<>
|
||||
void FGCtrls2Props<FGNetCtrls>( FGNetCtrls *net, bool honor_freezes,
|
||||
bool net_byte_order )
|
||||
{
|
||||
int i;
|
||||
|
||||
SGPropertyNode * node;
|
||||
|
||||
if ( net_byte_order ) {
|
||||
// convert from network byte order
|
||||
net->version = htonl(net->version);
|
||||
htond(net->aileron);
|
||||
htond(net->elevator);
|
||||
htond(net->rudder);
|
||||
htond(net->aileron_trim);
|
||||
htond(net->elevator_trim);
|
||||
htond(net->rudder_trim);
|
||||
htond(net->flaps);
|
||||
htond(net->speedbrake);
|
||||
htond(net->spoilers);
|
||||
net->flaps_power = htonl(net->flaps_power);
|
||||
net->flap_motor_ok = htonl(net->flap_motor_ok);
|
||||
|
||||
net->num_engines = htonl(net->num_engines);
|
||||
for ( i = 0; i < (int)net->num_engines; ++i ) {
|
||||
net->master_bat[i] = htonl(net->master_bat[i]);
|
||||
net->master_alt[i] = htonl(net->master_alt[i]);
|
||||
net->magnetos[i] = htonl(net->magnetos[i]);
|
||||
net->starter_power[i] = htonl(net->starter_power[i]);
|
||||
htond(net->throttle[i]);
|
||||
htond(net->mixture[i]);
|
||||
net->fuel_pump_power[i] = htonl(net->fuel_pump_power[i]);
|
||||
htond(net->prop_advance[i]);
|
||||
htond(net->condition[i]);
|
||||
net->engine_ok[i] = htonl(net->engine_ok[i]);
|
||||
net->mag_left_ok[i] = htonl(net->mag_left_ok[i]);
|
||||
net->mag_right_ok[i] = htonl(net->mag_right_ok[i]);
|
||||
net->spark_plugs_ok[i] = htonl(net->spark_plugs_ok[i]);
|
||||
net->oil_press_status[i] = htonl(net->oil_press_status[i]);
|
||||
net->fuel_pump_ok[i] = htonl(net->fuel_pump_ok[i]);
|
||||
}
|
||||
|
||||
net->num_tanks = htonl(net->num_tanks);
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
|
||||
net->fuel_selector[i] = htonl(net->fuel_selector[i]);
|
||||
}
|
||||
|
||||
net->cross_feed = htonl(net->cross_feed);
|
||||
htond(net->brake_left);
|
||||
htond(net->brake_right);
|
||||
htond(net->copilot_brake_left);
|
||||
htond(net->copilot_brake_right);
|
||||
htond(net->brake_parking);
|
||||
net->gear_handle = htonl(net->gear_handle);
|
||||
net->master_avionics = htonl(net->master_avionics);
|
||||
htond(net->wind_speed_kt);
|
||||
htond(net->wind_dir_deg);
|
||||
htond(net->turbulence_norm);
|
||||
htond(net->temp_c);
|
||||
htond(net->press_inhg);
|
||||
htond(net->hground);
|
||||
htond(net->magvar);
|
||||
net->icing = htonl(net->icing);
|
||||
net->speedup = htonl(net->speedup);
|
||||
net->freeze = htonl(net->freeze);
|
||||
}
|
||||
|
||||
if ( net->version != FG_NET_CTRLS_VERSION ) {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Version mismatch with raw controls packet format." );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"FlightGear needs version = " << FG_NET_CTRLS_VERSION
|
||||
<< " but is receiving version = " << net->version );
|
||||
}
|
||||
node = fgGetNode("/controls/flight", true);
|
||||
node->setDoubleValue( "aileron", net->aileron );
|
||||
node->setDoubleValue( "elevator", net->elevator );
|
||||
node->setDoubleValue( "rudder", net->rudder );
|
||||
node->setDoubleValue( "aileron-trim", net->aileron_trim );
|
||||
node->setDoubleValue( "elevator-trim", net->elevator_trim );
|
||||
node->setDoubleValue( "rudder-trim", net->rudder_trim );
|
||||
node->setDoubleValue( "flaps", net->flaps );
|
||||
node->setDoubleValue( "speedbrake", net->speedbrake ); //JWW
|
||||
// or
|
||||
node->setDoubleValue( "spoilers", net->spoilers ); //JWW
|
||||
// cout << "NET->Spoilers: " << net->spoilers << endl;
|
||||
fgSetBool( "/systems/electrical/outputs/flaps", net->flaps_power > 0 );
|
||||
node->setBoolValue( "flaps-serviceable", net->flap_motor_ok > 0 );
|
||||
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
|
||||
// Controls
|
||||
node = fgGetNode("/controls/engines/engine", i);
|
||||
node->getChild( "throttle" )->setDoubleValue( net->throttle[i] );
|
||||
node->getChild( "mixture" )->setDoubleValue( net->mixture[i] );
|
||||
node->getChild( "propeller-pitch" )
|
||||
->setDoubleValue( net->prop_advance[i] );
|
||||
node->getChild( "condition" )
|
||||
->setDoubleValue( net->condition[i] );
|
||||
node->getChild( "magnetos" )->setDoubleValue( net->magnetos[i] );
|
||||
node->getChild( "starter" )->setDoubleValue( net->starter_power[i] );
|
||||
node->getChild( "feed_tank" )->setIntValue( net->feed_tank_to[i] );
|
||||
node->getChild( "reverser" )->setBoolValue( net->reverse[i] > 0 );
|
||||
// Faults
|
||||
SGPropertyNode *faults = node->getNode( "faults", true );
|
||||
faults->setBoolValue( "serviceable", net->engine_ok[i] > 0 );
|
||||
faults->setBoolValue( "left-magneto-serviceable",
|
||||
net->mag_left_ok[i] > 0 );
|
||||
faults->setBoolValue( "right-magneto-serviceable",
|
||||
net->mag_right_ok[i] > 0);
|
||||
faults->setBoolValue( "spark-plugs-serviceable",
|
||||
net->spark_plugs_ok[i] > 0);
|
||||
faults->setIntValue( "oil-pressure-status", net->oil_press_status[i] );
|
||||
faults->setBoolValue( "fuel-pump-serviceable", net->fuel_pump_ok[i] > 0);
|
||||
}
|
||||
|
||||
fgSetBool( "/systems/electrical/outputs/fuel-pump",
|
||||
net->fuel_pump_power[0] > 0);
|
||||
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
|
||||
node = fgGetNode( "/controls/fuel/tank", i );
|
||||
node->getChild( "fuel_selector" )
|
||||
->setBoolValue( net->fuel_selector[i] > 0 );
|
||||
// node->getChild( "to_tank" )->xfer_tank( i, net->xfer_to[i] );
|
||||
}
|
||||
node = fgGetNode( "/controls/gear" );
|
||||
if ( node != NULL ) {
|
||||
node->getChild( "brake-left" )->setDoubleValue( net->brake_left );
|
||||
node->getChild( "brake-right" )->setDoubleValue( net->brake_right );
|
||||
node->getChild( "copilot-brake-left" )
|
||||
->setDoubleValue( net->copilot_brake_left );
|
||||
node->getChild( "copilot-brake-right" )
|
||||
->setDoubleValue( net->copilot_brake_right );
|
||||
node->getChild( "brake-parking" )->setDoubleValue( net->brake_parking );
|
||||
}
|
||||
|
||||
node = fgGetNode( "/controls/gear", true );
|
||||
node->setBoolValue( "gear-down", net->gear_handle > 0 );
|
||||
// node->setDoubleValue( "brake-parking", net->brake_parking );
|
||||
// node->setDoubleValue( net->brake_left );
|
||||
// node->setDoubleValue( net->brake_right );
|
||||
|
||||
node = fgGetNode( "/controls/switches", true );
|
||||
node->setBoolValue( "master-bat", net->master_bat[0] != 0 );
|
||||
node->setBoolValue( "master-alt", net->master_alt[0] != 0 );
|
||||
node->setBoolValue( "master-avionics", net->master_avionics > 0 );
|
||||
|
||||
node = fgGetNode( "/environment", true );
|
||||
node->setDoubleValue( "wind-speed-kt", net->wind_speed_kt );
|
||||
node->setDoubleValue( "wind-from-heading-deg", net->wind_dir_deg );
|
||||
node->setDoubleValue( "turbulence/magnitude-norm", net->turbulence_norm );
|
||||
node->setDoubleValue( "magnetic-variation-deg", net->magvar );
|
||||
|
||||
node->setDoubleValue( "/environment/temperature-degc",
|
||||
net->temp_c );
|
||||
node->setDoubleValue( "/environment/pressure-sea-level-inhg",
|
||||
net->press_inhg );
|
||||
|
||||
// ground elevation ???
|
||||
|
||||
fgSetDouble("/hazards/icing/wing", net->icing);
|
||||
|
||||
node = fgGetNode( "/radios", true );
|
||||
node->setDoubleValue( "comm/frequencies/selected-mhz[0]", net->comm_1 );
|
||||
node->setDoubleValue( "nav/frequencies/selected-mhz[0]", net->nav_1 );
|
||||
node->setDoubleValue( "nav[1]/frequencies/selected-mhz[0]", net->nav_2 );
|
||||
|
||||
fgSetDouble( "/sim/speed-up", net->speedup );
|
||||
|
||||
if ( honor_freezes ) {
|
||||
node = fgGetNode( "/sim/freeze", true );
|
||||
node->setBoolValue( "master", (net->freeze & 0x01) > 0 );
|
||||
node->setBoolValue( "position", (net->freeze & 0x02) > 0 );
|
||||
node->setBoolValue( "fuel", (net->freeze & 0x04) > 0 );
|
||||
}
|
||||
}
|
||||
|
||||
#if FG_HAVE_DDS
|
||||
// Populate the FG_DDS_Ctrls structure from the property tree.
|
||||
template<>
|
||||
void FGProps2Ctrls<FG_DDS_Ctrls>( FG_DDS_Ctrls *dds, bool honor_freezes, bool net_byte_order )
|
||||
{
|
||||
int i;
|
||||
SGPropertyNode *node;
|
||||
SGPropertyNode *fuelpump;
|
||||
SGPropertyNode *tempnode;
|
||||
|
||||
// fill in values
|
||||
node = fgGetNode("/controls/flight", true);
|
||||
dds->version = FG_DDS_CTRLS_VERSION;
|
||||
dds->aileron = node->getDoubleValue( "aileron" );
|
||||
dds->elevator = node->getDoubleValue( "elevator" );
|
||||
dds->rudder = node->getDoubleValue( "rudder" );
|
||||
dds->aileron_trim = node->getDoubleValue( "aileron-trim" );
|
||||
dds->elevator_trim = node->getDoubleValue( "elevator-trim" );
|
||||
dds->rudder_trim = node->getDoubleValue( "rudder-trim" );
|
||||
dds->flaps = node->getDoubleValue( "flaps" );
|
||||
dds->speedbrake = node->getDoubleValue( "speedbrake" );
|
||||
dds->spoilers = node->getDoubleValue( "spoilers" );
|
||||
dds->flaps_power
|
||||
= fgGetDouble( "/systems/electrical/outputs/flaps", 1.0 ) >= 1.0;
|
||||
dds->flap_motor_ok = node->getBoolValue( "flaps-serviceable" );
|
||||
|
||||
dds->num_engines = FGNetCtrls::FG_MAX_ENGINES;
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
|
||||
// Controls
|
||||
node = fgGetNode("/controls/engines/engine", i );
|
||||
fuelpump = fgGetNode("/systems/electrical/outputs/fuel-pump", i );
|
||||
|
||||
tempnode = node->getChild("starter");
|
||||
if ( tempnode != NULL ) {
|
||||
dds->starter_power[i] = ( tempnode->getDoubleValue() >= 1.0 );
|
||||
}
|
||||
tempnode = node->getChild("master-bat");
|
||||
if ( tempnode != NULL ) {
|
||||
dds->master_bat[i] = tempnode->getBoolValue();
|
||||
}
|
||||
tempnode = node->getChild("master-alt");
|
||||
if ( tempnode != NULL ) {
|
||||
dds->master_alt[i] = tempnode->getBoolValue();
|
||||
}
|
||||
|
||||
dds->throttle[i] = node->getDoubleValue( "throttle", 0.0 );
|
||||
dds->mixture[i] = node->getDoubleValue( "mixture", 0.0 );
|
||||
dds->prop_advance[i] = node->getDoubleValue( "propeller-pitch", 0.0 );
|
||||
dds->condition[i] = node->getDoubleValue( "condition", 0.0 );
|
||||
dds->magnetos[i] = node->getIntValue( "magnetos", 0 );
|
||||
if ( i == 0 ) {
|
||||
// cout << "Magnetos -> " << node->getIntValue( "magnetos", 0 );
|
||||
}
|
||||
if ( i == 0 ) {
|
||||
// cout << "Starter -> " << node->getIntValue( "starter", false )
|
||||
// << endl;
|
||||
}
|
||||
|
||||
if ( fuelpump != NULL ) {
|
||||
dds->fuel_pump_power[i] = ( fuelpump->getDoubleValue() >= 1.0 );
|
||||
} else {
|
||||
dds->fuel_pump_power[i] = 0;
|
||||
}
|
||||
|
||||
// Faults
|
||||
SGPropertyNode *faults = node->getChild( "faults", 0, true );
|
||||
dds->engine_ok[i] = faults->getBoolValue( "serviceable", true );
|
||||
dds->mag_left_ok[i]
|
||||
= faults->getBoolValue( "left-magneto-serviceable", true );
|
||||
dds->mag_right_ok[i]
|
||||
= faults->getBoolValue( "right-magneto-serviceable", true);
|
||||
dds->spark_plugs_ok[i]
|
||||
= faults->getBoolValue( "spark-plugs-serviceable", true );
|
||||
dds->oil_press_status[i]
|
||||
= faults->getIntValue( "oil-pressure-status", 0 );
|
||||
dds->fuel_pump_ok[i]
|
||||
= faults->getBoolValue( "fuel-pump-serviceable", true );
|
||||
}
|
||||
dds->num_tanks = FGNetCtrls::FG_MAX_TANKS;
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
|
||||
node = fgGetNode("/controls/fuel/tank", i);
|
||||
if ( node->getChild("fuel_selector") != 0 ) {
|
||||
dds->fuel_selector[i]
|
||||
= node->getChild("fuel_selector")->getBoolValue();
|
||||
} else {
|
||||
dds->fuel_selector[i] = false;
|
||||
}
|
||||
}
|
||||
node = fgGetNode("/controls/gear", true);
|
||||
dds->brake_left = node->getChild("brake-left")->getDoubleValue();
|
||||
dds->brake_right = node->getChild("brake-right")->getDoubleValue();
|
||||
dds->copilot_brake_left
|
||||
= node->getChild("copilot-brake-left")->getDoubleValue();
|
||||
dds->copilot_brake_right
|
||||
= node->getChild("copilot-brake-right")->getDoubleValue();
|
||||
dds->brake_parking = node->getChild("brake-parking")->getDoubleValue();
|
||||
|
||||
dds->gear_handle = fgGetBool( "/controls/gear/gear-down" );
|
||||
|
||||
dds->master_avionics = fgGetBool("/controls/switches/master-avionics");
|
||||
|
||||
dds->wind_speed_kt = fgGetDouble("/environment/wind-speed-kt");
|
||||
dds->wind_dir_deg = fgGetDouble("/environment/wind-from-heading-deg");
|
||||
dds->turbulence_norm =
|
||||
fgGetDouble("/environment/turbulence/magnitude-norm");
|
||||
|
||||
dds->temp_c = fgGetDouble("/environment/temperature-degc");
|
||||
dds->press_inhg = fgGetDouble("/environment/pressure-sea-level-inhg");
|
||||
|
||||
dds->hground = fgGetDouble("/position/ground-elev-m");
|
||||
dds->magvar = fgGetDouble("/environment/magnetic-variation-deg");
|
||||
|
||||
dds->icing = fgGetBool("/hazards/icing/wing");
|
||||
|
||||
dds->speedup = fgGetInt("/sim/speed-up");
|
||||
dds->freeze = 0;
|
||||
if ( honor_freezes ) {
|
||||
if ( fgGetBool("/sim/freeze/master") ) {
|
||||
dds->freeze |= 0x01;
|
||||
}
|
||||
if ( fgGetBool("/sim/freeze/position") ) {
|
||||
dds->freeze |= 0x02;
|
||||
}
|
||||
if ( fgGetBool("/sim/freeze/fuel") ) {
|
||||
dds->freeze |= 0x04;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the property tree from the FG_DDS_Ctrls structure.
|
||||
template<>
|
||||
void FGCtrls2Props<FG_DDS_Ctrls>( FG_DDS_Ctrls *dds, bool honor_freezes, bool net_byte_order )
|
||||
{
|
||||
int i;
|
||||
|
||||
SGPropertyNode * node;
|
||||
|
||||
if ( dds->version != FG_DDS_CTRLS_VERSION ) {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Version mismatch with raw controls packet format." );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"FlightGear needs version = " << FG_DDS_CTRLS_VERSION
|
||||
<< " but is receiving version = " << dds->version );
|
||||
}
|
||||
node = fgGetNode("/controls/flight", true);
|
||||
node->setDoubleValue( "aileron", dds->aileron );
|
||||
node->setDoubleValue( "elevator", dds->elevator );
|
||||
node->setDoubleValue( "rudder", dds->rudder );
|
||||
node->setDoubleValue( "aileron-trim", dds->aileron_trim );
|
||||
node->setDoubleValue( "elevator-trim", dds->elevator_trim );
|
||||
node->setDoubleValue( "rudder-trim", dds->rudder_trim );
|
||||
node->setDoubleValue( "flaps", dds->flaps );
|
||||
node->setDoubleValue( "speedbrake", dds->speedbrake ); //JWW
|
||||
// or
|
||||
node->setDoubleValue( "spoilers", dds->spoilers ); //JWW
|
||||
// cout << "NET->Spoilers: " << dds->spoilers << endl;
|
||||
fgSetBool( "/systems/electrical/outputs/flaps", dds->flaps_power > 0 );
|
||||
node->setBoolValue( "flaps-serviceable", dds->flap_motor_ok > 0 );
|
||||
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
|
||||
// Controls
|
||||
node = fgGetNode("/controls/engines/engine", i);
|
||||
node->getChild( "throttle" )->setDoubleValue( dds->throttle[i] );
|
||||
node->getChild( "mixture" )->setDoubleValue( dds->mixture[i] );
|
||||
node->getChild( "propeller-pitch" )
|
||||
->setDoubleValue( dds->prop_advance[i] );
|
||||
node->getChild( "condition" )
|
||||
->setDoubleValue( dds->condition[i] );
|
||||
node->getChild( "magnetos" )->setDoubleValue( dds->magnetos[i] );
|
||||
node->getChild( "starter" )->setDoubleValue( dds->starter_power[i] );
|
||||
node->getChild( "feed_tank" )->setIntValue( dds->feed_tank_to[i] );
|
||||
node->getChild( "reverser" )->setBoolValue( dds->reverse[i] > 0 );
|
||||
// Faults
|
||||
SGPropertyNode *faults = node->getNode( "faults", true );
|
||||
faults->setBoolValue( "serviceable", dds->engine_ok[i] > 0 );
|
||||
faults->setBoolValue( "left-magneto-serviceable",
|
||||
dds->mag_left_ok[i] > 0 );
|
||||
faults->setBoolValue( "right-magneto-serviceable",
|
||||
dds->mag_right_ok[i] > 0);
|
||||
faults->setBoolValue( "spark-plugs-serviceable",
|
||||
dds->spark_plugs_ok[i] > 0);
|
||||
faults->setIntValue( "oil-pressure-status", dds->oil_press_status[i] );
|
||||
faults->setBoolValue( "fuel-pump-serviceable", dds->fuel_pump_ok[i] > 0);
|
||||
}
|
||||
|
||||
fgSetBool( "/systems/electrical/outputs/fuel-pump",
|
||||
dds->fuel_pump_power[0] > 0);
|
||||
|
||||
for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
|
||||
node = fgGetNode( "/controls/fuel/tank", i );
|
||||
node->getChild( "fuel_selector" )
|
||||
->setBoolValue( dds->fuel_selector[i] > 0 );
|
||||
// node->getChild( "to_tank" )->xfer_tank( i, dds->xfer_to[i] );
|
||||
}
|
||||
node = fgGetNode( "/controls/gear" );
|
||||
if ( node != NULL ) {
|
||||
node->getChild( "brake-left" )->setDoubleValue( dds->brake_left );
|
||||
node->getChild( "brake-right" )->setDoubleValue( dds->brake_right );
|
||||
node->getChild( "copilot-brake-left" )
|
||||
->setDoubleValue( dds->copilot_brake_left );
|
||||
node->getChild( "copilot-brake-right" )
|
||||
->setDoubleValue( dds->copilot_brake_right );
|
||||
node->getChild( "brake-parking" )->setDoubleValue( dds->brake_parking );
|
||||
}
|
||||
|
||||
node = fgGetNode( "/controls/gear", true );
|
||||
node->setBoolValue( "gear-down", dds->gear_handle > 0 );
|
||||
// node->setDoubleValue( "brake-parking", dds->brake_parking );
|
||||
// node->setDoubleValue( dds->brake_left );
|
||||
// node->setDoubleValue( dds->brake_right );
|
||||
|
||||
node = fgGetNode( "/controls/switches", true );
|
||||
node->setBoolValue( "master-bat", dds->master_bat[0] != 0 );
|
||||
node->setBoolValue( "master-alt", dds->master_alt[0] != 0 );
|
||||
node->setBoolValue( "master-avionics", dds->master_avionics > 0 );
|
||||
|
||||
node = fgGetNode( "/environment", true );
|
||||
node->setDoubleValue( "wind-speed-kt", dds->wind_speed_kt );
|
||||
node->setDoubleValue( "wind-from-heading-deg", dds->wind_dir_deg );
|
||||
node->setDoubleValue( "turbulence/magnitude-norm", dds->turbulence_norm );
|
||||
node->setDoubleValue( "magnetic-variation-deg", dds->magvar );
|
||||
|
||||
node->setDoubleValue( "/environment/temperature-degc",
|
||||
dds->temp_c );
|
||||
node->setDoubleValue( "/environment/pressure-sea-level-inhg",
|
||||
dds->press_inhg );
|
||||
|
||||
// ground elevation ???
|
||||
|
||||
fgSetDouble("/hazards/icing/wing", dds->icing);
|
||||
|
||||
node = fgGetNode( "/radios", true );
|
||||
node->setDoubleValue( "comm/frequencies/selected-mhz[0]", dds->comm_1 );
|
||||
node->setDoubleValue( "nav/frequencies/selected-mhz[0]", dds->nav_1 );
|
||||
node->setDoubleValue( "nav[1]/frequencies/selected-mhz[0]", dds->nav_2 );
|
||||
|
||||
fgSetDouble( "/sim/speed-up", dds->speedup );
|
||||
|
||||
if ( honor_freezes ) {
|
||||
node = fgGetNode( "/sim/freeze", true );
|
||||
node->setBoolValue( "master", (dds->freeze & 0x01) > 0 );
|
||||
node->setBoolValue( "position", (dds->freeze & 0x02) > 0 );
|
||||
node->setBoolValue( "fuel", (dds->freeze & 0x04) > 0 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// open hailing frequencies
|
||||
bool FGNativeCtrls::open() {
|
||||
if ( is_enabled() ) {
|
||||
|
@ -730,9 +92,9 @@ bool FGNativeCtrls::process() {
|
|||
if ( get_direction() == SG_IO_OUT )
|
||||
{
|
||||
if ( io->get_type() == sgDDSType ) {
|
||||
FGProps2Ctrls( &ctrls.dds, true, true );
|
||||
FGProps2Ctrls( globals->get_props(), &ctrls.dds, true, true );
|
||||
} else {
|
||||
FGProps2Ctrls( &ctrls.net, true, true );
|
||||
FGProps2Ctrls( globals->get_props(), &ctrls.net, true, true );
|
||||
}
|
||||
|
||||
if ( ! io->write( buf, length ) ) {
|
||||
|
@ -745,17 +107,17 @@ bool FGNativeCtrls::process() {
|
|||
if ( io->get_type() == sgFileType ) {
|
||||
if ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "Success reading data." );
|
||||
FGCtrls2Props( &ctrls.net, true, true );
|
||||
FGCtrls2Props( globals->get_props(), &ctrls.net, true, true );
|
||||
}
|
||||
} else if ( io->get_type() == sgDDSType ) {
|
||||
while ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "Success reading data." );
|
||||
FGCtrls2Props( &ctrls.dds, true, true );
|
||||
FGCtrls2Props( globals->get_props(), &ctrls.dds, true, true );
|
||||
}
|
||||
} else {
|
||||
while ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "Success reading data." );
|
||||
FGCtrls2Props( &ctrls.net, true, true );
|
||||
FGCtrls2Props( globals->get_props(), &ctrls.net, true, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,17 +61,4 @@ public:
|
|||
bool close();
|
||||
};
|
||||
|
||||
|
||||
// Helper functions which may be useful outside this class
|
||||
|
||||
// Populate the FGNetCtrls/FG_DDS_Ctrls structure from the property tree.
|
||||
template<typename T>
|
||||
void FGProps2Ctrls( T *net, bool honor_freezes, bool net_byte_order );
|
||||
|
||||
// Update the property tree from the FGNetCtrls/FG_DDS_Ctrls structure.
|
||||
template<typename T>
|
||||
void FGCtrls2Props( T *net, bool honor_freezes, bool net_byte_order );
|
||||
|
||||
#endif // _FG_NATIVE_CTRLS_HXX
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#endif
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/io/lowlevel.hxx> // endian tests
|
||||
#include <simgear/io/iochannel.hxx>
|
||||
#include <simgear/timing/sg_time.hxx>
|
||||
|
||||
|
@ -39,6 +38,7 @@
|
|||
#include <Main/globals.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
#include "native_structs.hxx"
|
||||
#include "native_fdm.hxx"
|
||||
|
||||
// FreeBSD works better with this included last ... (?)
|
||||
|
@ -50,682 +50,6 @@
|
|||
# include <netinet/in.h> // htonl() ntohl()
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Float version
|
||||
static void htonf (float &x)
|
||||
{
|
||||
if ( sgIsLittleEndian() ) {
|
||||
int *Float_Overlay;
|
||||
int Holding_Buffer;
|
||||
|
||||
Float_Overlay = (int *) &x;
|
||||
Holding_Buffer = Float_Overlay [0];
|
||||
|
||||
Float_Overlay [0] = htonl (Holding_Buffer);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void FGProps2FDM<FGNetFDM>( FGNetFDM *net, bool net_byte_order ) {
|
||||
unsigned int i;
|
||||
|
||||
FlightProperties fdm_state;
|
||||
|
||||
// Version sanity checking
|
||||
net->version = FG_NET_FDM_VERSION;
|
||||
|
||||
// Aero parameters
|
||||
net->longitude = fdm_state.get_Longitude();
|
||||
net->latitude = fdm_state.get_Latitude();
|
||||
net->altitude = fdm_state.get_Altitude() * SG_FEET_TO_METER;
|
||||
net->agl = fdm_state.get_Altitude_AGL() * SG_FEET_TO_METER;
|
||||
net->phi = fdm_state.get_Phi();
|
||||
net->theta = fdm_state.get_Theta();
|
||||
net->psi = fdm_state.get_Psi();
|
||||
net->alpha = fdm_state.get_Alpha();
|
||||
net->beta = fdm_state.get_Beta();
|
||||
net->phidot = fdm_state.get_Phi_dot_degps() * SG_DEGREES_TO_RADIANS;
|
||||
net->thetadot = fdm_state.get_Theta_dot_degps()
|
||||
* SG_DEGREES_TO_RADIANS;
|
||||
net->psidot = fdm_state.get_Psi_dot_degps() * SG_DEGREES_TO_RADIANS;
|
||||
|
||||
net->vcas = fdm_state.get_V_calibrated_kts();
|
||||
net->climb_rate = fdm_state.get_Climb_Rate();
|
||||
|
||||
net->v_north = fdm_state.get_V_north();
|
||||
net->v_east = fdm_state.get_V_east();
|
||||
net->v_down = fdm_state.get_V_down();
|
||||
net->v_body_u = fdm_state.get_uBody();
|
||||
net->v_body_v = fdm_state.get_vBody();
|
||||
net->v_body_w = fdm_state.get_wBody();
|
||||
|
||||
net->A_X_pilot = fdm_state.get_A_X_pilot();
|
||||
net->A_Y_pilot = fdm_state.get_A_Y_pilot();
|
||||
net->A_Z_pilot = fdm_state.get_A_Z_pilot();
|
||||
|
||||
net->stall_warning = fgGetDouble("/sim/alarms/stall-warning", 0.0);
|
||||
net->slip_deg
|
||||
= fgGetDouble("/instrumentation/slip-skid-ball/indicated-slip-skid");
|
||||
|
||||
// Engine parameters
|
||||
net->num_engines = FGNetFDM::FG_MAX_ENGINES;
|
||||
for ( i = 0; i < net->num_engines; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("engines/engine", i, true);
|
||||
if ( node->getBoolValue( "running" ) ) {
|
||||
net->eng_state[i] = 2;
|
||||
} else if ( node->getBoolValue( "cranking" ) ) {
|
||||
net->eng_state[i] = 1;
|
||||
} else {
|
||||
net->eng_state[i] = 0;
|
||||
}
|
||||
net->rpm[i] = node->getDoubleValue( "rpm" );
|
||||
net->fuel_flow[i] = node->getDoubleValue( "fuel-flow-gph" );
|
||||
net->fuel_px[i] = node->getDoubleValue( "fuel-px-psi" );
|
||||
net->egt[i] = node->getDoubleValue( "egt-degf" );
|
||||
// cout << "egt = " << aero->EGT << endl;
|
||||
net->cht[i] = node->getDoubleValue( "cht-degf" );
|
||||
net->mp_osi[i] = node->getDoubleValue( "mp-osi" );
|
||||
net->tit[i] = node->getDoubleValue( "tit" );
|
||||
net->oil_temp[i] = node->getDoubleValue( "oil-temperature-degf" );
|
||||
net->oil_px[i] = node->getDoubleValue( "oil-pressure-psi" );
|
||||
}
|
||||
|
||||
// Consumables
|
||||
net->num_tanks = FGNetFDM::FG_MAX_TANKS;
|
||||
for ( i = 0; i < net->num_tanks; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("/consumables/fuel/tank", i, true);
|
||||
net->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
|
||||
net->tank_selected[i] = node->getBoolValue("selected");
|
||||
net->capacity_m3[i] = node->getDoubleValue("capacity-m3");
|
||||
net->unusable_m3[i] = node->getDoubleValue("unusable-m3");
|
||||
net->density_kgpm3[i] = node->getDoubleValue("density-kgpm3");
|
||||
net->level_m3[i] = node->getDoubleValue("level-m3");
|
||||
}
|
||||
|
||||
// Gear and flaps
|
||||
net->num_wheels = FGNetFDM::FG_MAX_WHEELS;
|
||||
for (i = 0; i < net->num_wheels; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("/gear/gear", i, true);
|
||||
net->wow[i] = node->getIntValue("wow");
|
||||
net->gear_pos[i] = node->getDoubleValue("position-norm");
|
||||
net->gear_steer[i] = node->getDoubleValue("steering-norm");
|
||||
net->gear_compression[i] = node->getDoubleValue("compression-norm");
|
||||
}
|
||||
|
||||
// the following really aren't used in this context
|
||||
net->cur_time = globals->get_time_params()->get_cur_time();
|
||||
net->warp = globals->get_warp();
|
||||
net->visibility = fgGetDouble("/environment/visibility-m");
|
||||
|
||||
// Control surface positions
|
||||
SGPropertyNode *node = fgGetNode("/surface-positions", true);
|
||||
net->elevator = node->getDoubleValue( "elevator-pos-norm" );
|
||||
net->elevator_trim_tab
|
||||
= node->getDoubleValue( "elevator-trim-tab-pos-norm" );
|
||||
// FIXME: CLO 10/28/04 - This really should be separated out into 2 values
|
||||
net->left_flap = node->getDoubleValue( "flap-pos-norm" );
|
||||
net->right_flap = node->getDoubleValue( "flap-pos-norm" );
|
||||
net->left_aileron = node->getDoubleValue( "left-aileron-pos-norm" );
|
||||
net->right_aileron = node->getDoubleValue( "right-aileron-pos-norm" );
|
||||
net->rudder = node->getDoubleValue( "rudder-pos-norm" );
|
||||
net->nose_wheel = node->getDoubleValue( "nose-wheel-pos-norm" );
|
||||
net->speedbrake = node->getDoubleValue( "speedbrake-pos-norm" );
|
||||
net->spoilers = node->getDoubleValue( "spoilers-pos-norm" );
|
||||
|
||||
if ( net_byte_order ) {
|
||||
// Convert the net buffer to network format
|
||||
net->version = htonl(net->version);
|
||||
|
||||
htond(net->longitude);
|
||||
htond(net->latitude);
|
||||
htond(net->altitude);
|
||||
htonf(net->agl);
|
||||
htonf(net->phi);
|
||||
htonf(net->theta);
|
||||
htonf(net->psi);
|
||||
htonf(net->alpha);
|
||||
htonf(net->beta);
|
||||
|
||||
htonf(net->phidot);
|
||||
htonf(net->thetadot);
|
||||
htonf(net->psidot);
|
||||
htonf(net->vcas);
|
||||
htonf(net->climb_rate);
|
||||
htonf(net->v_north);
|
||||
htonf(net->v_east);
|
||||
htonf(net->v_down);
|
||||
htonf(net->v_body_u);
|
||||
htonf(net->v_body_v);
|
||||
htonf(net->v_body_w);
|
||||
|
||||
htonf(net->A_X_pilot);
|
||||
htonf(net->A_Y_pilot);
|
||||
htonf(net->A_Z_pilot);
|
||||
|
||||
htonf(net->stall_warning);
|
||||
htonf(net->slip_deg);
|
||||
|
||||
for ( i = 0; i < net->num_engines; ++i ) {
|
||||
net->eng_state[i] = htonl(net->eng_state[i]);
|
||||
htonf(net->rpm[i]);
|
||||
htonf(net->fuel_flow[i]);
|
||||
htonf(net->fuel_px[i]);
|
||||
htonf(net->egt[i]);
|
||||
htonf(net->cht[i]);
|
||||
htonf(net->mp_osi[i]);
|
||||
htonf(net->tit[i]);
|
||||
htonf(net->oil_temp[i]);
|
||||
htonf(net->oil_px[i]);
|
||||
}
|
||||
net->num_engines = htonl(net->num_engines);
|
||||
|
||||
for ( i = 0; i < net->num_tanks; ++i ) {
|
||||
htonf(net->fuel_quantity[i]);
|
||||
htonl(net->tank_selected[i]);
|
||||
htond(net->capacity_m3[i]);
|
||||
htond(net->unusable_m3[i]);
|
||||
htond(net->density_kgpm3[i]);
|
||||
htond(net->level_m3[i]);
|
||||
}
|
||||
net->num_tanks = htonl(net->num_tanks);
|
||||
|
||||
for ( i = 0; i < net->num_wheels; ++i ) {
|
||||
net->wow[i] = htonl(net->wow[i]);
|
||||
htonf(net->gear_pos[i]);
|
||||
htonf(net->gear_steer[i]);
|
||||
htonf(net->gear_compression[i]);
|
||||
}
|
||||
net->num_wheels = htonl(net->num_wheels);
|
||||
|
||||
net->cur_time = htonl( net->cur_time );
|
||||
net->warp = htonl( net->warp );
|
||||
htonf(net->visibility);
|
||||
|
||||
htonf(net->elevator);
|
||||
htonf(net->elevator_trim_tab);
|
||||
htonf(net->left_flap);
|
||||
htonf(net->right_flap);
|
||||
htonf(net->left_aileron);
|
||||
htonf(net->right_aileron);
|
||||
htonf(net->rudder);
|
||||
htonf(net->nose_wheel);
|
||||
htonf(net->speedbrake);
|
||||
htonf(net->spoilers);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void FGFDM2Props<FGNetFDM>( FGNetFDM *net, bool net_byte_order ) {
|
||||
unsigned int i;
|
||||
FlightProperties fdm_state;
|
||||
|
||||
if ( net_byte_order ) {
|
||||
// Convert to the net buffer from network format
|
||||
net->version = ntohl(net->version);
|
||||
|
||||
htond(net->longitude);
|
||||
htond(net->latitude);
|
||||
htond(net->altitude);
|
||||
htonf(net->agl);
|
||||
htonf(net->phi);
|
||||
htonf(net->theta);
|
||||
htonf(net->psi);
|
||||
htonf(net->alpha);
|
||||
htonf(net->beta);
|
||||
|
||||
htonf(net->phidot);
|
||||
htonf(net->thetadot);
|
||||
htonf(net->psidot);
|
||||
htonf(net->vcas);
|
||||
htonf(net->climb_rate);
|
||||
htonf(net->v_north);
|
||||
htonf(net->v_east);
|
||||
htonf(net->v_down);
|
||||
htonf(net->v_body_u);
|
||||
htonf(net->v_body_v);
|
||||
htonf(net->v_body_w);
|
||||
|
||||
htonf(net->A_X_pilot);
|
||||
htonf(net->A_Y_pilot);
|
||||
htonf(net->A_Z_pilot);
|
||||
|
||||
htonf(net->stall_warning);
|
||||
htonf(net->slip_deg);
|
||||
|
||||
net->num_engines = htonl(net->num_engines);
|
||||
for ( i = 0; i < net->num_engines; ++i ) {
|
||||
net->eng_state[i] = htonl(net->eng_state[i]);
|
||||
htonf(net->rpm[i]);
|
||||
htonf(net->fuel_flow[i]);
|
||||
htonf(net->fuel_px[i]);
|
||||
htonf(net->egt[i]);
|
||||
htonf(net->cht[i]);
|
||||
htonf(net->mp_osi[i]);
|
||||
htonf(net->tit[i]);
|
||||
htonf(net->oil_temp[i]);
|
||||
htonf(net->oil_px[i]);
|
||||
}
|
||||
|
||||
net->num_tanks = htonl(net->num_tanks);
|
||||
for ( i = 0; i < net->num_tanks; ++i ) {
|
||||
htonf(net->fuel_quantity[i]);
|
||||
htonl(net->tank_selected[i]);
|
||||
htond(net->capacity_m3[i]);
|
||||
htond(net->unusable_m3[i]);
|
||||
htond(net->density_kgpm3[i]);
|
||||
htond(net->level_m3[i]);
|
||||
}
|
||||
|
||||
net->num_wheels = htonl(net->num_wheels);
|
||||
for ( i = 0; i < net->num_wheels; ++i ) {
|
||||
net->wow[i] = htonl(net->wow[i]);
|
||||
htonf(net->gear_pos[i]);
|
||||
htonf(net->gear_steer[i]);
|
||||
htonf(net->gear_compression[i]);
|
||||
}
|
||||
|
||||
net->cur_time = htonl(net->cur_time);
|
||||
net->warp = ntohl(net->warp);
|
||||
htonf(net->visibility);
|
||||
|
||||
htonf(net->elevator);
|
||||
htonf(net->elevator_trim_tab);
|
||||
htonf(net->left_flap);
|
||||
htonf(net->right_flap);
|
||||
htonf(net->left_aileron);
|
||||
htonf(net->right_aileron);
|
||||
htonf(net->rudder);
|
||||
htonf(net->nose_wheel);
|
||||
htonf(net->speedbrake);
|
||||
htonf(net->spoilers);
|
||||
}
|
||||
|
||||
if ( net->version == FG_NET_FDM_VERSION ) {
|
||||
// cout << "pos = " << net->longitude << " " << net->latitude << endl;
|
||||
// cout << "sea level rad = " << fdm_state.get_Sea_level_radius()
|
||||
// << endl;
|
||||
|
||||
fdm_state.set_Latitude(net->latitude);
|
||||
fdm_state.set_Longitude(net->longitude);
|
||||
fdm_state.set_Altitude(net->altitude * SG_METER_TO_FEET);
|
||||
|
||||
if ( net->agl > -9000 ) {
|
||||
fdm_state.set_Altitude_AGL( net->agl * SG_METER_TO_FEET );
|
||||
} else {
|
||||
double agl_m = net->altitude
|
||||
- fdm_state.get_Runway_altitude_m();
|
||||
fdm_state.set_Altitude_AGL( agl_m * SG_METER_TO_FEET );
|
||||
}
|
||||
fdm_state.set_Euler_Angles( net->phi,
|
||||
net->theta,
|
||||
net->psi );
|
||||
fdm_state.set_Alpha( net->alpha );
|
||||
fdm_state.set_Beta( net->beta );
|
||||
fdm_state.set_Euler_Rates( net->phidot,
|
||||
net->thetadot,
|
||||
net->psidot );
|
||||
fdm_state.set_V_calibrated_kts( net->vcas );
|
||||
fdm_state.set_Climb_Rate( net->climb_rate );
|
||||
fdm_state.set_Velocities_Local( net->v_north,
|
||||
net->v_east,
|
||||
net->v_down );
|
||||
fdm_state.set_Velocities_Body( net->v_body_u,
|
||||
net->v_body_v,
|
||||
net->v_body_w );
|
||||
|
||||
fdm_state.set_Accels_Pilot_Body( net->A_X_pilot,
|
||||
net->A_Y_pilot,
|
||||
net->A_Z_pilot );
|
||||
|
||||
fgSetDouble( "/sim/alarms/stall-warning", net->stall_warning );
|
||||
fgSetDouble( "/instrumentation/slip-skid-ball/indicated-slip-skid",
|
||||
net->slip_deg );
|
||||
fgSetBool( "/instrumentation/slip-skid-ball/override", true );
|
||||
|
||||
for ( i = 0; i < net->num_engines; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode( "engines/engine", i, true );
|
||||
|
||||
// node->setBoolValue("running", t->isRunning());
|
||||
// node->setBoolValue("cranking", t->isCranking());
|
||||
|
||||
// cout << net->eng_state[i] << endl;
|
||||
if ( net->eng_state[i] == 0 ) {
|
||||
node->setBoolValue( "cranking", false );
|
||||
node->setBoolValue( "running", false );
|
||||
} else if ( net->eng_state[i] == 1 ) {
|
||||
node->setBoolValue( "cranking", true );
|
||||
node->setBoolValue( "running", false );
|
||||
} else if ( net->eng_state[i] == 2 ) {
|
||||
node->setBoolValue( "cranking", false );
|
||||
node->setBoolValue( "running", true );
|
||||
}
|
||||
|
||||
node->setDoubleValue( "rpm", net->rpm[i] );
|
||||
node->setDoubleValue( "fuel-flow-gph", net->fuel_flow[i] );
|
||||
node->setDoubleValue( "fuel-px-psi", net->fuel_px[i] );
|
||||
node->setDoubleValue( "egt-degf", net->egt[i] );
|
||||
node->setDoubleValue( "cht-degf", net->cht[i] );
|
||||
node->setDoubleValue( "mp-osi", net->mp_osi[i] );
|
||||
node->setDoubleValue( "tit", net->tit[i] );
|
||||
node->setDoubleValue( "oil-temperature-degf", net->oil_temp[i] );
|
||||
node->setDoubleValue( "oil-pressure-psi", net->oil_px[i] );
|
||||
}
|
||||
|
||||
for (i = 0; i < net->num_tanks; ++i ) {
|
||||
SGPropertyNode * node
|
||||
= fgGetNode("/consumables/fuel/tank", i, true);
|
||||
node->setDoubleValue("level-gal_us", net->fuel_quantity[i]);
|
||||
node->setBoolValue("selected", net->tank_selected[i] > 0);
|
||||
node->setDoubleValue("capacity-m3", net->capacity_m3[i]);
|
||||
node->setDoubleValue("unusable-m3", net->unusable_m3[i]);
|
||||
node->setDoubleValue("density-kgpm3", net->density_kgpm3[i]);
|
||||
node->setDoubleValue("level-m3", net->level_m3[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < net->num_wheels; ++i ) {
|
||||
SGPropertyNode * node = fgGetNode("/gear/gear", i, true);
|
||||
node->setDoubleValue("wow", net->wow[i] );
|
||||
node->setDoubleValue("position-norm", net->gear_pos[i] );
|
||||
node->setDoubleValue("steering-norm", net->gear_steer[i] );
|
||||
node->setDoubleValue("compression-norm", net->gear_compression[i] );
|
||||
}
|
||||
|
||||
/* these are ignored for now ... */
|
||||
/*
|
||||
if ( net->cur_time ) {
|
||||
fgSetLong("/sim/time/cur-time-override", net->cur_time);
|
||||
}
|
||||
|
||||
globals->set_warp( net->warp );
|
||||
last_warp = net->warp;
|
||||
*/
|
||||
|
||||
SGPropertyNode *node = fgGetNode("/surface-positions", true);
|
||||
node->setDoubleValue("elevator-pos-norm", net->elevator);
|
||||
node->setDoubleValue("elevator-trim-tab-pos-norm",
|
||||
net->elevator_trim_tab);
|
||||
// FIXME: CLO 10/28/04 - This really should be separated out
|
||||
// into 2 values
|
||||
node->setDoubleValue("flap-pos-norm", net->left_flap);
|
||||
node->setDoubleValue("flap-pos-norm", net->right_flap);
|
||||
node->setDoubleValue("left-aileron-pos-norm", net->left_aileron);
|
||||
node->setDoubleValue("right-aileron-pos-norm", net->right_aileron);
|
||||
node->setDoubleValue("rudder-pos-norm", net->rudder);
|
||||
node->setDoubleValue("nose-wheel-pos-norm", net->nose_wheel);
|
||||
node->setDoubleValue("speedbrake-pos-norm", net->speedbrake);
|
||||
node->setDoubleValue("spoilers-pos-norm", net->spoilers);
|
||||
} else {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: version mismatch in Net FGFDM2Props()" );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tread " << net->version << " need " << FG_NET_FDM_VERSION );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tNeeds to upgrade net_fdm.hxx and recompile." );
|
||||
}
|
||||
}
|
||||
|
||||
#if FG_HAVE_DDS
|
||||
template<>
|
||||
void FGProps2FDM<FG_DDS_FDM>( FG_DDS_FDM *dds, bool net_byte_order ) {
|
||||
unsigned int i;
|
||||
|
||||
FlightProperties fdm_state;
|
||||
|
||||
// Version sanity checking
|
||||
dds->version = FG_DDS_FDM_VERSION;
|
||||
|
||||
// Aero parameters
|
||||
dds->longitude = fdm_state.get_Longitude();
|
||||
dds->latitude = fdm_state.get_Latitude();
|
||||
dds->altitude = fdm_state.get_Altitude() * SG_FEET_TO_METER;
|
||||
dds->agl = fdm_state.get_Altitude_AGL() * SG_FEET_TO_METER;
|
||||
dds->phi = fdm_state.get_Phi();
|
||||
dds->theta = fdm_state.get_Theta();
|
||||
dds->psi = fdm_state.get_Psi();
|
||||
dds->alpha = fdm_state.get_Alpha();
|
||||
dds->beta = fdm_state.get_Beta();
|
||||
dds->phidot = fdm_state.get_Phi_dot_degps() * SG_DEGREES_TO_RADIANS;
|
||||
dds->thetadot = fdm_state.get_Theta_dot_degps() * SG_DEGREES_TO_RADIANS;
|
||||
dds->psidot = fdm_state.get_Psi_dot_degps() * SG_DEGREES_TO_RADIANS;
|
||||
|
||||
dds->vcas = fdm_state.get_V_calibrated_kts();
|
||||
dds->climb_rate = fdm_state.get_Climb_Rate();
|
||||
|
||||
dds->v_north = fdm_state.get_V_north();
|
||||
dds->v_east = fdm_state.get_V_east();
|
||||
dds->v_down = fdm_state.get_V_down();
|
||||
dds->v_body_u = fdm_state.get_uBody();
|
||||
dds->v_body_v = fdm_state.get_vBody();
|
||||
dds->v_body_w = fdm_state.get_wBody();
|
||||
|
||||
dds->A_X_pilot = fdm_state.get_A_X_pilot();
|
||||
dds->A_Y_pilot = fdm_state.get_A_Y_pilot();
|
||||
dds->A_Z_pilot = fdm_state.get_A_Z_pilot();
|
||||
|
||||
dds->stall_warning = fgGetDouble("/sim/alarms/stall-warning", 0.0);
|
||||
dds->slip_deg
|
||||
= fgGetDouble("/instrumentation/slip-skid-ball/indicated-slip-skid");
|
||||
|
||||
// Engine parameters
|
||||
dds->num_engines = FGNetFDM::FG_MAX_ENGINES;
|
||||
for ( i = 0; i < dds->num_engines; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("engines/engine", i, true);
|
||||
if ( node->getBoolValue( "running" ) ) {
|
||||
dds->eng_state[i] = 2;
|
||||
} else if ( node->getBoolValue( "cranking" ) ) {
|
||||
dds->eng_state[i] = 1;
|
||||
} else {
|
||||
dds->eng_state[i] = 0;
|
||||
}
|
||||
dds->rpm[i] = node->getDoubleValue( "rpm" );
|
||||
dds->fuel_flow[i] = node->getDoubleValue( "fuel-flow-gph" );
|
||||
dds->fuel_px[i] = node->getDoubleValue( "fuel-px-psi" );
|
||||
dds->egt[i] = node->getDoubleValue( "egt-degf" );
|
||||
// cout << "egt = " << aero->EGT << endl;
|
||||
dds->cht[i] = node->getDoubleValue( "cht-degf" );
|
||||
dds->mp_osi[i] = node->getDoubleValue( "mp-osi" );
|
||||
dds->tit[i] = node->getDoubleValue( "tit" );
|
||||
dds->oil_temp[i] = node->getDoubleValue( "oil-temperature-degf" );
|
||||
dds->oil_px[i] = node->getDoubleValue( "oil-pressure-psi" );
|
||||
}
|
||||
|
||||
// Consumables
|
||||
dds->num_tanks = FGNetFDM::FG_MAX_TANKS;
|
||||
for ( i = 0; i < dds->num_tanks; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("/consumables/fuel/tank", i, true);
|
||||
dds->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
|
||||
dds->tank_selected[i] = node->getBoolValue("selected");
|
||||
dds->capacity_m3[i] = node->getDoubleValue("capacity-m3");
|
||||
dds->unusable_m3[i] = node->getDoubleValue("unusable-m3");
|
||||
dds->density_kgpm3[i] = node->getDoubleValue("density-kgpm3");
|
||||
dds->level_m3[i] = node->getDoubleValue("level-m3");
|
||||
}
|
||||
|
||||
// Gear and flaps
|
||||
dds->num_wheels = FGNetFDM::FG_MAX_WHEELS;
|
||||
for (i = 0; i < dds->num_wheels; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("/gear/gear", i, true);
|
||||
dds->wow[i] = node->getIntValue("wow");
|
||||
dds->gear_pos[i] = node->getDoubleValue("position-norm");
|
||||
dds->gear_steer[i] = node->getDoubleValue("steering-norm");
|
||||
dds->gear_compression[i] = node->getDoubleValue("compression-norm");
|
||||
}
|
||||
|
||||
// the following really aren't used in this context
|
||||
dds->cur_time = globals->get_time_params()->get_cur_time();
|
||||
dds->warp = globals->get_warp();
|
||||
dds->visibility = fgGetDouble("/environment/visibility-m");
|
||||
|
||||
// Control surface positions
|
||||
SGPropertyNode *node = fgGetNode("/surface-positions", true);
|
||||
dds->elevator = node->getDoubleValue( "elevator-pos-norm" );
|
||||
dds->elevator_trim_tab
|
||||
= node->getDoubleValue( "elevator-trim-tab-pos-norm" );
|
||||
// FIXME: CLO 10/28/04 - This really should be separated out into 2 values
|
||||
dds->left_flap = node->getDoubleValue( "flap-pos-norm" );
|
||||
dds->right_flap = node->getDoubleValue( "flap-pos-norm" );
|
||||
dds->left_aileron = node->getDoubleValue( "left-aileron-pos-norm" );
|
||||
dds->right_aileron = node->getDoubleValue( "right-aileron-pos-norm" );
|
||||
dds->rudder = node->getDoubleValue( "rudder-pos-norm" );
|
||||
dds->nose_wheel = node->getDoubleValue( "nose-wheel-pos-norm" );
|
||||
dds->speedbrake = node->getDoubleValue( "speedbrake-pos-norm" );
|
||||
dds->spoilers = node->getDoubleValue( "spoilers-pos-norm" );
|
||||
}
|
||||
|
||||
template<>
|
||||
void FGFDM2Props<FG_DDS_FDM>( FG_DDS_FDM *dds, bool net_byte_order ) {
|
||||
unsigned int i;
|
||||
FlightProperties fdm_state;
|
||||
|
||||
if ( dds->version == FG_DDS_FDM_VERSION ) {
|
||||
// cout << "pos = " << dds->longitude << " " << dds->latitude << endl;
|
||||
// cout << "sea level rad = " << fdm_state.get_Sea_level_radius()
|
||||
// << endl;
|
||||
|
||||
fdm_state.set_Latitude(dds->latitude);
|
||||
fdm_state.set_Longitude(dds->longitude);
|
||||
fdm_state.set_Altitude(dds->altitude * SG_METER_TO_FEET);
|
||||
|
||||
if ( dds->agl > -9000 ) {
|
||||
fdm_state.set_Altitude_AGL( dds->agl * SG_METER_TO_FEET );
|
||||
} else {
|
||||
double agl_m = dds->altitude
|
||||
- fdm_state.get_Runway_altitude_m();
|
||||
fdm_state.set_Altitude_AGL( agl_m * SG_METER_TO_FEET );
|
||||
}
|
||||
fdm_state.set_Euler_Angles( dds->phi,
|
||||
dds->theta,
|
||||
dds->psi );
|
||||
fdm_state.set_Alpha( dds->alpha );
|
||||
fdm_state.set_Beta( dds->beta );
|
||||
fdm_state.set_Euler_Rates( dds->phidot,
|
||||
dds->thetadot,
|
||||
dds->psidot );
|
||||
fdm_state.set_V_calibrated_kts( dds->vcas );
|
||||
fdm_state.set_Climb_Rate( dds->climb_rate );
|
||||
fdm_state.set_Velocities_Local( dds->v_north,
|
||||
dds->v_east,
|
||||
dds->v_down );
|
||||
fdm_state.set_Velocities_Body( dds->v_body_u,
|
||||
dds->v_body_v,
|
||||
dds->v_body_w );
|
||||
|
||||
fdm_state.set_Accels_Pilot_Body( dds->A_X_pilot,
|
||||
dds->A_Y_pilot,
|
||||
dds->A_Z_pilot );
|
||||
|
||||
fgSetDouble( "/sim/alarms/stall-warning", dds->stall_warning );
|
||||
fgSetDouble( "/instrumentation/slip-skid-ball/indicated-slip-skid",
|
||||
dds->slip_deg );
|
||||
fgSetBool( "/instrumentation/slip-skid-ball/override", true );
|
||||
|
||||
for ( i = 0; i < dds->num_engines; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode( "engines/engine", i, true );
|
||||
|
||||
// node->setBoolValue("running", t->isRunning());
|
||||
// node->setBoolValue("cranking", t->isCranking());
|
||||
// cout << dds->eng_state[i] << endl;
|
||||
if ( dds->eng_state[i] == 0 ) {
|
||||
node->setBoolValue( "cranking", false );
|
||||
node->setBoolValue( "running", false );
|
||||
} else if ( dds->eng_state[i] == 1 ) {
|
||||
node->setBoolValue( "cranking", true );
|
||||
node->setBoolValue( "running", false );
|
||||
} else if ( dds->eng_state[i] == 2 ) {
|
||||
node->setBoolValue( "cranking", false );
|
||||
node->setBoolValue( "running", true );
|
||||
}
|
||||
|
||||
node->setDoubleValue( "rpm", dds->rpm[i] );
|
||||
node->setDoubleValue( "fuel-flow-gph", dds->fuel_flow[i] );
|
||||
node->setDoubleValue( "fuel-px-psi", dds->fuel_px[i] );
|
||||
node->setDoubleValue( "egt-degf", dds->egt[i] );
|
||||
node->setDoubleValue( "cht-degf", dds->cht[i] );
|
||||
node->setDoubleValue( "mp-osi", dds->mp_osi[i] );
|
||||
node->setDoubleValue( "tit", dds->tit[i] );
|
||||
node->setDoubleValue( "oil-temperature-degf", dds->oil_temp[i] );
|
||||
node->setDoubleValue( "oil-pressure-psi", dds->oil_px[i] );
|
||||
}
|
||||
|
||||
for (i = 0; i < dds->num_tanks; ++i ) {
|
||||
SGPropertyNode * node
|
||||
= fgGetNode("/consumables/fuel/tank", i, true);
|
||||
node->setDoubleValue("level-gal_us", dds->fuel_quantity[i]);
|
||||
node->setBoolValue("selected", dds->tank_selected[i] > 0);
|
||||
node->setDoubleValue("capacity-m3", dds->capacity_m3[i]);
|
||||
node->setDoubleValue("unusable-m3", dds->unusable_m3[i]);
|
||||
node->setDoubleValue("density-kgpm3", dds->density_kgpm3[i]);
|
||||
node->setDoubleValue("level-m3", dds->level_m3[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < dds->num_wheels; ++i ) {
|
||||
SGPropertyNode * node = fgGetNode("/gear/gear", i, true);
|
||||
node->setDoubleValue("wow", dds->wow[i] );
|
||||
node->setDoubleValue("position-norm", dds->gear_pos[i] );
|
||||
node->setDoubleValue("steering-norm", dds->gear_steer[i] );
|
||||
node->setDoubleValue("compression-norm", dds->gear_compression[i] );
|
||||
}
|
||||
|
||||
/* these are ignored for now ... */
|
||||
/*
|
||||
if ( dds->cur_time ) {
|
||||
fgSetLong("/sim/time/cur-time-override", dds->cur_time);
|
||||
}
|
||||
|
||||
globals->set_warp( dds->warp );
|
||||
last_warp = dds->warp;
|
||||
*/
|
||||
SGPropertyNode *node = fgGetNode("/surface-positions", true);
|
||||
node->setDoubleValue("elevator-pos-norm", dds->elevator);
|
||||
node->setDoubleValue("elevator-trim-tab-pos-norm",
|
||||
dds->elevator_trim_tab);
|
||||
// FIXME: CLO 10/28/04 - This really should be separated out
|
||||
// into 2 values
|
||||
node->setDoubleValue("flap-pos-norm", dds->left_flap);
|
||||
node->setDoubleValue("flap-pos-norm", dds->right_flap);
|
||||
node->setDoubleValue("left-aileron-pos-norm", dds->left_aileron);
|
||||
node->setDoubleValue("right-aileron-pos-norm", dds->right_aileron);
|
||||
node->setDoubleValue("rudder-pos-norm", dds->rudder);
|
||||
node->setDoubleValue("nose-wheel-pos-norm", dds->nose_wheel);
|
||||
node->setDoubleValue("speedbrake-pos-norm", dds->speedbrake);
|
||||
node->setDoubleValue("spoilers-pos-norm", dds->spoilers);
|
||||
} else {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: version mismatch in DDS FGFDM2Props()" );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tread " << dds->version << " need " << FG_DDS_FDM_VERSION );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tNeeds to upgrade DDS/dds_fdm.hxx and recompile." );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// open hailing frequencies
|
||||
bool FGNativeFDM::open() {
|
||||
if ( is_enabled() ) {
|
||||
|
@ -773,9 +97,9 @@ bool FGNativeFDM::process() {
|
|||
if ( get_direction() == SG_IO_OUT ) {
|
||||
|
||||
if ( io->get_type() == sgDDSType ) {
|
||||
FGProps2FDM( &fdm.dds );
|
||||
FGProps2FDM( globals->get_props(), &fdm.dds );
|
||||
} else {
|
||||
FGProps2FDM( &fdm.net );
|
||||
FGProps2FDM( globals->get_props(), &fdm.net );
|
||||
}
|
||||
|
||||
if ( ! io->write( buf, length ) ) {
|
||||
|
@ -786,17 +110,17 @@ bool FGNativeFDM::process() {
|
|||
if ( io->get_type() == sgFileType ) {
|
||||
if ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "Success reading data." );
|
||||
FGFDM2Props( &fdm.net );
|
||||
FGFDM2Props( globals->get_props(), &fdm.net );
|
||||
}
|
||||
} else if ( io->get_type() == sgDDSType ) {
|
||||
while ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_INFO, " Success reading data." );
|
||||
FGFDM2Props( &fdm.dds );
|
||||
FGFDM2Props( globals->get_props(), &fdm.dds );
|
||||
}
|
||||
} else {
|
||||
while ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_INFO, " Success reading data." );
|
||||
FGFDM2Props( &fdm.net );
|
||||
FGFDM2Props( globals->get_props(), &fdm.net );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,17 +60,4 @@ public:
|
|||
bool close();
|
||||
};
|
||||
|
||||
|
||||
// Helper functions which may be useful outside this class
|
||||
|
||||
// Populate the FGNetFDM/FG_DDS_FDM structure from the property tree.
|
||||
template<typename T>
|
||||
void FGProps2FDM( T *net, bool net_byte_order = true );
|
||||
|
||||
// Update the property tree from the FGNetFDM/FG_DDS_FDM structure.
|
||||
template<typename T>
|
||||
void FGFDM2Props( T *net, bool net_byte_order = true );
|
||||
|
||||
#endif // _FG_NATIVE_FDM_HXX
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <Scenery/scenery.hxx>
|
||||
#include <FDM/flightProperties.hxx>
|
||||
|
||||
#include "native_structs.hxx"
|
||||
#include "native_gui.hxx"
|
||||
|
||||
// FreeBSD works better with this included last ... (?)
|
||||
|
@ -51,416 +52,6 @@
|
|||
# include <netinet/in.h> // htonl() ntohl()
|
||||
#endif
|
||||
|
||||
// #define FG_USE_NETWORK_BYTE_ORDER
|
||||
#if defined( FG_USE_NETWORK_BYTE_ORDER )
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
static void htonf (float &x)
|
||||
{
|
||||
if ( sgIsLittleEndian() ) {
|
||||
int *Float_Overlay;
|
||||
int Holding_Buffer;
|
||||
|
||||
Float_Overlay = (int *) &x;
|
||||
Holding_Buffer = Float_Overlay [0];
|
||||
|
||||
Float_Overlay [0] = htonl (Holding_Buffer);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<>
|
||||
void FGProps2GUI<FGNetGUI>( FGNetGUI *net ) {
|
||||
static SGPropertyNode *nav_freq
|
||||
= fgGetNode("/instrumentation/nav/frequencies/selected-mhz", true);
|
||||
static SGPropertyNode *nav_target_radial
|
||||
= fgGetNode("/instrumentation/nav/radials/target-radial-deg", true);
|
||||
static SGPropertyNode *nav_inrange
|
||||
= fgGetNode("/instrumentation/nav/in-range", true);
|
||||
static SGPropertyNode *nav_loc
|
||||
= fgGetNode("/instrumentation/nav/nav-loc", true);
|
||||
static SGPropertyNode *nav_gs_dist_signed
|
||||
= fgGetNode("/instrumentation/nav/gs-distance", true);
|
||||
static SGPropertyNode *nav_loc_dist
|
||||
= fgGetNode("/instrumentation/nav/nav-distance", true);
|
||||
static SGPropertyNode *nav_reciprocal_radial
|
||||
= fgGetNode("/instrumentation/nav/radials/reciprocal-radial-deg", true);
|
||||
static SGPropertyNode *nav_gs_deflection
|
||||
= fgGetNode("/instrumentation/nav/gs-needle-deflection", true);
|
||||
unsigned int i;
|
||||
|
||||
static FlightProperties* fdm_state = new FlightProperties;
|
||||
|
||||
// Version sanity checking
|
||||
net->version = FG_NET_GUI_VERSION;
|
||||
|
||||
// Aero parameters
|
||||
net->longitude = fdm_state->get_Longitude();
|
||||
net->latitude = fdm_state->get_Latitude();
|
||||
net->altitude = fdm_state->get_Altitude() * SG_FEET_TO_METER;
|
||||
net->phi = fdm_state->get_Phi();
|
||||
net->theta = fdm_state->get_Theta();
|
||||
net->psi = fdm_state->get_Psi();
|
||||
|
||||
// Velocities
|
||||
net->vcas = fdm_state->get_V_calibrated_kts();
|
||||
net->climb_rate = fdm_state->get_Climb_Rate();
|
||||
|
||||
// Consumables
|
||||
net->num_tanks = FGNetGUI::FG_MAX_TANKS;
|
||||
for ( i = 0; i < net->num_tanks; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("/consumables/fuel/tank", i, true);
|
||||
net->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
|
||||
}
|
||||
|
||||
// Environment
|
||||
net->cur_time = globals->get_time_params()->get_cur_time();
|
||||
net->warp = globals->get_warp();
|
||||
net->ground_elev = fdm_state->get_Runway_altitude_m();
|
||||
|
||||
// Approach
|
||||
net->tuned_freq = nav_freq->getDoubleValue();
|
||||
net->nav_radial = nav_target_radial->getDoubleValue();
|
||||
net->in_range = nav_inrange->getBoolValue();
|
||||
|
||||
if ( nav_loc->getBoolValue() ) {
|
||||
// is an ILS
|
||||
net->dist_nm
|
||||
= nav_gs_dist_signed->getDoubleValue()
|
||||
* SG_METER_TO_NM;
|
||||
} else {
|
||||
// is a VOR
|
||||
net->dist_nm = nav_loc_dist->getDoubleValue()
|
||||
* SG_METER_TO_NM;
|
||||
}
|
||||
|
||||
net->course_deviation_deg
|
||||
= nav_reciprocal_radial->getDoubleValue()
|
||||
- nav_target_radial->getDoubleValue();
|
||||
|
||||
if ( net->course_deviation_deg < -1000.0
|
||||
|| net->course_deviation_deg > 1000.0 )
|
||||
{
|
||||
// Sanity check ...
|
||||
net->course_deviation_deg = 0.0;
|
||||
}
|
||||
while ( net->course_deviation_deg > 180.0 ) {
|
||||
net->course_deviation_deg -= 360.0;
|
||||
}
|
||||
while ( net->course_deviation_deg < -180.0 ) {
|
||||
net->course_deviation_deg += 360.0;
|
||||
}
|
||||
if ( fabs(net->course_deviation_deg) > 90.0 )
|
||||
net->course_deviation_deg
|
||||
= ( net->course_deviation_deg<0.0
|
||||
? -net->course_deviation_deg - 180.0
|
||||
: -net->course_deviation_deg + 180.0 );
|
||||
|
||||
if ( nav_loc->getBoolValue() ) {
|
||||
// is an ILS
|
||||
net->gs_deviation_deg
|
||||
= nav_gs_deflection->getDoubleValue()
|
||||
/ 5.0;
|
||||
} else {
|
||||
// is an ILS
|
||||
net->gs_deviation_deg = -9999.0;
|
||||
}
|
||||
|
||||
#if defined( FG_USE_NETWORK_BYTE_ORDER )
|
||||
// Convert the net buffer to network format
|
||||
net->version = htonl(net->version);
|
||||
|
||||
htond(net->longitude);
|
||||
htond(net->latitude);
|
||||
htonf(net->altitude);
|
||||
htonf(net->phi);
|
||||
htonf(net->theta);
|
||||
htonf(net->psi);
|
||||
htonf(net->vcas);
|
||||
htonf(net->climb_rate);
|
||||
|
||||
for ( i = 0; i < net->num_tanks; ++i ) {
|
||||
htonf(net->fuel_quantity[i]);
|
||||
}
|
||||
net->num_tanks = htonl(net->num_tanks);
|
||||
|
||||
net->cur_time = htonl( net->cur_time );
|
||||
net->warp = htonl( net->warp );
|
||||
net->ground_elev = htonl( net->ground_elev );
|
||||
|
||||
htonf(net->tuned_freq);
|
||||
htonf(net->nav_radial);
|
||||
net->in_range = htonl( net->in_range );
|
||||
htonf(net->dist_nm);
|
||||
htonf(net->course_deviation_deg);
|
||||
htonf(net->gs_deviation_deg);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
void FGGUI2Props<FGNetGUI>( FGNetGUI *net ) {
|
||||
unsigned int i;
|
||||
|
||||
#if defined( FG_USE_NETWORK_BYTE_ORDER )
|
||||
// Convert to the net buffer from network format
|
||||
net->version = ntohl(net->version);
|
||||
|
||||
htond(net->longitude);
|
||||
htond(net->latitude);
|
||||
htonf(net->altitude);
|
||||
htonf(net->phi);
|
||||
htonf(net->theta);
|
||||
htonf(net->psi);
|
||||
htonf(net->vcas);
|
||||
htonf(net->climb_rate);
|
||||
|
||||
net->num_tanks = htonl(net->num_tanks);
|
||||
for ( i = 0; i < net->num_tanks; ++i ) {
|
||||
htonf(net->fuel_quantity[i]);
|
||||
}
|
||||
|
||||
net->cur_time = ntohl(net->cur_time);
|
||||
net->warp = ntohl(net->warp);
|
||||
net->ground_elev = htonl( net->ground_elev );
|
||||
|
||||
htonf(net->tuned_freq);
|
||||
htonf(net->nav_radial);
|
||||
net->in_range = htonl( net->in_range );
|
||||
htonf(net->dist_nm);
|
||||
htonf(net->course_deviation_deg);
|
||||
htonf(net->gs_deviation_deg);
|
||||
#endif
|
||||
|
||||
if ( net->version == FG_NET_GUI_VERSION ) {
|
||||
FlightProperties fdm_state;
|
||||
|
||||
// cout << "pos = " << net->longitude << " " << net->latitude << endl;
|
||||
// cout << "sea level rad = " << fdm_state->get_Sea_level_radius()
|
||||
// << endl;
|
||||
|
||||
fdm_state.set_Latitude(net->latitude);
|
||||
fdm_state.set_Longitude(net->longitude);
|
||||
fdm_state.set_Altitude(net->altitude * SG_METER_TO_FEET);
|
||||
|
||||
fdm_state.set_Euler_Angles( net->phi,
|
||||
net->theta,
|
||||
net->psi );
|
||||
|
||||
fdm_state.set_V_calibrated_kts( net->vcas );
|
||||
fdm_state.set_Climb_Rate( net->climb_rate );
|
||||
|
||||
for (i = 0; i < net->num_tanks; ++i ) {
|
||||
SGPropertyNode * node
|
||||
= fgGetNode("/consumables/fuel/tank", i, true);
|
||||
node->setDoubleValue("level-gal_us", net->fuel_quantity[i] );
|
||||
}
|
||||
|
||||
if ( net->cur_time ) {
|
||||
fgSetLong("/sim/time/cur-time-override", net->cur_time);
|
||||
}
|
||||
|
||||
globals->set_warp( net->warp );
|
||||
|
||||
// Approach
|
||||
fgSetDouble( "/instrumentation/nav[0]/frequencies/selected-mhz",
|
||||
net->tuned_freq );
|
||||
fgSetBool( "/instrumentation/nav[0]/in-range", net->in_range > 0);
|
||||
fgSetDouble( "/instrumentation/dme/indicated-distance-nm", net->dist_nm );
|
||||
fgSetDouble( "/instrumentation/nav[0]/heading-needle-deflection",
|
||||
net->course_deviation_deg );
|
||||
fgSetDouble( "/instrumentation/nav[0]/gs-needle-deflection",
|
||||
net->gs_deviation_deg );
|
||||
} else {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: version mismatch in FGNetNativeGUI2Props()" );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tread " << net->version << " need " << FG_NET_GUI_VERSION );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tNeed to upgrade net_fdm.hxx and recompile." );
|
||||
}
|
||||
}
|
||||
|
||||
#if FG_HAVE_DDS
|
||||
template<>
|
||||
void FGProps2GUI<FG_DDS_GUI>( FG_DDS_GUI *dds ) {
|
||||
static SGPropertyNode *nav_freq
|
||||
= fgGetNode("/instrumentation/nav/frequencies/selected-mhz", true);
|
||||
static SGPropertyNode *nav_target_radial
|
||||
= fgGetNode("/instrumentation/nav/radials/target-radial-deg", true);
|
||||
static SGPropertyNode *nav_inrange
|
||||
= fgGetNode("/instrumentation/nav/in-range", true);
|
||||
static SGPropertyNode *nav_loc
|
||||
= fgGetNode("/instrumentation/nav/nav-loc", true);
|
||||
static SGPropertyNode *nav_gs_dist_signed
|
||||
= fgGetNode("/instrumentation/nav/gs-distance", true);
|
||||
static SGPropertyNode *nav_loc_dist
|
||||
= fgGetNode("/instrumentation/nav/nav-distance", true);
|
||||
static SGPropertyNode *nav_reciprocal_radial
|
||||
= fgGetNode("/instrumentation/nav/radials/reciprocal-radial-deg", true);
|
||||
static SGPropertyNode *nav_gs_deflection
|
||||
= fgGetNode("/instrumentation/nav/gs-needle-deflection", true);
|
||||
unsigned int i;
|
||||
|
||||
static FlightProperties* fdm_state = new FlightProperties;
|
||||
|
||||
// Version sanity checking
|
||||
dds->version = FG_DDS_GUI_VERSION;
|
||||
|
||||
// Aero parameters
|
||||
dds->longitude = fdm_state->get_Longitude();
|
||||
dds->latitude = fdm_state->get_Latitude();
|
||||
dds->altitude = fdm_state->get_Altitude() * SG_FEET_TO_METER;
|
||||
dds->phi = fdm_state->get_Phi();
|
||||
dds->theta = fdm_state->get_Theta();
|
||||
dds->psi = fdm_state->get_Psi();
|
||||
|
||||
// Velocities
|
||||
dds->vcas = fdm_state->get_V_calibrated_kts();
|
||||
dds->climb_rate = fdm_state->get_Climb_Rate();
|
||||
|
||||
// Consumables
|
||||
dds->num_tanks = FGNetGUI::FG_MAX_TANKS;
|
||||
for ( i = 0; i < dds->num_tanks; ++i ) {
|
||||
SGPropertyNode *node = fgGetNode("/consumables/fuel/tank", i, true);
|
||||
dds->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
|
||||
}
|
||||
|
||||
// Environment
|
||||
dds->cur_time = globals->get_time_params()->get_cur_time();
|
||||
dds->warp = globals->get_warp();
|
||||
dds->ground_elev = fdm_state->get_Runway_altitude_m();
|
||||
|
||||
// Approach
|
||||
dds->tuned_freq = nav_freq->getDoubleValue();
|
||||
dds->nav_radial = nav_target_radial->getDoubleValue();
|
||||
dds->in_range = nav_inrange->getBoolValue();
|
||||
|
||||
if ( nav_loc->getBoolValue() ) {
|
||||
// is an ILS
|
||||
dds->dist_nm
|
||||
= nav_gs_dist_signed->getDoubleValue()
|
||||
* SG_METER_TO_NM;
|
||||
} else {
|
||||
// is a VOR
|
||||
dds->dist_nm = nav_loc_dist->getDoubleValue()
|
||||
* SG_METER_TO_NM;
|
||||
}
|
||||
|
||||
dds->course_deviation_deg
|
||||
= nav_reciprocal_radial->getDoubleValue()
|
||||
- nav_target_radial->getDoubleValue();
|
||||
|
||||
if ( dds->course_deviation_deg < -1000.0
|
||||
|| dds->course_deviation_deg > 1000.0 )
|
||||
{
|
||||
// Sanity check ...
|
||||
dds->course_deviation_deg = 0.0;
|
||||
}
|
||||
while ( dds->course_deviation_deg > 180.0 ) {
|
||||
dds->course_deviation_deg -= 360.0;
|
||||
}
|
||||
while ( dds->course_deviation_deg > 180.0 ) {
|
||||
dds->course_deviation_deg -= 360.0;
|
||||
}
|
||||
while ( dds->course_deviation_deg < -180.0 ) {
|
||||
dds->course_deviation_deg += 360.0;
|
||||
}
|
||||
if ( fabs(dds->course_deviation_deg) > 90.0 )
|
||||
dds->course_deviation_deg
|
||||
= ( dds->course_deviation_deg<0.0
|
||||
? -dds->course_deviation_deg - 180.0
|
||||
: -dds->course_deviation_deg + 180.0 );
|
||||
|
||||
if ( nav_loc->getBoolValue() ) {
|
||||
// is an ILS
|
||||
dds->gs_deviation_deg
|
||||
= nav_gs_deflection->getDoubleValue()
|
||||
/ 5.0;
|
||||
} else {
|
||||
// is an ILS
|
||||
dds->gs_deviation_deg = -9999.0;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void FGGUI2Props<FG_DDS_GUI>( FG_DDS_GUI *dds ) {
|
||||
unsigned int i;
|
||||
|
||||
if ( dds->version == FG_DDS_GUI_VERSION ) {
|
||||
FlightProperties fdm_state;
|
||||
|
||||
// cout << "pos = " << dds->longitude << " " << dds->latitude << endl;
|
||||
// cout << "sea level rad = " << fdm_state->get_Sea_level_radius()
|
||||
// << endl;
|
||||
|
||||
fdm_state.set_Latitude(dds->latitude);
|
||||
fdm_state.set_Longitude(dds->longitude);
|
||||
fdm_state.set_Altitude(dds->altitude * SG_METER_TO_FEET);
|
||||
|
||||
fdm_state.set_Euler_Angles( dds->phi,
|
||||
dds->theta,
|
||||
dds->psi );
|
||||
|
||||
fdm_state.set_V_calibrated_kts( dds->vcas );
|
||||
fdm_state.set_Climb_Rate( dds->climb_rate );
|
||||
|
||||
for (i = 0; i < dds->num_tanks; ++i ) {
|
||||
SGPropertyNode * node
|
||||
= fgGetNode("/consumables/fuel/tank", i, true);
|
||||
node->setDoubleValue("level-gal_us", dds->fuel_quantity[i] );
|
||||
}
|
||||
|
||||
if ( dds->cur_time ) {
|
||||
fgSetLong("/sim/time/cur-time-override", dds->cur_time);
|
||||
}
|
||||
|
||||
globals->set_warp( dds->warp );
|
||||
|
||||
// Approach
|
||||
fgSetDouble( "/instrumentation/nav[0]/frequencies/selected-mhz",
|
||||
dds->tuned_freq );
|
||||
fgSetBool( "/instrumentation/nav[0]/in-range", dds->in_range > 0);
|
||||
fgSetDouble( "/instrumentation/dme/indicated-distance-nm", dds->dist_nm );
|
||||
fgSetDouble( "/instrumentation/nav[0]/heading-needle-deflection",
|
||||
dds->course_deviation_deg );
|
||||
fgSetDouble( "/instrumentation/nav[0]/gs-needle-deflection",
|
||||
dds->gs_deviation_deg );
|
||||
} else {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: version mismatch in FGNetNativeGUI2Props()" );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tread " << dds->version << " need " << FG_DDS_GUI_VERSION );
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"\tNeed to upgrade net_fdm.hxx and recompile." );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// open hailing frequencies
|
||||
bool FGNativeGUI::open() {
|
||||
if ( is_enabled() ) {
|
||||
|
@ -506,9 +97,9 @@ bool FGNativeGUI::process() {
|
|||
if ( get_direction() == SG_IO_OUT ) {
|
||||
// cout << "size of fdm_state = " << length << endl;
|
||||
if ( io->get_type() == sgDDSType ) {
|
||||
FGProps2GUI( &gui.dds );
|
||||
FGProps2GUI( globals->get_props(), &gui.dds );
|
||||
} else {
|
||||
FGProps2GUI( &gui.net );
|
||||
FGProps2GUI( globals->get_props(), &gui.net );
|
||||
}
|
||||
|
||||
if ( ! io->write( buf, length ) ) {
|
||||
|
@ -519,17 +110,17 @@ bool FGNativeGUI::process() {
|
|||
if ( io->get_type() == sgFileType ) {
|
||||
if ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_DEBUG, "Success reading data." );
|
||||
FGGUI2Props( &gui.net );
|
||||
FGGUI2Props( globals->get_props(), &gui.net );
|
||||
}
|
||||
} if ( io->get_type() == sgDDSType ) {
|
||||
while ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_DEBUG, "Success reading data." );
|
||||
FGGUI2Props( &gui.dds );
|
||||
FGGUI2Props( globals->get_props(), &gui.dds );
|
||||
}
|
||||
} else {
|
||||
while ( io->read( buf, length ) == length ) {
|
||||
SG_LOG( SG_IO, SG_DEBUG, "Success reading data." );
|
||||
FGGUI2Props( &gui.net );
|
||||
FGGUI2Props( globals->get_props(), &gui.net );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,18 +57,4 @@ public:
|
|||
bool close();
|
||||
};
|
||||
|
||||
|
||||
// Helper functions which may be useful outside this class
|
||||
|
||||
// Populate the FGNetGUI/FG_DDS_GUI structure from the property tree.
|
||||
template<typename T>
|
||||
void FGProps2GUI( T *net );
|
||||
|
||||
// Update the property tree from the FGNetGUI/FG_DDS_GUI structure.
|
||||
template<typename T>
|
||||
void FGGUI2Props( T *net );
|
||||
|
||||
|
||||
#endif // _FG_NATIVE_GUI_HXX
|
||||
|
||||
|
||||
|
|
1768
src/Network/native_structs.cxx
Normal file
1768
src/Network/native_structs.cxx
Normal file
File diff suppressed because it is too large
Load diff
52
src/Network/native_structs.hxx
Normal file
52
src/Network/native_structs.hxx
Normal file
|
@ -0,0 +1,52 @@
|
|||
// native_fdm.hxx -- FGFS "Native" flight dynamics protocal class
|
||||
//
|
||||
// Written by Curtis Olson, started September 2001.
|
||||
//
|
||||
// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
// Helper functions which may be useful outside this class
|
||||
|
||||
// Populate the FGNetFDM/FG_DDS_FDM structure from the property tree.
|
||||
template<typename T>
|
||||
void FGProps2FDM( SGPropertyNode *props, T *net, bool net_byte_order = true );
|
||||
|
||||
// Update the property tree from the FGNetFDM/FG_DDS_FDM structure.
|
||||
template<typename T>
|
||||
void FGFDM2Props( SGPropertyNode *props, T *net, bool net_byte_order = true );
|
||||
|
||||
|
||||
// Populate the FGNetGUI/FG_DDS_GUI structure from the property tree.
|
||||
template<typename T>
|
||||
void FGProps2GUI( SGPropertyNode *props, T *net );
|
||||
|
||||
// Update the property tree from the FGNetGUI/FG_DDS_GUI structure.
|
||||
template<typename T>
|
||||
void FGGUI2Props( SGPropertyNode *props, T *net );
|
||||
|
||||
|
||||
// Populate the FGNetCtrls/FG_DDS_Ctrls structure from the property tree.
|
||||
template<typename T>
|
||||
void FGProps2Ctrls( SGPropertyNode *props, T *net, bool honor_freezes, bool net_byte_order );
|
||||
|
||||
// Update the property tree from the FGNetCtrls/FG_DDS_Ctrls structure.
|
||||
template<typename T>
|
||||
void FGCtrls2Props( SGPropertyNode *props, T *net, bool honor_freezes, bool net_byte_order );
|
Loading…
Reference in a new issue