From: curt Date: Thu, 20 Jul 2000 04:16:59 +0000 (+0000) Subject: Merged some of Alex's code changes. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=7a2ef1d57c330eb6265487a14a70b9633cf9991f;p=flightgear.git Merged some of Alex's code changes. Updates for better windows support in the Joystick module. --- diff --git a/src/Cockpit/radiostack.cxx b/src/Cockpit/radiostack.cxx index 09ddfa404..78b177f04 100644 --- a/src/Cockpit/radiostack.cxx +++ b/src/Cockpit/radiostack.cxx @@ -103,7 +103,7 @@ void FGRadioStack::update( double lon, double lat, double elev ) { nav1_loclat, nav1_loclon, &az1, &az2, &s ); nav1_heading = az1; - // Alex: nav1_heading = az1 - FGBFI::getMagVar() / RAD_TO_DEG; + // Alex: nav1_heading = - (az1 - FGBFI::getMagVar() / RAD_TO_DEG); // cout << " heading = " << nav1_heading // << " dist = " << nav1_dist << endl; @@ -147,7 +147,7 @@ void FGRadioStack::update( double lon, double lat, double elev ) { nav2_loclat, nav2_loclon, &az1, &az2, &s ); nav2_heading = az1; - // Alex: nav2_heading = az1 - FGBFI::getMagVar() / RAD_TO_DEG; + // Alex: nav2_heading = - (az1 - FGBFI::getMagVar() / RAD_TO_DEG); // cout << " heading = " << nav2_heading // << " dist = " << nav2_dist << endl; diff --git a/src/Cockpit/steam.cxx b/src/Cockpit/steam.cxx index 6eab60f61..5955cda94 100644 --- a/src/Cockpit/steam.cxx +++ b/src/Cockpit/steam.cxx @@ -90,7 +90,7 @@ double FGSteam::get_TC_std () { _CatchUp(); return the_TC_std; } //////////////////////////////////////////////////////////////////////// -int FGSteam::_UpdatesPending = 999; /* Forces filter to reset */ +int FGSteam::_UpdatesPending = 1000000; /* Forces filter to reset */ void FGSteam::update ( int timesteps ) @@ -147,7 +147,7 @@ void FGSteam::_CatchUp() just to be on the safe side. Doing it more than once will waste CPU time but doesn't hurt anything really. */ - if ( _UpdatesPending == 999 ) + if ( _UpdatesPending > 999999 ) { FGFeature::register_int ( "Avionics/NAV1/Localizer", &NAV1_LOC ); FGFeature::register_double ( "Avionics/NAV1/Latitude", &NAV1_Lat ); FGFeature::register_double ( "Avionics/NAV1/Longitude", &NAV1_Lon ); @@ -321,10 +321,8 @@ void FGSteam::_CatchUp() > have it tumble when you exceed the usual pitch or bank limits, > put in those insidious turning errors ... for now anyway. */ - // cout << "Updates pending = " << _UpdatesPending << endl; - if ( _UpdatesPending > 999 ) { + if ( _UpdatesPending > 999999 ) the_DG_err = FGBFI::getMagVar(); - } the_DG_degps = 0.0; /* HACK! */ if (dt<1.0) the_DG_err += dt * the_DG_degps; the_DG_deg = FGBFI::getHeading () - the_DG_err; diff --git a/src/Controls/controls.cxx b/src/Controls/controls.cxx index ff097a4ab..e4f828c1e 100644 --- a/src/Controls/controls.cxx +++ b/src/Controls/controls.cxx @@ -32,7 +32,8 @@ FGControls::FGControls() : aileron( 0.0 ), elevator( 0.0 ), elevator_trim( 1.969572E-03 ), - rudder( 0.0 ) + rudder( 0.0 ), + throttle_idle( true ) { for ( int engine = 0; engine < MAX_ENGINES; engine++ ) { throttle[engine] = 0.0; @@ -46,11 +47,12 @@ FGControls::FGControls() : void FGControls::reset_all() { - controls.set_aileron(0.0); - controls.set_elevator(0.0); - controls.set_elevator_trim(0.0); - controls.set_rudder(0.0); - controls.set_throttle(FGControls::ALL_ENGINES, 0.0); + set_aileron(0.0); + set_elevator(0.0); + set_elevator_trim(0.0); + set_rudder(0.0); + set_throttle(FGControls::ALL_ENGINES, 0.0); + throttle_idle = true; } diff --git a/src/Controls/controls.hxx b/src/Controls/controls.hxx index 08f840950..54405b761 100644 --- a/src/Controls/controls.hxx +++ b/src/Controls/controls.hxx @@ -58,6 +58,7 @@ private: double flaps; double throttle[MAX_ENGINES]; double brake[MAX_WHEELS]; + bool throttle_idle; inline void CLAMP(double *x, double min, double max ) { if ( *x < min ) { *x = min; } diff --git a/src/FDM/LaRCsim.cxx b/src/FDM/LaRCsim.cxx index dc4dbc7b2..1305f0972 100644 --- a/src/FDM/LaRCsim.cxx +++ b/src/FDM/LaRCsim.cxx @@ -85,10 +85,10 @@ int FGLaRCsim::update( int multiloop ) { } // copy control positions into the LaRCsim structure - Lat_control = controls.get_aileron(); + Lat_control = controls.get_aileron() / current_options.get_speed_up(); Long_control = controls.get_elevator(); Long_trim = controls.get_elevator_trim(); - Rudder_pedal = controls.get_rudder(); + Rudder_pedal = controls.get_rudder() / current_options.get_speed_up(); Flap_handle = 30.0 * controls.get_flaps(); Throttle_pct = controls.get_throttle( 0 ) * 1.0; Brake_pct[0] = controls.get_brake( 1 ); diff --git a/src/Joystick/joystick.cxx b/src/Joystick/joystick.cxx index 37d710217..b0d49c502 100644 --- a/src/Joystick/joystick.cxx +++ b/src/Joystick/joystick.cxx @@ -39,8 +39,12 @@ using std::string; +#ifdef WIN32 +static const int MAX_JOYSTICKS = 2; +#else static const int MAX_JOYSTICKS = 10; -static const int MAX_AXES = 10; +#endif +static const int MAX_AXES = _JS_MAX_AXES; static const int MAX_BUTTONS = 10; @@ -48,16 +52,16 @@ static const int MAX_BUTTONS = 10; * Property names for joysticks and axes. */ static const char * jsNames[] = { - "js0", "js1", "js2", "js3", "js4", - "js5", "js6", "js7", "js8", "js9" + "js0", "js1", "js2", "js3", "js4", + "js5", "js6", "js7", "js8", "js9" }; static const char * axisNames[] = { - "axis0", "axis1", "axis2", "axis3", "axis4", - "axis5", "axis6", "axis7", "axis8", "axis9" + "axis0", "axis1", "axis2", "axis3", "axis4", + "axis5", "axis6", "axis7", "axis8", "axis9" }; static const char * buttonNames[] = { - "button0", "button1", "button2", "button3", "button4", - "button5", "button6", "button7", "button8", "button9" + "button0", "button1", "button2", "button3", "button4", + "button5", "button6", "button7", "button8", "button9" }; @@ -65,13 +69,13 @@ static const char * buttonNames[] = { * Settings for a single axis. */ struct axis { - axis () : value(0), offset(0.0), factor(1.0), - last_value(9999999), tolerance(0.002) {} - SGValue * value; - float offset; - float factor; - float last_value; - float tolerance; + axis () : value(0), offset(0.0), factor(1.0), + last_value(9999999), tolerance(0.002) {} + SGValue * value; + float offset; + float factor; + float last_value; + float tolerance; }; @@ -79,18 +83,18 @@ struct axis { * Settings for a single button. */ struct button { - enum Action { - TOGGLE, - SWITCH, - ADJUST - }; - button () : value(0), step(0.0), action(ADJUST), isRepeatable(true), - lastState(-1) {} - SGValue * value; - float step; - Action action; - bool isRepeatable; - int lastState; + enum Action { + TOGGLE, + SWITCH, + ADJUST + }; + button () : value(0), step(0.0), action(ADJUST), isRepeatable(true), + lastState(-1) {} + SGValue * value; + float step; + Action action; + bool isRepeatable; + int lastState; }; @@ -98,10 +102,16 @@ struct button { * Settings for a single joystick. */ struct joystick { - virtual ~joystick () { delete js; delete axes; } - jsJoystick * js; - axis * axes; - button * buttons; + virtual ~joystick () { + delete js; + delete axes; + delete buttons; + } + int naxes; + int nbuttons; + jsJoystick * js; + axis * axes; + button * buttons; }; @@ -117,91 +127,91 @@ static joystick joysticks[MAX_JOYSTICKS]; static void setupDefaults () { - SGPropertyList &props = current_properties; - - // Default axis 0 to aileron - if (!props.getValue("/input/js0/axis0/control")) { - props.setStringValue("/input/js0/axis0/control", "/controls/aileron"); - props.setFloatValue("/input/js0/axis0/dead-band", 0.1); - } - - // Default axis 1 to elevator - if (!props.getValue("/input/js0/axis1/control")) { - props.setStringValue("/input/js0/axis1/control", "/controls/elevator"); - props.setFloatValue("/input/js0/axis1/dead-band", 0.1); - props.setFloatValue("/input/js0/axis1/factor", -1.0); - } - - // Default axis 2 to throttle - // We need to fiddle with the offset - // and factor to make it work - if (!props.getValue("/input/js0/axis2/control")) { - props.setStringValue("/input/js0/axis2/control", "/controls/throttle"); - props.setFloatValue("/input/js0/axis2/dead-band", 0.0); - props.setFloatValue("/input/js0/axis2/offset", -1.0); - props.setFloatValue("/input/js0/axis2/factor", -0.5); - } - - // Default axis 3 to rudder - if (!props.getValue("/input/js0/axis3/control")) { - props.setStringValue("/input/js0/axis3/control", "/controls/rudder"); - props.setFloatValue("/input/js0/axis3/dead-band", 0.3); - } - - // Default button 0 to all brakes - if (!props.getValue("/input/js0/button0/control")) { - props.setStringValue("/input/js0/button0/action", "switch"); - props.setStringValue("/input/js0/button0/control", "/controls/brake"); - props.setFloatValue("/input/js0/button0/step", 1.0); - props.setFloatValue("/input/js0/button0/repeatable", false); - } - - // Default button 1 to left brake. - if (!props.getValue("/input/js0/button1/control")) { - props.setStringValue("/input/js0/button1/action", "switch"); - props.setStringValue("/input/js0/button1/control", "/controls/left-brake"); - props.setFloatValue("/input/js0/button1/step", 1.0); - props.setFloatValue("/input/js0/button1/repeatable", false); - } - - // Default button 2 to right brake. - if (!props.getValue("/input/js0/button2/control")) { - props.setStringValue("/input/js0/button2/action", "switch"); - props.setStringValue("/input/js0/button2/control", - "/controls/right-brake"); - props.setFloatValue("/input/js0/button2/step", 1.0); - props.setFloatValue("/input/js0/button2/repeatable", false); - } - - // Default buttons 3 and 4 to elevator trim - if (!props.getValue("/input/js0/button3/control")) { - props.setStringValue("/input/js0/button3/action", "adjust"); - props.setStringValue("/input/js0/button3/control", - "/controls/elevator-trim"); - props.setFloatValue("/input/js0/button3/step", 0.001); - props.setBoolValue("/input/js0/button3/repeatable", true); - } - if (!props.getValue("/input/js0/button4/control")) { - props.setStringValue("/input/js0/button4/action", "adjust"); - props.setStringValue("/input/js0/button4/control", - "/controls/elevator-trim"); - props.setFloatValue("/input/js0/button4/step", -0.001); - props.setBoolValue("/input/js0/button4/repeatable", true); - } - - // Default buttons 5 and 6 to flaps - if (!props.getValue("/input/js0/button5/control")) { - props.setStringValue("/input/js0/button5/action", "adjust"); - props.setStringValue("/input/js0/button5/control", "/controls/flaps"); - props.setFloatValue("/input/js0/button5/step", -0.34); - props.setBoolValue("/input/js0/button5/repeatable", false); - } - if (!props.getValue("/input/js0/button6/control")) { - props.setStringValue("/input/js0/button6/action", "adjust"); - props.setStringValue("/input/js0/button6/control", "/controls/flaps"); - props.setFloatValue("/input/js0/button6/step", 0.34); - props.setBoolValue("/input/js0/button6/repeatable", false); - } + SGPropertyList &props = current_properties; + + // Default axis 0 to aileron + if (!props.getValue("/input/js0/axis0/control")) { + props.setStringValue("/input/js0/axis0/control", "/controls/aileron"); + props.setFloatValue("/input/js0/axis0/dead-band", 0.1); + } + + // Default axis 1 to elevator + if (!props.getValue("/input/js0/axis1/control")) { + props.setStringValue("/input/js0/axis1/control", "/controls/elevator"); + props.setFloatValue("/input/js0/axis1/dead-band", 0.1); + props.setFloatValue("/input/js0/axis1/factor", -1.0); + } + + // Default axis 2 to throttle + // We need to fiddle with the offset + // and factor to make it work + if (!props.getValue("/input/js0/axis2/control")) { + props.setStringValue("/input/js0/axis2/control", "/controls/throttle"); + props.setFloatValue("/input/js0/axis2/dead-band", 0.0); + props.setFloatValue("/input/js0/axis2/offset", -1.0); + props.setFloatValue("/input/js0/axis2/factor", -0.5); + } + + // Default axis 3 to rudder + if (!props.getValue("/input/js0/axis3/control")) { + props.setStringValue("/input/js0/axis3/control", "/controls/rudder"); + props.setFloatValue("/input/js0/axis3/dead-band", 0.3); + } + + // Default button 0 to all brakes + if (!props.getValue("/input/js0/button0/control")) { + props.setStringValue("/input/js0/button0/action", "switch"); + props.setStringValue("/input/js0/button0/control", "/controls/brake"); + props.setFloatValue("/input/js0/button0/step", 1.0); + props.setFloatValue("/input/js0/button0/repeatable", false); + } + + // Default button 1 to left brake. + if (!props.getValue("/input/js0/button1/control")) { + props.setStringValue("/input/js0/button1/action", "switch"); + props.setStringValue("/input/js0/button1/control", "/controls/left-brake"); + props.setFloatValue("/input/js0/button1/step", 1.0); + props.setFloatValue("/input/js0/button1/repeatable", false); + } + + // Default button 2 to right brake. + if (!props.getValue("/input/js0/button2/control")) { + props.setStringValue("/input/js0/button2/action", "switch"); + props.setStringValue("/input/js0/button2/control", + "/controls/right-brake"); + props.setFloatValue("/input/js0/button2/step", 1.0); + props.setFloatValue("/input/js0/button2/repeatable", false); + } + + // Default buttons 3 and 4 to elevator trim + if (!props.getValue("/input/js0/button3/control")) { + props.setStringValue("/input/js0/button3/action", "adjust"); + props.setStringValue("/input/js0/button3/control", + "/controls/elevator-trim"); + props.setFloatValue("/input/js0/button3/step", 0.001); + props.setBoolValue("/input/js0/button3/repeatable", true); + } + if (!props.getValue("/input/js0/button4/control")) { + props.setStringValue("/input/js0/button4/action", "adjust"); + props.setStringValue("/input/js0/button4/control", + "/controls/elevator-trim"); + props.setFloatValue("/input/js0/button4/step", -0.001); + props.setBoolValue("/input/js0/button4/repeatable", true); + } + + // Default buttons 5 and 6 to flaps + if (!props.getValue("/input/js0/button5/control")) { + props.setStringValue("/input/js0/button5/action", "adjust"); + props.setStringValue("/input/js0/button5/control", "/controls/flaps"); + props.setFloatValue("/input/js0/button5/step", -0.34); + props.setBoolValue("/input/js0/button5/repeatable", false); + } + if (!props.getValue("/input/js0/button6/control")) { + props.setStringValue("/input/js0/button6/action", "adjust"); + props.setStringValue("/input/js0/button6/control", "/controls/flaps"); + props.setFloatValue("/input/js0/button6/step", 0.34); + props.setBoolValue("/input/js0/button6/repeatable", false); + } } @@ -211,209 +221,220 @@ setupDefaults () int fgJoystickInit() { - bool seen_joystick = false; + bool seen_joystick = false; - FG_LOG(FG_INPUT, FG_INFO, "Initializing joysticks"); + FG_LOG(FG_INPUT, FG_INFO, "Initializing joysticks"); - setupDefaults(); - - for (int i = 0; i < MAX_JOYSTICKS; i++) { - jsJoystick * js = new jsJoystick(i); - joysticks[i].js = js; - if (js->notWorking()) { - FG_LOG(FG_INPUT, FG_INFO, "Joystick " << i << " not found"); - continue; - } + setupDefaults(); - FG_LOG(FG_INPUT, FG_INFO, "Initializing joystick " << i); - seen_joystick = true; - - // Set up range arrays - float minRange[js->getNumAxes()]; - float maxRange[js->getNumAxes()]; - float center[js->getNumAxes()]; - - // Initialize with default values - js->getMinRange(minRange); - js->getMaxRange(maxRange); - js->getCenter(center); - - // Allocate axes and buttons - joysticks[i].axes = new axis[js->getNumAxes()]; - joysticks[i].buttons = new button[MAX_BUTTONS]; - - - // - // Initialize the axes. - // - for (int j = 0; j < min(js->getNumAxes(), MAX_AXES); j++) { - axis &a = joysticks[i].axes[j]; - - string base = "/input/"; - base += jsNames[i]; - base += '/'; - base += axisNames[j]; - FG_LOG(FG_INPUT, FG_INFO, " Axis " << j << ':'); - - // Control property - string name = base; - name += "/control"; - SGValue * value = current_properties.getValue(name); - if (value == 0) { - FG_LOG(FG_INPUT, FG_INFO, " no control defined"); - continue; - } - const string &control = value->getStringValue(); - a.value = current_properties.getValue(control, true); - FG_LOG(FG_INPUT, FG_INFO, " using control " << control); - - // Dead band - name = base; - name += "/dead-band"; - value = current_properties.getValue(name); - if (value != 0) - js->setDeadBand(j, value->getFloatValue()); - FG_LOG(FG_INPUT, FG_INFO, " dead-band is " << js->getDeadBand(j)); - - // Offset - name = base; - name += "/offset"; - value = current_properties.getValue(name); - if (value != 0) - a.offset = value->getFloatValue(); - FG_LOG(FG_INPUT, FG_INFO, " offset is " << a.offset); - - - // Factor - name = base; - name += "/factor"; - value = current_properties.getValue(name); - if (value != 0) - a.factor = value->getFloatValue(); - FG_LOG(FG_INPUT, FG_INFO, " factor is " << a.factor); - - - // Tolerance - name = base; - name += "/tolerance"; - value = current_properties.getValue(name); - if (value != 0) - a.tolerance = value->getFloatValue(); - FG_LOG(FG_INPUT, FG_INFO, " tolerance is " << a.tolerance); - - - // Saturation - name = base; - name += "/saturation"; - value = current_properties.getValue(name); - if (value != 0) - js->setSaturation(j, value->getFloatValue()); - FG_LOG(FG_INPUT, FG_INFO, " saturation is " << js->getSaturation(j)); - - // Minimum range - name = base; - name += "/min-range"; - value = current_properties.getValue(name); - if (value != 0) - minRange[j] = value->getFloatValue(); - FG_LOG(FG_INPUT, FG_INFO, " min-range is " << minRange[j]); - - // Maximum range - name = base; - name += "/max-range"; - value = current_properties.getValue(name); - if (value != 0) - maxRange[j] = value->getFloatValue(); - FG_LOG(FG_INPUT, FG_INFO, " max-range is " << maxRange[j]); - - // Center - name = base; - name += "/center"; - value = current_properties.getValue(name); - if (value != 0) - center[j] = value->getFloatValue(); - FG_LOG(FG_INPUT, FG_INFO, " center is " << center[j]); - } + for (int i = 0; i < MAX_JOYSTICKS; i++) { + jsJoystick * js = new jsJoystick(i); + joysticks[i].js = js; + if (js->notWorking()) { + FG_LOG(FG_INPUT, FG_INFO, "Joystick " << i << " not found"); + continue; + } +#ifdef WIN32 + JOYCAPS jsCaps ; + joyGetDevCaps( i, &jsCaps, sizeof(jsCaps) ); + int nbuttons = jsCaps.wNumButtons; +#else + int nbuttons = MAX_BUTTONS; +#endif + + int naxes = js->getNumAxes(); + joysticks[i].naxes = naxes; + joysticks[i].nbuttons = nbuttons; + + FG_LOG(FG_INPUT, FG_INFO, "Initializing joystick " << i); + seen_joystick = true; + + // Set up range arrays + float minRange[naxes]; + float maxRange[naxes]; + float center[naxes]; + + // Initialize with default values + js->getMinRange(minRange); + js->getMaxRange(maxRange); + js->getCenter(center); + + // Allocate axes and buttons + joysticks[i].axes = new axis[naxes]; + joysticks[i].buttons = new button[nbuttons]; + + + // + // Initialize the axes. + // + for (int j = 0; j < naxes; j++) { + axis &a = joysticks[i].axes[j]; + + string base = "/input/"; + base += jsNames[i]; + base += '/'; + base += axisNames[j]; + FG_LOG(FG_INPUT, FG_INFO, " Axis " << j << ':'); + + // Control property + string name = base; + name += "/control"; + SGValue * value = current_properties.getValue(name); + if (value == 0) { + FG_LOG(FG_INPUT, FG_INFO, " no control defined"); + continue; + } + const string &control = value->getStringValue(); + a.value = current_properties.getValue(control, true); + FG_LOG(FG_INPUT, FG_INFO, " using control " << control); + + // Dead band + name = base; + name += "/dead-band"; + value = current_properties.getValue(name); + if (value != 0) + js->setDeadBand(j, value->getFloatValue()); + FG_LOG(FG_INPUT, FG_INFO, " dead-band is " << js->getDeadBand(j)); + + // Offset + name = base; + name += "/offset"; + value = current_properties.getValue(name); + if (value != 0) + a.offset = value->getFloatValue(); + FG_LOG(FG_INPUT, FG_INFO, " offset is " << a.offset); + + + // Factor + name = base; + name += "/factor"; + value = current_properties.getValue(name); + if (value != 0) + a.factor = value->getFloatValue(); + FG_LOG(FG_INPUT, FG_INFO, " factor is " << a.factor); + + + // Tolerance + name = base; + name += "/tolerance"; + value = current_properties.getValue(name); + if (value != 0) + a.tolerance = value->getFloatValue(); + FG_LOG(FG_INPUT, FG_INFO, " tolerance is " << a.tolerance); + + + // Saturation + name = base; + name += "/saturation"; + value = current_properties.getValue(name); + if (value != 0) + js->setSaturation(j, value->getFloatValue()); + FG_LOG(FG_INPUT, FG_INFO, " saturation is " << js->getSaturation(j)); + + // Minimum range + name = base; + name += "/min-range"; + value = current_properties.getValue(name); + if (value != 0) + minRange[j] = value->getFloatValue(); + FG_LOG(FG_INPUT, FG_INFO, " min-range is " << minRange[j]); + + // Maximum range + name = base; + name += "/max-range"; + value = current_properties.getValue(name); + if (value != 0) + maxRange[j] = value->getFloatValue(); + FG_LOG(FG_INPUT, FG_INFO, " max-range is " << maxRange[j]); + + // Center + name = base; + name += "/center"; + value = current_properties.getValue(name); + if (value != 0) + center[j] = value->getFloatValue(); + FG_LOG(FG_INPUT, FG_INFO, " center is " << center[j]); + } - // - // Initialize the buttons. - // - for (int j = 0; j < MAX_BUTTONS; j++) { - button &b = joysticks[i].buttons[j]; + // + // Initialize the buttons. + // + for (int j = 0; j < nbuttons; j++) { + button &b = joysticks[i].buttons[j]; - string base = "/input/"; - base += jsNames[i]; - base += '/'; - base += buttonNames[j]; - FG_LOG(FG_INPUT, FG_INFO, " Button " << j << ':'); - - // Control property - string name = base; - name += "/control"; - cout << "Trying name " << name << endl; - SGValue * value = current_properties.getValue(name); - if (value == 0) { - FG_LOG(FG_INPUT, FG_INFO, " no control defined"); - continue; - } - const string &control = value->getStringValue(); - b.value = current_properties.getValue(control, true); - FG_LOG(FG_INPUT, FG_INFO, " using control " << control); - - // Step - name = base; - name += "/step"; - value = current_properties.getValue(name); - if (value != 0) - b.step = value->getFloatValue(); - FG_LOG(FG_INPUT, FG_INFO, " step is " << b.step); - - // Type - name = base; - name += "/action"; - value = current_properties.getValue(name); - string action = "adjust"; - if (value != 0) - action = value->getStringValue(); - if (action == "toggle") { - b.action = button::TOGGLE; - b.isRepeatable = false; - } else if (action == "switch") { - b.action = button::SWITCH; - b.isRepeatable = false; - } else if (action == "adjust") { - b.action = button::ADJUST; - b.isRepeatable = true; - } else { - FG_LOG(FG_INPUT, FG_ALERT, " unknown action " << action); - action = "adjust"; - b.action = button::ADJUST; - b.isRepeatable = true; - } - FG_LOG(FG_INPUT, FG_INFO, " action is " << action); - - // Repeatability. - name = base; - name += "/repeatable"; - value = current_properties.getValue(name); - if (value != 0) - b.isRepeatable = value->getBoolValue(); - FG_LOG(FG_INPUT, FG_INFO, (b.isRepeatable ? - " repeatable" : " not repeatable")); - } + string base = "/input/"; + base += jsNames[i]; + base += '/'; + base += buttonNames[j]; + FG_LOG(FG_INPUT, FG_INFO, " Button " << j << ':'); + + // Control property + string name = base; + name += "/control"; + cout << "Trying name " << name << endl; + SGValue * value = current_properties.getValue(name); + if (value == 0) { + FG_LOG(FG_INPUT, FG_INFO, " no control defined"); + continue; + } + const string &control = value->getStringValue(); + b.value = current_properties.getValue(control, true); + FG_LOG(FG_INPUT, FG_INFO, " using control " << control); + + // Step + name = base; + name += "/step"; + value = current_properties.getValue(name); + if (value != 0) + b.step = value->getFloatValue(); + FG_LOG(FG_INPUT, FG_INFO, " step is " << b.step); + + // Type + name = base; + name += "/action"; + value = current_properties.getValue(name); + string action = "adjust"; + if (value != 0) + action = value->getStringValue(); + if (action == "toggle") { + b.action = button::TOGGLE; + b.isRepeatable = false; + } else if (action == "switch") { + b.action = button::SWITCH; + b.isRepeatable = false; + } else if (action == "adjust") { + b.action = button::ADJUST; + b.isRepeatable = true; + } else { + FG_LOG(FG_INPUT, FG_ALERT, " unknown action " << action); + action = "adjust"; + b.action = button::ADJUST; + b.isRepeatable = true; + } + FG_LOG(FG_INPUT, FG_INFO, " action is " << action); + + // Repeatability. + name = base; + name += "/repeatable"; + value = current_properties.getValue(name); + if (value != 0) + b.isRepeatable = value->getBoolValue(); + FG_LOG(FG_INPUT, FG_INFO, (b.isRepeatable ? + " repeatable" : " not repeatable")); + } - js->setMinRange(minRange); - js->setMaxRange(maxRange); - js->setCenter(center); - } + js->setMinRange(minRange); + js->setMaxRange(maxRange); + js->setCenter(center); + } - if (seen_joystick) - FG_LOG(FG_INPUT, FG_INFO, "Done initializing joysticks"); - else - FG_LOG(FG_INPUT, FG_ALERT, "No joysticks detected"); + if (seen_joystick) + FG_LOG(FG_INPUT, FG_INFO, "Done initializing joysticks"); + else + FG_LOG(FG_INPUT, FG_ALERT, "No joysticks detected"); - return seen_joystick; + return seen_joystick; } @@ -423,112 +444,112 @@ fgJoystickInit() int fgJoystickRead() { - int buttons; + int buttons; - for (int i = 0; i < MAX_JOYSTICKS; i++) { - jsJoystick * js = joysticks[i].js; - float axis_values[js->getNumAxes()]; - if (js->notWorking()) { - continue; - } + for (int i = 0; i < MAX_JOYSTICKS; i++) { + jsJoystick * js = joysticks[i].js; + float axis_values[joysticks[i].naxes]; + if (js->notWorking()) { + continue; + } - js->read(&buttons, axis_values); - - // - // Axes - // - for (int j = 0; j < min(MAX_AXES, js->getNumAxes()); j++) { - bool flag = true; - axis &a = joysticks[i].axes[j]; - - // If the axis hasn't changed, don't - // force the value. - if (fabs(axis_values[j] - a.last_value) <= a.tolerance) - continue; - else - a.last_value = axis_values[j]; - - if (a.value) - flag = a.value->setDoubleValue((axis_values[j] + a.offset) * - a.factor); - if (!flag) - FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick " - << i << ", axis " << j); - } + js->read(&buttons, axis_values); - // - // Buttons - // - for (int j = 0; j < MAX_BUTTONS; j++) { - bool flag; - button &b = joysticks[i].buttons[j]; - if (b.value == 0) - continue; - - // Button is on. - if ((buttons & (1 << j)) > 0) { - // Repeating? - if (b.lastState == 1 && !b.isRepeatable) - continue; - - switch (b.action) { - case button::TOGGLE: - if (b.step != 0.0) { - if (b.value->getDoubleValue() == 0.0) - flag = b.value->setDoubleValue(b.step); - else - flag = b.value->setDoubleValue(0.0); - } else { - if (b.value->getBoolValue()) - flag = b.value->setBoolValue(false); + // + // Axes + // + for (int j = 0; j < joysticks[i].naxes; j++) { + bool flag = true; + axis &a = joysticks[i].axes[j]; + + // If the axis hasn't changed, don't + // force the value. + if (fabs(axis_values[j] - a.last_value) <= a.tolerance) + continue; else - flag = b.value->setBoolValue(true); - } - break; - case button::SWITCH: - flag = b.value->setDoubleValue(b.step); - break; - case button::ADJUST: - if (!b.value->setDoubleValue(b.value->getDoubleValue() + b.step)) - FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick " - << i << ", axis " << j); - break; - default: - flag = false; - break; - } - b.lastState = 1; - - // Button is off - } else { - // Repeating? - if (b.lastState == 0 && !b.isRepeatable) - continue; - - switch (b.action) { - case button::TOGGLE: - // no op - break; - case button::SWITCH: - flag = b.value->setDoubleValue(0.0); - break; - case button::ADJUST: - // no op - break; - default: - flag = false; - break; + a.last_value = axis_values[j]; + + if (a.value) + flag = a.value->setDoubleValue((axis_values[j] + a.offset) * + a.factor); + if (!flag) + FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick " + << i << ", axis " << j); } - b.lastState = 0; - } - if (!flag) - FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for " - << jsNames[i] << ' ' << buttonNames[j]); + // + // Buttons + // + for (int j = 0; j < joysticks[i].nbuttons; j++) { + bool flag; + button &b = joysticks[i].buttons[j]; + if (b.value == 0) + continue; + + // Button is on. + if ((buttons & (1 << j)) > 0) { + // Repeating? + if (b.lastState == 1 && !b.isRepeatable) + continue; + + switch (b.action) { + case button::TOGGLE: + if (b.step != 0.0) { + if (b.value->getDoubleValue() == 0.0) + flag = b.value->setDoubleValue(b.step); + else + flag = b.value->setDoubleValue(0.0); + } else { + if (b.value->getBoolValue()) + flag = b.value->setBoolValue(false); + else + flag = b.value->setBoolValue(true); + } + break; + case button::SWITCH: + flag = b.value->setDoubleValue(b.step); + break; + case button::ADJUST: + if (!b.value->setDoubleValue(b.value->getDoubleValue() + b.step)) + FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick " + << i << ", axis " << j); + break; + default: + flag = false; + break; + } + b.lastState = 1; + + // Button is off + } else { + // Repeating? + if (b.lastState == 0 && !b.isRepeatable) + continue; + + switch (b.action) { + case button::TOGGLE: + // no op + break; + case button::SWITCH: + flag = b.value->setDoubleValue(0.0); + break; + case button::ADJUST: + // no op + break; + default: + flag = false; + break; + } + + b.lastState = 0; + } + if (!flag) + FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for " + << jsNames[i] << ' ' << buttonNames[j]); + } } - } - return true; + return true; } // end of joystick.cxx diff --git a/src/Main/bfi.cxx b/src/Main/bfi.cxx index aafa5cd16..e46c55c79 100644 --- a/src/Main/bfi.cxx +++ b/src/Main/bfi.cxx @@ -139,6 +139,10 @@ FGBFI::init () getThrottle, setThrottle); current_properties.tieDouble("/controls/flaps", getFlaps, setFlaps); + current_properties.tieBool ("/controls/flaps/raise", + 0, setFlapsRaise); + current_properties.tieBool ("/controls/flaps/lower", + 0, setFlapsLower); current_properties.tieDouble("/controls/aileron", getAileron, setAileron); current_properties.tieDouble("/controls/rudder", @@ -779,6 +783,24 @@ FGBFI::setFlaps (double flaps) } +void +FGBFI::setFlapsRaise (bool step) +{ + if (step) + controls.set_flaps(controls.get_flaps() - 0.26); + printf ( "Raise: %i\n", step ); +} + + +void +FGBFI::setFlapsLower (bool step) +{ + if (step) + controls.set_flaps(controls.get_flaps() + 0.26); + printf ( "Lower: %i\n", step ); +} + + /** * Get the aileron, from -1.0 (left) to 1.0 (right). */ diff --git a/src/Main/bfi.hxx b/src/Main/bfi.hxx index d13a99567..867acce49 100644 --- a/src/Main/bfi.hxx +++ b/src/Main/bfi.hxx @@ -116,6 +116,8 @@ public: static void setThrottle (double throttle); static void setFlaps (double flaps); + static void setFlapsRaise (bool step); + static void setFlapsLower (bool step); static void setAileron (double aileron); static void setRudder (double rudder); static void setElevator (double elevator); diff --git a/src/Network/ray.cxx b/src/Network/ray.cxx index 0cb0b0567..0173f9275 100644 --- a/src/Network/ray.cxx +++ b/src/Network/ray.cxx @@ -45,11 +45,14 @@ FGRAY::~FGRAY() { } -// Ray Woodworth's motion chair has between 3 and 5 axes installed. +// Ray Woodworth (949) 262-9118 has a three axis motion chair. +// // It expects +/- 5V signals for full scale. In channel order, axes are: // roll, pitch, yaw, sway, surge, heave // The drivers are capable of generating (in the same order) -// +/- 30deg, 30deg, 15deg, 12in, 12in, 12in +// +/- 30deg, 30deg, 30deg, 12in, 12in, 12in +// The signs of the motion are such that positive volts gives +// head right, head back, feet right, body right, body back, body up // // In this code implementation, the voltage outputs are generated // using a ComputerBoards DDA06/Jr card and the associated Linux driver. @@ -62,7 +65,7 @@ bool FGRAY::gen_message() { // cout << "generating RayWoodworth message" << endl; FGInterface *f = cur_fdm_state; int axis, subaxis; - const double fullscale[6] = { -0.8, -0.8, -0.25, /* radians */ + const double fullscale[6] = { -0.5, -0.5, -0.5, /* radians */ -0.3, -0.3, -0.15 /* meters */ }; /* Figure out how big our timesteps are */ @@ -99,10 +102,12 @@ bool FGRAY::gen_message() { } /* Make sure the angles are reasonable onscale */ - while ( ang_pos < -M_PI ) { + /* We use an asymmetric mapping so that the chair behaves + reasonably when upside down. Otherwise it oscillates. */ + while ( ang_pos < -2*M_PI/3 ) { ang_pos += 2 * M_PI; } - while ( ang_pos > M_PI ) { + while ( ang_pos > 4*M_PI/3 ) { ang_pos -= 2 * M_PI; } @@ -136,7 +141,7 @@ bool FGRAY::gen_message() { ang_pos -= chair_heading; /* Wash out the error at 5 sec timeconstant because a standard rate turn is 3 deg/sec and the chair - can represent 15 degrees full scale. */ + can just about represent 30 degrees full scale. */ chair_heading += ang_pos * dt * 0.2; /* If they turn fast, at 90 deg error subtract 30 deg */ if ( fabs(ang_pos) > M_PI / 2 )