JSBSim Flight Dynamics Model 1.3.0 (09 Apr 2026)
An Open Source Flight Dynamics and Control Software Library in C++
Loading...
Searching...
No Matches
FGStateSpace.h
1/*
2 * FGStateSpace.h
3 * Copyright (C) James Goppert 2010 <james.goppert@gmail.com>
4 *
5 * FGStateSpace.h is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by the
7 * Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * FGStateSpace.h is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef JSBSim_FGStateSpace_H
20#define JSBSim_FGStateSpace_H
21
22#include "FGFDMExec.h"
23#include "models/FGPropulsion.h"
24#include "models/FGAccelerations.h"
25#include "models/propulsion/FGEngine.h"
26#include "models/propulsion/FGThruster.h"
27#include "models/propulsion/FGTurbine.h"
28#include "models/propulsion/FGTurboProp.h"
29#include "models/FGAuxiliary.h"
30#include "models/FGFCS.h"
31#include <fstream>
32#include <iostream>
33#include <limits>
34
35namespace JSBSim
36{
37
39{
40public:
41
42 // component class
44 {
45 protected:
46 FGStateSpace * m_stateSpace;
47 FGFDMExec * m_fdm;
48 std::string m_name, m_unit;
49 public:
50 Component(const std::string & name, const std::string & unit) :
51 m_stateSpace(), m_fdm(), m_name(name), m_unit(unit) {};
52 virtual ~Component() {};
53 virtual double get() const = 0;
54 virtual void set(double val) = 0;
55 virtual double getDeriv() const
56 {
57 // by default should calculate using finite difference approx
58 std::vector<double> x0 = m_stateSpace->x.get();
59 double f0 = get();
60 double dt0 = m_fdm->GetDeltaT();
61 double time0 = m_fdm->GetSimTime();
62 m_fdm->Setdt(1./120.);
63 m_fdm->DisableOutput();
64 m_fdm->Run();
65 double f1 = get();
66 m_stateSpace->x.set(x0);
67 if (m_fdm->GetDebugLevel() > 1)
68 {
69 FGLogging log(LogLevel::DEBUG);
70 log << std::scientific
71 << "name: " << m_name
72 << "\nf1: " << f0
73 << "\nf2: " << f1
74 << "\ndt: " << m_fdm->GetDeltaT()
75 << "\tdf/dt: " << (f1-f0)/m_fdm->GetDeltaT()
76 << std::fixed << "\n";
77 }
78 double deriv = (f1-f0)/m_fdm->GetDeltaT();
79 m_fdm->Setdt(dt0); // restore original value
80 m_fdm->Setsim_time(time0);
81 m_fdm->EnableOutput();
82 return deriv;
83 }
84 void setStateSpace(FGStateSpace * stateSpace)
85 {
86 m_stateSpace = stateSpace;
87 }
88 void setFdm(FGFDMExec * fdm)
89 {
90 m_fdm = fdm;
91 }
92 const std::string & getName() const
93 {
94 return m_name;
95 }
96 const std::string & getUnit() const
97 {
98 return m_unit;
99 }
100 };
101
102 // component vector class
104 {
105 public:
106 ComponentVector(FGFDMExec * fdm, FGStateSpace * stateSpace) :
107 m_stateSpace(stateSpace), m_fdm(fdm), m_components() {}
108 ComponentVector & operator=(ComponentVector & componentVector)
109 {
110 m_stateSpace = componentVector.m_stateSpace;
111 m_fdm = componentVector.m_fdm;
112 m_components = componentVector.m_components;
113 return *this;
114 }
115 ComponentVector(const ComponentVector & componentVector) :
116 m_stateSpace(componentVector.m_stateSpace),
117 m_fdm(componentVector.m_fdm),
118 m_components(componentVector.m_components)
119 {
120 }
121 void add(Component * comp)
122 {
123 comp->setStateSpace(m_stateSpace);
124 comp->setFdm(m_fdm);
125 m_components.push_back(comp);
126 }
127 size_t getSize() const
128 {
129 return m_components.size();
130 }
131 Component * getComp(int i) const
132 {
133 return m_components[i];
134 };
135 Component * getComp(int i)
136 {
137 return m_components[i];
138 };
139 double get(int i) const
140 {
141 return m_components[i]->get();
142 };
143 void set(int i, double val)
144 {
145 m_components[i]->set(val);
146 m_stateSpace->run();
147 };
148 double get(int i)
149 {
150 return m_components[i]->get();
151 };
152 std::vector<double> get() const
153 {
154 std::vector<double> val;
155 for (unsigned int i=0;i<getSize();i++) val.push_back(m_components[i]->get());
156 return val;
157 }
158 void get(double * array) const
159 {
160 for (unsigned int i=0;i<getSize();i++) array[i] = m_components[i]->get();
161 }
162 double getDeriv(int i)
163 {
164 return m_components[i]->getDeriv();
165 };
166 std::vector<double> getDeriv() const
167 {
168 std::vector<double> val;
169 for (unsigned int i=0;i<getSize();i++) val.push_back(m_components[i]->getDeriv());
170 return val;
171 }
172 void getDeriv(double * array) const
173 {
174 for (unsigned int i=0;i<getSize();i++) array[i] = m_components[i]->getDeriv();
175 }
176 void set(std::vector<double> vals)
177 {
178 for (unsigned int i=0;i<getSize();i++) m_components[i]->set(vals[i]);
179 m_stateSpace->run();
180 }
181 void set(double * array)
182 {
183 for (unsigned int i=0;i<getSize();i++) m_components[i]->set(array[i]);
184 m_stateSpace->run();
185 }
186 std::string getName(int i) const
187 {
188 return m_components[i]->getName();
189 };
190 std::vector<std::string> getName() const
191 {
192 std::vector<std::string> name;
193 for (unsigned int i=0;i<getSize();i++) name.push_back(m_components[i]->getName());
194 return name;
195 }
196 std::string getUnit(int i) const
197 {
198 return m_components[i]->getUnit();
199 };
200 std::vector<std::string> getUnit() const
201 {
202 std::vector<std::string> unit;
203 for (unsigned int i=0;i<getSize();i++) unit.push_back(m_components[i]->getUnit());
204 return unit;
205 }
206 void clear() {
207 m_components.clear();
208 }
209 private:
210 FGStateSpace * m_stateSpace;
211 FGFDMExec * m_fdm;
212 std::vector<Component *> m_components;
213 };
214
215 // component vectors
216 ComponentVector x, u, y;
217
218 // constructor
219 FGStateSpace(FGFDMExec * fdm) : x(fdm,this), u(fdm,this), y(fdm,this), m_fdm(fdm) {};
220
221 void setFdm(FGFDMExec * fdm) { m_fdm = fdm; }
222
223 void run() {
224 // initialize
225 m_fdm->Initialize(m_fdm->GetIC().get());
226
227 for (unsigned int i=0; i<m_fdm->GetPropulsion()->GetNumEngines(); i++) {
228 m_fdm->GetPropulsion()->GetEngine(i)->InitRunning();
229 }
230
231 // wait for stable state
232 double cost = stateSum();
233 for(int i=0;i<1000;i++) {
234 m_fdm->GetPropulsion()->GetSteadyState();
235 m_fdm->SetTrimStatus(true);
236 m_fdm->DisableOutput();
237 m_fdm->SuspendIntegration();
238 m_fdm->Run();
239 m_fdm->SetTrimStatus(false);
240 m_fdm->EnableOutput();
241 m_fdm->ResumeIntegration();
242
243 double costNew = stateSum();
244 double dcost = fabs(costNew - cost);
245 if (dcost < std::numeric_limits<double>::epsilon()) {
246 if(m_fdm->GetDebugLevel() > 1) {
247 FGLogging log(LogLevel::DEBUG);
248 log << "cost convergd, i: " << i << "\n";
249 }
250 break;
251 }
252 if (i > 1000) {
253 if(m_fdm->GetDebugLevel() > 1) {
254 FGLogging log(LogLevel::DEBUG);
255 log << "cost failed to converge, dcost: "
256 << std::scientific
257 << dcost << "\n";
258 }
259 break;
260 }
261 cost = costNew;
262 }
263 }
264
265 double stateSum() {
266 double sum = 0;
267 for (unsigned int i=0;i<x.getSize();i++) sum += x.get(i);
268 return sum;
269 }
270
271 void clear() {
272 x.clear();
273 u.clear();
274 y.clear();
275 }
276
277 // deconstructor
278 virtual ~FGStateSpace() {};
279
280 // linearization function
281 void linearize(std::vector<double> x0, std::vector<double> u0, std::vector<double> y0,
282 std::vector< std::vector<double> > & A,
283 std::vector< std::vector<double> > & B,
284 std::vector< std::vector<double> > & C,
285 std::vector< std::vector<double> > & D);
286
287
288private:
289
290 // compute numerical jacobian of a matrix
291 void numericalJacobian(std::vector< std::vector<double> > & J, ComponentVector & y,
292 ComponentVector & x, const std::vector<double> & y0,
293 const std::vector<double> & x0, double h=1e-5, bool computeYDerivative = false);
294
295 // flight dynamcis model
296 FGFDMExec * m_fdm;
297
298public:
299
300 // components
301
302 class Vt : public Component
303 {
304 public:
305 Vt() : Component("Vt","ft/s") {};
306 double get() const
307 {
308 return m_fdm->GetAuxiliary()->GetVt();
309 }
310 void set(double val)
311 {
312 m_fdm->GetIC()->SetVtrueFpsIC(val);
313 }
314 double getDeriv() const
315 {
316
317 return (m_fdm->GetPropagate()->GetUVW(1)*m_fdm->GetAccelerations()->GetUVWdot(1) +
318 m_fdm->GetPropagate()->GetUVW(2)*m_fdm->GetAccelerations()->GetUVWdot(2) +
319 m_fdm->GetPropagate()->GetUVW(3)*m_fdm->GetAccelerations()->GetUVWdot(3))/
320 m_fdm->GetAuxiliary()->GetVt(); // from lewis, vtrue dot
321 }
322
323 };
324
325 class VGround : public Component
326 {
327 public:
328 VGround() : Component("VGround","ft/s") {};
329 double get() const
330 {
331 return m_fdm->GetAuxiliary()->GetVground();
332 }
333 void set(double val)
334 {
335 m_fdm->GetIC()->SetVgroundFpsIC(val);
336 }
337 };
338
339 class AccelX : public Component
340 {
341 public:
342 AccelX() : Component("AccelX","ft/s^2") {};
343 double get() const
344 {
345 return m_fdm->GetAuxiliary()->GetPilotAccel(1);
346 }
347 void set(double val)
348 {
349 // XXX: not possible to implement currently
350 }
351 };
352
353 class AccelY : public Component
354 {
355 public:
356 AccelY() : Component("AccelY","ft/s^2") {};
357 double get() const
358 {
359 return m_fdm->GetAuxiliary()->GetPilotAccel(2);
360 }
361 void set(double val)
362 {
363 // XXX: not possible to implement currently
364 }
365 };
366
367 class AccelZ : public Component
368 {
369 public:
370 AccelZ() : Component("AccelZ","ft/s^2") {};
371 double get() const
372 {
373 return m_fdm->GetAuxiliary()->GetPilotAccel(3);
374 }
375 void set(double val)
376 {
377 // XXX: not possible to implement currently
378 }
379 };
380
381 class Alpha : public Component
382 {
383 public:
384 Alpha() : Component("Alpha","rad") {};
385 double get() const
386 {
387 return m_fdm->GetAuxiliary()->Getalpha();
388 }
389 void set(double val)
390 {
391 double beta = m_fdm->GetIC()->GetBetaDegIC();
392 double psi = m_fdm->GetIC()->GetPsiRadIC();
393 double theta = m_fdm->GetIC()->GetThetaRadIC();
394 m_fdm->GetIC()->SetAlphaRadIC(val);
395 m_fdm->GetIC()->SetBetaRadIC(beta);
396 m_fdm->GetIC()->SetPsiRadIC(psi);
397 m_fdm->GetIC()->SetThetaRadIC(theta);
398 }
399 double getDeriv() const
400 {
401 return m_fdm->GetAuxiliary()->Getadot();
402 }
403 };
404
405 class Theta : public Component
406 {
407 public:
408 Theta() : Component("Theta","rad") {};
409 double get() const
410 {
411 return m_fdm->GetPropagate()->GetEuler(2);
412 }
413 void set(double val)
414 {
415 m_fdm->GetIC()->SetFlightPathAngleRadIC(val-m_fdm->GetIC()->GetAlphaRadIC());
416 //m_fdm->GetIC()->SetThetaRadIC(val);
417 }
418 double getDeriv() const
419 {
420 return m_fdm->GetAuxiliary()->GetEulerRates(2);
421 }
422 };
423
424 class Q : public Component
425 {
426 public:
427 Q() : Component("Q","rad/s") {};
428 double get() const
429 {
430 return m_fdm->GetPropagate()->GetPQR(2);
431 }
432 void set(double val)
433 {
434 m_fdm->GetIC()->SetQRadpsIC(val);
435 }
436 double getDeriv() const
437 {
438 return m_fdm->GetAccelerations()->GetPQRdot(2);
439 }
440 };
441
442 class Alt : public Component
443 {
444 public:
445 Alt() : Component("Alt","ft") {};
446 double get() const
447 {
448 return m_fdm->GetPropagate()->GetAltitudeASL();
449 }
450 void set(double val)
451 {
452 m_fdm->GetIC()->SetAltitudeASLFtIC(val);
453 }
454 double getDeriv() const
455 {
456 return m_fdm->GetPropagate()->Gethdot();
457 }
458 };
459
460 class Beta : public Component
461 {
462 public:
463 Beta() : Component("Beta","rad") {};
464 double get() const
465 {
466 return m_fdm->GetAuxiliary()->Getbeta();
467 }
468 void set(double val)
469 {
470 double psi = m_fdm->GetIC()->GetPsiRadIC();
471 m_fdm->GetIC()->SetBetaRadIC(val);
472 m_fdm->GetIC()->SetPsiRadIC(psi);
473 }
474 double getDeriv() const
475 {
476 return m_fdm->GetAuxiliary()->Getbdot();
477 }
478 };
479
480 class Phi : public Component
481 {
482 public:
483 Phi() : Component("Phi","rad") {};
484 double get() const
485 {
486 return m_fdm->GetPropagate()->GetEuler(1);
487 }
488 void set(double val)
489 {
490 m_fdm->GetIC()->SetPhiRadIC(val);
491 }
492 double getDeriv() const
493 {
494 return m_fdm->GetAuxiliary()->GetEulerRates(1);
495 }
496 };
497
498 class P : public Component
499 {
500 public:
501 P() : Component("P","rad/s") {};
502 double get() const
503 {
504 return m_fdm->GetPropagate()->GetPQR(1);
505 }
506 void set(double val)
507 {
508 m_fdm->GetIC()->SetPRadpsIC(val);
509 }
510 double getDeriv() const
511 {
512 return m_fdm->GetAccelerations()->GetPQRdot(1);
513 }
514 };
515
516 class R : public Component
517 {
518 public:
519 R() : Component("R","rad/s") {};
520 double get() const
521 {
522 return m_fdm->GetPropagate()->GetPQR(3);
523 }
524 void set(double val)
525 {
526 m_fdm->GetIC()->SetRRadpsIC(val);
527 }
528 double getDeriv() const
529 {
530 return m_fdm->GetAccelerations()->GetPQRdot(3);
531 }
532 };
533
534 class Psi : public Component
535 {
536 public:
537 Psi() : Component("Psi","rad") {};
538 double get() const
539 {
540 return m_fdm->GetPropagate()->GetEuler(3);
541 }
542 void set(double val)
543 {
544 m_fdm->GetIC()->SetPsiRadIC(val);
545 }
546 double getDeriv() const
547 {
548 return m_fdm->GetAuxiliary()->GetEulerRates(3);
549 }
550 };
551
552 class ThrottleCmd : public Component
553 {
554 public:
555 ThrottleCmd() : Component("ThtlCmd","norm") {};
556 double get() const
557 {
558 return m_fdm->GetFCS()->GetThrottleCmd(0);
559 }
560 void set(double val)
561 {
562 for (unsigned int i=0;i<m_fdm->GetPropulsion()->GetNumEngines();i++)
563 m_fdm->GetFCS()->SetThrottleCmd(i,val);
564 m_fdm->GetFCS()->Run(true);
565 }
566 };
567
568 class ThrottlePos : public Component
569 {
570 public:
571 ThrottlePos() : Component("ThtlPos","norm") {};
572 double get() const
573 {
574 return m_fdm->GetFCS()->GetThrottlePos(0);
575 }
576 void set(double val)
577 {
578 for (unsigned int i=0;i<m_fdm->GetPropulsion()->GetNumEngines();i++)
579 m_fdm->GetFCS()->SetThrottlePos(i,val);
580 }
581 };
582
583 class DaCmd : public Component
584 {
585 public:
586 DaCmd() : Component("DaCmd","norm") {};
587 double get() const
588 {
589 return m_fdm->GetFCS()->GetDaCmd();
590 }
591 void set(double val)
592 {
593 m_fdm->GetFCS()->SetDaCmd(val);
594 m_fdm->GetFCS()->Run(true);
595 }
596 };
597
598 class DaPos : public Component
599 {
600 public:
601 DaPos() : Component("DaPos","norm") {};
602 double get() const
603 {
604 return m_fdm->GetFCS()->GetDaLPos();
605 }
606 void set(double val)
607 {
608 m_fdm->GetFCS()->SetDaLPos(ofRad,val);
609 m_fdm->GetFCS()->SetDaRPos(ofRad,val); // TODO: check if this is neg.
610 }
611 };
612
613 class DeCmd : public Component
614 {
615 public:
616 DeCmd() : Component("DeCmd","norm") {};
617 double get() const
618 {
619 return m_fdm->GetFCS()->GetDeCmd();
620 }
621 void set(double val)
622 {
623 m_fdm->GetFCS()->SetDeCmd(val);
624 m_fdm->GetFCS()->Run(true);
625 }
626 };
627
628 class DePos : public Component
629 {
630 public:
631 DePos() : Component("DePos","norm") {};
632 double get() const
633 {
634 return m_fdm->GetFCS()->GetDePos();
635 }
636 void set(double val)
637 {
638 m_fdm->GetFCS()->SetDePos(ofRad,val);
639 }
640 };
641
642 class DrCmd : public Component
643 {
644 public:
645 DrCmd() : Component("DrCmd","norm") {};
646 double get() const
647 {
648 return m_fdm->GetFCS()->GetDrCmd();
649 }
650 void set(double val)
651 {
652 m_fdm->GetFCS()->SetDrCmd(val);
653 m_fdm->GetFCS()->Run(true);
654 }
655 };
656
657 class DrPos : public Component
658 {
659 public:
660 DrPos() : Component("DrPos","norm") {};
661 double get() const
662 {
663 return m_fdm->GetFCS()->GetDrPos();
664 }
665 void set(double val)
666 {
667 m_fdm->GetFCS()->SetDrPos(ofRad,val);
668 }
669 };
670
671 class Rpm0 : public Component
672 {
673 public:
674 Rpm0() : Component("Rpm0","rev/min") {};
675 double get() const
676 {
677 return m_fdm->GetPropulsion()->GetEngine(0)->GetThruster()->GetRPM();
678 }
679 void set(double val)
680 {
681 m_fdm->GetPropulsion()->GetEngine(0)->GetThruster()->SetRPM(val);
682 }
683 };
684
685 class Rpm1 : public Component
686 {
687 public:
688 Rpm1() : Component("Rpm1","rev/min") {};
689 double get() const
690 {
691 return m_fdm->GetPropulsion()->GetEngine(1)->GetThruster()->GetRPM();
692 }
693 void set(double val)
694 {
695 m_fdm->GetPropulsion()->GetEngine(1)->GetThruster()->SetRPM(val);
696 }
697 };
698
699 class Rpm2 : public Component
700 {
701 public:
702 Rpm2() : Component("Rpm2","rev/min") {};
703 double get() const
704 {
705 return m_fdm->GetPropulsion()->GetEngine(2)->GetThruster()->GetRPM();
706 }
707 void set(double val)
708 {
709 m_fdm->GetPropulsion()->GetEngine(2)->GetThruster()->SetRPM(val);
710 }
711 };
712
713 class Rpm3 : public Component
714 {
715 public:
716 Rpm3() : Component("Rpm3","rev/min") {};
717 double get() const
718 {
719 return m_fdm->GetPropulsion()->GetEngine(3)->GetThruster()->GetRPM();
720 }
721 void set(double val)
722 {
723 m_fdm->GetPropulsion()->GetEngine(3)->GetThruster()->SetRPM(val);
724 }
725 };
726
727 class PropPitch : public Component
728 {
729 public:
730 PropPitch() : Component("Prop Pitch","deg") {};
731 double get() const
732 {
733 return m_fdm->GetPropulsion()->GetEngine(0)->GetThruster()->GetPitch();
734 }
735 void set(double val)
736 {
737 for (unsigned int i=0;i<m_fdm->GetPropulsion()->GetNumEngines();i++)
738 m_fdm->GetPropulsion()->GetEngine(i)->GetThruster()->SetPitch(val);
739 }
740 };
741
742 class Longitude : public Component
743 {
744 public:
745 Longitude() : Component("Longitude","rad") {};
746 double get() const
747 {
748 return m_fdm->GetPropagate()->GetLongitude();
749 }
750 void set(double val)
751 {
752 m_fdm->GetIC()->SetLongitudeRadIC(val);
753 }
754 double getDeriv() const
755 {
756 return m_fdm->GetPropagate()->GetVel(2)/(cos(m_fdm->GetPropagate()->GetLatitude())*m_fdm->GetPropagate()->GetRadius());
757 }
758 };
759
760 class Latitude : public Component
761 {
762 public:
763 Latitude() : Component("Latitude","rad") {};
764 double get() const
765 {
766 return m_fdm->GetPropagate()->GetLatitude();
767 }
768 void set(double val)
769 {
770 m_fdm->GetIC()->SetLatitudeRadIC(val);
771 }
772 double getDeriv() const
773 {
774 return m_fdm->GetPropagate()->GetVel(1)/(m_fdm->GetPropagate()->GetRadius());
775 }
776 };
777
778 class Pi : public Component
779 {
780 public:
781 Pi() : Component("P inertial","rad/s") {};
782 double get() const
783 {
784 return m_fdm->GetPropagate()->GetPQRi(1);
785 }
786 void set(double val)
787 {
788 //Set PQR from PQRi
789 //VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
790 m_fdm->GetIC()->SetQRadpsIC(val + \
791 (m_fdm->GetPropagate()->GetPQR(1) - m_fdm->GetPropagate()->GetPQRi(1)));
792 }
793 double getDeriv() const
794 {
795 return m_fdm->GetAccelerations()->GetPQRdot(1);
796 }
797 };
798
799 class Qi : public Component
800 {
801 public:
802 Qi() : Component("Q inertial","rad/s") {};
803 double get() const
804 {
805 return m_fdm->GetPropagate()->GetPQRi(2);
806 }
807 void set(double val)
808 {
809 //Set PQR from PQRi
810 //VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
811 m_fdm->GetIC()->SetQRadpsIC(val + \
812 (m_fdm->GetPropagate()->GetPQR(2) - m_fdm->GetPropagate()->GetPQRi(2)));
813 }
814 double getDeriv() const
815 {
816 return m_fdm->GetAccelerations()->GetPQRdot(2);
817 }
818 };
819
820 class Ri : public Component
821 {
822 public:
823 Ri() : Component("R inertial","rad/s") {};
824 double get() const
825 {
826 return m_fdm->GetPropagate()->GetPQRi(3);
827 }
828 void set(double val)
829 {
830 //Set PQR from PQRi
831 //VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
832 m_fdm->GetIC()->SetQRadpsIC(val + \
833 (m_fdm->GetPropagate()->GetPQR(3) - m_fdm->GetPropagate()->GetPQRi(3)));
834 }
835 double getDeriv() const
836 {
837 return m_fdm->GetAccelerations()->GetPQRdot(3);
838 }
839 };
840
841 class Vn : public Component
842 {
843 public:
844 Vn() : Component("Vel north","feet/s") {};
845 double get() const
846 {
847 return m_fdm->GetPropagate()->GetVel(1);
848 }
849 void set(double val)
850 {
851 m_fdm->GetIC()->SetVNorthFpsIC(val);
852 }
853 double getDeriv() const
854 {
855 //get NED accel from body accel
856 return (m_fdm->GetPropagate()->GetTb2l()*m_fdm->GetAccelerations()->GetUVWdot())(1);
857 }
858 };
859
860 class Ve : public Component
861 {
862 public:
863 Ve() : Component("Vel east","feet/s") {};
864 double get() const
865 {
866 return m_fdm->GetPropagate()->GetVel(2);
867 }
868 void set(double val)
869 {
870 m_fdm->GetIC()->SetVEastFpsIC(val);
871 }
872 double getDeriv() const
873 {
874 //get NED accel from body accel
875 return (m_fdm->GetPropagate()->GetTb2l()*m_fdm->GetAccelerations()->GetUVWdot())(2);
876 }
877 };
878
879 class Vd : public Component
880 {
881 public:
882 Vd() : Component("Vel down","feet/s") {};
883 double get() const
884 {
885 return m_fdm->GetPropagate()->GetVel(3);
886 }
887 void set(double val)
888 {
889 m_fdm->GetIC()->SetVDownFpsIC(val);
890 }
891 double getDeriv() const
892 {
893 //get NED accel from body accel
894 return (m_fdm->GetPropagate()->GetTb2l()*m_fdm->GetAccelerations()->GetUVWdot())(3);
895 }
896 };
897
898 class COG : public Component
899 {
900 public:
901 COG() : Component("Course Over Ground","rad") {};
902 double get() const
903 {
904 //cog = atan2(Ve,Vn)
905 return atan2(m_fdm->GetPropagate()->GetVel(2),m_fdm->GetPropagate()->GetVel(1));
906 }
907 void set(double val)
908 {
909 //set Vn and Ve according to vGround and COG
910 m_fdm->GetIC()->SetVNorthFpsIC(m_fdm->GetAuxiliary()->GetVground()*cos(val));
911 m_fdm->GetIC()->SetVEastFpsIC(m_fdm->GetAuxiliary()->GetVground()*sin(val));
912 }
913 double getDeriv() const
914 {
915 double Vn = m_fdm->GetPropagate()->GetVel(1);
916 double Vndot = (m_fdm->GetPropagate()->GetTb2l()*m_fdm->GetAccelerations()->GetUVWdot())(1);
917 double Ve = m_fdm->GetPropagate()->GetVel(2);
918 double Vedot = (m_fdm->GetPropagate()->GetTb2l()*m_fdm->GetAccelerations()->GetUVWdot())(2);
919
920 //dCOG/dt = dCOG/dVe*dVe/dt + dCOG/dVn*dVn/dt
921 return Vn/(Vn*Vn+Ve*Ve)*Vedot - Ve/(Vn*Vn+Ve*Ve)*Vndot;
922 }
923 };
924
925};
926
927// stream output
928std::ostream &operator<<(std::ostream &out, const FGStateSpace::Component &c );
929std::ostream &operator<<(std::ostream &out, const FGStateSpace::ComponentVector &v );
930std::ostream &operator<<(std::ostream &out, const FGStateSpace &ss );
931std::ostream &operator<<( std::ostream &out, const std::vector< std::vector<double> > &vec2d );
932std::ostream &operator<<( std::ostream &out, const std::vector<double> &vec );
933
934} // JSBSim
935
936#endif
937
938// vim:ts=4:sw=4
Encapsulates the JSBSim simulation executive.
Definition FGFDMExec.h:185
void EnableOutput(void)
Enables data logging to all outputs.
Definition FGFDMExec.h:487
std::shared_ptr< FGInitialCondition > GetIC(void) const
Returns a pointer to the FGInitialCondition object.
Definition FGFDMExec.h:390
int GetDebugLevel(void) const
Retrieves the current debug level setting.
Definition FGFDMExec.h:602
double GetDeltaT(void) const
Returns the simulation delta T.
Definition FGFDMExec.h:553
double Setsim_time(double cur_time)
Sets the current sim time.
bool Run(void)
This function executes each scheduled model in succession.
void DisableOutput(void)
Disables data logging to all outputs.
Definition FGFDMExec.h:485
std::shared_ptr< FGPropulsion > GetPropulsion(void) const
Returns the FGPropulsion pointer.
double GetSimTime(void) const
Returns the cumulative simulation time in seconds.
Definition FGFDMExec.h:550
void Setdt(double delta_t)
Sets the integration time step for the simulation executive.
Definition FGFDMExec.h:572
void SuspendIntegration(void)
Suspends the simulation and sets the delta T to zero.
Definition FGFDMExec.h:556
void Initialize(const FGInitialCondition *FGIC)
Initializes the simulation with initial conditions.
void ResumeIntegration(void)
Resumes the simulation by resetting delta T to the correct value.
Definition FGFDMExec.h:559
Main namespace for the JSBSim Flight Dynamics Model.
Definition FGFDMExec.cpp:71
ostream & operator<<(ostream &os, const FGColumnVector3 &col)
Write vector to a stream.