]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/models/FGFCS.cpp
Merge branch 'next' of gitorious.org:fg/flightgear into next
[flightgear.git] / src / FDM / JSBSim / models / FGFCS.cpp
index 8dd5fc8f818ba5e9f176576be660fa1b3c3ff43f..f5bbba07d885103ff29cb796df7993f3df08bd34 100644 (file)
@@ -6,7 +6,7 @@
  Purpose:      Model the flight controls
  Called by:    FDMExec
 
- ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
+ ------------- Copyright (C) 1999  Jon S. Berndt (jon@jsbsim.org) -------------
 
  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free Software
@@ -38,31 +38,34 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCS.h"
-#include <FGFDMExec.h>
-#include <input_output/FGPropertyManager.h>
+#include "FGFDMExec.h"
+#include "FGGroundReactions.h"
+#include "input_output/FGPropertyManager.h"
 #include <fstream>
-
-#include <models/flight_control/FGFilter.h>
-#include <models/flight_control/FGDeadBand.h>
-#include <models/flight_control/FGGain.h>
-#include <models/flight_control/FGPID.h>
-#include <models/flight_control/FGGradient.h>
-#include <models/flight_control/FGSwitch.h>
-#include <models/flight_control/FGSummer.h>
-#include <models/flight_control/FGKinemat.h>
-#include <models/flight_control/FGFCSFunction.h>
-#include <models/flight_control/FGSensor.h>
-#include <models/flight_control/FGActuator.h>
+#include <sstream>
+#include <iomanip>
+
+#include "models/flight_control/FGFilter.h"
+#include "models/flight_control/FGDeadBand.h"
+#include "models/flight_control/FGGain.h"
+#include "models/flight_control/FGPID.h"
+#include "models/flight_control/FGSwitch.h"
+#include "models/flight_control/FGSummer.h"
+#include "models/flight_control/FGKinemat.h"
+#include "models/flight_control/FGFCSFunction.h"
+#include "models/flight_control/FGSensor.h"
+#include "models/flight_control/FGActuator.h"
+#include "models/flight_control/FGAccelerometer.h"
+#include "models/flight_control/FGMagnetometer.h"
+#include "models/flight_control/FGGyro.h"
+
+using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id$";
+static const char *IdSrc = "$Id: FGFCS.cpp,v 1.68 2010/03/18 13:21:24 jberndt Exp $";
 static const char *IdHdr = ID_FCS;
 
-#if defined(WIN32) && !defined(__CYGWIN__)
-#define snprintf _snprintf
-#endif
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -76,6 +79,7 @@ FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
   PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
   GearCmd = GearPos = 1; // default to gear down
   LeftBrake = RightBrake = CenterBrake = 0.0;
+  TailhookPos = WingFoldPos = 0.0; 
 
   bind();
   for (i=0;i<NForms;i++) {
@@ -102,8 +106,6 @@ FGFCS::~FGFCS()
 
   unsigned int i;
 
-  for (i=0;i<sensors.size();i++) delete sensors[i];
-  sensors.clear();
   for (i=0;i<APComponents.size();i++) delete APComponents[i];
   APComponents.clear();
   for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
@@ -111,8 +113,6 @@ FGFCS::~FGFCS()
   for (i=0;i<Systems.size();i++) delete Systems[i];
   Systems.clear();
 
-  for (unsigned int i=0; i<interface_properties.size(); i++) delete interface_properties[i];
-  interface_properties.clear();
 
   Debug(1);
 }
@@ -134,12 +134,52 @@ bool FGFCS::InitModel(void)
 
   DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
   PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
