]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/FGFCS.cpp
Make yasim accept the launchbar and hook properties. They are not tied to anything...
[flightgear.git] / src / FDM / JSBSim / FGFCS.cpp
index 5aaf4e30686a5c49cec3b425a7d6d6ed9b095e79..daa900a6827e9c77c20a165376180b663791b17a 100644 (file)
@@ -1,52 +1,44 @@
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
  Module:       FGFCS.cpp
  Author:       Jon Berndt
  Date started: 12/12/98
  Purpose:      Model the flight controls
  Called by:    FDMExec
+
  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
+
  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., 59 Temple
  Place - Suite 330, Boston, MA  02111-1307, USA.
+
  Further information about the GNU General Public License can also be found on
  the world wide web at http://www.gnu.org.
+
 FUNCTIONAL DESCRIPTION
 --------------------------------------------------------------------------------
 This class models the flight controls for a specific airplane
+
 HISTORY
 --------------------------------------------------------------------------------
 12/12/98   JSB   Created
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCS.h"
-#include "FGState.h"
 #include "FGFDMExec.h"
-#include "FGAtmosphere.h"
-#include "FGAircraft.h"
-#include "FGTranslation.h"
-#include "FGRotation.h"
-#include "FGPosition.h"
-#include "FGAuxiliary.h"
-#include "FGOutput.h"
 #include "FGPropertyManager.h"
 
 #include "filtersjb/FGFilter.h"
@@ -82,15 +74,13 @@ FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
   LeftBrake = RightBrake = CenterBrake = 0.0;
   APAttitudeSetPt = APAltitudeSetPt = APHeadingSetPt = APAirspeedSetPt = 0.0;
   DoNormalize=true;
-  
-  eMode = mNone;
 
   bind();
   for (i=0;i<=NForms;i++) {
     DePos[i] = DaLPos[i] = DaRPos[i] = DrPos[i] = 0.0;
     DfPos[i] = DsbPos[i] = DspPos[i] = 0.0;
   }
-    
+
   for (i=0;i<NNorm;i++) { ToNormalize[i]=-1;}
   Debug(0);
 }
@@ -110,13 +100,13 @@ FGFCS::~FGFCS()
   MixturePos.clear();
   PropAdvanceCmd.clear();
   PropAdvance.clear();
-
+  SteerPosDeg.clear();
 
   unsigned int i;
 
   for (i=0;i<APComponents.size();i++) delete APComponents[i];
   for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
-  
+
   Debug(1);
 }
 
@@ -126,26 +116,25 @@ bool FGFCS::Run(void)
 {
   unsigned int i;
 
-  if (!FGModel::Run()) {
-    for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
-    for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
-    for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
-    for (i=0; i<APComponents.size(); i++)  {
-      eMode = mAP;
-      APComponents[i]->Run();
-      eMode = mNone;
-    }
-    for (i=0; i<FCSComponents.size(); i++)  {
-      eMode = mFCS;
-      FCSComponents[i]->Run();
-      eMode = mNone;
-    }
-    if (DoNormalize) Normalize();
+  if (FGModel::Run()) return true; // fast exit if nothing to do
 
-    return false;
-  } else {
-    return true;
+  // Set the default engine commands
+  for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
+  for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
+  for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
+
+  // Set the default steering angle
+  for (i=0; i<SteerPosDeg.size(); i++) {
+    FGLGear* gear = GroundReactions->GetGearUnit(i);
+    SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
   }
+
+  for (i=0; i<APComponents.size(); i++) APComponents[i]->Run(); // cycle AP components
+  for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->Run(); // cycle FCS components
+
+  if (DoNormalize) Normalize();
+
+  return false;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -219,7 +208,7 @@ double FGFCS::GetThrottlePos(int engineNum) const
          << " engines exist, but attempted throttle position setting is for engine "
          << engineNum << endl;
   }
-  return 0.0; 
+  return 0.0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -306,9 +295,11 @@ bool FGFCS::Load(FGConfigFile* AC_cfg)
   }
 
 # ifndef macintosh
-  file = "control/" + fname + ".xml";
+//  file = "control/" + fname + ".xml";
+  file = FDMExec->GetAircraftPath() + "/" + FDMExec->GetModelName() + "/" + fname + ".xml";
 # else
