43 #include "FGFCSComponent.h" 44 #include "input_output/FGXMLElement.h" 45 #include "math/FGPropertyValue.h" 46 #include "models/FGFCS.h" 52 IDENT(IdSrc,
"$Id: FGFCSComponent.cpp,v 1.42 2016/02/27 16:54:15 bcoconni Exp $");
53 IDENT(IdHdr,ID_FCSCOMPONENT);
59 FGFCSComponent::FGFCSComponent(
FGFCS* _fcs,
Element* element) : fcs(_fcs)
61 Element *input_element,*init_element, *clip_el;
62 Input = Output = clipmin = clipmax = delay_time = 0.0;
65 ClipMinPropertyNode = ClipMaxPropertyNode = 0;
66 clipMinSign = clipMaxSign = 1.0;
67 IsOutput = clip =
false;
68 string input,init, clip_string;
71 PropertyManager = fcs->GetPropertyManager();
72 if (element->
GetName() == string(
"lag_filter")) {
74 }
else if (element->
GetName() == string(
"lead_lag_filter")) {
75 Type =
"LEAD_LAG_FILTER";
76 }
else if (element->
GetName() == string(
"washout_filter")) {
77 Type =
"WASHOUT_FILTER";
78 }
else if (element->
GetName() == string(
"second_order_filter")) {
79 Type =
"SECOND_ORDER_FILTER";
80 }
else if (element->
GetName() == string(
"integrator")) {
82 }
else if (element->
GetName() == string(
"summer")) {
84 }
else if (element->
GetName() == string(
"pure_gain")) {
86 }
else if (element->
GetName() == string(
"scheduled_gain")) {
87 Type =
"SCHEDULED_GAIN";
88 }
else if (element->
GetName() == string(
"aerosurface_scale")) {
89 Type =
"AEROSURFACE_SCALE";
90 }
else if (element->
GetName() == string(
"switch")) {
92 }
else if (element->
GetName() == string(
"kinematic")) {
94 }
else if (element->
GetName() == string(
"deadband")) {
96 }
else if (element->
GetName() == string(
"fcs_function")) {
97 Type =
"FCS_FUNCTION";
98 }
else if (element->
GetName() == string(
"pid")) {
100 }
else if (element->
GetName() == string(
"sensor")) {
102 }
else if (element->
GetName() == string(
"accelerometer")) {
103 Type =
"ACCELEROMETER";
104 }
else if (element->
GetName() == string(
"magnetometer")) {
105 Type =
"MAGNETOMETER";
106 }
else if (element->
GetName() == string(
"gyro")) {
108 }
else if (element->
GetName() == string(
"actuator")) {
110 }
else if (element->
GetName() == string(
"waypoint_heading")) {
111 Type =
"WAYPOINT_HEADING";
112 }
else if (element->
GetName() == string(
"waypoint_distance")) {
113 Type =
"WAYPOINT_DISTANCE";
114 }
else if (element->
GetName() == string(
"angle")) {
116 }
else if (element->
GetName() == string(
"distributor")) {
117 Type =
"DISTRIBUTOR";
125 while (init_element) {
127 if (init[0] ==
'-') {
128 InitSigns.push_back(-1.0);
131 InitSigns.push_back( 1.0);
134 if (PropertyManager->HasNode(init)) {
141 InitNames.push_back( init );
147 while (input_element) {
149 if (input[0] ==
'-') {
150 InputSigns.push_back(-1.0);
153 InputSigns.push_back( 1.0);
156 if (PropertyManager->HasNode(input)) {
163 InputNames.push_back( input );
172 FGPropertyNode* OutputNode = PropertyManager->GetNode( output_node_name,
true );
173 OutputNodes.push_back(OutputNode);
175 cerr << endl <<
" Unable to process property: " << output_node_name << endl;
176 throw(
string(
"Invalid output property name in flight control definition"));
185 if (delayType.length() > 0) {
186 if (delayType ==
"time") {
187 delay = (
unsigned int)(delay_time / dt);
188 }
else if (delayType ==
"frames") {
189 delay = (
unsigned int)delay_time;
191 cerr <<
"Unallowed delay type" << endl;
194 delay = (
unsigned int)(delay_time / dt);
196 output_array.resize(delay);
197 for (
unsigned int i=0; i<delay; i++) output_array[i] = 0.0;
203 if (!is_number(clip_string)) {
204 if (clip_string[0] ==
'-') {
206 clip_string.erase(0,1);
208 ClipMinPropertyNode = PropertyManager->GetNode( clip_string );
213 if (!is_number(clip_string)) {
214 if (clip_string[0] ==
'-') {
216 clip_string.erase(0,1);
218 ClipMaxPropertyNode = PropertyManager->GetNode( clip_string );
233 for (
unsigned int i=0; i<InputNodes.size(); i++) {
234 delete InputNodes[i];
240 void FGFCSComponent::ResetPastStates(
void)
243 for (
unsigned int i = 0; i < output_array.size(); ++i)
244 output_array[i] = 0.0;
249 void FGFCSComponent::SetOutput(
void)
251 for (
unsigned int i=0; i<OutputNodes.size(); i++) OutputNodes[i]->setDoubleValue(Output);
256 void FGFCSComponent::SetDtForFrameCount(
int FrameCount)
258 dt = fcs->GetDt() * FrameCount;
263 void FGFCSComponent::Delay(
void)
265 output_array[index] = Output;
266 if ((
unsigned int)index == delay-1) index = 0;
268 Output = output_array[index];
273 void FGFCSComponent::Clip(
void)
276 if (ClipMinPropertyNode != 0) clipmin = clipMinSign*ClipMinPropertyNode->getDoubleValue();
277 if (ClipMaxPropertyNode != 0) clipmax = clipMaxSign*ClipMaxPropertyNode->getDoubleValue();
278 if (Output > clipmax) Output = clipmax;
279 else if (Output < clipmin) Output = clipmin;
292 void FGFCSComponent::bind(
void)
295 if (Name.find(
"/") == string::npos) {
300 PropertyManager->
Tie( tmp,
this, &FGFCSComponent::GetOutput);
322 void FGFCSComponent::Debug(
int from)
324 if (debug_lvl <= 0)
return;
328 cout << endl <<
" Loading Component \"" << Name
329 <<
"\" of type: " << Type << endl;
334 if (ClipMinPropertyNode != 0L) {
335 if (clipMinSign < 0.0) propsign=
"-";
336 cout <<
" Minimum limit: " << propsign << ClipMinPropertyNode->GetName() << endl;
338 cout <<
" Minimum limit: " << clipmin << endl;
343 if (ClipMaxPropertyNode != 0L) {
344 if (clipMaxSign < 0.0) propsign=
"-";
345 cout <<
" Maximum limit: " << propsign << ClipMaxPropertyNode->GetName() << endl;
347 cout <<
" Maximum limit: " << clipmax << endl;
350 if (delay > 0) cout <<
" Frame delay: " << delay
351 <<
" frames (" << delay*dt <<
" sec)" << endl;
354 if (debug_lvl & 2 ) {
355 if (from == 0) cout <<
"Instantiated: FGFCSComponent" << endl;
356 if (from == 1) cout <<
"Destroyed: FGFCSComponent" << endl;
358 if (debug_lvl & 4 ) {
360 if (debug_lvl & 8 ) {
362 if (debug_lvl & 16) {
364 if (debug_lvl & 64) {
366 cout << IdSrc << endl;
367 cout << IdHdr << endl;
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
virtual ~FGFCSComponent()
Destructor.
std::string mkPropertyName(std::string name, bool lowercase)
Property-ify a name replaces spaces with '-' and, optionally, makes name all lower case...
Represents a property value which can use late binding.
Class wrapper for property handling.
Element * FindElement(const std::string &el="")
Searches for a specified element.
double FindElementValueAsNumber(const std::string &el="")
Searches for the named element and returns the data belonging to it as a number.
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
double GetDataAsNumber(void)
Converts the element data to a number.
const std::string & GetName(void) const
Retrieves the element name.
std::string FindElementValue(const std::string &el="")
Searches for the named element and returns the string data belonging to it.
std::string GetDataLine(unsigned int i=0)
Gets a line of data belonging to an element.
Encapsulates the Flight Control System (FCS) functionality.
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.