19 #include "initialization/FGInitialCondition.h" 20 #include "FGStateSpace.h" 28 void FGStateSpace::linearize(
29 std::vector<double> x0,
30 std::vector<double> u0,
31 std::vector<double> y0,
32 std::vector< std::vector<double> > & A,
33 std::vector< std::vector<double> > & B,
34 std::vector< std::vector<double> > & C,
35 std::vector< std::vector<double> > & D)
40 numericalJacobian(A,x,x,x0,x0,h,
true);
42 numericalJacobian(B,x,u,x0,u0,h,
true);
44 numericalJacobian(C,y,x,y0,x0,h);
46 numericalJacobian(D,y,u,y0,u0,h);
50 void FGStateSpace::numericalJacobian(std::vector< std::vector<double> > & J, ComponentVector & y,
51 ComponentVector & x,
const std::vector<double> & y0,
const std::vector<double> & x0,
double h,
bool computeYDerivative)
53 size_t nX = x.getSize();
54 size_t nY = y.getSize();
55 double f1 = 0, f2 = 0, fn1 = 0, fn2 = 0;
57 for (
unsigned int iY=0;iY<nY;iY++)
60 for (
unsigned int iX=0;iX<nX;iX++)
63 x.set(iX,x.get(iX)+h);
64 if (computeYDerivative) f1 = y.getDeriv(iY);
68 x.set(iX,x.get(iX)+2*h);
69 if (computeYDerivative) f2 = y.getDeriv(iY);
73 x.set(iX,x.get(iX)-h);
74 if (computeYDerivative) fn1 = y.getDeriv(iY);
78 x.set(iX,x.get(iX)-2*h);
79 if (computeYDerivative) fn2 = y.getDeriv(iY);
82 double diff1 = f1-fn1;
83 double diff2 = f2-fn2;
86 if (x.getComp(iX)->getUnit().compare(
"rad") == 0) {
87 while(diff1 > M_PI) diff1 -= 2*M_PI;
88 if(diff1 < -M_PI) diff1 += 2*M_PI;
89 if(diff2 > M_PI) diff2 -= 2*M_PI;
90 if(diff2 < -M_PI) diff2 += 2*M_PI;
91 }
else if (x.getComp(iX)->getUnit().compare(
"deg") == 0) {
92 if(diff1 > 180) diff1 -= 360;
93 if(diff1 < -180) diff1 += 360;
94 if(diff2 > 180) diff2 -= 360;
95 if(diff2 < -180) diff2 += 360;
97 J[iY][iX] = (8*diff1-diff2)/(12*h);
103 std::cout << std::scientific <<
"\ty:\t" << y.getName(iY) <<
"\tx:\t" 105 <<
"\tfn2:\t" << fn2 <<
"\tfn1:\t" << fn1
106 <<
"\tf1:\t" << f1 <<
"\tf2:\t" << f2
107 <<
"\tf1-fn1:\t" << f1-fn1
108 <<
"\tf2-fn2:\t" << f2-fn2
109 <<
"\tdf/dx:\t" << J[iY][iX]
110 << std::fixed << std::endl;
116 std::ostream &operator<<( std::ostream &out,
const FGStateSpace::Component &c )
118 out <<
"\t" << c.getName()
119 <<
"\t" << c.getUnit()
120 <<
"\t:\t" << c.get();
124 std::ostream &operator<<( std::ostream &out,
const FGStateSpace::ComponentVector &v )
126 for (
unsigned int i=0; i< v.getSize(); i++)
128 out << *(v.getComp(i)) <<
"\n";
134 std::ostream &operator<<( std::ostream &out,
const FGStateSpace &ss )
136 out <<
"\nX:\n" << ss.x
142 std::ostream &operator<<( std::ostream &out, const std::vector< std::vector<double> > &vec2d )
144 std::streamsize width = out.width();
145 size_t nI = vec2d.size();
146 out << std::left << std::setw(1) <<
"[" << std::right;
147 for (
unsigned int i=0;i<nI;i++)
150 size_t nJ = vec2d[i].size();
151 for (
unsigned int j=0;j<nJ;j++)
154 if (i==0 && j==0) out << std::setw(width-1) << vec2d[i][j];
155 else out << std::setw(width) << vec2d[i][j];
159 if ( i==nI-1 ) out <<
"]";
169 std::ostream &operator<<( std::ostream &out, const std::vector<double> &vec )
171 std::streamsize width = out.width();
172 size_t nI = vec.size();
173 out << std::left << std::setw(1) <<
"[" << std::right;
174 for (
unsigned int i=0;i<nI;i++)
176 if (i==0) out << std::setw(width-1) << vec[i];
177 else out << std::setw(width) << vec[i];
179 if ( i==nI-1 ) out <<
"]";
int GetDebugLevel(void) const
Retrieves the current debug level setting.