+  TailhookPos = WingFoldPos = 0.0;
 
   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 (unsigned int i=0; i<Systems.size(); i++) {
+    if (Systems[i]->GetType() == "LAG" ||
+        Systems[i]->GetType() == "LEAD_LAG" ||
+        Systems[i]->GetType() == "WASHOUT" ||
+        Systems[i]->GetType() == "SECOND_ORDER_FILTER" ||
+        Systems[i]->GetType() == "INTEGRATOR")
+    {
+      ((FGFilter*)Systems[i])->ResetPastStates();
+    } else if (Systems[i]->GetType() == "PID" ) {
+      ((FGPID*)Systems[i])->ResetPastStates();
+    }
+  }
+
+  for (unsigned int i=0; i<FCSComponents.size(); i++) {
+    if (FCSComponents[i]->GetType() == "LAG" ||
+        FCSComponents[i]->GetType() == "LEAD_LAG" ||
+        FCSComponents[i]->GetType() == "WASHOUT" ||
+        FCSComponents[i]->GetType() == "SECOND_ORDER_FILTER" ||
+        FCSComponents[i]->GetType() == "INTEGRATOR")
+    {
+      ((FGFilter*)FCSComponents[i])->ResetPastStates();
+    } else if (FCSComponents[i]->GetType() == "PID" ) {
+      ((FGPID*)FCSComponents[i])->ResetPastStates();
+    }
+  }
+
+  for (unsigned int i=0; i<APComponents.size(); i++) {
+    if (APComponents[i]->GetType() == "LAG" ||
+        APComponents[i]->GetType() == "LEAD_LAG" ||
+        APComponents[i]->GetType() == "WASHOUT" ||
+        APComponents[i]->GetType() == "SECOND_ORDER_FILTER" ||
+        APComponents[i]->GetType() == "INTEGRATOR")
+    {
+      ((FGFilter*)APComponents[i])->ResetPastStates();
+    } else if (APComponents[i]->GetType() == "PID" ) {
+      ((FGPID*)APComponents[i])->ResetPastStates();
+    }
+  }
+
   return true;
 }
   
@@ -158,6 +198,8 @@ bool FGFCS::Run(void)
   if (FGModel::Run()) return true; // fast exit if nothing to do
   if (FDMExec->Holding()) return false;
 
+  RunPreFunctions();
+
   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];
@@ -169,10 +211,6 @@ bool FGFCS::Run(void)
     SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
   }
 
-  // Cycle through the sensor, systems, autopilot, and flight control components
-  // Execute Sensors
-  for (i=0; i<sensors.size(); i++) sensors[i]->Run();
-
   // Execute Systems in order
   for (i=0; i<Systems.size(); i++) Systems[i]->Run();
 
@@ -182,6 +220,8 @@ bool FGFCS::Run(void)
   // Execute Flight Control System
   for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->Run();
 
+  RunPostFunctions();
+
   return false;
 }
 
