]> git.mxchange.org Git - flightgear.git/commitdiff
Merged some of Alex's code changes.
authorcurt <curt>
Thu, 20 Jul 2000 04:16:59 +0000 (04:16 +0000)
committercurt <curt>
Thu, 20 Jul 2000 04:16:59 +0000 (04:16 +0000)
Updates for better windows support in the Joystick module.

src/Cockpit/radiostack.cxx
src/Cockpit/steam.cxx
src/Controls/controls.cxx
src/Controls/controls.hxx
src/FDM/LaRCsim.cxx
src/Joystick/joystick.cxx
src/Main/bfi.cxx
src/Main/bfi.hxx
src/Network/ray.cxx

index 09ddfa404e92d619eaa62b451612fd915733d347..78b177f041aa961d3bdd9c229900e14924b64725 100644 (file)
@@ -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;
index 6eab60f61b317ad7f099b180679829d77e9d3f12..5955cda94e0595d8999b083d209186f732d5b6f4 100644 (file)
@@ -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;
index ff097a4ab89fb79690a67ec210ca8aa3591d6e69..e4f828c1e7f577bcd5a150774b3ef1b794c95372 100644 (file)
@@ -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;
 }
 
 
index 08f840950941050133a43417096d5bc6c5c80ac5..54405b7619e26a415afd2b09b5d51beef2cd48d9 100644 (file)
@@ -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; }
index dc4dbc7b28d1edfb76f7997b007f6128147938be..1305f0972603ceba20763dbe9478bd71d0ebaf86 100644 (file)
@@ -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 );
index 37d7102174c7e213f6e7f1842eda8f648518ad52..b0d49c50226a6372b8f26e957d269f8251cf931f 100644 (file)
 
 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
index aafa5cd1628a5a5af712855b541a43e5af37773e..e46c55c790d47ac99e6a651c79bcdc9abcea682b 100644 (file)
@@ -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).
  */
index d13a99567a4b3e5c607b05251e76300ead4e15ea..867acce49e1570aa484f01606596be05487217b7 100644 (file)
@@ -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);
index 0cb0b05672fac3a1ea43b95addbb2e5cc8633d1d..0173f927579dbb180c28e63097bcb27920ae2a5b 100644 (file)
@@ -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 )