From ec827732226e905a8a0ce9af700b63b183b18c5c Mon Sep 17 00:00:00 2001 From: curt Date: Fri, 24 Dec 2004 01:23:27 +0000 Subject: [PATCH] More work on the ATC FS hardware interface. --- src/Network/ATC-Main.cxx | 243 ++++++++ src/Network/ATC-Main.hxx | 98 ++++ src/Network/{atc610x.cxx => ATC-Outputs.cxx} | 556 +++++++++---------- src/Network/ATC-Outputs.hxx | 90 +++ src/Network/Makefile.am | 3 +- src/Network/atc610x.hxx | 185 ------ 6 files changed, 703 insertions(+), 472 deletions(-) create mode 100644 src/Network/ATC-Main.cxx create mode 100644 src/Network/ATC-Main.hxx rename src/Network/{atc610x.cxx => ATC-Outputs.cxx} (62%) create mode 100644 src/Network/ATC-Outputs.hxx delete mode 100644 src/Network/atc610x.hxx diff --git a/src/Network/ATC-Main.cxx b/src/Network/ATC-Main.cxx new file mode 100644 index 000000000..45f491d36 --- /dev/null +++ b/src/Network/ATC-Main.cxx @@ -0,0 +1,243 @@ +// ATC-Main.cxx -- FGFS interface to ATC hardware +// +// Written by Curtis Olson, started January 2002 +// +// Copyright (C) 2002 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include // atoi() atof() abs() +#include +#include +#include +#include //snprintf +#if defined( _MSC_VER ) || defined(__MINGW32__) +# include //lseek, read, write +#endif + +#include STL_STRING + +#include + +#include +#include +#include +#include +#include + +#include +#include
+#include
+ +#include "ATC-Main.hxx" + +SG_USING_STD(string); + + +// Lock the ATC hardware +static int fgATCMainLock( int fd ) { + // rewind + lseek( fd, 0, SEEK_SET ); + + char tmp[2]; + int result = read( fd, tmp, 1 ); + if ( result != 1 ) { + SG_LOG( SG_IO, SG_DEBUG, "Lock failed" ); + } + + return result; +} + + +// Write a radios command +static int fgATCMainRelease( int fd ) { + // rewind + lseek( fd, 0, SEEK_SET ); + + char tmp[2]; + tmp[0] = tmp[1] = 0; + int result = write( fd, tmp, 1 ); + + if ( result != 1 ) { + SG_LOG( SG_IO, SG_DEBUG, "Release failed" ); + } + + return result; +} + + +void FGATCMain::init_config() { +#if defined( unix ) || defined( __CYGWIN__ ) + // Next check home directory for .fgfsrc.hostname file + char *envp = ::getenv( "HOME" ); + if ( envp != NULL ) { + SGPath atcsim_config( envp ); + atcsim_config.append( ".fgfs-atc610x.xml" ); + readProperties( atcsim_config.str(), globals->get_props() ); + } +#endif +} + + +// Open and initialize ATC hardware +bool FGATCMain::open() { + if ( is_enabled() ) { + SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " + << "is already in use, ignoring" ); + return false; + } + + SG_LOG( SG_IO, SG_ALERT, + "Initializing ATC hardware, please wait ..." ); + + // This loads the config parameters generated by "simcal" + init_config(); + + ///////////////////////////////////////////////////////////////////// + // Open the /proc files + ///////////////////////////////////////////////////////////////////// + + string lock0_file = "/proc/atc610x/board0/lock"; + string lock1_file = "/proc/atc610x/board1/lock"; + + lock0_fd = ::open( lock0_file.c_str(), O_RDWR ); + if ( lock0_fd == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error opening %s", lock0_file.c_str() ); + perror( msg ); + exit( -1 ); + } + + lock1_fd = ::open( lock1_file.c_str(), O_RDWR ); + if ( lock1_fd == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error opening %s", lock1_file.c_str() ); + perror( msg ); + exit( -1 ); + } + + if ( input0_path.str().length() ) { + input0 = new FGATCInput( 0, input0_path ); + input0->open(); + } + if ( input1_path.str().length() ) { + input1 = new FGATCInput( 1, input1_path ); + input1->open(); + } + if ( output0_path.str().length() ) { + output0 = new FGATCOutput( 0, output0_path ); + output0->open( lock0_fd ); + } + if ( output1_path.str().length() ) { + output1 = new FGATCOutput( 1, output1_path ); + output1->open( lock1_fd ); + } + + set_hz( 30 ); // default to processing requests @ 30Hz + set_enabled( true ); + + ///////////////////////////////////////////////////////////////////// + // Finished initing hardware + ///////////////////////////////////////////////////////////////////// + + SG_LOG( SG_IO, SG_ALERT, + "Done initializing ATC hardware." ); + + return true; +} + + +bool FGATCMain::process() { + // Lock the hardware, skip if it's not ready yet + if ( fgATCMainLock( lock0_fd ) <= 0 ) { + return false; + } + if ( fgATCMainLock( lock1_fd ) <= 0 ) { + // lock0 will be locked here, so release before we return + fgATCMainRelease( lock0_fd ); + return false; + } + + // process the ATC inputs + if ( input0 != NULL ) { + input0->process(); + } + if ( input1 != NULL ) { + input1->process(); + } + + // run our custom nasal script. This is a layer above the raw + // hardware inputs. It handles situations where there isn't a + // direct 1-1 linear mapping between ATC functionality and FG + // functionality, and handles situations where FG expects more + // functionality from the interface than the ATC hardware can + // directly provide. + + FGNasalSys *n = (FGNasalSys*)globals->get_subsystem("nasal"); + bool result = n->parseAndRun( "atcsim.do_hardware()" ); + if ( !result ) { + SG_LOG( SG_GENERAL, SG_ALERT, + "Nasal: atcsim.do_hardware() failed!" ); + } + + // process the ATC outputs + if ( output0 != NULL ) { + output0->process(); + } + if ( output1 != NULL ) { + output1->process(); + } + + fgATCMainRelease( lock0_fd ); + fgATCMainRelease( lock1_fd ); + + return true; +} + + +bool FGATCMain::close() { + int result; + + result = ::close( lock0_fd ); + if ( result == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error closing lock0_fd" ); + perror( msg ); + exit( -1 ); + } + + result = ::close( lock1_fd ); + if ( result == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error closing lock1_fd" ); + perror( msg ); + exit( -1 ); + } + + return true; +} diff --git a/src/Network/ATC-Main.hxx b/src/Network/ATC-Main.hxx new file mode 100644 index 000000000..b6f4598a9 --- /dev/null +++ b/src/Network/ATC-Main.hxx @@ -0,0 +1,98 @@ +// ATC-Main.hxx -- FGFS interface to ATC 610x hardware +// +// Written by Curtis Olson, started January 2002. +// +// Copyright (C) 2002 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _FG_ATC_MAIN_HXX +#define _FG_ATC_MAIN_HXX + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include
+ +#include "protocol.hxx" + +#include "ATC-Inputs.hxx" +#include "ATC-Outputs.hxx" + + +class FGATCMain : public FGProtocol { + + FGATCInput *input0; // board0 input interface class + FGATCInput *input1; // board1 input interface class + FGATCOutput *output0; // board0 output interface class + FGATCOutput *output1; // board1 output interface class + + SGPath input0_path; + SGPath input1_path; + SGPath output0_path; + SGPath output1_path; + + int board; + + int lock0_fd; + int lock1_fd; + +public: + + FGATCMain() : + input0(NULL), + input1(NULL), + output0(NULL), + output1(NULL), + input0_path(""), + input1_path(""), + output0_path(""), + output1_path("") + { } + + ~FGATCMain() { + delete input0; + delete input1; + delete output0; + delete output1; + } + + // Open and initialize ATC 610x hardware + bool open(); + + void init_config(); + + bool process(); + + bool close(); + + inline void set_path_names( const SGPath &in0, const SGPath &in1, + const SGPath &out0, const SGPath &out1 ) + { + input0_path = in0; + input1_path = in1; + output0_path = out0; + output1_path = out1; + } +}; + + +#endif // _FG_ATC_MAIN_HXX diff --git a/src/Network/atc610x.cxx b/src/Network/ATC-Outputs.cxx similarity index 62% rename from src/Network/atc610x.cxx rename to src/Network/ATC-Outputs.cxx index 34c3d10f2..b73637f80 100644 --- a/src/Network/atc610x.cxx +++ b/src/Network/ATC-Outputs.cxx @@ -1,8 +1,8 @@ -// atc610x.cxx -- FGFS interface to ATC 610x hardware +// ATC-Outputs.hxx -- Translate FGFS properties to ATC hardware outputs. // -// Written by Curtis Olson, started January 2002 +// Written by Curtis Olson, started November 2004. // -// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt +// Copyright (C) 2004 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 @@ -27,36 +27,26 @@ #include -#include // atoi() atof() abs() -#include -#include -#include -#include //snprintf -#if defined( _MSC_VER ) || defined(__MINGW32__) -# include //lseek, read, write +#if defined( unix ) || defined( __CYGWIN__ ) +# include +# include +# include #endif #include STL_STRING -#include - #include -#include -#include -#include -#include -#include #include
-#include
-#include "atc610x.hxx" +#include "ATC-Outputs.hxx" SG_USING_STD(string); -// Lock the ATC 610 hardware -static int ATC610xLock( int fd ) { + +// Lock the ATC hardware +static int ATCLock( int fd ) { // rewind lseek( fd, 0, SEEK_SET ); @@ -70,8 +60,8 @@ static int ATC610xLock( int fd ) { } -// Write a radios command -static int ATC610xRelease( int fd ) { +// Release the ATC hardware +static int ATCRelease( int fd ) { // rewind lseek( fd, 0, SEEK_SET ); @@ -87,10 +77,22 @@ static int ATC610xRelease( int fd ) { } -// Write a radios command -static int ATC610xSetRadios( int fd, - unsigned char data[ATC_RADIO_DISPLAY_BYTES] ) +// Constructor: The _board parameter specifies which board to +// reference. Possible values are 0 or 1. The _config_file parameter +// specifies the location of the output config file (xml) +FGATCOutput::FGATCOutput( const int _board, const SGPath &_config_file ) : + is_open(false), + lamps_out_node(NULL), + radio_display_node(NULL), + steppers_node(NULL) { + board = _board; + config = _config_file; +} + + +// Write a radios command +static int ATCSetRadios( int fd, unsigned char data[ATC_RADIO_DISPLAY_BYTES] ) { // rewind lseek( fd, 0, SEEK_SET ); @@ -105,7 +107,7 @@ static int ATC610xSetRadios( int fd, // Write a stepper command -static int ATC610xSetStepper( int fd, unsigned char channel, +static int ATCSetStepper( int fd, unsigned char channel, unsigned char value ) { // rewind @@ -127,7 +129,7 @@ static int ATC610xSetStepper( int fd, unsigned char channel, // Read status of last stepper written to -static unsigned char ATC610xReadStepper( int fd ) { +static unsigned char ATCReadStepper( int fd ) { int result; // rewind @@ -147,7 +149,7 @@ static unsigned char ATC610xReadStepper( int fd ) { // Turn a lamp on or off -void ATC610xSetLamp( int fd, int channel, bool value ) { +void ATCSetLamp( int fd, int channel, bool value ) { // lamp channels 0-63 are written to LampPort0, channels 64-127 // are written to LampPort1 @@ -169,65 +171,48 @@ void ATC610xSetLamp( int fd, int channel, bool value ) { } -void FGATC610x::init_config() { +void FGATCOutput::init_config() { #if defined( unix ) || defined( __CYGWIN__ ) - // Next check home directory for .fgfsrc.hostname file - char *envp = ::getenv( "HOME" ); - if ( envp != NULL ) { - SGPath atc610x_config( envp ); - atc610x_config.append( ".fgfs-atc610x.xml" ); - readProperties( atc610x_config.str(), globals->get_props() ); + if ( config.str()[0] != '/' ) { + // not an absolute path, prepend the standard location + SGPath tmp; + char *envp = ::getenv( "HOME" ); + if ( envp != NULL ) { + tmp = envp; + tmp.append( ".atcflightsim" ); + tmp.append( config.str() ); + config = tmp; + } } + readProperties( config.str(), globals->get_props() ); #endif } -// Open and initialize ATC 610x hardware -bool FGATC610x::open() { - if ( is_enabled() ) { - SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " - << "is already in use, ignoring" ); +// Open and initialize the ATC hardware +bool FGATCOutput::open( int lock_fd ) { + if ( is_open ) { + SG_LOG( SG_IO, SG_ALERT, "This board is already open for output! " + << board ); return false; } - SG_LOG( SG_IO, SG_ALERT, - "Initializing ATC 610x hardware, please wait ..." ); - // This loads the config parameters generated by "simcal" init_config(); - if ( input0_path.str().length() ) { - input0 = new FGATCInput( 0, input0_path ); - input0->open(); - } - if ( input1_path.str().length() ) { - input1 = new FGATCInput( 1, input1_path ); - input1->open(); - } - - set_hz( 30 ); // default to processing requests @ 30Hz - set_enabled( true ); - - board = 0; // 610x uses a single board number = 0 + SG_LOG( SG_IO, SG_ALERT, + "Initializing ATC hardware, please wait ..." ); - snprintf( lock_file, 256, "/proc/atc610x/board%d/lock", board ); snprintf( lamps_file, 256, "/proc/atc610x/board%d/lamps", board ); - snprintf( radios_file, 256, "/proc/atc610x/board%d/radios", board ); + snprintf( radio_display_file, 256, "/proc/atc610x/board%d/radios", board ); snprintf( stepper_file, 256, "/proc/atc610x/board%d/steppers", board ); +#if defined( unix ) || defined( __CYGWIN__ ) + ///////////////////////////////////////////////////////////////////// // Open the /proc files ///////////////////////////////////////////////////////////////////// - lock_fd = ::open( lock_file, O_RDWR ); - if ( lock_fd == -1 ) { - SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); - char msg[256]; - snprintf( msg, 256, "Error opening %s", lock_file ); - perror( msg ); - exit( -1 ); - } - lamps_fd = ::open( lamps_file, O_WRONLY ); if ( lamps_fd == -1 ) { SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); @@ -237,11 +222,11 @@ bool FGATC610x::open() { exit( -1 ); } - radios_fd = ::open( radios_file, O_RDWR ); - if ( radios_fd == -1 ) { + radio_display_fd = ::open( radio_display_file, O_RDWR ); + if ( radio_display_fd == -1 ) { SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); char msg[256]; - snprintf( msg, 256, "Error opening %s", radios_file ); + snprintf( msg, 256, "Error opening %s", radio_display_file ); perror( msg ); exit( -1 ); } @@ -255,6 +240,7 @@ bool FGATC610x::open() { exit( -1 ); } +#endif ///////////////////////////////////////////////////////////////////// // Home the compass stepper motor @@ -264,13 +250,13 @@ bool FGATC610x::open() { " - Homing the compass stepper motor" ); // Lock the hardware, keep trying until we succeed - while ( ATC610xLock( lock_fd ) <= 0 ); + while ( ATCLock( lock_fd ) <= 0 ); // Send the stepper home command - ATC610xSetStepper( stepper_fd, ATC_COMPASS_CH, ATC_STEPPER_HOME ); + ATCSetStepper( stepper_fd, ATC_COMPASS_CH, ATC_STEPPER_HOME ); // Release the hardware - ATC610xRelease( lock_fd ); + ATCRelease( lock_fd ); SG_LOG( SG_IO, SG_ALERT, " - Waiting for compass to come home." ); @@ -285,14 +271,14 @@ bool FGATC610x::open() { SG_LOG( SG_IO, SG_DEBUG, "Checking if compass home ..." ); } - while ( ATC610xLock( lock_fd ) <= 0 ); + while ( ATCLock( lock_fd ) <= 0 ); - unsigned char result = ATC610xReadStepper( stepper_fd ); + unsigned char result = ATCReadStepper( stepper_fd ); if ( result == 0 ) { home = true; } - ATC610xRelease( lock_fd ); + ATCRelease( lock_fd ); #if defined( _MSC_VER ) ulMilliSecondSleep(33); @@ -321,19 +307,19 @@ bool FGATC610x::open() { } // Lock the hardware, keep trying until we succeed - while ( ATC610xLock( lock_fd ) <= 0 ); + while ( ATCLock( lock_fd ) <= 0 ); // Set radio display - ATC610xSetRadios( radios_fd, radio_display_data ); + ATCSetRadios( radio_display_fd, radio_display_data ); - ATC610xRelease( lock_fd ); + ATCRelease( lock_fd ); ///////////////////////////////////////////////////////////////////// // Blank the lamps ///////////////////////////////////////////////////////////////////// for ( int i = 0; i < 128; ++i ) { - ATC610xSetLamp( lamps_fd, i, false ); + ATCSetLamp( lamps_fd, i, false ); } ///////////////////////////////////////////////////////////////////// @@ -341,205 +327,189 @@ bool FGATC610x::open() { ///////////////////////////////////////////////////////////////////// SG_LOG( SG_IO, SG_ALERT, - "Done initializing ATC 610x hardware." ); + "Done initializing ATC hardware." ); + + is_open = true; ///////////////////////////////////////////////////////////////////// // Connect up to property values ///////////////////////////////////////////////////////////////////// - mag_compass - = fgGetNode( "/instrumentation/magnetic-compass/indicated-heading-deg", - true ); + char base_name[256]; - dme_min = fgGetNode( "/instrumentation/dme/indicated-time-min", true ); - dme_kt = fgGetNode( "/instrumentation/dme/indicated-ground-speed-kt", - true ); - dme_nm = fgGetNode( "/instrumentation/dme/indicated-distance-nm", true ); - dme_in_range = fgGetNode( "/instrumentation/dme/in-range", true ); - - adf_bus_power = fgGetNode( "/systems/electrical/outputs/adf", true ); - dme_bus_power = fgGetNode( "/systems/electrical/outputs/dme", true ); - navcom1_bus_power = fgGetNode( "/systems/electrical/outputs/nav[0]", - true ); - navcom2_bus_power = fgGetNode( "/systems/electrical/outputs/nav[1]", - true ); - xpdr_bus_power = fgGetNode( "/systems/electrical/outputs/transponder", - true ); - - navcom1_power_btn = fgGetNode( "/instrumentation/comm[0]/inputs/power-btn", true ); - navcom2_power_btn = fgGetNode( "/instrumentation/comm[1]/inputs/power-btn", true ); - - com1_freq = fgGetNode( "/instrumentation/comm[0]/frequencies/selected-mhz", true ); - com1_stby_freq - = fgGetNode( "/instrumentation/comm[0]/frequencies/standby-mhz", true ); + snprintf( base_name, 256, "/output/atc-board[%d]/lamps", board ); + lamps_out_node = fgGetNode( base_name ); - com2_freq = fgGetNode( "/instrumentation/comm[1]/frequencies/selected-mhz", true ); - com2_stby_freq - = fgGetNode( "/instrumentation/comm[1]/frequencies/standby-mhz", true ); + snprintf( base_name, 256, "/output/atc-board[%d]/radio-display", board ); + radio_display_node = fgGetNode( base_name ); - nav1_freq = fgGetNode( "/instrumentation/nav[0]/frequencies/selected-mhz", true ); - nav1_stby_freq - = fgGetNode( "/instrumentation/nav[0]/frequencies/standby-mhz", true ); - nav1_obs = fgGetNode( "/instrumentation/nav[0]/radials/selected-deg", true ); - - nav2_freq = fgGetNode( "/instrumentation/nav[1]/frequencies/selected-mhz", true ); - nav2_stby_freq - = fgGetNode( "/instrumentation/nav[1]/frequencies/standby-mhz", true ); - nav2_obs = fgGetNode( "/instrumentation/nav[1]/radials/selected-deg", true ); - - adf_power_btn - = fgGetNode( "/instrumentation/kr-87/inputs/power-btn", true ); - adf_vol = fgGetNode( "/instrumentation/kr-87/inputs/volume", true ); - adf_adf_btn = fgGetNode( "/instrumentation/kr-87/inputs/adf-btn", true ); - adf_bfo_btn = fgGetNode( "/instrumentation/kr-87/inputs/bfo-btn", true ); - adf_freq = fgGetNode( "/instrumentation/kr-87/outputs/selected-khz", true ); - adf_stby_freq - = fgGetNode( "/instrumentation/kr-87/outputs/standby-khz", true ); - adf_stby_mode = fgGetNode( "/instrumentation/kr-87/modes/stby", true ); - adf_timer_mode = fgGetNode( "/instrumentation/kr-87/modes/timer", true ); - adf_count_mode = fgGetNode( "/instrumentation/kr-87/modes/count", true ); - adf_flight_timer - = fgGetNode( "/instrumentation/kr-87/outputs/flight-timer", true ); - adf_elapsed_timer - = fgGetNode( "/instrumentation/kr-87/outputs/elapsed-timer", - true ); - adf_ant_ann = fgGetNode( "/instrumentation/kr-87/annunciators/ant", true ); - adf_adf_ann = fgGetNode( "/instrumentation/kr-87/annunciators/adf", true ); - adf_bfo_ann = fgGetNode( "/instrumentation/kr-87/annunciators/bfo", true ); - adf_frq_ann = fgGetNode( "/instrumentation/kr-87/annunciators/frq", true ); - adf_flt_ann = fgGetNode( "/instrumentation/kr-87/annunciators/flt", true ); - adf_et_ann = fgGetNode( "/instrumentation/kr-87/annunciators/et", true ); - - inner = fgGetNode( "/instrumentation/marker-beacon/inner", true ); - middle = fgGetNode( "/instrumentation/marker-beacon/middle", true ); - outer = fgGetNode( "/instrumentation/marker-beacon/outer", true ); - - xpdr_ident_btn - = fgGetNode( "/instrumentation/kt-70/inputs/ident-btn", true ); - xpdr_digit1 = fgGetNode( "/instrumentation/kt-70/inputs/digit1", true ); - xpdr_digit2 = fgGetNode( "/instrumentation/kt-70/inputs/digit2", true ); - xpdr_digit3 = fgGetNode( "/instrumentation/kt-70/inputs/digit3", true ); - xpdr_digit4 = fgGetNode( "/instrumentation/kt-70/inputs/digit4", true ); - xpdr_func_knob - = fgGetNode( "/instrumentation/kt-70/inputs/func-knob", true ); - xpdr_id_code = fgGetNode( "/instrumentation/kt-70/outputs/id-code", true ); - xpdr_flight_level - = fgGetNode( "/instrumentation/kt-70/outputs/flight-level", true ); - xpdr_fl_ann = fgGetNode( "/instrumentation/kt-70/annunciators/fl", true ); - xpdr_alt_ann = fgGetNode( "/instrumentation/kt-70/annunciators/alt", true ); - xpdr_gnd_ann = fgGetNode( "/instrumentation/kt-70/annunciators/gnd", true ); - xpdr_on_ann = fgGetNode( "/instrumentation/kt-70/annunciators/on", true ); - xpdr_sby_ann = fgGetNode( "/instrumentation/kt-70/annunciators/sby", true ); - xpdr_reply_ann - = fgGetNode( "/instrumentation/kt-70/annunciators/reply", true ); + snprintf( base_name, 256, "/output/atc-board[%d]/steppers", board ); + steppers_node = fgGetNode( base_name ); - ati_bird - = fgGetNode( "/instrumentation/attitude-indicator/horizon-offset-deg", - true ); - alt_press = fgGetNode( "/instrumentation/altimeter/setting-inhg", true ); - adf_hdg = fgGetNode( "/instrumentation/kr-87/inputs/rotation-deg", true ); - hdg_bug = fgGetNode( "/autopilot/settings/heading-bug-deg", true ); - - elevator_center = fgGetNode( "/input/atc610x/elevator/center", true ); - elevator_min = fgGetNode( "/input/atc610x/elevator/min", true ); - elevator_max = fgGetNode( "/input/atc610x/elevator/max", true ); + return true; +} - ailerons_center = fgGetNode( "/input/atc610x/ailerons/center", true ); - ailerons_min = fgGetNode( "/input/atc610x/ailerons/min", true ); - ailerons_max = fgGetNode( "/input/atc610x/ailerons/max", true ); - rudder_center = fgGetNode( "/input/atc610x/rudder/center", true ); - rudder_min = fgGetNode( "/input/atc610x/rudder/min", true ); - rudder_max = fgGetNode( "/input/atc610x/rudder/max", true ); +///////////////////////////////////////////////////////////////////// +// Write the lights +///////////////////////////////////////////////////////////////////// - brake_left_min = fgGetNode( "/input/atc610x/brake-left/min", true ); - brake_left_max = fgGetNode( "/input/atc610x/brake-left/max", true ); +bool FGATCOutput::do_lamps() { + + if ( lamps_out_node != NULL ) { + for ( int i = 0; i < lamps_out_node->nChildren(); ++i ) { + // read the next config entry from the property tree + + SGPropertyNode *child = lamps_out_node->getChild(i); + string cname = child->getName(); + int index = child->getIndex(); + string name = ""; + string type = ""; + SGPropertyNode *src_prop = NULL; + if ( cname == "lamp" ) { + SGPropertyNode *prop; + prop = child->getChild( "name" ); + if ( prop != NULL ) { + name = prop->getStringValue(); + } + prop = child->getChild( "type" ); + if ( prop != NULL ) { + type = prop->getStringValue(); + } + prop = child->getChild( "prop" ); + if ( prop != NULL ) { + src_prop = fgGetNode( prop->getStringValue(), true ); + } + ATCSetLamp( lamps_fd, index, src_prop->getBoolValue() ); + } else { + SG_LOG( SG_IO, SG_DEBUG, + "Input config error, expecting 'lamp' but found " + << cname ); + } + } + } - brake_right_min = fgGetNode( "/input/atc610x/brake-right/min", true ); - brake_right_max = fgGetNode( "/input/atc610x/brake-right/max", true ); + return true; +} - throttle_min = fgGetNode( "/input/atc610x/throttle/min", true ); - throttle_max = fgGetNode( "/input/atc610x/throttle/max", true ); - mixture_min = fgGetNode( "/input/atc610x/mixture/min", true ); - mixture_max = fgGetNode( "/input/atc610x/mixture/max", true ); +///////////////////////////////////////////////////////////////////// +// Update the radio display +///////////////////////////////////////////////////////////////////// - trim_center = fgGetNode( "/input/atc610x/trim/center", true ); - trim_min = fgGetNode( "/input/atc610x/trim/min", true ); - trim_max = fgGetNode( "/input/atc610x/trim/max", true ); - nav1vol_min = fgGetNode( "/input/atc610x/nav1vol/min", true ); - nav1vol_max = fgGetNode( "/input/atc610x/nav1vol/max", true ); +static bool navcom1_has_power() { + static SGPropertyNode *navcom1_bus_power + = fgGetNode( "/systems/electrical/outputs/nav[0]", true ); + static SGPropertyNode *navcom1_power_btn + = fgGetNode( "/instrumentation/comm[0]/inputs/power-btn", true ); - nav2vol_min = fgGetNode( "/input/atc610x/nav2vol/min", true ); - nav2vol_max = fgGetNode( "/input/atc610x/nav2vol/max", true ); + return (navcom1_bus_power->getDoubleValue() > 1.0) + && navcom1_power_btn->getBoolValue(); +} - ignore_flight_controls - = fgGetNode( "/input/atc610x/ignore-flight-controls", true ); +static bool navcom2_has_power() { + static SGPropertyNode *navcom2_bus_power + = fgGetNode( "/systems/electrical/outputs/nav[1]", true ); + static SGPropertyNode *navcom2_power_btn + = fgGetNode( "/instrumentation/comm[1]/inputs/power-btn", true ); - comm1_serviceable - = fgGetNode( "/instrumentation/comm[0]/serviceable", true ); - comm2_serviceable - = fgGetNode( "/instrumentation/comm[1]/serviceable", true ); - nav1_serviceable = fgGetNode( "/instrumentation/nav[0]/serviceable", true ); - nav2_serviceable = fgGetNode( "/instrumentation/nav[1]/serviceable", true ); - adf_serviceable = fgGetNode( "/instrumentation/adf/serviceable", true ); - xpdr_serviceable - = fgGetNode( "/instrumentation/kt-70/inputs/serviceable", true ); - dme_serviceable = fgGetNode( "/instrumentation/dme/serviceable", true ); + return (navcom2_bus_power->getDoubleValue() > 1.0) + && navcom2_power_btn->getBoolValue(); +} - dme_selector - = fgGetNode( "/input/atc-board/radio-switches/raw/dme-switch-position"); +static bool dme_has_power() { + static SGPropertyNode *dme_bus_power + = fgGetNode( "/systems/electrical/outputs/dme", true ); + + return (dme_bus_power->getDoubleValue() > 1.0); +} - // default to having everything serviceable - comm1_serviceable->setBoolValue( true ); - comm2_serviceable->setBoolValue( true ); - nav1_serviceable->setBoolValue( true ); - nav2_serviceable->setBoolValue( true ); - adf_serviceable->setBoolValue( true ); - xpdr_serviceable->setBoolValue( true ); - dme_serviceable->setBoolValue( true ); +static bool adf_has_power() { + static SGPropertyNode *adf_bus_power + = fgGetNode( "/systems/electrical/outputs/adf", true ); + static SGPropertyNode *adf_power_btn + = fgGetNode( "/instrumentation/kr-87/inputs/power-btn", true ); - return true; + return (adf_bus_power->getDoubleValue() > 1.0) + && adf_power_btn->getBoolValue(); } +static bool xpdr_has_power() { + static SGPropertyNode *xpdr_bus_power + = fgGetNode( "/systems/electrical/outputs/transponder", true ); + static SGPropertyNode *xpdr_func_knob + = fgGetNode( "/instrumentation/kt-70/inputs/func-knob", true ); -///////////////////////////////////////////////////////////////////// -// Write the lights -///////////////////////////////////////////////////////////////////// + return (xpdr_bus_power->getDoubleValue() > 1.0) + && (xpdr_func_knob->getIntValue() > 0); +} -bool FGATC610x::do_lights() { - - // Marker beacons - ATC610xSetLamp( lamps_fd, 4, inner->getBoolValue() ); - ATC610xSetLamp( lamps_fd, 5, middle->getBoolValue() ); - ATC610xSetLamp( lamps_fd, 3, outer->getBoolValue() ); - - // ADF annunciators - ATC610xSetLamp( lamps_fd, 11, adf_ant_ann->getBoolValue() ); // ANT - ATC610xSetLamp( lamps_fd, 12, adf_adf_ann->getBoolValue() ); // ADF - ATC610xSetLamp( lamps_fd, 13, adf_bfo_ann->getBoolValue() ); // BFO - ATC610xSetLamp( lamps_fd, 14, adf_frq_ann->getBoolValue() ); // FRQ - ATC610xSetLamp( lamps_fd, 15, adf_flt_ann->getBoolValue() ); // FLT - ATC610xSetLamp( lamps_fd, 16, adf_et_ann->getBoolValue() ); // ET - - // Transponder annunciators - ATC610xSetLamp( lamps_fd, 17, xpdr_fl_ann->getBoolValue() ); // FL - ATC610xSetLamp( lamps_fd, 18, xpdr_alt_ann->getBoolValue() ); // ALT - ATC610xSetLamp( lamps_fd, 19, xpdr_gnd_ann->getBoolValue() ); // GND - ATC610xSetLamp( lamps_fd, 20, xpdr_on_ann->getBoolValue() ); // ON - ATC610xSetLamp( lamps_fd, 21, xpdr_sby_ann->getBoolValue() ); // SBY - ATC610xSetLamp( lamps_fd, 22, xpdr_reply_ann->getBoolValue() ); // R +bool FGATCOutput::do_radio_display() { + static SGPropertyNode *dme_serviceable + = fgGetNode( "/instrumentation/dme/serviceable", true ); + static SGPropertyNode *dme_in_range + = fgGetNode( "/instrumentation/dme/in-range", true ); + static SGPropertyNode *dme_min + = fgGetNode( "/instrumentation/dme/indicated-time-min", true ); + static SGPropertyNode *dme_kt + = fgGetNode( "/instrumentation/dme/indicated-ground-speed-kt", true ); + static SGPropertyNode *dme_nm + = fgGetNode( "/instrumentation/dme/indicated-distance-nm", true ); + + static SGPropertyNode *comm1_serviceable + = fgGetNode( "/instrumentation/comm[0]/serviceable", true ); + static SGPropertyNode *com1_freq + = fgGetNode( "/instrumentation/comm[0]/frequencies/selected-mhz", true); + static SGPropertyNode *com1_stby_freq + = fgGetNode( "/instrumentation/comm[0]/frequencies/standby-mhz", true ); - return true; -} + static SGPropertyNode *comm2_serviceable + = fgGetNode( "/instrumentation/comm[1]/serviceable", true ); + static SGPropertyNode *com2_freq + = fgGetNode( "/instrumentation/comm[1]/frequencies/selected-mhz", true); + static SGPropertyNode *com2_stby_freq + = fgGetNode( "/instrumentation/comm[1]/frequencies/standby-mhz", true ); + static SGPropertyNode *nav1_serviceable + = fgGetNode( "/instrumentation/nav[0]/serviceable", true ); + static SGPropertyNode *nav1_freq + = fgGetNode( "/instrumentation/nav[0]/frequencies/selected-mhz", true ); + static SGPropertyNode *nav1_stby_freq + = fgGetNode( "/instrumentation/nav[0]/frequencies/standby-mhz", true ); -///////////////////////////////////////////////////////////////////// -// Update the radio display -///////////////////////////////////////////////////////////////////// + static SGPropertyNode *nav2_serviceable + = fgGetNode( "/instrumentation/nav[1]/serviceable", true ); + static SGPropertyNode *nav2_freq + = fgGetNode( "/instrumentation/nav[1]/frequencies/selected-mhz", true ); + static SGPropertyNode *nav2_stby_freq + = fgGetNode( "/instrumentation/nav[1]/frequencies/standby-mhz", true ); + + static SGPropertyNode *adf_serviceable + = fgGetNode( "/instrumentation/adf/serviceable", true ); + static SGPropertyNode *adf_freq + = fgGetNode( "/instrumentation/kr-87/outputs/selected-khz", true ); + static SGPropertyNode *adf_stby_freq + = fgGetNode( "/instrumentation/kr-87/outputs/standby-khz", true ); + static SGPropertyNode *adf_stby_mode + = fgGetNode( "/instrumentation/kr-87/modes/stby", true ); + static SGPropertyNode *adf_timer_mode + = fgGetNode( "/instrumentation/kr-87/modes/timer", true ); + // static SGPropertyNode *adf_count_mode + // = fgGetNode( "/instrumentation/kr-87/modes/count", true ); + static SGPropertyNode *adf_flight_timer + = fgGetNode( "/instrumentation/kr-87/outputs/flight-timer", true ); + static SGPropertyNode *adf_elapsed_timer + = fgGetNode( "/instrumentation/kr-87/outputs/elapsed-timer", true ); -bool FGATC610x::do_radio_display() { + static SGPropertyNode *xpdr_serviceable + = fgGetNode( "/instrumentation/kt-70/inputs/serviceable", true ); + static SGPropertyNode *xpdr_func_knob + = fgGetNode( "/instrumentation/kt-70/inputs/func-knob", true ); + static SGPropertyNode *xpdr_flight_level + = fgGetNode( "/instrumentation/kt-70/outputs/flight-level", true ); + static SGPropertyNode *xpdr_id_code + = fgGetNode( "/instrumentation/kt-70/outputs/id-code", true ); char digits[10]; int i; @@ -881,7 +851,7 @@ bool FGATC610x::do_radio_display() { radio_display_data[40] = 0xff; } - ATC610xSetRadios( radios_fd, radio_display_data ); + ATCSetRadios( radio_display_fd, radio_display_data ); return true; } @@ -891,7 +861,11 @@ bool FGATC610x::do_radio_display() { // Drive the stepper motors ///////////////////////////////////////////////////////////////////// -bool FGATC610x::do_steppers() { +bool FGATCOutput::do_steppers() { + SGPropertyNode *mag_compass + = fgGetNode( "/instrumentation/magnetic-compass/indicated-heading-deg", + true ); + float diff = mag_compass->getFloatValue() - compass_position; while ( diff < -180.0 ) { diff += 360.0; } while ( diff > 180.0 ) { diff -= 360.0; } @@ -913,54 +887,64 @@ bool FGATC610x::do_steppers() { // sync compass_position with hardware position compass_position += (float)steps / 4.0; - ATC610xSetStepper( stepper_fd, ATC_COMPASS_CH, cmd ); + ATCSetStepper( stepper_fd, ATC_COMPASS_CH, cmd ); } return true; } -bool FGATC610x::process() { - - // Lock the hardware, skip if it's not ready yet - if ( ATC610xLock( lock_fd ) > 0 ) { +// process the hardware outputs. This code assumes the calling layer +// will lock the hardware. +bool FGATCOutput::process() { + if ( !is_open ) { + SG_LOG( SG_IO, SG_ALERT, "This board has not been opened for output! " + << board ); + return false; + } - // process the ATC inputs - if ( input0 != NULL ) { - input0->process(); - } - if ( input1 != NULL ) { - input1->process(); - } + do_lamps(); + do_radio_display(); + do_steppers(); + + return true; +} - // run our custom nasal script. This is a layer above the raw - // hardware inputs. It handles situations where there isn't a - // direct 1-1 linear mapping between ATC functionality and FG - // functionality, and handles situations where FG expects more - // functionality from the interface than the ATC hardware can - // directly provide. - - FGNasalSys *n = (FGNasalSys*)globals->get_subsystem("nasal"); - bool result = n->parseAndRun( "atcsim.do_hardware()" ); - if ( !result ) { - SG_LOG( SG_GENERAL, SG_ALERT, - "do_atcflightsim_hardware() failed!" ); - } - do_lights(); - do_radio_display(); - do_steppers(); - - ATC610xRelease( lock_fd ); +bool FGATCOutput::close() { - return true; - } else { - return false; +#if defined( unix ) || defined( __CYGWIN__ ) + + int result; + + result = ::close( lamps_fd ); + if ( result == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error closing %s", lamps_file ); + perror( msg ); + exit( -1 ); } -} + result = ::close( radio_display_fd ); + if ( result == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error closing %s", radio_display_file ); + perror( msg ); + exit( -1 ); + } -bool FGATC610x::close() { + result = ::close( stepper_fd ); + if ( result == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error closing %s", stepper_file ); + perror( msg ); + exit( -1 ); + } + +#endif return true; } diff --git a/src/Network/ATC-Outputs.hxx b/src/Network/ATC-Outputs.hxx new file mode 100644 index 000000000..ee43d136c --- /dev/null +++ b/src/Network/ATC-Outputs.hxx @@ -0,0 +1,90 @@ +// ATC-Outputs.hxx -- Translate FGFS properties into ATC hardware outputs +// +// Written by Curtis Olson, started November 2004. +// +// Copyright (C) 2004 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _FG_ATC_OUTPUTS_HXX +#define _FG_ATC_OUTPUTS_HXX + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include
+ +#define ATC_RADIO_DISPLAY_BYTES 48 +#define ATC_COMPASS_CH 5 +#define ATC_STEPPER_HOME 0xC0 + + +class FGATCOutput { + + int is_open; + + int board; + SGPath config; + + int lock_fd; + int lamps_fd; + int radio_display_fd; + int stepper_fd; + + char lamps_file[256]; + char radio_display_file[256]; + char stepper_file[256]; + + unsigned char radio_display_data[ATC_RADIO_DISPLAY_BYTES]; + + SGPropertyNode *lamps_out_node; + SGPropertyNode *radio_display_node; + SGPropertyNode *steppers_node; + + void init_config(); + bool do_lamps(); + bool do_radio_display(); + bool do_steppers(); + + // hardwired stepper motor code + float compass_position; + +public: + + // Constructor: The _board parameter specifies which board to + // reference. Possible values are 0 or 1. The _config_file + // parameter specifies the location of the output config file (xml) + FGATCOutput( const int _board, const SGPath &_config_file ); + + // Destructor + ~FGATCOutput() { } + + // need to pass in atc hardware lock_fd so that the radios and + // lamps can be blanked and so that the compass can be homed. + bool open( int lock_fd ); + + // process the hardware outputs. This code assumes the calling + // layer will lock the hardware. + bool process(); + + bool close(); +}; + + +#endif // _FG_ATC_OUTPUTS_HXX diff --git a/src/Network/Makefile.am b/src/Network/Makefile.am index d4fa7dc7c..7c90fe0d2 100644 --- a/src/Network/Makefile.am +++ b/src/Network/Makefile.am @@ -17,8 +17,9 @@ endif libNetwork_a_SOURCES = \ protocol.cxx protocol.hxx \ + ATC-Main.cxx ATC-Main.hxx \ ATC-Inputs.cxx ATC-Inputs.hxx \ - atc610x.cxx atc610x.hxx \ + ATC-Outputs.cxx ATC-Outputs.hxx \ atlas.cxx atlas.hxx \ garmin.cxx garmin.hxx \ httpd.cxx httpd.hxx \ diff --git a/src/Network/atc610x.hxx b/src/Network/atc610x.hxx deleted file mode 100644 index 98c3fcd03..000000000 --- a/src/Network/atc610x.hxx +++ /dev/null @@ -1,185 +0,0 @@ -// atc610x.hxx -- FGFS interface to ATC 610x hardware -// -// Written by Curtis Olson, started January 2002. -// -// Copyright (C) 2002 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// -// $Id$ - - -#ifndef _FG_ATC610X_HXX -#define _FG_ATC610X_HXX - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include
- -#include "protocol.hxx" - -#include "ATC-Inputs.hxx" - - -#define ATC_COMPASS_CH 5 -#define ATC_STEPPER_HOME 0xC0 -#define ATC_RADIO_DISPLAY_BYTES 48 - - -class FGATC610x : public FGProtocol { - - FGATCInput *input0; // board0 input interface class - FGATCInput *input1; // board1 input interface class - - SGPath input0_path; - SGPath input1_path; - SGPath output0_path; - SGPath output1_path; - - int board; - - int lock_fd; - int lamps_fd; - int radios_fd; - int stepper_fd; - - char lock_file[256]; - char lamps_file[256]; - char radios_file[256]; - char stepper_file[256]; - - unsigned char radio_display_data[ATC_RADIO_DISPLAY_BYTES]; - unsigned char radio_switch_data[ATC_RADIO_SWITCH_BYTES]; - - float compass_position; - - // Electrical system state - SGPropertyNode *adf_bus_power, *dme_bus_power, *xpdr_bus_power; - SGPropertyNode *navcom1_bus_power, *navcom2_bus_power; - - // Property tree variables - SGPropertyNode *mag_compass; - SGPropertyNode *dme_min, *dme_kt, *dme_nm; - SGPropertyNode *dme_in_range; - SGPropertyNode *navcom1_power_btn, *navcom2_power_btn; - SGPropertyNode *com1_freq, *com1_stby_freq; - SGPropertyNode *com2_freq, *com2_stby_freq; - SGPropertyNode *nav1_freq, *nav1_stby_freq, *nav1_obs; - SGPropertyNode *nav2_freq, *nav2_stby_freq, *nav2_obs; - SGPropertyNode *adf_adf_btn, *adf_bfo_btn; - SGPropertyNode *adf_power_btn, *adf_vol; - SGPropertyNode *adf_freq, *adf_stby_freq; - SGPropertyNode *adf_stby_mode, *adf_timer_mode; - SGPropertyNode *adf_count_mode, *adf_flight_timer, *adf_elapsed_timer; - SGPropertyNode *adf_ant_ann, *adf_adf_ann, *adf_bfo_ann, *adf_frq_ann; - SGPropertyNode *adf_flt_ann, *adf_et_ann, *adf_hdg, *hdg_bug; - SGPropertyNode *inner, *middle, *outer; - SGPropertyNode *xpdr_ident_btn; - SGPropertyNode *xpdr_digit1, *xpdr_digit2, *xpdr_digit3, *xpdr_digit4; - SGPropertyNode *xpdr_func_knob, *xpdr_id_code, *xpdr_flight_level; - SGPropertyNode *xpdr_fl_ann, *xpdr_alt_ann, *xpdr_gnd_ann, *xpdr_on_ann; - SGPropertyNode *xpdr_sby_ann, *xpdr_reply_ann; - SGPropertyNode *ati_bird, *alt_press; - - // Faults - SGPropertyNode *comm1_serviceable, *comm2_serviceable; - SGPropertyNode *nav1_serviceable, *nav2_serviceable; - SGPropertyNode *adf_serviceable, *xpdr_serviceable, *dme_serviceable; - - // Configuration values - SGPropertyNode *elevator_center, *elevator_min, *elevator_max; - SGPropertyNode *ailerons_center, *ailerons_min, *ailerons_max; - SGPropertyNode *rudder_center, *rudder_min, *rudder_max; - SGPropertyNode *brake_left_min, *brake_left_max; - SGPropertyNode *brake_right_min, *brake_right_max; - SGPropertyNode *throttle_min, *throttle_max; - SGPropertyNode *mixture_min, *mixture_max; - SGPropertyNode *trim_center, *trim_min, *trim_max; - SGPropertyNode *nav1vol_min, *nav1vol_max; - SGPropertyNode *nav2vol_min, *nav2vol_max; - - // raw switch positions - SGPropertyNode *dme_selector; - SGPropertyNode *ignore_flight_controls; - - int dme_switch; - - bool do_lights(); - bool do_radio_display(); - bool do_steppers(); - - // convenience - inline bool adf_has_power() const { - return (adf_bus_power->getDoubleValue() > 1.0) - && adf_power_btn->getBoolValue(); - } - inline bool dme_has_power() const { - return (dme_bus_power->getDoubleValue() > 1.0) - && dme_switch; - } - inline bool navcom1_has_power() const { - return (navcom1_bus_power->getDoubleValue() > 1.0) - && navcom1_power_btn->getBoolValue(); - } - inline bool navcom2_has_power() const { - return (navcom2_bus_power->getDoubleValue() > 1.0) - && navcom2_power_btn->getBoolValue(); - } - inline bool xpdr_has_power() const { - return (xpdr_bus_power->getDoubleValue() > 1.0) - && (xpdr_func_knob->getIntValue() > 0); - } - -public: - - FGATC610x() : - input0(NULL), - input1(NULL), - input0_path(""), - input1_path(""), - output0_path(""), - output1_path("") - { } - - ~FGATC610x() { - delete input0; - delete input1; - } - - // Open and initialize ATC 610x hardware - bool open(); - - void init_config(); - - bool process(); - - bool close(); - - inline void set_path_names( const SGPath &in0, const SGPath &in1, - const SGPath &out0, const SGPath &out1 ) - { - input0_path = in0; - input1_path = in1; - output0_path = out0; - output1_path = out1; - } -}; - - -#endif // _FG_ATC610X_HXX -- 2.39.5