diff --git a/src/Instrumentation/Makefile.am b/src/Instrumentation/Makefile.am index 72c6472cb..579e0a27f 100644 --- a/src/Instrumentation/Makefile.am +++ b/src/Instrumentation/Makefile.am @@ -9,12 +9,14 @@ libInstrumentation_a_SOURCES = \ attitude_indicator.cxx attitude_indicator.hxx \ clock.cxx clock.hxx \ dme.cxx dme.hxx \ + encoder.cxx encoder.hxx \ gps.cxx gps.hxx \ gyro.cxx gyro.hxx \ heading_indicator.cxx heading_indicator.hxx \ kr_87.hxx kr_87.cxx \ mag_compass.cxx mag_compass.hxx \ slip_skid_ball.cxx slip_skid_ball.hxx \ + transponder.cxx transponder.hxx \ turn_indicator.cxx turn_indicator.hxx \ vertical_speed_indicator.cxx vertical_speed_indicator.hxx diff --git a/src/Instrumentation/encoder.cxx b/src/Instrumentation/encoder.cxx new file mode 100644 index 000000000..725daa799 --- /dev/null +++ b/src/Instrumentation/encoder.cxx @@ -0,0 +1,133 @@ +// encoder.cxx -- class to impliment an altitude encoder +// +// Written by Roy Vegard Ovesen, started September 2004. +// +// Copyright (C) 2004 Roy Vegard Ovesen - rvovesen@tiscali.no +// +// 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. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "encoder.hxx" + + +// Altitude based on pressure difference from sea level. +// pressure difference inHG, altitude ft +static double altitude_data[][2] = { + { -8.41, -8858.27 }, + { 0.00, 0.00 }, + { 3.05, 2952.76 }, + { 5.86, 5905.51 }, + { 8.41, 8858.27 }, + { 10.74, 11811.02 }, + { 12.87, 14763.78 }, + { 14.78, 17716.54 }, + { 16.55, 20669.29 }, + { 18.13, 23622.05 }, + { 19.62, 26574.80 }, + { 20.82, 29527.56 }, + { 21.96, 32480.31 }, + { 23.01, 35433.07 }, + { 23.91, 38385.83 }, + { 24.71, 41338.58 }, + { 25.40, 44291.34 }, + { 26.00, 47244.09 }, + { 26.51, 50196.85 }, + { 26.96, 53149.61 }, + { 27.35, 56102.36 }, + { 27.68, 59055.12 }, + { 27.98, 62007.87 }, + { 29.62, 100000.00 }, // just to fill it in + { -1, -1 } +}; + +int round (double value, int nearest=1) +{ + return ((int) (value/nearest + 0.5)) * nearest; +} + +Encoder::Encoder(SGPropertyNode *node) + : + altitudeTable(new SGInterpTable), + name("encoder"), + num(0), + staticPort("/systems/static") +{ + for (int i = 0; altitude_data[i][0] != -1; i++) + altitudeTable->addEntry(altitude_data[i][0], altitude_data[i][1]); + + int i; + for ( i = 0; i < node->nChildren(); ++i ) { + SGPropertyNode *child = node->getChild(i); + string cname = child->getName(); + string cval = child->getStringValue(); + if ( cname == "name" ) { + name = cval; + } else if ( cname == "number" ) { + num = child->getIntValue(); + } else if ( cname == "static-port" ) { + staticPort = cval; + } else { + SG_LOG( SG_INSTR, SG_WARN, + "Error in encoder config logic" ); + if ( name.length() ) { + SG_LOG( SG_INSTR, SG_WARN, "Section = " << name ); + } + } + } +} + + +Encoder::~Encoder() +{ + delete altitudeTable; +} + + +void Encoder::init() +{ + string branch; + branch = "/instrumentation/" + name; + staticPort += "/pressure-inhg"; + + SGPropertyNode *node = fgGetNode(branch.c_str(), num, true ); + // Inputs + staticPressureNode = fgGetNode(staticPort.c_str(), true); + busPowerNode = fgGetNode("/systems/electrical/outputs/encoder", true); + serviceableNode = node->getChild("serviceable", 0, true); + // Outputs + pressureAltitudeNode = node->getChild("pressure-alt-ft", 0, true); + modeCAltitudeNode = node->getChild("mode-c-alt-ft", 0, true); + // Init + serviceableNode->setBoolValue(true); +} + + +void Encoder::update(double dt) +{ + if (serviceableNode->getBoolValue()) + { + double staticPressure = staticPressureNode->getDoubleValue(); + double pressureAltitude = + altitudeTable->interpolate(29.92 - staticPressure); + int pressureAlt = round(pressureAltitude, 10); + int modeCAltitude = round(pressureAltitude, 100); + + pressureAltitudeNode->setIntValue(pressureAlt); + modeCAltitudeNode->setIntValue(modeCAltitude); + } +} diff --git a/src/Instrumentation/encoder.hxx b/src/Instrumentation/encoder.hxx new file mode 100644 index 000000000..0faad1538 --- /dev/null +++ b/src/Instrumentation/encoder.hxx @@ -0,0 +1,61 @@ +// encoder.hxx -- class to impliment an altitude encoder +// +// Written by Roy Vegard Ovesen, started September 2004. +// +// Copyright (C) 2004 Roy Vegard Ovesen - rvovesen@tiscali.no +// +// 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. + +#ifndef ENCODER_HXX +#define ENCODER_HXX 1 + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#include
+ +#include +#include + + +class Encoder : public SGSubsystem +{ +public: + Encoder(SGPropertyNode *node); + ~Encoder(); + + void init (); + void update (double dt); + +private: + // Inputs + SGPropertyNode_ptr staticPressureNode; + SGPropertyNode_ptr busPowerNode; + SGPropertyNode_ptr serviceableNode; + + // Outputs + SGPropertyNode_ptr pressureAltitudeNode; + SGPropertyNode_ptr modeCAltitudeNode; + + // Internal + string name; + int num; + string staticPort; + + SGInterpTable* altitudeTable; +}; + +#endif // ENCODER_HXX diff --git a/src/Instrumentation/instrument_mgr.cxx b/src/Instrumentation/instrument_mgr.cxx index b41189640..5a47f63a3 100644 --- a/src/Instrumentation/instrument_mgr.cxx +++ b/src/Instrumentation/instrument_mgr.cxx @@ -23,32 +23,20 @@ #include "attitude_indicator.hxx" #include "clock.hxx" #include "dme.hxx" +#include "encoder.hxx" #include "gps.hxx" #include "heading_indicator.hxx" #include "kr_87.hxx" #include "mag_compass.hxx" #include "slip_skid_ball.hxx" +#include "transponder.hxx" #include "turn_indicator.hxx" #include "vertical_speed_indicator.hxx" FGInstrumentMgr::FGInstrumentMgr () { - //set_subsystem("asi", new AirspeedIndicator(0)); - //set_subsystem("asi-backup", new AirspeedIndicator(1, 1, 1)); set_subsystem("annunciator", new Annunciator); - //set_subsystem("ai", new AttitudeIndicator); - //set_subsystem("alt", new Altimeter); - //set_subsystem("ti", new TurnIndicator); - //set_subsystem("ball", new SlipSkidBall); - //set_subsystem("hi", new HeadingIndicator); - //set_subsystem("vsi", new VerticalSpeedIndicator); - //set_subsystem("compass", new MagCompass); - //set_subsystem("dme", new DME, 1.0); - //set_subsystem("adf", new ADF, 0.15); - //set_subsystem("gps", new GPS, 0.45); - //set_subsystem("clock", new Clock, 0.25); - //set_subsystem("nhi", new NewHeadingIndicator); config_props = new SGPropertyNode; @@ -120,6 +108,9 @@ bool FGInstrumentMgr::build () } else if ( name == "dme" ) { set_subsystem( "instrument" + temp.str(), new DME( node ), 1.0 ); + } else if ( name == "encoder" ) { + set_subsystem( "instrument" + temp.str(), + new Encoder( node ) ); } else if ( name == "heading-indicator" ) { set_subsystem( "instrument" + temp.str(), new HeadingIndicator( node ) ); @@ -132,6 +123,9 @@ bool FGInstrumentMgr::build () } else if ( name == "slip-skid-ball" ) { set_subsystem( "instrument" + temp.str(), new SlipSkidBall( node ) ); + } else if ( name == "transponder" ) { + set_subsystem( "instrument" + temp.str(), + new Transponder( node ) ); } else if ( name == "turn-indicator" ) { set_subsystem( "instrument" + temp.str(), new TurnIndicator( node ) ); diff --git a/src/Instrumentation/transponder.cxx b/src/Instrumentation/transponder.cxx new file mode 100644 index 000000000..882bd160a --- /dev/null +++ b/src/Instrumentation/transponder.cxx @@ -0,0 +1,111 @@ +// transponder.cxx -- class to impliment a transponder +// +// Written by Roy Vegard Ovesen, started September 2004. +// +// Copyright (C) 2004 Roy Vegard Ovesen - rvovesen@tiscali.no +// +// 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. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "transponder.hxx" + +Transponder::Transponder(SGPropertyNode *node) + : + name("transponder"), + num(0), + encoder("/instrumentation/encoder") +{ + int i; + for ( i = 0; i < node->nChildren(); ++i ) { + SGPropertyNode *child = node->getChild(i); + string cname = child->getName(); + string cval = child->getStringValue(); + if ( cname == "name" ) { + name = cval; + } else if ( cname == "number" ) { + num = child->getIntValue(); + } else if ( cname == "encoder" ) { + encoder = cval; + } else { + SG_LOG( SG_INSTR, SG_WARN, + "Error in transponder config logic" ); + if ( name.length() ) { + SG_LOG( SG_INSTR, SG_WARN, "Section = " << name ); + } + } + } +} + + +Transponder::~Transponder() +{ +} + + +void Transponder::init() +{ + string branch; + branch = "/instrumentation/" + name; + encoder += "/mode-c-alt-ft"; + + SGPropertyNode *node = fgGetNode(branch.c_str(), num, true ); + // Inputs + pressureAltitudeNode = fgGetNode(encoder.c_str(), true); + busPowerNode = fgGetNode("/systems/electrical/outputs/transponder", true); + serviceableNode = node->getChild("serviceable", 0, true); + // Outputs + idCodeNode = node->getChild("id-code", 0, true); + flightLevelNode = node->getChild("flight-level", 0, true); + // Init + serviceableNode->setBoolValue(true); +} + + +void Transponder::update(double dt) +{ + if (serviceableNode->getBoolValue()) + { + int idCode = idCodeNode->getIntValue(); + if (idCode < 0) + idCode = 0; + int firstDigit = idCode % 10; + int secondDigit = (idCode/10) % 10; + int thirdDigit = (idCode/100) % 10; + int fourthDigit = (idCode/1000) % 10; + + if (firstDigit-7 > 0) + idCode -= firstDigit-7; + if (secondDigit-7 > 0) + idCode -= (secondDigit-7) * 10; + if (thirdDigit-7 > 0) + idCode -= (thirdDigit-7) * 100; + if (fourthDigit-7 > 0) + idCode -= (fourthDigit-7) * 1000; + + if (idCode > 7777) + idCode = 7777; + else if (idCode < 0) + idCode = 0; + + idCodeNode->setIntValue(idCode); + + int pressureAltitude = pressureAltitudeNode->getIntValue(); + int flightLevel = pressureAltitude / 100; + flightLevelNode->setIntValue(flightLevel); + } +} diff --git a/src/Instrumentation/transponder.hxx b/src/Instrumentation/transponder.hxx new file mode 100644 index 000000000..88a9dedec --- /dev/null +++ b/src/Instrumentation/transponder.hxx @@ -0,0 +1,58 @@ +// transponder.hxx -- class to impliment a transponder +// +// Written by Roy Vegard Ovesen, started September 2004. +// +// Copyright (C) 2004 Roy Vegard Ovesen - rvovesen@tiscali.no +// +// 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. + +#ifndef TRANSPONDER_HXX +#define TRANSPONDER_HXX 1 + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#include
+ +#include + + +class Transponder : public SGSubsystem +{ +public: + Transponder(SGPropertyNode *node); + ~Transponder(); + + void init (); + void update (double dt); + +private: + // Inputs + SGPropertyNode_ptr pressureAltitudeNode; + SGPropertyNode_ptr busPowerNode; + SGPropertyNode_ptr serviceableNode; + + // Outputs + SGPropertyNode_ptr idCodeNode; + SGPropertyNode_ptr flightLevelNode; + + // Internal + string name; + int num; + string encoder; +}; + +#endif // TRANSPONDER_HXX