@@ -415,7 +455,7 @@ void FGFCS::SetMixturePos(int engineNum, double setting)
 
   if (engineNum < (int)ThrottlePos.size()) {
     if (engineNum < 0) {
-      for (ctr=0;ctr<=MixtureCmd.size();ctr++) MixturePos[ctr] = MixtureCmd[ctr];
+      for (ctr=0;ctr<MixtureCmd.size();ctr++) MixturePos[ctr] = MixtureCmd[ctr];
     } else {
       MixturePos[engineNum] = setting;
     }
@@ -445,7 +485,7 @@ void FGFCS::SetPropAdvance(int engineNum, double setting)
 
   if (engineNum < (int)ThrottlePos.size()) {
     if (engineNum < 0) {
-      for (ctr=0;ctr<=PropAdvanceCmd.size();ctr++) PropAdvance[ctr] = PropAdvanceCmd[ctr];
+      for (ctr=0;ctr<PropAdvanceCmd.size();ctr++) PropAdvance[ctr] = PropAdvanceCmd[ctr];
     } else {
       PropAdvance[engineNum] = setting;
     }
@@ -475,7 +515,7 @@ void FGFCS::SetPropFeather(int engineNum, bool setting)
 
   if (engineNum < (int)ThrottlePos.size()) {
     if (engineNum < 0) {
-      for (ctr=0;ctr<=PropFeatherCmd.size();ctr++) PropFeather[ctr] = PropFeatherCmd[ctr];
+      for (ctr=0;ctr<PropFeatherCmd.size();ctr++) PropFeather[ctr] = PropFeatherCmd[ctr];
     } else {
       PropFeather[engineNum] = setting;
     }
@@ -486,35 +526,34 @@ void FGFCS::SetPropFeather(int engineNum, bool setting)
 
 bool FGFCS::Load(Element* el, SystemType systype)
 {
-  string name, file, fname, interface_property_string, parent_name;
+  string name, file, fname="", interface_property_string, parent_name;
   vector <FGFCSComponent*> *Components;
-  Element *component_element, *property_element, *sensor_element;
+  Element *component_element;
   Element *channel_element;
 
   Components=0;
 
-  string separator = "/";
-#ifdef macintosh
-  separator = ";";
-#endif
-
 // ToDo: The handling of name and file attributes could be improved, here,
 //       considering that a name can be in the external file, as well.
 
   name = el->GetAttributeValue("name");
 
-  if (name.empty()) {
+  if (name.empty() || !el->GetAttributeValue("file").empty()) {
     fname = el->GetAttributeValue("file");
     if (systype == stSystem) {
       file = FindSystemFullPathname(fname);
     } else { 
-    file = FDMExec->GetFullAircraftPath() + separator + fname + ".xml";
+      file = FDMExec->GetFullAircraftPath() + "/" + fname + ".xml";
     }
     if (fname.empty()) {
       cerr << "FCS, Autopilot, or system does not appear to be defined inline nor in a file" << endl;
       return false;
     } else {
       document = LoadXMLDocument(file);
+      if (!document) {
+        cerr << "Error loading file " << file << endl;
+        return false;
+      }
       name = document->GetAttributeValue("name");
     }
   } else {
@@ -533,46 +572,50 @@ bool FGFCS::Load(Element* el, SystemType systype)
   }
   Debug(2);
 
-  // ToDo: How do these get untied?
-  // ToDo: Consider having INPUT and OUTPUT interface properties. Would then
-  //       have to duplicate this block of code after channel read code.
-  //       Input properties could be write only (nah), and output could be read
-  //       only.
-
   if (document->GetName() == "flight_control") bindModel();
 
-  // Interface properties from any autopilot, flight control, or other system are
-  // all stored in the interface properties array.
-
-  property_element = document->FindElement("property");
-  while (property_element) {
-    double value=0.0;
-    if ( ! property_element->GetAttributeValue("value").empty())
-      value = property_element->GetAttributeValueAsNumber("value");
-    interface_properties.push_back(new double(value));
-    interface_property_string = property_element->GetDataLine();
-    PropertyManager->Tie(interface_property_string, interface_properties.back());
-    property_element = document->FindNextElement("property");
-  }
-
-  // Any sensor elements that are outside of a channel (in either the autopilot
-  // or the flight_control, or even any possible "system") are placed into the global
-  // "sensors" array, and are executed prior to any autopilot, flight control, or
-  // system.
-
-  sensor_element = document->FindElement("sensor");
-  while (sensor_element) {
-    try {
-      sensors.push_back(new FGSensor(this, sensor_element));
-    } catch (string s) {
-      cerr << highint << fgred << endl << "  " << s << endl;
-      return false;
+  FGModel::Load(document); // Load interface properties from document
+
+  // After reading interface properties in a file, read properties in the local
+  // flight_control, autopilot, or system element. This allows general-purpose
+  // systems to be defined in a file, with overrides or initial loaded constants
+  // supplied in the relevant element of the aircraft configuration file.
+
+  Element* property_element = 0;
+
+  if (!fname.empty()) {
+    property_element = el->FindElement("property");
+    if (property_element && debug_lvl > 0) cout << endl << "    Overriding properties" << endl << endl;
+    while (property_element) {
+      double value=0.0;
+      if ( ! property_element->GetAttributeValue("value").empty())
+        value = property_element->GetAttributeValueAsNumber("value");
+
+      interface_property_string = property_element->GetDataLine();
+      if (PropertyManager->HasNode(interface_property_string)) {
+        FGPropertyManager* node = PropertyManager->GetNode(interface_property_string);
+        if (debug_lvl > 0)
+          cout << "      " << "Overriding value for property " << interface_property_string
+               << " (old value: " << node->getDoubleValue() << "  new value: " << value << ")" << endl;
+        node->setDoubleValue(value);
+      } else {
+        interface_properties.push_back(new double(value));
+        PropertyManager->Tie(interface_property_string, interface_properties.back());
+        if (debug_lvl > 0)
+          cout << "      " << interface_property_string << " (initial value: " << value << ")" << endl;
+      }
+      
+      property_element = el->FindNextElement("property");
     }
-    sensor_element = document->FindNextElement("sensor");
   }
 
   channel_element = document->FindElement("channel");
   while (channel_element) {
+  
+    if (debug_lvl > 0)
+      cout << endl << highint << fgblue << "    Channel " 
+         << normint << channel_element->GetAttributeValue("name") << reset << endl;
+  
     component_element = channel_element->GetElement();
     while (component_element) {
       try {
@@ -604,6 +647,12 @@ bool FGFCS::Load(Element* el, SystemType systype)
           Components->push_back(new FGActuator(this, component_element));
         } else if (component_element->GetName() == string("sensor")) {
           Components->push_back(new FGSensor(this, component_element));
+        } else if (component_element->GetName() == string("accelerometer")) {
+          Components->push_back(new FGAccelerometer(this, component_element));
+        } else if (component_element->GetName() == string("magnetometer")) {
+          Components->push_back(new FGMagnetometer(this, component_element));
+        } else if (component_element->GetName() == string("gyro")) {
+          Components->push_back(new FGGyro(this, component_element));
         } else {
           cerr << "Unknown FCS component: " << component_element->GetName() << endl;
         }
@@ -641,55 +690,55 @@ double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGFCS::FindSystemFullPathname(string system_filename)
+string FGFCS::FindSystemFullPathname(const string& sysfilename)
 {
   string fullpath, localpath;
+  string system_filename = sysfilename;
   string systemPath = FDMExec->GetSystemsPath();
   string aircraftPath = FDMExec->GetFullAircraftPath();
   ifstream system_file;
 
-  string separator = "/";
-# ifdef macintosh
-  separator = ";";
-# endif
+  fullpath = systemPath + "/";
+  localpath = aircraftPath + "/Systems/";
 
-  fullpath = systemPath + separator;
-  localpath = aircraftPath + separator + "Systems" + separator;
+  if (system_filename.length() <=4 || system_filename.substr(system_filename.length()-4, 4) != ".xml") {
+    system_filename.append(".xml");
+  }
 
-  system_file.open(string(fullpath + system_filename + ".xml").c_str());
+  system_file.open(string(fullpath + system_filename).c_str());
   if ( !system_file.is_open()) {
-    system_file.open(string(localpath + system_filename + ".xml").c_str());
+    system_file.open(string(localpath + system_filename).c_str());
       if ( !system_file.is_open()) {
         cerr << " Could not open system file: " << system_filename << " in path "
              << fullpath << " or " << localpath << endl;
         return string("");
       } else {
-        return string(localpath + system_filename + ".xml");
+        return string(localpath + system_filename);
       }
   }
-  return string(fullpath + system_filename + ".xml");
+  return string(fullpath + system_filename);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-ifstream* FGFCS::FindSystemFile(string system_filename)
+ifstream* FGFCS::FindSystemFile(const string& sysfilename)
 {
   string fullpath, localpath;
+  string system_filename = sysfilename;
   string systemPath = FDMExec->GetSystemsPath();
   string aircraftPath = FDMExec->GetFullAircraftPath();
   ifstream* system_file = new ifstream();
 
-  string separator = "/";
-# ifdef macintosh
-  separator = ";";
-# endif
+  fullpath = systemPath + "/";
+  localpath = aircraftPath + "/Systems/";
 
-  fullpath = systemPath + separator;
-  localpath = aircraftPath + separator + "Systems" + separator;
+  if (system_filename.substr(system_filename.length()-4, 4) != ".xml") {
+    system_filename.append(".xml");
+  }
 
-  system_file->open(string(fullpath + system_filename + ".xml").c_str());
+  system_file->open(string(fullpath + system_filename).c_str());
   if ( !system_file->is_open()) {
-    system_file->open(string(localpath + system_filename + ".xml").c_str());
+    system_file->open(string(localpath + system_filename).c_str());
       if ( !system_file->is_open()) {
         cerr << " Could not open system file: " << system_filename << " in path "
              << fullpath << " or " << localpath << endl;
@@ -700,7 +749,7 @@ ifstream* FGFCS::FindSystemFile(string system_filename)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGFCS::GetComponentStrings(string delimeter)
+string FGFCS::GetComponentStrings(const string& delimiter)
 {
   unsigned int comp;
   string CompStrings = "";
@@ -709,7 +758,7 @@ string FGFCS::GetComponentStrings(string delimeter)
 
   for (unsigned int i=0; i<Systems.size(); i++) {
     if (firstime) firstime = false;
-    else          CompStrings += delimeter;
+    else          CompStrings += delimiter;
 
     CompStrings += Systems[i]->GetName();
     total_count++;
@@ -718,7 +767,7 @@ string FGFCS::GetComponentStrings(string delimeter)
   for (comp = 0; comp < APComponents.size(); comp++)
   {
     if (firstime) firstime = false;
-    else          CompStrings += delimeter;
+    else          CompStrings += delimiter;
 
     CompStrings += APComponents[comp]->GetName();
     total_count++;
@@ -726,7 +775,7 @@ string FGFCS::GetComponentStrings(string delimeter)
 
   for (comp = 0; comp < FCSComponents.size(); comp++) {
     if (firstime) firstime = false;
-    else          CompStrings += delimeter;
+    else          CompStrings += delimiter;
 
     CompStrings += FCSComponents[comp]->GetName();
     total_count++;
@@ -737,43 +786,39 @@ string FGFCS::GetComponentStrings(string delimeter)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-string FGFCS::GetComponentValues(string delimeter)
+string FGFCS::GetComponentValues(const string& delimiter)
 {
+  std::ostringstream buf;
+
   unsigned int comp;
-  string CompValues = "";
-  char buffer[20];
   bool firstime = true;
   int total_count=0;
 
   for (unsigned int i=0; i<Systems.size(); i++) {
     if (firstime) firstime = false;
-    else          CompValues += delimeter;
+    else          buf << delimiter;
 
-    sprintf(buffer, "%9.6f", Systems[i]->GetOutput());
-    CompValues += string(buffer);
+    buf << setprecision(9) << Systems[i]->GetOutput();
     total_count++;
   }
 
   for (comp = 0; comp < APComponents.size(); comp++) {
     if (firstime) firstime = false;
-    else          CompValues += delimeter;
+    else          buf << delimiter;
 
-    sprintf(buffer, "%9.6f", APComponents[comp]->GetOutput());
-    CompValues += string(buffer);
+    buf << setprecision(9) << APComponents[comp]->GetOutput();
     total_count++;
   }
 
   for (comp = 0; comp < FCSComponents.size(); comp++) {
     if (firstime) firstime = false;
-    else          CompValues += delimeter;
+    else          buf << delimiter;
 
-    sprintf(buffer, "%9.6f", FCSComponents[comp]->GetOutput());
-    CompValues += string(buffer);
+    buf << setprecision(9) << FCSComponents[comp]->GetOutput();
     total_count++;
   }
 
-  CompValues += "\0";
-  return CompValues;
+  return buf.str();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -861,40 +906,42 @@ void FGFCS::bind(void)
   PropertyManager->Tie("fcs/right-brake-cmd-norm", this, &FGFCS::GetRBrake, &FGFCS::SetRBrake);
   PropertyManager->Tie("fcs/center-brake-cmd-norm", this, &FGFCS::GetCBrake, &FGFCS::SetCBrake);
   PropertyManager->Tie("fcs/steer-cmd-norm", this, &FGFCS::GetDsCmd, &FGFCS::SetDsCmd);
+
+  PropertyManager->Tie("gear/tailhook-pos-norm", this, &FGFCS::GetTailhookPos, &FGFCS::SetTailhookPos);
+  PropertyManager->Tie("fcs/wing-fold-pos-norm", this, &FGFCS::GetWingFoldPos, &FGFCS::SetWingFoldPos);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Technically, this function should probably bind propulsion type specific controls
 // rather than mixture and prop-advance.
-//
 
 void FGFCS::bindThrottle(unsigned int num)
 {
-  char tmp[80];
+  string tmp;
 
-  snprintf(tmp, 80, "fcs/throttle-cmd-norm[%u]",num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetThrottleCmd,
+  tmp = CreateIndexedPropertyName("fcs/throttle-cmd-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottleCmd,
                                         &FGFCS::SetThrottleCmd);
-  snprintf(tmp, 80, "fcs/throttle-pos-norm[%u]",num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetThrottlePos,
+  tmp = CreateIndexedPropertyName("fcs/throttle-pos-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottlePos,
                                         &FGFCS::SetThrottlePos);
-  snprintf(tmp, 80, "fcs/mixture-cmd-norm[%u]",num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetMixtureCmd,
+  tmp = CreateIndexedPropertyName("fcs/mixture-cmd-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixtureCmd,
                                         &FGFCS::SetMixtureCmd);
-  snprintf(tmp, 80, "fcs/mixture-pos-norm[%u]",num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetMixturePos,
+  tmp = CreateIndexedPropertyName("fcs/mixture-pos-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixturePos,
                                         &FGFCS::SetMixturePos);
-  snprintf(tmp, 80, "fcs/advance-cmd-norm[%u]",num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetPropAdvanceCmd,
+  tmp = CreateIndexedPropertyName("fcs/advance-cmd-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvanceCmd,
                                         &FGFCS::SetPropAdvanceCmd);
-  snprintf(tmp, 80, "fcs/advance-pos-norm[%u]", num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetPropAdvance,
+  tmp = CreateIndexedPropertyName("fcs/advance-pos-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvance,
                                         &FGFCS::SetPropAdvance);
-  snprintf(tmp, 80, "fcs/feather-cmd-norm[%u]", num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetFeatherCmd,
+  tmp = CreateIndexedPropertyName("fcs/feather-cmd-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetFeatherCmd,
                                         &FGFCS::SetFeatherCmd);
-  snprintf(tmp, 80, "fcs/feather-pos-norm[%u]", num);
-  PropertyManager->Tie( tmp, this, num, &FGFCS::GetPropFeather,
+  tmp = CreateIndexedPropertyName("fcs/feather-pos-norm", num);
+  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropFeather,
                                         &FGFCS::SetPropFeather);
 }
 
@@ -903,12 +950,12 @@ void FGFCS::bindThrottle(unsigned int num)
 void FGFCS::bindModel(void)
 {
   unsigned int i;
-  char tmp[80];
+  string tmp;
 
   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);
+      tmp = CreateIndexedPropertyName("fcs/steer-pos-deg", i);
+      PropertyManager->Tie( tmp.c_str(), this, i, &FGFCS::GetSteerPosDeg, &FGFCS::SetSteerPosDeg);
     }
   }
 }
@@ -938,7 +985,7 @@ void FGFCS::Debug(int from)
 
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 2) { // Loader
-      cout << endl << "  Flight Control (" << Name << ")" << endl;
+      cout << endl << "  " << Name << endl;
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification