40 #include "FGFCSComponent.h"
41 #include "models/FGFCS.h"
42 #include "math/FGParameterValue.h"
52 FGFCSComponent::FGFCSComponent(
FGFCS* _fcs,
Element* element) : fcs(_fcs)
54 Input = Output = delay_time = 0.0;
57 clip = cyclic_clip =
false;
58 dt = fcs->GetChannelDeltaT();
60 PropertyManager = fcs->GetPropertyManager();
61 if (element->
GetName() ==
string(
"lag_filter")) {
63 }
else if (element->
GetName() ==
string(
"lead_lag_filter")) {
64 Type =
"LEAD_LAG_FILTER";
65 }
else if (element->
GetName() ==
string(
"washout_filter")) {
66 Type =
"WASHOUT_FILTER";
67 }
else if (element->
GetName() ==
string(
"second_order_filter")) {
68 Type =
"SECOND_ORDER_FILTER";
69 }
else if (element->
GetName() ==
string(
"integrator")) {
71 }
else if (element->
GetName() ==
string(
"summer")) {
73 }
else if (element->
GetName() ==
string(
"pure_gain")) {
75 }
else if (element->
GetName() ==
string(
"scheduled_gain")) {
76 Type =
"SCHEDULED_GAIN";
77 }
else if (element->
GetName() ==
string(
"aerosurface_scale")) {
78 Type =
"AEROSURFACE_SCALE";
79 }
else if (element->
GetName() ==
string(
"switch")) {
81 }
else if (element->
GetName() ==
string(
"kinematic")) {
83 }
else if (element->
GetName() ==
string(
"deadband")) {
85 }
else if (element->
GetName() ==
string(
"fcs_function")) {
86 Type =
"FCS_FUNCTION";
87 }
else if (element->
GetName() ==
string(
"pid")) {
89 }
else if (element->
GetName() ==
string(
"sensor")) {
91 }
else if (element->
GetName() ==
string(
"accelerometer")) {
92 Type =
"ACCELEROMETER";
93 }
else if (element->
GetName() ==
string(
"magnetometer")) {
94 Type =
"MAGNETOMETER";
95 }
else if (element->
GetName() ==
string(
"gyro")) {
97 }
else if (element->
GetName() ==
string(
"actuator")) {
99 }
else if (element->
GetName() ==
string(
"waypoint_heading")) {
100 Type =
"WAYPOINT_HEADING";
101 }
else if (element->
GetName() ==
string(
"waypoint_distance")) {
102 Type =
"WAYPOINT_DISTANCE";
103 }
else if (element->
GetName() ==
string(
"angle")) {
105 }
else if (element->
GetName() ==
string(
"distributor")) {
106 Type =
"DISTRIBUTOR";
114 while (init_element) {
121 while (input_element) {
131 bool node_exists = PropertyManager->HasNode(output_node_name);
132 FGPropertyNode* OutputNode = PropertyManager->GetNode( output_node_name,
true );
134 cerr << out_elem->
ReadFrom() <<
" Unable to process property: "
135 << output_node_name << endl;
136 throw(
string(
"Invalid output property name in flight control definition"));
138 OutputNodes.push_back(OutputNode);
144 OutputNode->setDoubleValue(Output);
152 if (delayType.length() > 0) {
153 if (delayType ==
"time") {
154 delay = (
unsigned int)(delay_time / dt);
155 }
else if (delayType ==
"frames") {
156 delay = (
unsigned int)delay_time;
158 cerr <<
"Unallowed delay type" << endl;
161 delay = (
unsigned int)(delay_time / dt);
163 output_array.resize(delay);
164 for (
unsigned int i=0; i<delay; i++) output_array[i] = 0.0;
172 <<
"Element <min> is missing, <clipto> is ignored." << endl;
181 <<
"Element <max> is missing, <clipto> is ignored." << endl;
206 void FGFCSComponent::ResetPastStates(
void)
209 for (
auto &elm: output_array)
215 void FGFCSComponent::CheckInputNodes(
size_t MinNodes,
size_t MaxNodes, Element* el)
217 size_t num = InputNodes.size();
219 if (num < MinNodes) {
220 cerr << el->ReadFrom()
221 <<
" Not enough <input> nodes are provided" << endl
222 <<
" Expecting " << MinNodes <<
" while " << num
223 <<
" are provided." << endl;
224 throw(
"Some inputs are missing.");
227 if (num > MaxNodes) {
228 cerr << el->ReadFrom()
229 <<
" Too many <input> nodes are provided" << endl
230 <<
" Expecting " << MaxNodes <<
" while " << num
231 <<
" are provided." << endl
232 <<
" The last " << num-MaxNodes <<
" input nodes will be ignored."
239 void FGFCSComponent::SetOutput(
void)
241 for (
auto node: OutputNodes)
242 node->setDoubleValue(Output);
247 void FGFCSComponent::Delay(
void)
249 if (fcs->GetTrimStatus()) {
252 std::fill(output_array.begin(), output_array.end(), Output);
255 output_array[index] = Output;
256 if ((
unsigned int)index == delay-1) index = 0;
258 Output = output_array[index];
264 void FGFCSComponent::Clip(
void)
267 double vmin = ClipMin->GetValue();
268 double vmax = ClipMax->GetValue();
269 double range = vmax - vmin;
272 cerr <<
"Trying to clip with a max value (" << vmax <<
") from "
273 << ClipMax->GetName() <<
" lower than the min value (" << vmin
274 <<
") from " << ClipMin->GetName() <<
"." << endl
275 <<
"Clipping is ignored." << endl;
279 if (cyclic_clip && range != 0.0) {
280 double value = Output - vmin;
281 Output = fmod(value, range) + vmin;
299 void FGFCSComponent::bind(Element* el)
302 if (Name.find(
"/") == string::npos)
307 bool node_exists = PropertyManager->HasNode(tmp);
308 FGPropertyNode* node = PropertyManager->GetNode(tmp,
true);
311 OutputNodes.push_back(node);
317 node->setDoubleValue(Output);
320 cerr << el->ReadFrom()
321 <<
"Could not get or create property " << tmp << endl;
344 void FGFCSComponent::Debug(
int from)
346 if (debug_lvl <= 0)
return;
350 cout << endl <<
" Loading Component \"" << Name
351 <<
"\" of type: " << Type << endl;
354 cout <<
" Minimum limit: " << ClipMin->GetName() << endl;
355 cout <<
" Maximum limit: " << ClipMax->GetName() << endl;
357 if (delay > 0) cout <<
" Frame delay: " << delay
358 <<
" frames (" << delay*dt <<
" sec)" << endl;
361 if (debug_lvl & 2 ) {
362 if (from == 0) cout <<
"Instantiated: FGFCSComponent" << endl;
363 if (from == 1) cout <<
"Destroyed: FGFCSComponent" << endl;
365 if (debug_lvl & 4 ) {
367 if (debug_lvl & 8 ) {
369 if (debug_lvl & 16) {
371 if (debug_lvl & 64) {