1 /*******************************************************************************
3 Header: FGInitialCondition.cpp
7 ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA.
23 Further information about the GNU General Public License can also be found on
24 the world wide web at http://www.gnu.org.
28 --------------------------------------------------------------------------------
32 FUNCTIONAL DESCRIPTION
33 --------------------------------------------------------------------------------
35 The purpose of this class is to take a set of initial conditions and provide
36 a kinematically consistent set of body axis velocity components, euler
37 angles, and altitude. This class does not attempt to trim the model i.e.
38 the sim will most likely start in a very dynamic state (unless, of course,
39 you have chosen your IC's wisely) even after setting it up with this class.
41 ********************************************************************************
43 *******************************************************************************/
46 # include <simgear/compiler.h>
47 # ifdef SG_HAVE_STD_INCLUDES
53 # if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
60 #include "FGInitialCondition.h"
61 #include <FGFDMExec.h>
62 #include <models/FGInertial.h>
63 #include <models/FGAtmosphere.h>
64 #include <models/FGAerodynamics.h>
65 #include <models/FGPropagate.h>
66 #include <input_output/FGPropertyManager.h>
67 #include <models/FGPropulsion.h>
68 #include <input_output/FGXMLParse.h>
72 static const char *IdSrc = "$Id$";
73 static const char *IdHdr = ID_INITIALCONDITION;
75 //******************************************************************************
77 FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec)
94 sea_level_radius = FDMExec->GetInertial()->RefRadius();
95 radius_to_vehicle = FDMExec->GetInertial()->RefRadius();
98 salpha=sbeta=stheta=sphi=spsi=sgamma=0;
99 calpha=cbeta=ctheta=cphi=cpsi=cgamma=1;
101 if(FDMExec != NULL ) {
103 fdmex->GetPropagate()->Seth(altitude);
104 fdmex->GetAtmosphere()->Run();
105 PropertyManager=fdmex->GetPropertyManager();
108 cout << "FGInitialCondition: This class requires a pointer to a valid FGFDMExec object" << endl;
114 //******************************************************************************
116 FGInitialCondition::~FGInitialCondition()
122 //******************************************************************************
124 void FGInitialCondition::SetVcalibratedKtsIC(double tt) {
126 if(getMachFromVcas(&mach,tt*ktstofps)) {
127 //cout << "Mach: " << mach << endl;
130 vt=mach*fdmex->GetAtmosphere()->GetSoundSpeed();
131 ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
132 //cout << "Vt: " << vt*fpstokts << " Vc: " << vc*fpstokts << endl;
135 cout << "Failed to get Mach number for given Vc and altitude, Vc unchanged." << endl;
136 cout << "Please mail the set of initial conditions used to apeden@earthlink.net" << endl;
140 //******************************************************************************
142 void FGInitialCondition::SetVequivalentKtsIC(double tt) {
145 vt=ve*1/sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
146 mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
150 //******************************************************************************
152 void FGInitialCondition::SetVgroundFpsIC(double tt) {
158 vnorth = vg*cos(psi); veast = vg*sin(psi); vdown = 0;
160 ua = u + uw; va = v + vw; wa = w + ww;
161 vt = sqrt( ua*ua + va*va + wa*wa );
163 vxz = sqrt( u*u + w*w );
164 if( w != 0 ) alpha = atan2( w, u );
165 if( vxz != 0 ) beta = atan2( v, vxz );
166 mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
168 ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
171 //******************************************************************************
173 void FGInitialCondition::SetVtrueFpsIC(double tt) {
176 mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
178 ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
181 //******************************************************************************
183 void FGInitialCondition::SetMachIC(double tt) {
185 lastSpeedSet=setmach;
186 vt=mach*fdmex->GetAtmosphere()->GetSoundSpeed();
188 ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
189 //cout << "Vt: " << vt*fpstokts << " Vc: " << vc*fpstokts << endl;
192 //******************************************************************************
194 void FGInitialCondition::SetClimbRateFpmIC(double tt) {
195 SetClimbRateFpsIC(tt/60.0);
198 //******************************************************************************
200 void FGInitialCondition::SetClimbRateFpsIC(double tt) {
205 sgamma=sin(gamma); cgamma=cos(gamma);
209 //******************************************************************************
211 void FGInitialCondition::SetFlightPathAngleRadIC(double tt) {
213 sgamma=sin(gamma); cgamma=cos(gamma);
218 //******************************************************************************
220 void FGInitialCondition::SetAlphaRadIC(double tt) {
222 salpha=sin(alpha); calpha=cos(alpha);
226 //******************************************************************************
228 void FGInitialCondition::SetThetaRadIC(double tt) {
230 stheta=sin(theta); ctheta=cos(theta);
234 //******************************************************************************
236 void FGInitialCondition::SetBetaRadIC(double tt) {
238 sbeta=sin(beta); cbeta=cos(beta);
243 //******************************************************************************
245 void FGInitialCondition::SetPhiRadIC(double tt) {
247 sphi=sin(phi); cphi=cos(phi);
251 //******************************************************************************
253 void FGInitialCondition::SetPsiRadIC(double tt) {
255 spsi=sin(psi); cpsi=cos(psi);
259 //******************************************************************************
261 void FGInitialCondition::SetUBodyFpsIC(double tt) {
263 vt=sqrt(u*u + v*v + w*w);
267 //******************************************************************************
269 void FGInitialCondition::SetVBodyFpsIC(double tt) {
271 vt=sqrt(u*u + v*v + w*w);
275 //******************************************************************************
277 void FGInitialCondition::SetWBodyFpsIC(double tt) {
279 vt=sqrt( u*u + v*v + w*w );
283 //******************************************************************************
285 double FGInitialCondition::GetUBodyFpsIC(void) const {
286 if(lastSpeedSet == setvg )
289 return vt*calpha*cbeta - uw;
292 //******************************************************************************
294 double FGInitialCondition::GetVBodyFpsIC(void) const {
295 if( lastSpeedSet == setvg )
298 return vt*sbeta - vw;
302 //******************************************************************************
304 double FGInitialCondition::GetWBodyFpsIC(void) const {
305 if( lastSpeedSet == setvg )
308 return vt*salpha*cbeta -ww;
311 //******************************************************************************
313 void FGInitialCondition::SetWindNEDFpsIC(double wN, double wE, double wD ) {
314 wnorth = wN; weast = wE; wdown = wD;
315 lastWindSet = setwned;
317 if(lastSpeedSet == setvg)
321 //******************************************************************************
323 void FGInitialCondition::SetCrossWindKtsIC(double cross){
324 wcross=cross*ktstofps;
327 if(lastSpeedSet == setvg)
332 //******************************************************************************
334 // positive from left
335 void FGInitialCondition::SetHeadWindKtsIC(double head){
339 if(lastSpeedSet == setvg)
344 //******************************************************************************
346 void FGInitialCondition::SetWindDownKtsIC(double wD) {
349 if(lastSpeedSet == setvg)
353 //******************************************************************************
355 void FGInitialCondition::SetWindMagKtsIC(double mag) {
359 if(lastSpeedSet == setvg)
363 //******************************************************************************
365 void FGInitialCondition::SetWindDirDegIC(double dir) {
369 if(lastSpeedSet == setvg)
374 //******************************************************************************
376 void FGInitialCondition::calcWindUVW(void) {
378 switch(lastWindSet) {
380 wnorth=wmag*cos(wdir);
381 weast=wmag*sin(wdir);
384 wnorth=whead*cos(psi) + wcross*cos(psi+M_PI/2);
385 weast=whead*sin(psi) + wcross*sin(psi+M_PI/2);
390 uw=wnorth*ctheta*cpsi +
393 vw=wnorth*( sphi*stheta*cpsi - cphi*spsi ) +
394 weast*( sphi*stheta*spsi + cphi*cpsi ) +
396 ww=wnorth*(cphi*stheta*cpsi + sphi*spsi) +
397 weast*(cphi*stheta*spsi - sphi*cpsi) +
401 /* cout << "FGInitialCondition::calcWindUVW: wnorth, weast, wdown "
402 << wnorth << ", " << weast << ", " << wdown << endl;
403 cout << "FGInitialCondition::calcWindUVW: theta, phi, psi "
404 << theta << ", " << phi << ", " << psi << endl;
405 cout << "FGInitialCondition::calcWindUVW: uw, vw, ww "
406 << uw << ", " << vw << ", " << ww << endl; */
410 //******************************************************************************
412 void FGInitialCondition::SetAltitudeFtIC(double tt) {
414 fdmex->GetPropagate()->Seth(altitude);
415 fdmex->GetAtmosphere()->Run();
416 //lets try to make sure the user gets what they intended
418 switch(lastSpeedSet) {
422 SetVtrueKtsIC(vt*fpstokts);
425 SetVcalibratedKtsIC(vc*fpstokts);
428 SetVequivalentKtsIC(ve*fpstokts);
439 //******************************************************************************
441 void FGInitialCondition::SetAltitudeAGLFtIC(double tt) {
442 SetAltitudeFtIC(terrain_altitude + tt);
445 //******************************************************************************
447 void FGInitialCondition::SetSeaLevelRadiusFtIC(double tt) {
448 sea_level_radius = tt;
451 //******************************************************************************
453 void FGInitialCondition::SetTerrainAltitudeFtIC(double tt) {
457 //******************************************************************************
459 void FGInitialCondition::calcUVWfromNED(void) {
460 u=vnorth*ctheta*cpsi +
463 v=vnorth*( sphi*stheta*cpsi - cphi*spsi ) +
464 veast*( sphi*stheta*spsi + cphi*cpsi ) +
466 w=vnorth*( cphi*stheta*cpsi + sphi*spsi ) +
467 veast*( cphi*stheta*spsi - sphi*cpsi ) +
471 //******************************************************************************
473 void FGInitialCondition::SetVnorthFpsIC(double tt) {
476 vt=sqrt(u*u + v*v + w*w);
480 //******************************************************************************
482 void FGInitialCondition::SetVeastFpsIC(double tt) {
485 vt=sqrt(u*u + v*v + w*w);
489 //******************************************************************************
491 void FGInitialCondition::SetVdownFpsIC(double tt) {
494 vt=sqrt(u*u + v*v + w*w);
495 SetClimbRateFpsIC(-1*vdown);
499 //******************************************************************************
501 bool FGInitialCondition::getMachFromVcas(double *Mach,double vcas) {
507 sfunc=&FGInitialCondition::calcVcas;
508 if(findInterval(vcas,guess)) {
509 if(solve(&mach,vcas))
515 //******************************************************************************
517 bool FGInitialCondition::getAlpha(void) {
519 double guess=theta-gamma;
521 if(vt < 0.01) return 0;
524 xmin=fdmex->GetAerodynamics()->GetAlphaCLMin();
525 xmax=fdmex->GetAerodynamics()->GetAlphaCLMax();
526 sfunc=&FGInitialCondition::GammaEqOfAlpha;
527 if(findInterval(0,guess)){
538 //******************************************************************************
540 bool FGInitialCondition::getTheta(void) {
542 double guess=alpha+gamma;
544 if(vt < 0.01) return 0;
548 sfunc=&FGInitialCondition::GammaEqOfTheta;
549 if(findInterval(0,guess)){
560 //******************************************************************************
562 double FGInitialCondition::GammaEqOfTheta(double Theta) {
564 double sTheta,cTheta;
566 //theta=Theta; stheta=sin(theta); ctheta=cos(theta);
567 sTheta=sin(Theta); cTheta=cos(Theta);
569 a=wdown + vt*calpha*cbeta + uw;
570 b=vt*sphi*sbeta + vw*sphi;
571 c=vt*cphi*salpha*cbeta + ww*cphi;
572 return vt*sgamma - ( a*sTheta - (b+c)*cTheta);
575 //******************************************************************************
577 double FGInitialCondition::GammaEqOfAlpha(double Alpha) {
579 double sAlpha,cAlpha;
580 sAlpha=sin(Alpha); cAlpha=cos(Alpha);
581 a=wdown + vt*cAlpha*cbeta + uw;
582 b=vt*sphi*sbeta + vw*sphi;
583 c=vt*cphi*sAlpha*cbeta + ww*cphi;
585 return vt*sgamma - ( a*stheta - (b+c)*ctheta );
588 //******************************************************************************
590 double FGInitialCondition::calcVcas(double Mach) {
592 double p=fdmex->GetAtmosphere()->GetPressure();
593 double psl=fdmex->GetAtmosphere()->GetPressureSL();
594 double rhosl=fdmex->GetAtmosphere()->GetDensitySL();
595 double pt,A,B,D,vcas;
597 if(Mach < 1) //calculate total pressure assuming isentropic flow
598 pt=p*pow((1 + 0.2*Mach*Mach),3.5);
600 // shock in front of pitot tube, we'll assume its normal and use
601 // the Rayleigh Pitot Tube Formula, i.e. the ratio of total
602 // pressure behind the shock to the static pressure in front
605 //the normal shock assumption should not be a bad one -- most supersonic
606 //aircraft place the pitot probe out front so that it is the forward
607 //most point on the aircraft. The real shock would, of course, take
608 //on something like the shape of a rounded-off cone but, here again,
609 //the assumption should be good since the opening of the pitot probe
610 //is very small and, therefore, the effects of the shock curvature
611 //should be small as well. AFAIK, this approach is fairly well accepted
612 //within the aerospace community
614 B = 5.76*Mach*Mach/(5.6*Mach*Mach - 0.8);
616 // The denominator above is zero for Mach ~ 0.38, for which
617 // we'll never be here, so we're safe
619 D = (2.8*Mach*Mach-0.4)*0.4167;
623 A = pow(((pt-p)/psl+1),0.28571);
624 vcas = sqrt(7*psl/rhosl*(A-1));
625 //cout << "calcVcas: vcas= " << vcas*fpstokts << " mach= " << Mach << " pressure: " << pt << endl;
629 //******************************************************************************
631 bool FGInitialCondition::findInterval(double x,double guess) {
632 //void find_interval(inter_params &ip,eqfunc f,double y,double constant, int &flag){
636 double flo,fhi,fguess;
639 fguess=(this->*sfunc)(guess)-x;
645 if(lo < xmin) lo=xmin;
646 if(hi > xmax) hi=xmax;
648 flo=(this->*sfunc)(lo)-x;
649 fhi=(this->*sfunc)(hi)-x;
650 if(flo*fhi <=0) { //found interval with root
652 if(flo*fguess <= 0) { //narrow interval down a bit
653 hi=lo+step; //to pass solver interval that is as
656 else if(fhi*fguess <= 0) {
660 //cout << "findInterval: i=" << i << " Lo= " << lo << " Hi= " << hi << endl;
662 while((found == 0) && (i <= 100));
668 //******************************************************************************
670 bool FGInitialCondition::solve(double *y,double x)
672 double x1,x2,x3,f1,f2,f3,d,d0;
674 double const relax =0.9;
682 f1=(this->*sfunc)(x1)-x;
683 f3=(this->*sfunc)(x3)-x;
688 while ((fabs(d) > eps) && (i < 100)) {
690 x2 = x1-d*d0*f1/(f3-f1);
692 f2=(this->*sfunc)(x2)-x;
693 //cout << "solve x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl;
694 //cout << " " << f1 << "," << f2 << "," << f3 << endl;
696 if(fabs(f2) <= 0.001) {
698 } else if(f1*f2 <= 0.0) {
702 } else if(f2*f3 <= 0) {
715 //cout << "Success= " << success << " Vcas: " << vcas*fpstokts << " Mach: " << x2 << endl;
719 //******************************************************************************
721 double FGInitialCondition::GetWindDirDegIC(void) const {
723 return atan2(weast,wnorth)*radtodeg;
730 //******************************************************************************
732 bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
734 string resetDef, acpath;
735 ifstream initialization_file;
736 FGXMLParse initialization_file_parser;
737 Element *document, *el;
745 if( useStoredPath ) {
746 acpath = fdmex->GetAircraftPath() + sep + fdmex->GetModelName();
747 resetDef = acpath + sep + rstfile + ".xml";
752 initialization_file.open(resetDef.c_str());
753 if ( !initialization_file.is_open()) {
754 cerr << "Could not open initialization file: " << resetDef << endl;
758 readXML(initialization_file, initialization_file_parser);
759 document = initialization_file_parser.GetDocument(); // document holds the
760 // initialization description
761 if (document->GetName() != string("initialize")) {
762 cerr << "File: " << resetDef << " is not a reset file" << endl;
766 if (document->FindElement("ubody"))
767 SetUBodyFpsIC(document->FindElementValueAsNumberConvertTo("ubody", "FT/SEC"));
768 if (document->FindElement("vbody"))
769 SetVBodyFpsIC(document->FindElementValueAsNumberConvertTo("vbody", "FT/SEC"));
770 if (document->FindElement("wbody"))
771 SetWBodyFpsIC(document->FindElementValueAsNumberConvertTo("wbody", "FT/SEC"));
772 if (document->FindElement("latitude"))
773 SetLatitudeDegIC(document->FindElementValueAsNumberConvertTo("latitude", "DEG"));
774 if (document->FindElement("longitude"))
775 SetLongitudeDegIC(document->FindElementValueAsNumberConvertTo("longitude", "DEG"));
776 if (document->FindElement("phi"))
777 SetPhiDegIC(document->FindElementValueAsNumberConvertTo("phi", "DEG"));
778 if (document->FindElement("theta"))
779 SetThetaDegIC(document->FindElementValueAsNumberConvertTo("theta", "DEG"));
780 if (document->FindElement("psi"))
781 SetPsiDegIC(document->FindElementValueAsNumberConvertTo("psi", "DEG"));
782 if (document->FindElement("alpha"))
783 SetAlphaDegIC(document->FindElementValueAsNumberConvertTo("alpha", "DEG"));
784 if (document->FindElement("beta"))
785 SetBetaDegIC(document->FindElementValueAsNumberConvertTo("beta", "DEG"));
786 if (document->FindElement("gamma"))
787 SetFlightPathAngleDegIC(document->FindElementValueAsNumberConvertTo("gamma", "DEG"));
788 if (document->FindElement("roc"))
789 SetClimbRateFpmIC(document->FindElementValueAsNumberConvertTo("roc", "FT/SEC"));
790 if (document->FindElement("altitude"))
791 SetAltitudeFtIC(document->FindElementValueAsNumberConvertTo("altitude", "FT"));
792 if (document->FindElement("winddir"))
793 SetWindDirDegIC(document->FindElementValueAsNumberConvertTo("winddir", "DEG"));
794 if (document->FindElement("vwind"))
795 SetWindMagKtsIC(document->FindElementValueAsNumberConvertTo("vwind", "FT/SEC"));
796 if (document->FindElement("hwind"))
797 SetHeadWindKtsIC(document->FindElementValueAsNumberConvertTo("hwind", "KTS"));
798 if (document->FindElement("xwind"))
799 SetCrossWindKtsIC(document->FindElementValueAsNumberConvertTo("xwind", "KTS"));
800 if (document->FindElement("vc"))
801 SetVcalibratedKtsIC(document->FindElementValueAsNumberConvertTo("vc", "FT/SEC"));
802 if (document->FindElement("mach"))
803 SetMachIC(document->FindElementValueAsNumber("mach"));
804 if (document->FindElement("vground"))
805 SetVgroundKtsIC(document->FindElementValueAsNumberConvertTo("vground", "FT/SEC"));
806 if (document->FindElement("running")) {
807 n = document->FindElementValueAsNumber("running");
809 FGPropulsion* propulsion = fdmex->GetPropulsion();
810 for(int i=0; i<propulsion->GetNumEngines(); i++) {
811 propulsion->GetEngine(i)->SetRunning(true);
821 //******************************************************************************
823 void FGInitialCondition::bind(void){
824 PropertyManager->Tie("ic/vc-kts", this,
825 &FGInitialCondition::GetVcalibratedKtsIC,
826 &FGInitialCondition::SetVcalibratedKtsIC,
828 PropertyManager->Tie("ic/ve-kts", this,
829 &FGInitialCondition::GetVequivalentKtsIC,
830 &FGInitialCondition::SetVequivalentKtsIC,
832 PropertyManager->Tie("ic/vg-kts", this,
833 &FGInitialCondition::GetVgroundKtsIC,
834 &FGInitialCondition::SetVgroundKtsIC,
836 PropertyManager->Tie("ic/vt-kts", this,
837 &FGInitialCondition::GetVtrueKtsIC,
838 &FGInitialCondition::SetVtrueKtsIC,
840 PropertyManager->Tie("ic/mach", this,
841 &FGInitialCondition::GetMachIC,
842 &FGInitialCondition::SetMachIC,
844 PropertyManager->Tie("ic/roc-fpm", this,
845 &FGInitialCondition::GetClimbRateFpmIC,
846 &FGInitialCondition::SetClimbRateFpmIC,
848 PropertyManager->Tie("ic/gamma-deg", this,
849 &FGInitialCondition::GetFlightPathAngleDegIC,
850 &FGInitialCondition::SetFlightPathAngleDegIC,
852 PropertyManager->Tie("ic/alpha-deg", this,
853 &FGInitialCondition::GetAlphaDegIC,
854 &FGInitialCondition::SetAlphaDegIC,
856 PropertyManager->Tie("ic/beta-deg", this,
857 &FGInitialCondition::GetBetaDegIC,
858 &FGInitialCondition::SetBetaDegIC,
860 PropertyManager->Tie("ic/theta-deg", this,
861 &FGInitialCondition::GetThetaDegIC,
862 &FGInitialCondition::SetThetaDegIC,
864 PropertyManager->Tie("ic/phi-deg", this,
865 &FGInitialCondition::GetPhiDegIC,
866 &FGInitialCondition::SetPhiDegIC,
868 PropertyManager->Tie("ic/psi-true-deg", this,
869 &FGInitialCondition::GetPsiDegIC );
870 PropertyManager->Tie("ic/lat-gc-deg", this,
871 &FGInitialCondition::GetLatitudeDegIC,
872 &FGInitialCondition::SetLatitudeDegIC,
874 PropertyManager->Tie("ic/long-gc-deg", this,
875 &FGInitialCondition::GetLongitudeDegIC,
876 &FGInitialCondition::SetLongitudeDegIC,
878 PropertyManager->Tie("ic/h-sl-ft", this,
879 &FGInitialCondition::GetAltitudeFtIC,
880 &FGInitialCondition::SetAltitudeFtIC,
882 PropertyManager->Tie("ic/h-agl-ft", this,
883 &FGInitialCondition::GetAltitudeAGLFtIC,
884 &FGInitialCondition::SetAltitudeAGLFtIC,
886 PropertyManager->Tie("ic/sea-level-radius-ft", this,
887 &FGInitialCondition::GetSeaLevelRadiusFtIC,
888 &FGInitialCondition::SetSeaLevelRadiusFtIC,
890 PropertyManager->Tie("ic/terrain-altitude-ft", this,
891 &FGInitialCondition::GetTerrainAltitudeFtIC,
892 &FGInitialCondition::SetTerrainAltitudeFtIC,
894 PropertyManager->Tie("ic/vg-fps", this,
895 &FGInitialCondition::GetVgroundFpsIC,
896 &FGInitialCondition::SetVgroundFpsIC,
898 PropertyManager->Tie("ic/vt-fps", this,
899 &FGInitialCondition::GetVtrueFpsIC,
900 &FGInitialCondition::SetVtrueFpsIC,
902 PropertyManager->Tie("ic/vw-bx-fps", this,
903 &FGInitialCondition::GetWindUFpsIC);
904 PropertyManager->Tie("ic/vw-by-fps", this,
905 &FGInitialCondition::GetWindVFpsIC);
906 PropertyManager->Tie("ic/vw-bz-fps", this,
907 &FGInitialCondition::GetWindWFpsIC);
908 PropertyManager->Tie("ic/vw-north-fps", this,
909 &FGInitialCondition::GetWindNFpsIC);
910 PropertyManager->Tie("ic/vw-east-fps", this,
911 &FGInitialCondition::GetWindEFpsIC);
912 PropertyManager->Tie("ic/vw-down-fps", this,
913 &FGInitialCondition::GetWindDFpsIC);
914 PropertyManager->Tie("ic/vw-mag-fps", this,
915 &FGInitialCondition::GetWindFpsIC);
916 PropertyManager->Tie("ic/vw-dir-deg", this,
917 &FGInitialCondition::GetWindDirDegIC,
918 &FGInitialCondition::SetWindDirDegIC,
921 PropertyManager->Tie("ic/roc-fps", this,
922 &FGInitialCondition::GetClimbRateFpsIC,
923 &FGInitialCondition::SetClimbRateFpsIC,
925 PropertyManager->Tie("ic/u-fps", this,
926 &FGInitialCondition::GetUBodyFpsIC,
927 &FGInitialCondition::SetUBodyFpsIC,
929 PropertyManager->Tie("ic/v-fps", this,
930 &FGInitialCondition::GetVBodyFpsIC,
931 &FGInitialCondition::SetVBodyFpsIC,
933 PropertyManager->Tie("ic/w-fps", this,
934 &FGInitialCondition::GetWBodyFpsIC,
935 &FGInitialCondition::SetWBodyFpsIC,
938 PropertyManager->Tie("ic/gamma-rad", this,
939 &FGInitialCondition::GetFlightPathAngleRadIC,
940 &FGInitialCondition::SetFlightPathAngleRadIC,
942 PropertyManager->Tie("ic/alpha-rad", this,
943 &FGInitialCondition::GetAlphaRadIC,
944 &FGInitialCondition::SetAlphaRadIC,
946 PropertyManager->Tie("ic/theta-rad", this,
947 &FGInitialCondition::GetThetaRadIC,
948 &FGInitialCondition::SetThetaRadIC,
950 PropertyManager->Tie("ic/beta-rad", this,
951 &FGInitialCondition::GetBetaRadIC,
952 &FGInitialCondition::SetBetaRadIC,
954 PropertyManager->Tie("ic/phi-rad", this,
955 &FGInitialCondition::GetPhiRadIC,
956 &FGInitialCondition::SetPhiRadIC,
958 PropertyManager->Tie("ic/psi-true-rad", this,
959 &FGInitialCondition::GetPsiRadIC);
960 PropertyManager->Tie("ic/lat-gc-rad", this,
961 &FGInitialCondition::GetLatitudeRadIC,
962 &FGInitialCondition::SetLatitudeRadIC,
964 PropertyManager->Tie("ic/long-gc-rad", this,
965 &FGInitialCondition::GetLongitudeRadIC,
966 &FGInitialCondition::SetLongitudeRadIC,
968 PropertyManager->Tie("ic/p-rad_sec", this,
969 &FGInitialCondition::GetPRadpsIC,
970 &FGInitialCondition::SetPRadpsIC,
972 PropertyManager->Tie("ic/q-rad_sec", this,
973 &FGInitialCondition::GetQRadpsIC,
974 &FGInitialCondition::SetQRadpsIC,
976 PropertyManager->Tie("ic/r-rad_sec", this,
977 &FGInitialCondition::GetRRadpsIC,
978 &FGInitialCondition::SetRRadpsIC,
983 //******************************************************************************
985 void FGInitialCondition::unbind(void)
987 PropertyManager->Untie("ic/vc-kts");
988 PropertyManager->Untie("ic/ve-kts");
989 PropertyManager->Untie("ic/vg-kts");
990 PropertyManager->Untie("ic/vt-kts");
991 PropertyManager->Untie("ic/mach");
992 PropertyManager->Untie("ic/roc-fpm");
993 PropertyManager->Untie("ic/gamma-deg");
994 PropertyManager->Untie("ic/alpha-deg");
995 PropertyManager->Untie("ic/beta-deg");
996 PropertyManager->Untie("ic/theta-deg");
997 PropertyManager->Untie("ic/phi-deg");
998 PropertyManager->Untie("ic/psi-true-deg");
999 PropertyManager->Untie("ic/lat-gc-deg");
1000 PropertyManager->Untie("ic/long-gc-deg");
1001 PropertyManager->Untie("ic/h-sl-ft");
1002 PropertyManager->Untie("ic/h-agl-ft");
1003 PropertyManager->Untie("ic/sea-level-radius-ft");
1004 PropertyManager->Untie("ic/terrain-altitude-ft");
1005 PropertyManager->Untie("ic/vg-fps");
1006 PropertyManager->Untie("ic/vt-fps");
1007 PropertyManager->Untie("ic/vw-bx-fps");
1008 PropertyManager->Untie("ic/vw-by-fps");
1009 PropertyManager->Untie("ic/vw-bz-fps");
1010 PropertyManager->Untie("ic/vw-north-fps");
1011 PropertyManager->Untie("ic/vw-east-fps");
1012 PropertyManager->Untie("ic/vw-down-fps");
1013 PropertyManager->Untie("ic/vw-mag-fps");
1014 PropertyManager->Untie("ic/vw-dir-deg");
1016 PropertyManager->Untie("ic/roc-fps");
1018 PropertyManager->Untie("ic/u-fps");
1019 PropertyManager->Untie("ic/v-fps");
1020 PropertyManager->Untie("ic/w-fps");
1022 PropertyManager->Untie("ic/gamma-rad");
1023 PropertyManager->Untie("ic/alpha-rad");
1024 PropertyManager->Untie("ic/theta-rad");
1025 PropertyManager->Untie("ic/beta-rad");
1026 PropertyManager->Untie("ic/phi-rad");
1027 PropertyManager->Untie("ic/psi-true-rad");
1028 PropertyManager->Untie("ic/lat-gc-rad");
1029 PropertyManager->Untie("ic/long-gc-rad");
1030 PropertyManager->Untie("ic/p-rad_sec");
1031 PropertyManager->Untie("ic/q-rad_sec");
1032 PropertyManager->Untie("ic/r-rad_sec");
1036 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1037 // The bitmasked value choices are as follows:
1038 // unset: In this case (the default) JSBSim would only print
1039 // out the normally expected messages, essentially echoing
1040 // the config files as they are read. If the environment
1041 // variable is not set, debug_lvl is set to 1 internally
1042 // 0: This requests JSBSim not to output any messages
1044 // 1: This value explicity requests the normal JSBSim
1046 // 2: This value asks for a message to be printed out when
1047 // a class is instantiated
1048 // 4: When this value is set, a message is displayed when a
1049 // FGModel object executes its Run() method
1050 // 8: When this value is set, various runtime state variables
1051 // are printed out periodically
1052 // 16: When set various parameters are sanity checked and
1053 // a message is printed out when they go out of bounds
1055 void FGInitialCondition::Debug(int from)
1057 if (debug_lvl <= 0) return;
1059 if (debug_lvl & 1) { // Standard console startup message output
1061 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
1062 if (from == 0) cout << "Instantiated: FGInitialCondition" << endl;
1063 if (from == 1) cout << "Destroyed: FGInitialCondition" << endl;
1065 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
1067 if (debug_lvl & 8 ) { // Runtime state variables
1069 if (debug_lvl & 16) { // Sanity checking
1071 if (debug_lvl & 64) {
1072 if (from == 0) { // Constructor
1073 cout << IdSrc << endl;
1074 cout << IdHdr << endl;