X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2FATC-Inputs.cxx;h=be59770f89fda441e7f2b9bdc8a26da1acfe0afd;hb=b0dcb657e77579ecc79798ff365737095f96f9e2;hp=b43f1e18bd047565317dd74194d451e1a455ef00;hpb=2eeddb8c9f8ec974da57d41f9a6e12200497005f;p=flightgear.git diff --git a/src/Network/ATC-Inputs.cxx b/src/Network/ATC-Inputs.cxx index b43f1e18b..be59770f8 100644 --- a/src/Network/ATC-Inputs.cxx +++ b/src/Network/ATC-Inputs.cxx @@ -16,7 +16,7 @@ // // 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. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -27,16 +27,31 @@ #include -#include STL_STRING +#if defined( unix ) || defined( __CYGWIN__ ) +# include +# include +# include +# include +# include +# include +#endif + +#include +#include +#include + +#include #include +#include +#include #include
#include "ATC-Inputs.hxx" -SG_USING_STD(string); - +using std::string; +using std::vector; // Constructor: The _board parameter specifies which board to @@ -57,6 +72,7 @@ FGATCInput::FGATCInput( const int _board, const SGPath &_config_file ) : // Read analog inputs static void ATCReadAnalogInputs( int fd, unsigned char *analog_in_bytes ) { +#if defined( unix ) || defined( __CYGWIN__ ) // rewind lseek( fd, 0, SEEK_SET ); @@ -65,11 +81,13 @@ static void ATCReadAnalogInputs( int fd, unsigned char *analog_in_bytes ) { SG_LOG( SG_IO, SG_ALERT, "Read failed" ); exit( -1 ); } +#endif } // Read status of radio switches and knobs static void ATCReadRadios( int fd, unsigned char *switch_data ) { +#if defined( unix ) || defined( __CYGWIN__ ) // rewind lseek( fd, 0, SEEK_SET ); @@ -78,11 +96,13 @@ static void ATCReadRadios( int fd, unsigned char *switch_data ) { SG_LOG( SG_IO, SG_ALERT, "Read failed" ); exit( -1 ); } +#endif } // Read switch inputs static void ATCReadSwitches( int fd, unsigned char *switch_bytes ) { +#if defined( unix ) || defined( __CYGWIN__ ) // rewind lseek( fd, 0, SEEK_SET ); @@ -91,6 +111,7 @@ static void ATCReadSwitches( int fd, unsigned char *switch_bytes ) { SG_LOG( SG_IO, SG_ALERT, "Read failed" ); exit( -1 ); } +#endif } @@ -124,26 +145,21 @@ bool FGATCInput::open() { init_config(); SG_LOG( SG_IO, SG_ALERT, - "Initializing ATC 610x hardware, please wait ..." ); + "Initializing ATC input hardware, please wait ..." ); + + snprintf( analog_in_file, 256, + "/proc/atcflightsim/board%d/analog_in", board ); + snprintf( radios_file, 256, + "/proc/atcflightsim/board%d/radios", board ); + snprintf( switches_file, 256, + "/proc/atcflightsim/board%d/switches", board ); - snprintf( lock_file, 256, "/proc/atc610x/board%d/lock", board ); - snprintf( analog_in_file, 256, "/proc/atc610x/board%d/analog_in", board ); - snprintf( radios_file, 256, "/proc/atc610x/board%d/radios", board ); - snprintf( switches_file, 256, "/proc/atc610x/board%d/switches", 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 ); - } - analog_in_fd = ::open( analog_in_file, O_RDONLY ); if ( analog_in_fd == -1 ) { SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); @@ -171,12 +187,14 @@ bool FGATCInput::open() { exit( -1 ); } +#endif + ///////////////////////////////////////////////////////////////////// // Finished initing hardware ///////////////////////////////////////////////////////////////////// SG_LOG( SG_IO, SG_ALERT, - "Done initializing ATC 610x hardware." ); + "Done initializing ATC input hardware." ); is_open = true; @@ -209,18 +227,21 @@ bool FGATCInput::open() { ///////////////////////////////////////////////////////////////////// // scale a number between min and max (with center defined) to a scale -// from -1.0 to 1.0 -static double scale( int center, int min, int max, int value ) { +// from -1.0 to 1.0. The deadband value is symmetric, so specifying +// '1' will give you a deadband of +/-1 +static double scale( int center, int deadband, int min, int max, int value ) { // cout << center << " " << min << " " << max << " " << value << " "; double result; double range; - if ( value <= center ) { - range = center - min; - result = (value - center) / range; + if ( value <= (center - deadband) ) { + range = (center - deadband) - min; + result = (value - (center - deadband)) / range; + } else if ( value >= (center + deadband) ) { + range = max - (center + deadband); + result = (value - (center + deadband)) / range; } else { - range = max - center; - result = (value - center) / range; + result = 0.0; } if ( result < -1.0 ) result = -1.0; @@ -250,6 +271,18 @@ static double scale( int min, int max, int value ) { } +static double clamp( double min, double max, double value ) { + double result = value; + + if ( result < min ) result = min; + if ( result > max ) result = max; + + // cout << result << endl; + + return result; +} + + static int tony_magic( int raw, int obs[3] ) { int result = 0; @@ -384,10 +417,13 @@ bool FGATCInput::do_analog_in() { string name = ""; string type = ""; string subtype = ""; - vector output_nodes; output_nodes.clear(); + vector output_nodes; int center = -1; int min = 0; int max = 1023; + int deadband = 0; + int hysteresis = 0; + float offset = 0.0; float factor = 1.0; if ( cname == "channel" ) { SGPropertyNode *prop; @@ -422,6 +458,18 @@ bool FGATCInput::do_analog_in() { if ( prop != NULL ) { max = prop->getIntValue(); } + prop = child->getChild( "deadband" ); + if ( prop != NULL ) { + deadband = prop->getIntValue(); + } + prop = child->getChild( "hysteresis" ); + if ( prop != NULL ) { + hysteresis = prop->getIntValue(); + } + prop = child->getChild( "offset" ); + if ( prop != NULL ) { + offset = prop->getFloatValue(); + } prop = child->getChild( "factor" ); if ( prop != NULL ) { factor = prop->getFloatValue(); @@ -442,12 +490,37 @@ bool FGATCInput::do_analog_in() { { // "Cook" the raw value float scaled_value = 0.0f; + + if ( hysteresis > 0 ) { + int last_raw_value = 0; + prop = child->getChild( "last-raw-value", 0, true ); + last_raw_value = prop->getIntValue(); + + if ( abs(raw_value - last_raw_value) < hysteresis ) + { + // not enough movement stay put + raw_value = last_raw_value; + } else { + // update last raw value + prop->setIntValue( raw_value ); + } + } + if ( center >= 0 ) { - scaled_value = scale( center, min, max, raw_value ); + scaled_value = scale( center, deadband, + min, max, raw_value ); } else { scaled_value = scale( min, max, raw_value ); } scaled_value *= factor; + scaled_value += offset; + + // final sanity clamp + if ( center >= 0 ) { + scaled_value = clamp( -1.0, 1.0, scaled_value ); + } else { + scaled_value = clamp( 0.0, 1.0, scaled_value ); + } // update the property tree values for ( j = 0; j < (int)output_nodes.size(); ++j ) { @@ -458,11 +531,20 @@ bool FGATCInput::do_analog_in() { // "Cook" the raw value float scaled_value = 0.0f; if ( center >= 0 ) { - scaled_value = scale( center, min, max, raw_value ); + scaled_value = scale( center, deadband, + min, max, raw_value ); } else { scaled_value = scale( min, max, raw_value ); } scaled_value *= factor; + scaled_value += offset; + + // final sanity clamp + if ( center >= 0 ) { + scaled_value = clamp( -1.0, 1.0, scaled_value ); + } else { + scaled_value = clamp( 0.0, 1.0, scaled_value ); + } // update the property tree values for ( j = 0; j < (int)output_nodes.size(); ++j ) { @@ -537,7 +619,7 @@ bool FGATCInput::do_analog_in() { if ( value > max ) { value = max; } } - prop = child->getChild( "compass-heading" ); + prop = child->getChild( "compass-heading" ); if ( prop != NULL ) { bool compass = prop->getBoolValue(); if ( compass ) { @@ -579,9 +661,13 @@ static void update_switch_matrix( unsigned char switches = switch_data[row]; for( int column = 0; column < ATC_NUM_COLS; ++column ) { - switch_matrix[board][column][row] = switches & 1; - switches = switches >> 1; - } + if ( row < 8 ) { + switch_matrix[board][column][row] = switches & 1; + } else { + switch_matrix[board][row-8][8+column] = switches & 1; + } + switches = switches >> 1; + } } } @@ -602,12 +688,13 @@ bool FGATCInput::do_switches() { string cname = child->getName(); string name = ""; string type = ""; - vector output_nodes; output_nodes.clear(); + vector output_nodes; int row = -1; int col = -1; float factor = 1.0; int filter = -1; float scaled_value = 0.0f; + bool invert = false; // get common options @@ -631,6 +718,10 @@ bool FGATCInput::do_switches() { if ( prop != NULL ) { factor = prop->getFloatValue(); } + prop = child->getChild( "invert" ); + if ( prop != NULL ) { + invert = prop->getBoolValue(); + } prop = child->getChild( "steady-state-filter" ); if ( prop != NULL ) { filter = prop->getIntValue(); @@ -651,6 +742,11 @@ bool FGATCInput::do_switches() { // Fetch the raw value int raw_value = switch_matrix[board][row][col]; + // Invert + if ( invert ) { + raw_value = !raw_value; + } + // Cook the value scaled_value = (float)raw_value * factor; @@ -690,6 +786,42 @@ bool FGATCInput::do_switches() { // Cook the value scaled_value *= factor; + } else if ( cname == "additive-switch" ) { + float additive_value = 0.0f; + float increment = 0.0f; + + SGPropertyNode *pos; + int k = 0; + while ( (pos = child->getChild("position", k++)) != NULL ) { + // read the combo position entries from the property tree + + prop = pos->getChild( "row" ); + if ( prop != NULL ) { + row = prop->getIntValue(); + } + prop = pos->getChild( "col" ); + if ( prop != NULL ) { + col = prop->getIntValue(); + } + prop = pos->getChild( "value" ); + if ( prop != NULL ) { + increment = prop->getFloatValue(); + } + + // Fetch the raw value + int raw_value = switch_matrix[board][row][col]; + // cout << "sm[" << board << "][" << row << "][" << col + // << "] = " << raw_value << endl; + + if ( raw_value ) { + // set scaled_value to the first combo_value + // that matches and jump out of loop. + additive_value += increment; + } + } + + // Cook the value + scaled_value = additive_value * factor; } // handle filter request. The value of the switch must be @@ -759,14 +891,14 @@ bool FGATCInput::do_radio_switches() { if ( cname == "switch" ) { string name = ""; string type = ""; - vector output_nodes; output_nodes.clear(); + vector output_nodes; int byte_num = -1; - int right_shift = -1; + int right_shift = 0; int mask = 0xff; int factor = 1; int offset = 0; + bool invert = false; int scaled_value = 0; - // get common options SGPropertyNode *prop; @@ -805,12 +937,19 @@ bool FGATCInput::do_radio_switches() { if ( prop != NULL ) { offset = prop->getIntValue(); } + prop = child->getChild( "invert" ); + if ( prop != NULL ) { + invert = prop->getBoolValue(); + } // Fetch the raw value int raw_value = (radio_switch_data[byte_num] >> right_shift) & mask; // Cook the value + if ( invert ) { + raw_value = !raw_value; + } scaled_value = raw_value * factor + offset; // update the property tree values @@ -843,17 +982,15 @@ bool FGATCInput::process() { bool FGATCInput::close() { - int result; - result = ::close( lock_fd ); - if ( result == -1 ) { - SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); - char msg[256]; - snprintf( msg, 256, "Error closing %s", lock_file ); - perror( msg ); - exit( -1 ); +#if defined( unix ) || defined( __CYGWIN__ ) + + if ( !is_open ) { + return true; } + int result; + result = ::close( analog_in_fd ); if ( result == -1 ) { SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); @@ -881,5 +1018,7 @@ bool FGATCInput::close() { exit( -1 ); } +#endif + return true; }