-  file = "control;" + fname + ".xml";
+//  file = "control;" + fname + ".xml";
+  file = FDMExec->GetAircraftPath() + ";" + FDMExec->GetModelName() + ";" + fname + ".xml";
 # endif
 
   if (name.empty()) {
@@ -322,7 +313,7 @@ bool FGFCS::Load(FGConfigFile* AC_cfg)
         return false;
       } else {
         AC_cfg = FCS_cfg; // set local config file object pointer to FCS config
-                               // file object pointer
+                          // file object pointer
       }
     }
   } else {
@@ -331,16 +322,14 @@ bool FGFCS::Load(FGConfigFile* AC_cfg)
 
   if (delimiter == "AUTOPILOT") {
     Components = &APComponents;
-    eMode = mAP;
     Name = "Autopilot: " + name;
   } else if (delimiter == "FLIGHT_CONTROL") {
     Components = &FCSComponents;
-    eMode = mFCS;
     Name = "FCS: " + name;
   } else {
     cerr << endl << "Unknown FCS delimiter" << endl << endl;
   }
-  
+
   if (debug_lvl > 0) cout << "    Control System Name: " << Name << endl;
 
   while ((token = AC_cfg->GetValue()) != string("/" + delimiter)) {
@@ -383,14 +372,14 @@ bool FGFCS::Load(FGConfigFile* AC_cfg)
 
   string nodeName;
   for (i=0; i<Components->size(); i++) {
-    
-    if ( (((*Components)[i])->GetType() == "AEROSURFACE_SCALE" 
-          || ((*Components)[i])->GetType() == "KINEMAT")  
-                    && ((*Components)[i])->GetOutputNode() ) { 
+
+    if ( (((*Components)[i])->GetType() == "AEROSURFACE_SCALE"
+          || ((*Components)[i])->GetType() == "KINEMAT")
+                    && ((*Components)[i])->GetOutputNode() ) {
       nodeName = ((*Components)[i])->GetOutputNode()->GetName();
       if ( nodeName == "elevator-pos-rad" ) {
         ToNormalize[iDe]=i;
-      } else if ( nodeName  == "left-aileron-pos-rad" 
+      } else if ( nodeName  == "left-aileron-pos-rad"
                    || nodeName == "aileron-pos-rad" ) {
         ToNormalize[iDaL]=i;
       } else if ( nodeName == "right-aileron-pos-rad" ) {
@@ -405,49 +394,15 @@ bool FGFCS::Load(FGConfigFile* AC_cfg)
         ToNormalize[iDf]=i;
       }
     }
-  }     
-  
-  if (delimiter == "FLIGHT_CONTROL") bindModel();
+  }
 
-  eMode = mNone;
+  if (delimiter == "FLIGHT_CONTROL") bindModel();
 
   return true;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGFCS::GetComponentOutput(int idx)
-{
-  switch (eMode) {
-  case mFCS:
-    return FCSComponents[idx]->GetOutput();
-  case mAP:
-    return APComponents[idx]->GetOutput();
-  case mNone:
-    cerr << "Unknown FCS mode" << endl;
-    break;
-  }
-  return 0.0;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-string FGFCS::GetComponentName(int idx)
-{
-  switch (eMode) {
-  case mFCS:
-    return FCSComponents[idx]->GetName();
-  case mAP:
-    return APComponents[idx]->GetName();
-  case mNone:
-    cerr << "Unknown FCS mode" << endl;
-    break;
-  }
-  return string("");
-} 
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
 {
   switch (bg) {
@@ -465,7 +420,7 @@ double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGFCS::GetComponentStrings(void)
+string FGFCS::GetComponentStrings(string delimeter)
 {
   unsigned int comp;
   string CompStrings = "";
@@ -473,14 +428,14 @@ string FGFCS::GetComponentStrings(void)
 
   for (comp = 0; comp < FCSComponents.size(); comp++) {
     if (firstime) firstime = false;
-    else          CompStrings += ", ";
+    else          CompStrings += delimeter;
 
     CompStrings += FCSComponents[comp]->GetName();
   }
 
   for (comp = 0; comp < APComponents.size(); comp++)
   {
-    CompStrings += ", ";
+    CompStrings += delimeter;
     CompStrings += APComponents[comp]->GetName();
   }
 
@@ -489,23 +444,23 @@ string FGFCS::GetComponentStrings(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGFCS::GetComponentValues(void)
+string FGFCS::GetComponentValues(string delimeter)
 {
   unsigned int comp;
   string CompValues = "";
-  char buffer[10];
+  char buffer[12];
   bool firstime = true;
 
   for (comp = 0; comp < FCSComponents.size(); comp++) {
     if (firstime) firstime = false;
-    else          CompValues += ", ";
+    else          CompValues += delimeter;
 
     sprintf(buffer, "%9.6f", FCSComponents[comp]->GetOutput());
     CompValues += string(buffer);
   }
 
   for (comp = 0; comp < APComponents.size(); comp++) {
-    sprintf(buffer, ", %9.6f", APComponents[comp]->GetOutput());
+    sprintf(buffer, "%s%9.6f", delimeter.c_str(), APComponents[comp]->GetOutput());
     CompValues += string(buffer);
   }
 
@@ -526,20 +481,27 @@ void FGFCS::AddThrottle(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGFCS::AddGear(void)
+{
+  SteerPosDeg.push_back(0.0);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGFCS::Normalize(void) {
-  
+
   //not all of these are guaranteed to be defined for every model
   //those that are have an index >=0 in the ToNormalize array
   //ToNormalize is filled in Load()
-  
+
   if ( ToNormalize[iDe] > -1 ) {
     DePos[ofNorm] = FCSComponents[ToNormalize[iDe]]->GetOutputPct();
   }
-  
+
   if ( ToNormalize[iDaL] > -1 ) {
     DaLPos[ofNorm] = FCSComponents[ToNormalize[iDaL]]->GetOutputPct();
   }
-  
+
   if ( ToNormalize[iDaR] > -1 ) {
     DaRPos[ofNorm] = FCSComponents[ToNormalize[iDaR]]->GetOutputPct();
   }
@@ -547,19 +509,19 @@ void FGFCS::Normalize(void) {
   if ( ToNormalize[iDr] > -1 ) {
     DrPos[ofNorm] = FCSComponents[ToNormalize[iDr]]->GetOutputPct();
   }
-       
-  if ( ToNormalize[iDsb] > -1 ) { 
+
+  if ( ToNormalize[iDsb] > -1 ) {
     DsbPos[ofNorm] = FCSComponents[ToNormalize[iDsb]]->GetOutputPct();
   }
-  
+
   if ( ToNormalize[iDsp] > -1 ) {
     DspPos[ofNorm] = FCSComponents[ToNormalize[iDsp]]->GetOutputPct();
   }
-  
+
   if ( ToNormalize[iDf] > -1 ) {
     DfPos[ofNorm] = FCSComponents[ToNormalize[iDf]]->GetOutputPct();
   }
-  
+
   DePos[ofMag]  = fabs(DePos[ofRad]);
   DaLPos[ofMag] = fabs(DaLPos[ofRad]);
   DaRPos[ofMag] = fabs(DaRPos[ofRad]);
@@ -567,9 +529,9 @@ void FGFCS::Normalize(void) {
   DsbPos[ofMag] = fabs(DsbPos[ofRad]);
   DspPos[ofMag] = fabs(DspPos[ofRad]);
   DfPos[ofMag]  = fabs(DfPos[ofRad]);
-   
-}  
-    
+
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGFCS::bind(void)
@@ -586,6 +548,10 @@ void FGFCS::bind(void)
                        &FGFCS::GetDrCmd,
                        &FGFCS::SetDrCmd,
                        true);
+  PropertyManager->Tie("fcs/steer-cmd-norm", this,
+                       &FGFCS::GetDsCmd,
+                       &FGFCS::SetDsCmd,
+                       true);
   PropertyManager->Tie("fcs/flap-cmd-norm", this,
                        &FGFCS::GetDfCmd,
                        &FGFCS::SetDfCmd,
@@ -614,7 +580,7 @@ void FGFCS::bind(void)
                        &FGFCS::GetGearCmd,
                        &FGFCS::SetGearCmd,
                        true);
-  
+
   PropertyManager->Tie("fcs/left-aileron-pos-rad", this,ofRad,
                        &FGFCS::GetDaLPos,
                        &FGFCS::SetDaLPos,
@@ -627,7 +593,7 @@ void FGFCS::bind(void)
                        &FGFCS::GetDaLPos,
                        &FGFCS::SetDaLPos,
                        true);
+
   PropertyManager->Tie("fcs/right-aileron-pos-rad", this,ofRad,
                        &FGFCS::GetDaRPos,
                        &FGFCS::SetDaRPos,
@@ -640,20 +606,20 @@ void FGFCS::bind(void)
                        &FGFCS::GetDaRPos,
                        &FGFCS::SetDaRPos,
                        true);
-  
+
   PropertyManager->Tie("fcs/elevator-pos-rad", this, ofRad,
                        &FGFCS::GetDePos,
                        &FGFCS::SetDePos,
                        true );
   PropertyManager->Tie("fcs/elevator-pos-norm", this,ofNorm,
-                       &FGFCS::GetDePos,                       
+                       &FGFCS::GetDePos,
                        &FGFCS::SetDePos,
                        true );
   PropertyManager->Tie("fcs/mag-elevator-pos-rad", this,ofMag,
                        &FGFCS::GetDePos,
                        &FGFCS::SetDePos,
                        true );
-  
+
   PropertyManager->Tie("fcs/rudder-pos-rad", this,ofRad,
                        &FGFCS::GetDrPos,
                        &FGFCS::SetDrPos,
@@ -666,7 +632,7 @@ void FGFCS::bind(void)
                        &FGFCS::GetDrPos,
                        &FGFCS::SetDrPos,
                        true);
-                       
+
   PropertyManager->Tie("fcs/flap-pos-deg", this,ofRad,
                        &FGFCS::GetDfPos,
                        &FGFCS::SetDfPos,
@@ -675,7 +641,7 @@ void FGFCS::bind(void)
                        &FGFCS::GetDfPos,
                        &FGFCS::SetDfPos,
                        true);
-  
+
   PropertyManager->Tie("fcs/speedbrake-pos-rad", this,ofRad,
                        &FGFCS::GetDsbPos,
                        &FGFCS::SetDsbPos,
@@ -688,7 +654,7 @@ void FGFCS::bind(void)
                        &FGFCS::GetDsbPos,
                        &FGFCS::SetDsbPos,
                        true);
-                       
+
   PropertyManager->Tie("fcs/spoiler-pos-rad", this,ofRad,
                        &FGFCS::GetDspPos,
                        &FGFCS::SetDspPos,
@@ -701,7 +667,7 @@ void FGFCS::bind(void)
                        &FGFCS::GetDspPos,
                        &FGFCS::SetDspPos,
                        true);
-                       
+
   PropertyManager->Tie("gear/gear-pos-norm", this,
                        &FGFCS::GetGearPos,
                        &FGFCS::SetGearPos,
@@ -799,46 +765,55 @@ void FGFCS::bindModel(void)
 {
   unsigned i;
   char tmp[80];
-  
-  
+
   for (i=0; i<ThrottleCmd.size(); i++) {
     snprintf(tmp,80,"fcs/throttle-cmd-norm[%u]",i);
     PropertyManager->Tie( tmp,this,i,
                           &FGFCS::GetThrottleCmd,
                           &FGFCS::SetThrottleCmd,
                           true );
-    snprintf(tmp,80,"fcs/throttle-pos-norm[%u]",i);                      
+    snprintf(tmp,80,"fcs/throttle-pos-norm[%u]",i);
     PropertyManager->Tie( tmp,this,i,
                           &FGFCS::GetThrottlePos,
                           &FGFCS::SetThrottlePos,
                           true );
     if ( MixtureCmd.size() > i ) {
-      snprintf(tmp,80,"fcs/mixture-cmd-norm[%u]",i); 
+      snprintf(tmp,80,"fcs/mixture-cmd-norm[%u]",i);
       PropertyManager->Tie( tmp,this,i,
                             &FGFCS::GetMixtureCmd,
                             &FGFCS::SetMixtureCmd,
                             true );
-      snprintf(tmp,80,"fcs/mixture-pos-norm[%u]",i);                    
+      snprintf(tmp,80,"fcs/mixture-pos-norm[%u]",i);
       PropertyManager->Tie( tmp,this,i,
                             &FGFCS::GetMixturePos,
                             &FGFCS::SetMixturePos,
                             true );
     }
     if ( PropAdvanceCmd.size() > i ) {
-      snprintf(tmp,80,"fcs/advance-cmd-norm[%u]",i); 
+      snprintf(tmp,80,"fcs/advance-cmd-norm[%u]",i);
       PropertyManager->Tie( tmp,this,i,
                             &FGFCS::GetPropAdvanceCmd,
                             &FGFCS::SetPropAdvanceCmd,
                             true );
-      snprintf(tmp,80,"fcs/advance-pos-norm[%u]",i);                       
+      snprintf(tmp,80,"fcs/advance-pos-norm[%u]",i);
       PropertyManager->Tie( tmp,this,i,
                             &FGFCS::GetPropAdvance,
                             &FGFCS::SetPropAdvance,
                             true );
     }
   }
-}                            
-                          
+
+  for (i=0; i<SteerPosDeg.size(); i++) {
+    if (GroundReactions->GetGearUnit(i)->GetSteerable()) {
+      snprintf(tmp,80,"fcs/steer-pos-deg[%u]",i);
+      PropertyManager->Tie( tmp, this, i,
+                            &FGFCS::GetSteerPosDeg,
+                            &FGFCS::SetSteerPosDeg,
+                            true );
+    }
+  }
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGFCS::unbind(FGPropertyManager *node)
@@ -849,8 +824,8 @@ void FGFCS::unbind(FGPropertyManager *node)
       unbind( (FGPropertyManager*)node->getChild(i) );
     } else if( node->getChild(i)->isTied() ) {
       node->getChild(i)->untie();
-    } 
-  }        
+    }
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%