package is required.
bool FGCoefficient::Load(FGConfigFile *AC_cfg)
{
int start, end, n;
- string mult,prop;
+ string mult;
if (AC_cfg) {
name = AC_cfg->GetValue("NAME");
method = AC_cfg->GetValue("TYPE");
AC_cfg->GetNextConfigLine();
*AC_cfg >> description;
-
if (method == "EQUATION") type = EQUATION;
else if (method == "TABLE") type = TABLE;
else if (method == "VECTOR") type = VECTOR;
}
*AC_cfg >> multparmsRow;
- prop = State->GetPropertyName( multparmsRow );
- LookupR = PropertyManager->GetNode( prop );
+ LookupR = PropertyManager->GetNode( multparmsRow );
}
if (type == TABLE) {
*AC_cfg >> multparmsCol;
- prop = State->GetPropertyName( multparmsCol );
- LookupC = PropertyManager->GetNode( prop );
+ LookupC = PropertyManager->GetNode( multparmsCol );
}
// Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
// where each non-dimensionalizing parameter for this coefficient is
// separated by a | character
- *AC_cfg >> multparms;
+ string line=AC_cfg->GetCurrentLine();
+ unsigned j=0;
+ char tmp[255];
+ for(unsigned i=0;i<line.length(); i++ ) {
+ if( !isspace(line[i]) ) {
+ tmp[j]=line[i];
+ j++;
+ }
+ }
+ tmp[j]='\0'; multparms=tmp;
+ end = multparms.length();
- end = multparms.length();
n = multparms.find("|");
start = 0;
-
- if (multparms != string("FG_NONE")) {
+ if (multparms != string("none")) {
while (n < end && n >= 0) {
n -= start;
mult = multparms.substr(start,n);
- prop= State->GetPropertyName( mult );
- multipliers.push_back( PropertyManager->GetNode(prop) );
+ multipliers.push_back( resolveSymbol( mult ) );
start += n+1;
n = multparms.find("|",start);
}
- prop=State->GetPropertyName( multparms.substr(start,n) );
mult = multparms.substr(start,n);
- multipliers.push_back( PropertyManager->GetNode(prop) );
+ multipliers.push_back( resolveSymbol( mult ) );
// End of non-dimensionalizing parameter read-in
}
-
+ AC_cfg->GetNextConfigLine();
if (type == VALUE) {
*AC_cfg >> StaticValue;
} else if (type == VECTOR || type == TABLE) {
node->Untie("bias");
node->Untie("gain");
}
-
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGPropertyManager* FGCoefficient::resolveSymbol(string name){
+ FGPropertyManager* tmpn;
+ tmpn = PropertyManager->GetNode(name,false);
+ if( !tmpn ) {
+ cerr << "Coefficient multipliers cannot create properties, check spelling?" << endl;
+ exit(1);
+ }
+ return tmpn;
+}
+
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
FGAuxiliary* Auxiliary;
FGOutput* Output;
FGPropertyManager* PropertyManager;
+
+ FGPropertyManager* resolveSymbol(string name);
virtual void Debug(int from);
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGConfigFile& FGConfigFile::operator>>(eParam& val)
-{
- string::size_type pos, end;
-
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
- if (pos == CurrentLine.npos) pos = CurrentLine.length();
- end = CurrentLine.find_first_of(", ",pos+1);
- if (end == CurrentLine.npos) end = CurrentLine.length();
- string str = CurrentLine.substr(pos, end - pos);
- val = (eParam)atoi(str.c_str());
- CurrentIndex = end+1;
- if (end == pos) {
- GetNextConfigLine();
- *this >> val;
- } else {
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
- }
- return *this;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
FGConfigFile& FGConfigFile::operator>>(string& str)
{
string::size_type pos, end;
@return the next valid line from the config file OR "EOF" if end of file is
reached.*/
string GetNextConfigLine(void);
+
+ string GetCurrentLine(void) { return CurrentLine; }
/** Returns the value of the tag supplied.
@param
FGConfigFile& operator>>(double&);
FGConfigFile& operator>>(int&);
FGConfigFile& operator>>(string&);
- FGConfigFile& operator>>(eParam&);
void ResetLineIndexToZero(void);
private:
vector <FGFCSComponent*> *Components;
FGConfigFile *FCS_cfg;
+ Components=0;
// Determine if the FCS/Autopilot is defined inline in the aircraft configuration
// file or in a separate file. Set up the config file class as appropriate.
if (delimiter == "AUTOPILOT") {
Components = &APComponents;
eMode = mAP;
- Name = "Autopilot:" + name;
+ Name = "Autopilot: " + name;
} else if (delimiter == "FLIGHT_CONTROL") {
Components = &FCSComponents;
eMode = mFCS;
- Name = "FCS:" + name;
+ Name = "FCS: " + name;
} else {
cerr << endl << "Unknown FCS delimiter" << endl << endl;
}
break;
}
return string("");
-}
+}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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,
const double FGJSBBase::in3tom3 = 1.638706E-5;
const double FGJSBBase::Reng = 1716.0;
const double FGJSBBase::SHRatio = 1.40;
-const string FGJSBBase::needed_cfg_version = "1.58";
+const string FGJSBBase::needed_cfg_version = "1.60";
const string FGJSBBase::JSBSim_version = "0.9.2";
queue <FGJSBBase::Message*> FGJSBBase::Messages;
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-enum eParam {
- FG_UNDEF = 0,
- FG_TIME,
- FG_QBAR,
- FG_WINGAREA,
- FG_WINGSPAN,
- FG_CBAR,
- FG_ALPHA,
- FG_ALPHADOT,
- FG_BETA,
- FG_ABETA,
- FG_BETADOT,
- FG_PHI,
- FG_THT,
- FG_PSI,
- FG_PITCHRATE,
- FG_ROLLRATE,
- FG_YAWRATE,
- FG_AEROP,
- FG_AEROQ,
- FG_AEROR,
- FG_CL_SQRD,
- FG_MACH,
- FG_ALTITUDE,
- FG_BI2VEL,
- FG_CI2VEL,
- FG_ELEVATOR_POS,
- FG_AELEVATOR_POS,
- FG_NELEVATOR_POS,
- FG_AILERON_POS,
- FG_AAILERON_POS,
- FG_NAILERON_POS,
- FG_LEFT_AILERON_POS,
- FG_ALEFT_AILERON_POS,
- FG_NLEFT_AILERON_POS,
- FG_RIGHT_AILERON_POS,
- FG_ARIGHT_AILERON_POS,
- FG_NRIGHT_AILERON_POS,
- FG_RUDDER_POS,
- FG_ARUDDER_POS,
- FG_NRUDDER_POS,
- FG_SPDBRAKE_POS,
- FG_NSPDBRAKE_POS,
- FG_SPOILERS_POS,
- FG_NSPOILERS_POS,
- FG_FLAPS_POS,
- FG_NFLAPS_POS,
- FG_ELEVATOR_CMD,
- FG_AILERON_CMD,
- FG_RUDDER_CMD,
- FG_SPDBRAKE_CMD,
- FG_SPOILERS_CMD,
- FG_FLAPS_CMD,
- FG_THROTTLE_CMD,
- FG_THROTTLE_POS,
- FG_MIXTURE_CMD,
- FG_MIXTURE_POS,
- FG_MAGNETO_CMD,
- FG_STARTER_CMD,
- FG_ACTIVE_ENGINE,
- FG_HOVERB,
- FG_PITCH_TRIM_CMD,
- FG_YAW_TRIM_CMD,
- FG_ROLL_TRIM_CMD,
- FG_LEFT_BRAKE_CMD,
- FG_CENTER_BRAKE_CMD,
- FG_RIGHT_BRAKE_CMD,
- FG_SET_LOGGING,
- FG_ALPHAH,
- FG_ALPHAW,
- FG_LBARH, //normalized horizontal tail arm
- FG_LBARV, //normalized vertical tail arm
- FG_HTAILAREA,
- FG_VTAILAREA,
- FG_VBARH, //horizontal tail volume
- FG_VBARV, //vertical tail volume
- FG_GEAR_CMD,
- FG_GEAR_POS,
- FG_HYSTPARM,
- AP_ELEVATOR_CMD,
- AP_AILERON_CMD,
- AP_RUDDER_CMD,
- AP_THROTTLE_CMD,
- AP_SET_ATTITUDE,
- AP_SET_ALTITUDE,
- AP_SET_HEADING,
- AP_SET_AIRSPEED,
- AP_ACQUIRE_ATTITUDE,
- AP_ACQUIRE_ALTITUDE,
- AP_ACQUIRE_HEADING,
- AP_ACQUIRE_AIRSPEED,
- AP_ATTITUDE_HOLD_ON,
- AP_ALTITUDE_HOLD_ON,
- AP_HEADING_HOLD_ON,
- AP_AIRSPEED_HOLD_ON,
- AP_WINGSLEVEL_HOLD_ON
-};
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
#include <simgear/misc/props.hxx>
#include "FGPropertyManager.h"
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
string FGPropertyManager::mkPropertyName(string name, bool lowercase) {
+ /* do this two pass to avoid problems with characters getting skipped
+ because the index changed */
+
for(unsigned i=0;i<name.length();i++) {
if( lowercase && isupper(name[i]) )
name[i]=tolower(name[i]);
else if( isspace(name[i]) )
name[i]='-';
}
+ for(unsigned i=0;i<name.length();i++) {
+ if( name[i] == '/' )
+ name.erase(i,1);
+ }
+
return name;
}
-
+
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGPropertyManager*
newCondition = new struct condition();
while (token != string("/when")) {
if (token == "parameter") {
- prop_name = State->GetPropertyName( Script.GetValue("name") );
+ prop_name = Script.GetValue("name");
newCondition->TestParam.push_back( PropertyManager->GetNode(prop_name) );
newCondition->TestValue.push_back(strtod(Script.GetValue("value").c_str(), NULL));
newCondition->Comparison.push_back(Script.GetValue("comparison"));
} else if (token == "set") {
- prop_name = State->GetPropertyName( Script.GetValue("name") );
+ prop_name = Script.GetValue("name");
newCondition->SetParam.push_back( PropertyManager->GetNode(prop_name) );
newCondition->SetValue.push_back(strtod(Script.GetValue("value").c_str(), NULL));
newCondition->Triggered.push_back(false);
for(int i=0;i<3;i++) vQdot_prev[i].InitMatrix();
- InitPropertyMaps();
-
bind();
Debug(0);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGState::InitPropertyMaps(void)
-{
- ParamNameToProp[ "FG_TIME" ]="sim-time-sec";
- ParamNameToProp[ "FG_QBAR" ]="aero/qbar-psf";
- ParamNameToProp[ "FG_QBARUW" ]="aero/qbarUW-psf";
- ParamNameToProp[ "FG_QBARUV" ]="aero/qbarUV-psf";
- ParamNameToProp[ "FG_WINGAREA" ]="metrics/Sw-sqft";
- ParamNameToProp[ "FG_WINGSPAN" ]="metrics/bw-ft";
- ParamNameToProp[ "FG_CBAR" ]="metrics/cbarw-ft";
- ParamNameToProp[ "FG_ALPHA" ]="aero/alpha-rad";
- ParamNameToProp[ "FG_ALPHADOT" ]="aero/alphadot-rad_sec";
- ParamNameToProp[ "FG_BETA" ]="aero/beta-rad";
- ParamNameToProp[ "FG_ABETA" ]="aero/mag-beta-rad";
- ParamNameToProp[ "FG_BETADOT" ]="aero/betadot-rad_sec";
- ParamNameToProp[ "FG_PHI" ]="attitude/phi-rad";
- ParamNameToProp[ "FG_THT" ]="attitude/theta-rad";
- ParamNameToProp[ "FG_PSI" ]="attitude/psi-true-rad";
- ParamNameToProp[ "FG_PITCHRATE" ]="velocities/q-rad_sec";
- ParamNameToProp[ "FG_ROLLRATE" ]="velocities/p-rad_sec";
- ParamNameToProp[ "FG_YAWRATE" ]="velocities/r-rad_sec";
- ParamNameToProp[ "FG_AEROP" ]="velocities/p-aero-rad_sec";
- ParamNameToProp[ "FG_AEROQ" ]="velocities/q-aero-rad_sec";
- ParamNameToProp[ "FG_AEROR" ]="velocities/r-aero-rad_sec";
- ParamNameToProp[ "FG_CL_SQRD" ]="aero/cl-squared-norm";
- ParamNameToProp[ "FG_MACH" ]="velocities/mach-norm";
- ParamNameToProp[ "FG_ALTITUDE" ]="position/h-sl-ft";
- ParamNameToProp[ "FG_BI2VEL" ]="aero/bi2vel";
- ParamNameToProp[ "FG_CI2VEL" ]="aero/ci2vel";
- ParamNameToProp[ "FG_ELEVATOR_POS" ]="fcs/elevator-pos-rad";
- ParamNameToProp[ "FG_AELEVATOR_POS" ]="fcs/mag-elevator-pos-rad";
- ParamNameToProp[ "FG_NELEVATOR_POS" ]="fcs/elevator-pos-norm";
- ParamNameToProp[ "FG_AILERON_POS" ]="fcs/left-aileron-pos-rad";
- ParamNameToProp[ "FG_AAILERON_POS" ]="fcs/mag-aileron-pos-rad";
- ParamNameToProp[ "FG_NAILERON_POS" ]="fcs/left-aileron-pos-norm";
- ParamNameToProp[ "FG_LEFT_AILERON_POS" ]="fcs/left-aileron-pos-rad";
- ParamNameToProp[ "FG_ALEFT_AILERON_POS" ]="fcs/mag-left-aileron-pos-rad";
- ParamNameToProp[ "FG_NLEFT_AILERON_POS" ]="fcs/left-aileron-pos-norm";
- ParamNameToProp[ "FG_RIGHT_AILERON_POS" ]="fcs/right-aileron-pos-rad";
- ParamNameToProp[ "FG_ARIGHT_AILERON_POS" ]="fcs/mag-aileron-pos-rad";
- ParamNameToProp[ "FG_NRIGHT_AILERON_POS" ]="fcs/right-aileron-pos-norm";
- ParamNameToProp[ "FG_RUDDER_POS" ]="fcs/rudder-pos-rad";
- ParamNameToProp[ "FG_ARUDDER_POS" ]="fcs/mag-rudder-pos-rad";
- ParamNameToProp[ "FG_NRUDDER_POS" ]="fcs/rudder-pos-norm";
- ParamNameToProp[ "FG_SPDBRAKE_POS" ]="fcs/speedbrake-pos-rad";
- ParamNameToProp[ "FG_NSPDBRAKE_POS" ]="fcs/speedbrake-pos-norm";
- ParamNameToProp[ "FG_SPOILERS_POS" ]="fcs/spoiler-pos-rad";
- ParamNameToProp[ "FG_NSPOILERS_POS" ]="fcs/spoiler-pos-norm";
- ParamNameToProp[ "FG_FLAPS_POS" ]="fcs/flap-pos-deg";
- ParamNameToProp[ "FG_NFLAPS_POS" ]="fcs/flap-pos-norm";
- ParamNameToProp[ "FG_ELEVATOR_CMD" ]="fcs/elevator-cmd-norm";
- ParamNameToProp[ "FG_AILERON_CMD" ]="fcs/aileron-cmd-norm";
- ParamNameToProp[ "FG_RUDDER_CMD" ]="fcs/rudder-cmd-norm";
- ParamNameToProp[ "FG_SPDBRAKE_CMD" ]="fcs/speedbrake-cmd-norm";
- ParamNameToProp[ "FG_SPOILERS_CMD" ]="fcs/spoiler-cmd-norm";
- ParamNameToProp[ "FG_FLAPS_CMD" ]="fcs/flap-cmd-norm";
- ParamNameToProp[ "FG_THROTTLE_CMD" ]="fcs/throttle-cmd-norm";
- ParamNameToProp[ "FG_THROTTLE_POS" ]="fcs/throttle-pos-norm";
- ParamNameToProp[ "FG_MIXTURE_CMD" ]="fcs/mixture-cmd-norm";
- ParamNameToProp[ "FG_MIXTURE_POS" ]="fcs/mixture-pos-norm";
- ParamNameToProp[ "FG_MAGNETO_CMD" ]="propulsion/magneto_cmd";
- ParamNameToProp[ "FG_STARTER_CMD" ]="propulsion/starter_cmd";
- ParamNameToProp[ "FG_ACTIVE_ENGINE" ]="propulsion/active_engine";
- ParamNameToProp[ "FG_HOVERB" ]="aero/h_b-mac-ft";
- ParamNameToProp[ "FG_PITCH_TRIM_CMD" ]="fcs/pitch-trim-cmd-norm";
- ParamNameToProp[ "FG_YAW_TRIM_CMD" ]="fcs/yaw-trim-cmd-norm";
- ParamNameToProp[ "FG_ROLL_TRIM_CMD" ]="fcs/roll-trim-cmd-norm";
- ParamNameToProp[ "FG_LEFT_BRAKE_CMD" ]="fcs/left_brake";
- ParamNameToProp[ "FG_CENTER_BRAKE_CMD" ]="fcs/center_brake";
- ParamNameToProp[ "FG_RIGHT_BRAKE_CMD" ]="fcs/right_brake";
- ParamNameToProp[ "FG_SET_LOGGING" ]="sim/set_logging";
- ParamNameToProp[ "FG_ALPHAH" ]="aero/alpha-rad";
- ParamNameToProp[ "FG_ALPHAW" ]="aero/alpha-wing-rad";
- ParamNameToProp[ "FG_LBARH" ]="metrics/lh-norm";
- ParamNameToProp[ "FG_LBARV" ]="metrics/lv-norm";
- ParamNameToProp[ "FG_HTAILAREA" ]="metrics/Sh-sqft";
- ParamNameToProp[ "FG_VTAILAREA" ]="metrics/Sv-sqft";
- ParamNameToProp[ "FG_VBARH" ]="metrics/vbarh-norm";
- ParamNameToProp[ "FG_VBARV" ]="metrics/vbarv-norm";
- ParamNameToProp[ "FG_GEAR_CMD" ]="gear/gear-cmd-norm";
- ParamNameToProp[ "FG_GEAR_POS" ]="gear/gear-pos-norm";
- ParamNameToProp[ "FG_HYSTPARM" ]="aero/stall-hyst-norm";
- ParamNameToProp[ "AP_ELEVATOR_CMD" ]="jsbsim/ap/elevator_cmd";
- ParamNameToProp[ "AP_AILERON_CMD" ]="jsbsim/ap/aileron_cmd";
- ParamNameToProp[ "AP_RUDDER_CMD" ]="jsbsim/ap/rudder_cmd";
- ParamNameToProp[ "AP_THROTTLE_CMD" ]="jsbsim/ap/throttle_cmd";
- ParamNameToProp[ "AP_SET_ATTITUDE" ]="jsbsim/ap/set_attitude";
- ParamNameToProp[ "AP_SET_ALTITUDE" ]="jsbsim/ap/set_altitude";
- ParamNameToProp[ "AP_SET_HEADING" ]="jsbsim/ap/set_heading";
- ParamNameToProp[ "AP_SET_AIRSPEED" ]="jsbsim/ap/set_airspeed";
- ParamNameToProp[ "AP_ACQUIRE_ATTITUDE" ]="jsbsim/ap/acquire_attitude";
- ParamNameToProp[ "AP_ACQUIRE_ALTITUDE" ]="jsbsim/ap/acquire_altitude";
- ParamNameToProp[ "AP_ACQUIRE_HEADING" ]="jsbsim/ap/acquire_heading";
- ParamNameToProp[ "AP_ACQUIRE_AIRSPEED" ]="jsbsim/ap/acquire_aispeed";
- ParamNameToProp[ "AP_ATTITUDE_HOLD_ON" ]="jsbsim/ap/attitude_hold_on";
- ParamNameToProp[ "AP_ALTITUDE,_HOLD_ON" ]="jsbsim/ap/altitude_hold_on";
- ParamNameToProp[ "AP_HEADING_HOLD_ON" ]="jsbsim/ap/heading_hold_on";
- ParamNameToProp[ "AP_AIRSPEED_HOLD_ON" ]="jsbsim/ap/airspeed_hold_on";
- ParamNameToProp[ "AP_WINGSLEVEL_HOLD_ON" ]="jsbsim/ap/wingslevel_hold_on";
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
void FGState::bind(void)
{
PropertyManager->Tie("sim-time-sec",this,
*/
void ReportState(void);
- inline string GetPropertyName(string prm) { return ParamNameToProp[prm]; }
-
void bind();
void unbind();
FGPropulsion* Propulsion;
FGPropertyManager* PropertyManager;
- typedef map<string,string> ParamNameMap;
- ParamNameMap ParamNameToProp;
-
- void InitPropertyMaps(void);
-
void Debug(int from);
};
iAxes++;
}
TrimAxes.clear();
- cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
+ //cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*AC_cfg >> token;
}
}
-
+ FGFCSComponent::bind( PropertyManager->GetNode("fcs/components",true) );
Debug(0);
}
Type = "";
ID = 0;
Input = 0.0;
- InputNode = 0;
Output = 0.0;
OutputNode = 0;
IsOutput = false;
FGFCSComponent::~FGFCSComponent()
{
+ unbind();
Debug(1);
}
bool FGFCSComponent::Run(void)
{
- switch(InputType) {
- case itPilotAC:
- Input = InputNode->getDoubleValue();
- break;
- case itFCS:
- Input = fcs->GetComponentOutput(InputIdx);
- case itAP:
- // implement autopilot input mechanism
- break;
- case itBias:
- break;
- }
+
+ // switch(InputType) {
+// case itAP:
+// case itPilotAC:
+// Input = InputNode->getDoubleValue();
+// break;
+// case itFCS:
+// Input = fcs->GetComponentOutput(InputIdx);
+// case itBias:
+// break;
+// }
return true;
}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGPropertyManager* FGFCSComponent::resolveSymbol(string token) {
+ string prop;
+ FGPropertyManager* tmp=PropertyManager->GetNode(token,false);
+ if( !tmp ){
+ if( token.find("/") == token.npos )
+ prop = "model/" + token;
+ cerr << "Creating new property " << prop << endl;
+ tmp=PropertyManager->GetNode(token,true);
+ }
+ return tmp;
+}
+
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGFCSComponent::bind(FGPropertyManager *node) {
+ string tmp = "fcs/" + node->mkPropertyName(Name, true);
+ FGPropertyManager *tmpn;
+ PropertyManager->Tie( tmp,this, &FGFCSComponent::GetOutput);
+ node = node->GetNode( node->mkPropertyName(Name, true), true );
+ for(unsigned i=0;i<InputNodes.size();i++) {
+ tmpn=node->GetNode( "input-property",(int)i,true );
+ tmpn->setStringValue( InputNodes[i]->GetName().c_str() );
+ }
+ if(OutputNode) node->SetString("output-property",OutputNode->GetName());
+ node->Tie("output-value",this,&FGFCSComponent::GetOutput);
+ node->SetString("type",Type);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGFCSComponent::unbind(void) {
+ string name = "fcs";
+ FGPropertyManager *node=PropertyManager->GetNode(name);
+ node->Untie( PropertyManager->mkPropertyName(Name, true) );
+ name += "/components"
+ + PropertyManager->mkPropertyName(Name, true);
+ node= PropertyManager->GetNode(name);
+ node->Untie("output-value");
+}
+
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
#endif
#include <string>
+#include <vector>
#include "../FGJSBBase.h"
#include "../FGPropertyManager.h"
virtual bool Run(void);
virtual void SetOutput(void);
- inline double GetOutput (void) {return Output;}
+ inline double GetOutput (void) const {return Output;}
inline FGPropertyManager* GetOutputNode(void) { return OutputNode; }
- inline string GetName(void) {return Name;}
- inline string GetType(void) { return Type; }
- virtual double GetOutputPct(void) { return 0; }
-
+ inline string GetName(void) const {return Name;}
+ inline string GetType(void) const { return Type; }
+ virtual double GetOutputPct(void) const { return 0; }
+
+ virtual void bind(FGPropertyManager *node);
+ virtual void unbind( void );
+ FGPropertyManager* resolveSymbol(string token);
+
protected:
/// Pilot/Aircraft, FCS, Autopilot inputs
enum eInputType {itPilotAC, itFCS, itAP, itBias} InputType;
string Type;
string Name;
int ID;
- FGPropertyManager* InputNode;
+ vector<FGPropertyManager*> InputNodes;
int InputIdx;
double Input;
FGPropertyManager* OutputNode;
else if (token == "INPUT")
{
token = AC_cfg->GetValue("INPUT");
- if (token.find("FG_") != token.npos) {
+ if( InputNodes.size() > 0 ) {
+ cerr << "Filters can only accept one input" << endl;
+ } else {
*AC_cfg >> token;
- InputNode = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(token) );
- InputType = itPilotAC;
- } else {
- *AC_cfg >> InputIdx;
- InputType = itFCS;
- }
+ InputNodes.push_back( resolveSymbol(token) );
+ }
}
else if (token == "OUTPUT")
{
IsOutput = true;
*AC_cfg >> sOutputIdx;
- OutputNode = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(sOutputIdx) );
+ OutputNode = PropertyManager->GetNode( sOutputIdx );
}
else cerr << "Unknown filter type: " << token << endl;
}
cerr << "Unknown filter type" << endl;
break;
}
+ FGFCSComponent::bind( PropertyManager->GetNode("fcs/components",true) );
Debug(0);
}
Initialize = false;
} else {
-
+ Input = InputNodes[0]->getDoubleValue();
switch (FilterType) {
case eLag:
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
- cout << " ID: " << ID << endl;
- switch(InputType) {
- case itPilotAC:
- cout << " INPUT: " << InputNode->getName() << endl;
- break;
- case itFCS:
- cout << " INPUT: FCS Component " << InputIdx << " (" <<
- fcs->GetComponentName(InputIdx) << ")" << endl;
- break;
- case itAP:
- case itBias:
- break;
- }
+ cout << " INPUT: " << InputNodes[0]->getName() << endl;
cout << " C1: " << C1 << endl;
cout << " C2: " << C2 << endl;
cout << " C3: " << C3 << endl;
*AC_cfg >> ID;
} else if (token == "INPUT") {
token = AC_cfg->GetValue("INPUT");
- if (token.find("FG_") != token.npos) {
+ if( InputNodes.size() > 0 ) {
+ cerr << "Gains can only accept one input" << endl;
+ } else {
*AC_cfg >> token;
- InputNode = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(token) );
- InputType = itPilotAC;
- } else {
- *AC_cfg >> InputIdx;
- InputType = itFCS;
- }
+ InputNodes.push_back( resolveSymbol(token) );
+ }
} else if (token == "GAIN") {
*AC_cfg >> Gain;
} else if (token == "MIN") {
token = AC_cfg->GetValue("SCHEDULED_BY");
if (token.find("FG_") != token.npos) {
*AC_cfg >> strScheduledBy;
- ScheduledBy = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(strScheduledBy) );
+ ScheduledBy = PropertyManager->GetNode( strScheduledBy );
}
} else if (token == "OUTPUT") {
IsOutput = true;
*AC_cfg >> sOutputIdx;
- OutputNode = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(sOutputIdx) );
+ OutputNode = PropertyManager->GetNode( sOutputIdx );
} else {
AC_cfg->ResetLineIndexToZero();
*Table << *AC_cfg;
}
}
+
+ FGFCSComponent::bind( PropertyManager->GetNode("fcs/components",true) );
+
Debug(0);
}
double LookupVal = 0;
FGFCSComponent::Run(); // call the base class for initialization of Input
-
+ Input = InputNodes[0]->getDoubleValue();
if (Type == "PURE_GAIN") {
Output = Gain * Input;
} else if (Type == "SCHEDULED_GAIN") {
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
- cout << " ID: " << ID << endl;
- switch(InputType) {
- case itPilotAC:
- cout << " INPUT: " << InputNode->getName() << endl;
- break;
- case itFCS:
- cout << " INPUT: FCS Component " << InputIdx << " (" <<
- fcs->GetComponentName(InputIdx) << ")" << endl;
- break;
- case itAP:
- case itBias:
- break;
- }
+ cout << " INPUT: " << InputNodes[0]->getName() << endl;
cout << " GAIN: " << Gain << endl;
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
cout << " MIN: " << Min << endl;
{
Type = AC_cfg->GetValue("TYPE");
Name = AC_cfg->GetValue("NAME");
+
+ FGFCSComponent::bind( PropertyManager->GetNode("fcs/components",true) );
Debug(0);
}
*AC_cfg >> ID;
} else if (token == "INPUT") {
token = AC_cfg->GetValue("INPUT");
- if (token.find("FG_") != token.npos) {
+ if( InputNodes.size() > 0 ) {
+ cerr << "Kinemat can only accept one input" << endl;
+ } else {
*AC_cfg >> token;
- InputNode = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(token) );
- InputType = itPilotAC;
- } else {
- *AC_cfg >> InputIdx;
- InputType = itFCS;
- }
+ InputNodes.push_back( resolveSymbol(token) );
+ }
+
} else if ( token == "DETENTS" ) {
*AC_cfg >> NumDetents;
for (int i=0;i<NumDetents;i++) {
IsOutput = true;
*AC_cfg >> sOutputIdx;
- OutputNode = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(sOutputIdx) );
+ OutputNode = PropertyManager->GetNode(sOutputIdx);
}
}
+ FGFCSComponent::bind( PropertyManager->GetNode("fcs/components") );
Debug(0);
}
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
- cout << " ID: " << ID << endl;
- cout << " INPUT: " << InputNode->getName() << endl;
+ cout << " INPUT: " << InputNodes[0]->getName() << endl;
cout << " DETENTS: " << NumDetents << endl;
for (int i=0;i<NumDetents;i++) {
cout << " " << Detents[i] << " " << TransitionTimes[i] << endl;
AC_cfg(AC_cfg)
{
string token,sOutputIdx;
- eParam tmpInputIndex;
- InputRec *input;
clip = false;
clipmin = clipmax = 0.0;
Bias = 0.0;
- Inputs.clear();
Type = AC_cfg->GetValue("TYPE");
Name = AC_cfg->GetValue("NAME");
if (token == "ID") {
*AC_cfg >> ID;
} else if (token == "INPUT") {
- input = new InputRec;
token = AC_cfg->GetValue("INPUT");
- if (token.find("FG_") != token.npos) {
- *AC_cfg >> token;
- input->Node = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(token) );
- input->Idx=-1;
- input->Type = itPilotAC;
- } else if (token.find(".") != token.npos) { // bias
- *AC_cfg >> Bias;
- input->Node=0;
- input->Idx=0;
- input->Type=itBias;
- } else {
- *AC_cfg >> tmpInputIndex;
- input->Idx=tmpInputIndex;
- input->Node=0;
- input->Type=itFCS;
- }
- Inputs.push_back(input);
+ *AC_cfg >> token;
+ InputNodes.push_back( resolveSymbol(token) );
} else if (token == "CLIPTO") {
*AC_cfg >> clipmin >> clipmax;
if (clipmax > clipmin) {
} else if (token == "OUTPUT") {
IsOutput = true;
*AC_cfg >> sOutputIdx;
- OutputNode = PropertyManager->GetNode(
- fcs->GetState()->GetPropertyName(sOutputIdx) );
+ OutputNode = PropertyManager->GetNode(sOutputIdx);
}
}
+
+ FGFCSComponent::bind( PropertyManager->GetNode("fcs/components",true) );
Debug(0);
}
FGSummer::~FGSummer()
{
- unsigned i;
- for (i=0;i<Inputs.size();i++) {
- delete Inputs[i];
- }
Debug(1);
}
Output = 0.0;
- for (idx=0; idx<Inputs.size(); idx++) {
- switch (Inputs[idx]->Type) {
- case itPilotAC:
- Output += Inputs[idx]->Node->getDoubleValue();
- break;
- case itFCS:
- Output += fcs->GetComponentOutput(Inputs[idx]->Idx);
- break;
- case itBias:
- Output += Bias;
- break;
- }
+ for (idx=0; idx<InputNodes.size(); idx++) {
+ Output += InputNodes[idx]->getDoubleValue();
}
if (clip) {
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
- cout << " ID: " << ID << endl;
cout << " INPUTS: " << endl;
- for (unsigned i=0;i<Inputs.size();i++) {
- switch (Inputs[i]->Type) {
- case itPilotAC:
- cout << " " << Inputs[i]->Node->getName() << endl;
- break;
- case itFCS:
- cout << " FCS Component " << Inputs[i]->Idx << " (" <<
- fcs->GetComponentName(Inputs[i]->Idx) << ")" << endl;
- break;
- case itBias:
- cout << " " << "Bias of " << Bias << endl;
- break;
- }
+ for (unsigned i=0;i<InputNodes.size();i++) {
+ cout << " " << InputNodes[i]->getName() << endl;
}
if (clip) cout << " CLIPTO: " << clipmin
<< ", " << clipmax << endl;
private:
FGConfigFile* AC_cfg;
- typedef struct {
- FGPropertyManager* Node;
- int Idx;
- int Type;
- } InputRec;
- vector <InputRec*> Inputs;
bool clip;
double clipmin,clipmax;
double Bias;
Type = AC_cfg->GetValue("TYPE");
Name = AC_cfg->GetValue("NAME");
+ FGFCSComponent::bind( PropertyManager->GetNode("fcs/components",true) );
+
Debug(0);
}