namespace JSBSim {
-IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.189 2016/04/16 12:24:39 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.191 2016/05/16 18:19:57 bcoconni Exp $");
IDENT(IdHdr,ID_FDMEXEC);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GroundReactions->in.VcalibratedKts = Auxiliary->GetVcalibratedKTS();
GroundReactions->in.Temperature = Atmosphere->GetTemperature();
GroundReactions->in.TakeoffThrottle = (FCS->GetThrottlePos().size() > 0) ? (FCS->GetThrottlePos(0) > 0.90) : false;
- GroundReactions->in.SteerPosDeg = FCS->GetSteerPosDeg();
GroundReactions->in.BrakePos = FCS->GetBrakePos();
GroundReactions->in.FCSGearPos = FCS->GetGearPos();
GroundReactions->in.EmptyWeight = MassBalance->GetEmptyWeight();
Models[eOutput]->InitModel();
Run();
+ Propagate->InitializeDerivatives();
ResumeIntegration(); // Restores the integration rate to what it was.
if (debug_lvl > 0) {
Propagate->SetInitialState(FGIC);
Winds->SetWindNED(FGIC->GetWindNEDFpsIC());
Run();
- Propagate->InitializeDerivatives();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (element) {
result = ((FGGroundReactions*)Models[eGroundReactions])->Load(element);
if (!result) {
- cerr << endl << "Aircraft ground_reactions element has problems in file " << aircraftCfgFileName << endl;
+ cerr << endl << element->ReadFrom()
+ << "Aircraft ground_reactions element has problems in file "
+ << aircraftCfgFileName << endl;
return result;
}
- ((FGFCS*)Models[eSystems])->AddGear(((FGGroundReactions*)Models[eGroundReactions])->GetNumGearUnits());
} else {
cerr << endl << "No ground_reactions element was found in the aircraft config file." << endl;
return false;
FCS->SetDeCmd( globals->get_controls()->get_elevator());
FCS->SetPitchTrimCmd( globals->get_controls()->get_elevator_trim() );
FCS->SetDrCmd( -globals->get_controls()->get_rudder() );
- FCS->SetYawTrimCmd( -globals->get_controls()->get_rudder_trim() );
FCS->SetDsCmd( globals->get_controls()->get_rudder() );
+ FCS->SetYawTrimCmd( -globals->get_controls()->get_rudder_trim() );
FCS->SetDfCmd( globals->get_controls()->get_flaps() );
FCS->SetDsbCmd( globals->get_controls()->get_speedbrake() );
FCS->SetDspCmd( globals->get_controls()->get_spoilers() );
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGOutputTextFile.cpp,v 1.11 2014/02/17 05:02:38 jberndt Exp $");
+IDENT(IdSrc,"$Id: FGOutputTextFile.cpp,v 1.12 2016/05/22 10:28:23 bcoconni Exp $");
IDENT(IdHdr,ID_OUTPUTTEXTFILE);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
outstream << "F_{Gear x} (lbs)" + delimeter + "F_{Gear y} (lbs)" + delimeter + "F_{Gear z} (lbs)" + delimeter;
outstream << "F_{Ext x} (lbs)" + delimeter + "F_{Ext y} (lbs)" + delimeter + "F_{Ext z} (lbs)" + delimeter;
outstream << "F_{Buoyant x} (lbs)" + delimeter + "F_{Buoyant y} (lbs)" + delimeter + "F_{Buoyant z} (lbs)" + delimeter;
+ outstream << "F_{Weight x} (lbs)" + delimeter + "F_{Weight y} (lbs)" + delimeter + "F_{Weight z} (lbs)" + delimeter;
outstream << "F_{Total x} (lbs)" + delimeter + "F_{Total y} (lbs)" + delimeter + "F_{Total z} (lbs)";
}
if (SubSystems & ssMoments) {
outstream << Aerodynamics->GetLoD() << delimeter;
outstream << Aerodynamics->GetForces().Dump(delimeter) << delimeter;
outstream << Propulsion->GetForces().Dump(delimeter) << delimeter;
- outstream << GroundReactions->GetForces().Dump(delimeter) << delimeter;
+ outstream << Accelerations->GetGroundForces().Dump(delimeter) << delimeter;
outstream << ExternalReactions->GetForces().Dump(delimeter) << delimeter;
outstream << BuoyantForces->GetForces().Dump(delimeter) << delimeter;
- outstream << Aircraft->GetForces().Dump(delimeter);
+ outstream << Accelerations->GetWeight().Dump(delimeter) << delimeter;
+ outstream << Accelerations->GetForces().Dump(delimeter);
}
if (SubSystems & ssMoments) {
outstream << delimeter;
outstream << Aerodynamics->GetMoments().Dump(delimeter) << delimeter;
outstream << Aerodynamics->GetMomentsMRC().Dump(delimeter) << delimeter;
outstream << Propulsion->GetMoments().Dump(delimeter) << delimeter;
- outstream << GroundReactions->GetMoments().Dump(delimeter) << delimeter;
+ outstream << Accelerations->GetGroundMoments().Dump(delimeter) << delimeter;
outstream << ExternalReactions->GetMoments().Dump(delimeter) << delimeter;
outstream << BuoyantForces->GetMoments().Dump(delimeter) << delimeter;
- outstream << Aircraft->GetMoments().Dump(delimeter);
+ outstream << Accelerations->GetMoments().Dump(delimeter);
}
if (SubSystems & ssAtmosphere) {
outstream << delimeter;
#endif
#include <string>
-#include "simgear/props/props.hxx"
+#include "simgear/props/propertyObject.hxx"
#if !PROPS_STANDALONE
# include "simgear/math/SGMath.hxx"
#endif
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.29 2014/11/15 11:32:54 bcoconni Exp $"
+#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.30 2016/05/05 15:32:42 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
FGPropertyManager(void) { root = new FGPropertyNode; }
/// Constructor
- FGPropertyManager(FGPropertyNode* _root) : root(_root) {};
+ explicit FGPropertyManager(FGPropertyNode* _root) : root(_root) {};
/// Destructor
virtual ~FGPropertyManager(void) { Unbind(); }
}
}
+ template <class T> simgear::PropertyObject<T>
+ CreatePropertyObject(const std::string &path)
+ { return simgear::PropertyObject<T>(root->GetNode(path, true)); }
+
private:
std::vector<SGPropertyNode_ptr> tied_properties;
FGPropertyNode_ptr root;
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.23 2015/03/28 15:03:44 bcoconni Exp $"
+#define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.24 2016/04/17 13:13:29 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
private:
int sckt;
int sckt_in;
- int udpsckt;
DirectionType Direction;
ProtocolType Protocol;
struct sockaddr_in scktName;
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGTable.cpp,v 1.31 2014/01/13 10:46:03 ehofman Exp $");
+IDENT(IdSrc,"$Id: FGTable.cpp,v 1.32 2016/05/22 09:08:05 bcoconni Exp $");
IDENT(IdHdr,ID_TABLE);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
node = PropertyManager->GetNode(property_string);
if (node == 0) {
+ cerr << axisElement->ReadFrom();
throw("IndependentVar property, " + property_string + " in Table definition is not defined.");
}
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGAccelerations.cpp,v 1.28 2016/04/16 12:24:39 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGAccelerations.cpp,v 1.29 2016/05/22 10:28:23 bcoconni Exp $");
IDENT(IdHdr,ID_ACCELERATIONS);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PropertyManager->Tie("accelerations/gravity-ft_sec2", this, &FGAccelerations::GetGravAccelMagnitude);
PropertyManager->Tie("simulation/gravity-model", &gravType);
PropertyManager->Tie("simulation/gravitational-torque", &gravTorque);
+ PropertyManager->Tie("forces/fbx-weight-lbs", this, eX, (PMF)&FGAccelerations::GetWeight);
+ PropertyManager->Tie("forces/fby-weight-lbs", this, eY, (PMF)&FGAccelerations::GetWeight);
+ PropertyManager->Tie("forces/fbz-weight-lbs", this, eZ, (PMF)&FGAccelerations::GetWeight);
PropertyManager->Tie("forces/fbx-total-lbs", this, eX, (PMF)&FGAccelerations::GetForces);
PropertyManager->Tie("forces/fby-total-lbs", this, eY, (PMF)&FGAccelerations::GetForces);
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_ACCELERATIONS "$Id: FGAccelerations.h,v 1.19 2016/04/16 12:24:39 bcoconni Exp $"
+#define ID_ACCELERATIONS "$Id: FGAccelerations.h,v 1.20 2016/05/22 10:28:23 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
NASA SP-8024, May 1969
@author Jon S. Berndt, Mathias Froehlich, Bertrand Coconnier
- @version $Id: FGAccelerations.h,v 1.19 2016/04/16 12:24:39 bcoconni Exp $
+ @version $Id: FGAccelerations.h,v 1.20 2016/05/22 10:28:23 bcoconni Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@return The total moments applied on the body.
*/
double GetMoments(int idx) const { return in.Moment(idx) + vFrictionMoments(idx); }
+ FGColumnVector3 GetMoments(void) const { return in.Moment + vFrictionMoments; }
/** Retrieves the total forces applied on the body.
Retrieves the total forces applied on the body. This does include the
@return The total forces applied on the body.
*/
double GetForces(int idx) const { return in.Force(idx) + vFrictionForces(idx); }
+ FGColumnVector3 GetForces(void) const { return in.Force + vFrictionForces; }
/** Retrieves the ground moments applied on the body.
Retrieves the ground moments applied on the body. This does include the
@return The ground moments applied on the body.
*/
double GetGroundMoments(int idx) const { return in.GroundMoment(idx) + vFrictionMoments(idx); }
+ FGColumnVector3 GetGroundMoments(void) const { return in.GroundMoment + vFrictionMoments; }
/** Retrieves the ground forces applied on the body.
Retrieves the ground forces applied on the body. This does include the
ground normal reaction and friction forces.
- The vector for the total moments in the body frame is organized (Fx, Fy
+ The vector for the ground forces in the body frame is organized (Fx, Fy
, Fz). The vector is 1-based. In other words, GetGroundForces(1) returns
Fx. Various convenience enumerators are defined in FGJSBBase. The relevant
enumerators for the forces returned by this call are, eX=1, eY=2, eZ=3.
- units lbs
+ units lbs.
@param idx the index of the forces component desired (1-based).
@return The ground forces applied on the body.
*/
double GetGroundForces(int idx) const { return in.GroundForce(idx) + vFrictionForces(idx); }
+ FGColumnVector3 GetGroundForces(void) const { return in.GroundForce + vFrictionForces; }
+
+ /** Retrieves the weight applied on the body.
+ Retrieves the weight applied on the body i.e. the force that results from
+ the gravity applied to the body mass.
+ The vector for the weight forces in the body frame is organized (Fx, Fy ,
+ Fz). The vector is 1-based. In other words, GetWeight(1) returns
+ Fx. Various convenience enumerators are defined in FGJSBBase. The relevant
+ enumerators for the forces returned by this call are, eX=1, eY=2, eZ=3.
+ units lbs.
+ @param idx the index of the forces component desired (1-based).
+ @return The ground forces applied on the body.
+ */
+ double GetWeight(int idx) const { return in.Mass * (in.Ti2b * vGravAccel)(idx); }
+ FGColumnVector3 GetWeight(void) const { return in.Mass * in.Ti2b * vGravAccel; }
/** Initializes the FGAccelerations class prior to a new execution.
Initializes the class prior to a new execution when the input data stored
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.55 2014/09/03 17:26:28 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.58 2016/05/22 17:02:13 bcoconni Exp $");
IDENT(IdHdr,ID_AERODYNAMICS);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (FGModel::Run(Holding)) return true;
if (Holding) return false; // if paused don't execute
- unsigned int axis_ctr, ctr;
+ unsigned int axis_ctr;
const double twovel=2*in.Vt;
RunPreFunctions();
vFnative.InitMatrix();
vFnativeAtCG.InitMatrix();
- for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
- for (ctr=0; ctr < AeroFunctions[axis_ctr].size(); ctr++) {
- vFnative(axis_ctr+1) += AeroFunctions[axis_ctr][ctr]->GetValue();
+ for (axis_ctr = 0; axis_ctr < 3; ++axis_ctr) {
+ AeroFunctionArray::iterator f;
+
+ AeroFunctionArray* array = &AeroFunctions[axis_ctr];
+ for (f=array->begin(); f != array->end(); ++f) {
+ // Tell the Functions to cache values, so when the function values are
+ // being requested for output, the functions do not get calculated again
+ // in a context that might have changed, but instead use the values that
+ // have already been calculated for this frame.
+ (*f)->cacheValue(true);
+ vFnative(axis_ctr+1) += (*f)->GetValue();
}
- }
- for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
- for (ctr=0; ctr < AeroFunctionsAtCG[axis_ctr].size(); ctr++) {
- vFnativeAtCG(axis_ctr+1) += AeroFunctionsAtCG[axis_ctr][ctr]->GetValue();
+ array = &AeroFunctionsAtCG[axis_ctr];
+ for (f=array->begin(); f != array->end(); ++f) {
+ (*f)->cacheValue(true); // Same as above
+ vFnativeAtCG(axis_ctr+1) += (*f)->GetValue();
}
}
vMomentsMRC.InitMatrix();
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
- for (ctr = 0; ctr < AeroFunctions[axis_ctr+3].size(); ctr++) {
- vMomentsMRC(axis_ctr+1) += AeroFunctions[axis_ctr+3][ctr]->GetValue();
+ AeroFunctionArray* array = &AeroFunctions[axis_ctr+3];
+ for (AeroFunctionArray::iterator f=array->begin(); f != array->end(); ++f) {
+ // Tell the Functions to cache values, so when the function values are
+ // being requested for output, the functions do not get calculated again
+ // in a context that might have changed, but instead use the values that
+ // have already been calculated for this frame.
+ (*f)->cacheValue(true);
+ vMomentsMRC(axis_ctr+1) += (*f)->GetValue();
}
}
vMoments = vMomentsMRC + vDXYZcg*vForces; // M = r X F
bool FGAerodynamics::Load(Element *document)
{
- string parameter, axis, scratch;
+ string axis;
string scratch_unit="";
Element *temp_element, *axis_element, *function_element;
if (!apply_at_cg) {
try {
ca.push_back( new FGFunction(PropertyManager, function_element) );
- } catch (string const str) {
+ } catch (const string& str) {
cerr << endl << fgred << "Error loading aerodynamic function in "
<< current_func_name << ":" << str << " Aborting." << reset << endl;
return false;
} else {
try {
ca_atCG.push_back( new FGFunction(PropertyManager, function_element) );
- } catch (string const str) {
+ } catch (const string& str) {
cerr << endl << fgred << "Error loading aerodynamic function in "
<< current_func_name << ":" << str << " Aborting." << reset << endl;
return false;
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGAuxiliary.cpp,v 1.71 2016/01/10 12:12:59 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGAuxiliary.cpp,v 1.72 2016/05/21 11:45:22 bcoconni Exp $");
IDENT(IdHdr,ID_AUXILIARY);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double AeroV2 = vAeroUVW(eV)*vAeroUVW(eV);
double AeroW2 = vAeroUVW(eW)*vAeroUVW(eW);
double mUW = AeroU2 + AeroW2;
- double Vtdot = (vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eV)*in.vUVWdot(eV) + vAeroUVW(eW)*in.vUVWdot(eW))/Vt;
double Vt2 = Vt*Vt;
//if (vAeroUVW(eU) < 0.0) signU=-1;
if ( mUW >= 0.001 ) {
+ double Vtdot = (vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eV)*in.vUVWdot(eV) + vAeroUVW(eW)*in.vUVWdot(eW))/Vt;
adot = (vAeroUVW(eU)*in.vUVWdot(eW) - vAeroUVW(eW)*in.vUVWdot(eU))/mUW;
// bdot = (signU*mUW*in.vUVWdot(eV)
// - vAeroUVW(eV)*(vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eW)*in.vUVWdot(eW)))/(Vt2*sqrt(mUW));
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.94 2016/04/03 11:13:19 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.95 2016/05/16 18:19:57 bcoconni Exp $");
IDENT(IdHdr,ID_FCS);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex), ChannelRate(1)
+FGFCS::FGFCS(FGFDMExec* fdm) : FGModel(fdm), ChannelRate(1)
{
int i;
Name = "FGFCS";
systype = stFCS;
- DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
+ fdmex = fdm;
+ DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = 0;
PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
GearCmd = GearPos = 1; // default to gear down
BrakePos.resize(FGLGear::bgNumBrakeGroups);
MixturePos.clear();
PropAdvanceCmd.clear();
PropAdvance.clear();
- SteerPosDeg.clear();
PropFeatherCmd.clear();
PropFeather.clear();
for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = 0.0;
for (i=0; i<PropFeather.size(); i++) PropFeather[i] = 0.0;
- DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
+ DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = 0;
PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
TailhookPos = WingFoldPos = 0.0;
for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
for (i=0; i<PropFeather.size(); i++) PropFeather[i] = PropFeatherCmd[i];
- // Set the default steering angle
- for (i=0; i<SteerPosDeg.size(); i++) {
- FGLGear* gear = FDMExec->GetGroundReactions()->GetGearUnit(i);
- SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
- }
-
// Execute system channels in order
for (i=0; i<SystemChannels.size(); i++) {
if (debug_lvl & 4) cout << " Executing System Channel: " << SystemChannels[i]->GetName() << endl;
Debug(2);
- if (systype == stFCS) bindModel();
-
Element* channel_element = document->FindElement("channel");
while (channel_element) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGFCS::AddGear(unsigned int NumGear)
-{
- SteerPosDeg.clear();
- for (unsigned int i=0; i<NumGear; i++) SteerPosDeg.push_back(0.0);
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
double FGFCS::GetDt(void) const
{
return FDMExec->GetDeltaT()*rate;
PropertyManager->Tie("fcs/left-brake-cmd-norm", this, &FGFCS::GetLBrake, &FGFCS::SetLBrake);
PropertyManager->Tie("fcs/right-brake-cmd-norm", this, &FGFCS::GetRBrake, &FGFCS::SetRBrake);
PropertyManager->Tie("fcs/center-brake-cmd-norm", this, &FGFCS::GetCBrake, &FGFCS::SetCBrake);
- PropertyManager->Tie("fcs/steer-cmd-norm", this, &FGFCS::GetDsCmd, &FGFCS::SetDsCmd);
PropertyManager->Tie("gear/tailhook-pos-norm", this, &FGFCS::GetTailhookPos, &FGFCS::SetTailhookPos);
PropertyManager->Tie("fcs/wing-fold-pos-norm", this, &FGFCS::GetWingFoldPos, &FGFCS::SetWingFoldPos);
&FGFCS::SetPropFeather);
}
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFCS::bindModel(void)
-{
- unsigned int i;
- string tmp;
-
- for (i=0; i<SteerPosDeg.size(); i++) {
- if (FDMExec->GetGroundReactions()->GetGearUnit(i)->GetSteerable()) {
- tmp = CreateIndexedPropertyName("fcs/steer-pos-deg", i);
- PropertyManager->Tie( tmp.c_str(), this, i, &FGFCS::GetSteerPosDeg, &FGFCS::SetSteerPosDeg);
- }
- }
-}
-
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
#include "models/FGModel.h"
#include "models/FGLGear.h"
+#include "models/FGGroundReactions.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_FCS "$Id: FGFCS.h,v 1.50 2016/02/27 16:54:15 bcoconni Exp $"
+#define ID_FCS "$Id: FGFCS.h,v 1.53 2016/05/18 08:06:57 ehofman Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@property gear/tailhook-pos-norm
@author Jon S. Berndt
- @version $Revision: 1.50 $
+ @version $Revision: 1.53 $
@see FGActuator
@see FGDeadBand
@see FGFCSFunction
double GetDrCmd(void) const { return DrCmd; }
/** Gets the steering command.
- @return steering command in range from -1.0 - 1.0 */
- double GetDsCmd(void) const { return DsCmd; }
+ @return steering command in range from -1.0 - 1.0 */
+ double GetDsCmd(void) const { return fdmex->GetGroundReactions()->GetDsCmd(); }
/** Gets the flaps command.
@return flaps command in range from 0 to 1.0 */
const std::vector<double>& GetMixturePos() const {return MixturePos;}
- /** Gets the steering position.
- @return steering position in degrees */
- double GetSteerPosDeg(int gear) const { return SteerPosDeg[gear]; }
-
- const std::vector<double>& GetSteerPosDeg() const {return SteerPosDeg;}
-
/** Gets the gear position (0 up, 1 down), defaults to down
@return gear position (0 up, 1 down) */
double GetGearPos(void) const { return GearPos; }
void SetDrCmd(double cmd) { DrCmd = cmd; }
/** Sets the steering command
- @param cmd steering command in percent*/
- void SetDsCmd(double cmd) { DsCmd = cmd; }
+ @param cmd steering command in percent*/
+ void SetDsCmd(double cmd) { fdmex->GetGroundReactions()->SetDsCmd( cmd ); }
/** Sets the flaps command
@param cmd flaps command in percent*/
@param cmd normalized mixture setting (0.0 - 1.0)*/
void SetMixturePos(int engine, double cmd);
- /** Sets the steering position
- @param cmd steering position in degrees*/
- void SetSteerPosDeg(int gear, double pos) { SteerPosDeg[gear] = pos; }
-
/** Set the gear extend/retract position, defaults to down
@param gear position 0 up, 1 down */
void SetGearPos(double gearpos) { GearPos = gearpos; }
std::string FindFullPathName(const std::string& system_filename) const;
void AddThrottle(void);
- void AddGear(unsigned int NumGear);
double GetDt(void) const;
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
double GetChannelDeltaT(void) const { return GetDt() * ChannelRate; }
private:
- double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
+ double DaCmd, DeCmd, DrCmd, DfCmd, DsbCmd, DspCmd;
double DePos[NForms], DaLPos[NForms], DaRPos[NForms], DrPos[NForms];
double DfPos[NForms], DsbPos[NForms], DspPos[NForms];
double PTrimCmd, YTrimCmd, RTrimCmd;
std::vector <double> PropAdvance;
std::vector <bool> PropFeatherCmd;
std::vector <bool> PropFeather;
- std::vector <double> SteerPosDeg;
//double LeftBrake, RightBrake, CenterBrake; // Brake settings
std::vector <double> BrakePos; // left, center, right - defined by FGLGear:: enum
double GearCmd,GearPos;
double TailhookPos, WingFoldPos;
SystemType systype;
int ChannelRate;
+ FGFDMExec* fdmex;
typedef std::vector <FGFCSChannel*> Channels;
Channels SystemChannels;
void bind(void);
- void bindModel(void);
void bindThrottle(unsigned int);
void Debug(int from);
};
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.51 2014/06/09 11:52:07 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.52 2016/05/16 18:19:57 bcoconni Exp $");
IDENT(IdHdr,ID_GROUNDREACTIONS);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) :
FGModel(fgex),
- FGSurface(fgex)
+ FGSurface(fgex),
+ DsCmd(0.0)
{
Name = "FGGroundReactions";
vForces.InitMatrix();
vMoments.InitMatrix();
+ DsCmd = 0.0;
multipliers.clear();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+void FGGroundReactions::SetDsCmd(double cmd)
+{
+ DsCmd = cmd;
+ for (unsigned int i=0; i<lGear.size(); ++i)
+ lGear[i]->SetSteerCmd(cmd);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
bool FGGroundReactions::Load(Element* document)
{
int num=0;
PropertyManager->Tie("gear/num-units", this, &FGGroundReactions::GetNumGearUnits);
PropertyManager->Tie("gear/wow", this, &FGGroundReactions::GetWOW);
+ PropertyManager->Tie("fcs/steer-cmd-norm", this, &FGGroundReactions::GetDsCmd,
+ &FGGroundReactions::SetDsCmd);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include "FGLGear.h"
#include "math/FGColumnVector3.h"
-#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.28 2014/01/16 09:03:04 ehofman Exp $"
+#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.30 2016/05/16 18:19:57 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@return a pointer to the FGLGear instance of the gear unit requested */
FGLGear* GetGearUnit(int gear) const { return lGear[gear]; }
+ /** Gets the steering command.
+ @return steering command in range from -1.0 - 1.0 */
+ double GetDsCmd(void) const { return DsCmd; }
+
+ /** Sets the steering command
+ @param cmd steering command in percent*/
+ void SetDsCmd(double cmd);
+
void RegisterLagrangeMultiplier(LagrangeMultiplier* lmult) { multipliers.push_back(lmult); }
std::vector <LagrangeMultiplier*>* GetMultipliersList(void) { return &multipliers; }
FGColumnVector3 vForces;
FGColumnVector3 vMoments;
std::vector <LagrangeMultiplier*> multipliers;
+ double DsCmd;
void bind(void);
void Debug(int from);
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.120 2015/08/16 16:13:31 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.123 2016/05/16 18:19:57 bcoconni Exp $");
IDENT(IdHdr,ID_LGEAR);
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
GearNumber(number),
SteerAngle(0.0),
Castered(false),
- StaticFriction(false)
+ StaticFriction(false),
+ eSteerType(stSteer)
{
kSpring = bDamp = bDampRebound = dynamicFCoeff = staticFCoeff = rollingFCoeff = maxSteerAngle = 0;
isRetractable = false;
if (el->FindElement("max_steer"))
maxSteerAngle = el->FindElementValueAsNumberConvertTo("max_steer", "DEG");
- if (maxSteerAngle == 360) {
+ Element* castered_el = el->FindElement("castered");
+
+ if ((maxSteerAngle == 360 && !castered_el)
+ || (castered_el && castered_el->GetDataAsNumber() != 0.0)) {
eSteerType = stCaster;
Castered = true;
}
else
eSteerType = stSteer;
- Element* castering = el->FindElement("castered");
- if (castering) {
- if (castering->GetDataAsNumber() != 0.0) {
- eSteerType = stCaster;
- Castered = true;
- }
- else {
- if (maxSteerAngle == 0.0) {
- eSteerType = stFixed;
- }
- else {
- eSteerType = stSteer;
- }
- Castered = false;
- }
- }
-
GroundReactions = fdmex->GetGroundReactions();
ForceY_Table = 0;
LandingDistanceTraveled = TakeoffDistanceTraveled = TakeoffDistanceTraveled50ft = 0.0;
MaximumStrutForce = MaximumStrutTravel = 0.0;
SinkRate = GroundSpeed = 0.0;
+ SteerAngle = 0.0;
vWhlVelVec.InitMatrix();
void FGLGear::ComputeSlipAngle(void)
{
-// Check that the speed is non-null otherwise use the current angle
+// Check that the speed is non-null otherwise keep the current angle
if (vGroundWhlVel.Magnitude(eX,eY) > 1E-3)
WheelSlip = -atan2(vGroundWhlVel(eY), fabs(vGroundWhlVel(eX)))*radtodeg;
}
void FGLGear::ComputeSteeringAngle(void)
{
- switch (eSteerType) {
- case stSteer:
- SteerAngle = degtorad * in.SteerPosDeg[GearNumber];
- break;
- case stFixed:
- SteerAngle = 0.0;
- break;
- case stCaster:
- if (!Castered)
- SteerAngle = degtorad * in.SteerPosDeg[GearNumber];
- else {
- // Check that the speed is non-null otherwise use the current angle
+ if (Castered) {
+ // Check that the speed is non-null otherwise keep the current angle
if (vWhlVelVec.Magnitude(eX,eY) > 0.1)
SteerAngle = atan2(vWhlVelVec(eY), fabs(vWhlVelVec(eX)));
- }
- break;
- default:
- cerr << "Improper steering type membership detected for this gear." << endl;
- break;
}
}
property_name = base_property_name + "/pos-norm";
PropertyManager->Tie( property_name.c_str(), &GearPos );
}
+
+ if (eSteerType != stFixed) {
+ // This property allows the FCS to override the steering position angle that
+ // is set by the property fcs/steer-cmd-norm. The prefix fcs/ has been kept
+ // for backward compatibility.
+ string tmp = CreateIndexedPropertyName("fcs/steer-pos-deg", GearNumber);
+ PropertyManager->Tie(tmp.c_str(), this, &FGLGear::GetSteerAngleDeg, &FGLGear::SetSteerAngleDeg);
+ }
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_LGEAR "$Id: FGLGear.h,v 1.64 2014/01/28 09:42:21 ehofman Exp $"
+#define ID_LGEAR "$Id: FGLGear.h,v 1.65 2016/05/16 18:19:57 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
</contact>
@endcode
@author Jon S. Berndt
- @version $Id: FGLGear.h,v 1.64 2014/01/28 09:42:21 ehofman Exp $
+ @version $Id: FGLGear.h,v 1.65 2016/05/16 18:19:57 bcoconni Exp $
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
NASA-Ames", NASA CR-2497, January 1975
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
FGColumnVector3 UVW;
FGColumnVector3 vXYZcg; // CG coordinates expressed in the structural frame
FGLocation Location;
- std::vector <double> SteerPosDeg;
std::vector <double> BrakePos;
double FCSGearPos;
double EmptyWeight;
@return true if reporting is turned on */
bool GetReport(void) const { return ReportEnable; }
double GetSteerNorm(void) const { return radtodeg/maxSteerAngle*SteerAngle; }
- double GetDefaultSteerAngle(double cmd) const { return cmd*maxSteerAngle; }
+ void SetSteerCmd(double cmd) { SetSteerAngleDeg(cmd * maxSteerAngle); }
double GetstaticFCoeff(void) const { return staticFCoeff; }
int GetBrakeGroup(void) const { return (int)eBrakeGrp; }
bool IsBogey(void) const { return (eContactType == ctBOGEY);}
double GetGearUnitPos(void) const;
double GetSteerAngleDeg(void) const { return radtodeg*SteerAngle; }
+ void SetSteerAngleDeg(double angle) {
+ if (eSteerType != stFixed && !Castered)
+ SteerAngle = degtorad * angle;
+ }
const struct Inputs& in;
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGPropagate.cpp,v 1.130 2016/04/16 12:24:39 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGPropagate.cpp,v 1.131 2016/05/01 18:25:57 bcoconni Exp $");
IDENT(IdHdr,ID_PROPAGATE);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Propagate rotational / translational velocity, angular /translational position, respectively.
- Integrate(VState.qAttitudeECI, VState.vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position);
- Integrate(VState.vPQRi, in.vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate);
- Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
- Integrate(VState.vInertialVelocity, in.vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate);
+ if (!FDMExec->IntegrationSuspended()) {
+ Integrate(VState.qAttitudeECI, VState.vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position);
+ Integrate(VState.vPQRi, in.vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate);
+ Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
+ Integrate(VState.vInertialVelocity, in.vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate);
+ }
// CAUTION : the order of the operations below is very important to get transformation
// matrices that are consistent with the new state of the vehicle
// 1. Update the Earth position angle (EPA)
- VState.vLocation.IncrementEarthPositionAngle(in.vOmegaPlanet(eZ)*(in.DeltaT*rate));
+ VState.vLocation.IncrementEarthPositionAngle(in.vOmegaPlanet(eZ)*dt);
// 2. Update the Ti2ec and Tec2i transforms from the updated EPA
Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.85 2016/01/02 17:42:53 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.87 2016/05/05 15:38:09 bcoconni Exp $");
IDENT(IdHdr,ID_PROPULSION);
extern short debug_lvl;
numOxiTanks = numFuelTanks = 0;
ActiveEngine = -1; // -1: ALL, 0: Engine 1, 1: Engine 2 ...
tankJ.InitMatrix();
- refuel = dump = false;
DumpRate = 0.0;
RefuelRate = 6000.0;
FuelFreeze = false;
- TotalFuelQuantity = 0.0;
IsBound =
HavePistonEngine =
HaveTurbineEngine =
vMoments.InitMatrix();
for (unsigned int i=0; i<numTanks; i++) Tanks[i]->ResetToIC();
+ TotalFuelQuantity = 0.0;
+ TotalOxidizerQuantity = 0.0;
+ refuel = dump = false;
for (unsigned int i=0; i<numEngines; i++)
Engines[i]->ResetToIC();
}
TotalFuelQuantity = 0.0;
+ TotalOxidizerQuantity = 0.0;
for (i=0; i<numTanks; i++) {
Tanks[i]->Calculate( in.TotalDeltaT, in.TAT_c);
- if (Tanks[i]->GetType() == FGTank::ttFUEL) {
+ switch (Tanks[i]->GetType()) {
+ case FGTank::ttFUEL:
TotalFuelQuantity += Tanks[i]->GetContents();
+ break;
+ case FGTank::ttOXIDIZER:
+ TotalOxidizerQuantity += Tanks[i]->GetContents();
+ break;
+ default:
+ break;
}
}
- if (refuel) DoRefuel( in.TotalDeltaT );
- if (dump) DumpFuel( in.TotalDeltaT );
+ if (refuel.node() && refuel) DoRefuel( in.TotalDeltaT );
+ if (dump.node() && dump) DumpFuel( in.TotalDeltaT );
RunPostFunctions();
PropertyManager->Tie("propulsion/active_engine", this, (iPMF)&FGPropulsion::GetActiveEngine,
&FGPropulsion::SetActiveEngine, true);
- PropertyManager->Tie("propulsion/total-fuel-lbs", this, &FGPropulsion::GetTotalFuelQuantity);
- PropertyManager->Tie("propulsion/refuel", this, &FGPropulsion::GetRefuel,
- &FGPropulsion::SetRefuel, true);
- PropertyManager->Tie("propulsion/fuel_dump", this, &FGPropulsion::GetFuelDump,
- &FGPropulsion::SetFuelDump, true);
PropertyManager->Tie("forces/fbx-prop-lbs", this, eX, (PMF)&FGPropulsion::GetForces);
PropertyManager->Tie("forces/fby-prop-lbs", this, eY, (PMF)&FGPropulsion::GetForces);
PropertyManager->Tie("forces/fbz-prop-lbs", this, eZ, (PMF)&FGPropulsion::GetForces);
PropertyManager->Tie("moments/l-prop-lbsft", this, eX, (PMF)&FGPropulsion::GetMoments);
PropertyManager->Tie("moments/m-prop-lbsft", this, eY, (PMF)&FGPropulsion::GetMoments);
PropertyManager->Tie("moments/n-prop-lbsft", this, eZ, (PMF)&FGPropulsion::GetMoments);
+ TotalFuelQuantity = PropertyManager->CreatePropertyObject<double>("propulsion/total-fuel-lbs");
+ TotalOxidizerQuantity = PropertyManager->CreatePropertyObject<double>("propulsion/total-oxidizer-lbs");
+ refuel = PropertyManager->CreatePropertyObject<bool>("propulsion/refuel");
+ dump = PropertyManager->CreatePropertyObject<bool>("propulsion/fuel_dump");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include <vector>
#include <iosfwd>
+#include "simgear/props/propertyObject.hxx"
#include "FGModel.h"
#include "propulsion/FGEngine.h"
#include "math/FGMatrix33.h"
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.35 2015/01/07 23:22:59 dpculp Exp $"
+#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.36 2016/05/05 15:38:08 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@endcode
@author Jon S. Berndt
- @version $Id: FGPropulsion.h,v 1.35 2015/01/07 23:22:59 dpculp Exp $
+ @version $Id: FGPropulsion.h,v 1.36 2016/05/05 15:38:08 bcoconni Exp $
@see
FGEngine
FGTank
const FGColumnVector3& GetMoments(void) const {return vMoments;}
double GetMoments(int n) const {return vMoments(n);}
- bool GetRefuel(void) const {return refuel;}
- void SetRefuel(bool setting) {refuel = setting;}
- bool GetFuelDump(void) const {return dump;}
- void SetFuelDump(bool setting) {dump = setting;}
double Transfer(int source, int target, double amount);
void DoRefuel(double time_slice);
void DumpFuel(double time_slice);
std::string FindFullPathName(const std::string& filename) const;
inline int GetActiveEngine(void) const {return ActiveEngine;}
inline bool GetFuelFreeze(void) const {return FuelFreeze;}
- double GetTotalFuelQuantity(void) const {return TotalFuelQuantity;}
void SetMagnetos(int setting);
void SetStarter(int setting);
FGColumnVector3 vTankXYZ;
FGColumnVector3 vXYZtank_arm;
FGMatrix33 tankJ;
- bool refuel;
- bool dump;
+ simgear::PropertyObject<bool> refuel;
+ simgear::PropertyObject<bool> dump;
bool FuelFreeze;
- double TotalFuelQuantity;
+ simgear::PropertyObject<double> TotalFuelQuantity;
+ simgear::PropertyObject<double> TotalOxidizerQuantity;
double DumpRate;
double RefuelRate;
bool IsBound;
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGWaypoint.cpp,v 1.6 2015/09/20 20:53:13 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGWaypoint.cpp,v 1.8 2016/05/05 15:32:42 bcoconni Exp $");
IDENT(IdHdr,ID_WAYPOINT);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
source_longitude_unit = 1.0;
if (element->FindElement("target_latitude") ) {
- target_latitude_pNode = PropertyManager->GetNode(element->FindElementValue("target_latitude"));
+ target_latitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("target_latitude"));
if (element->FindElement("target_latitude")->HasAttribute("unit")) {
if (element->FindElement("target_latitude")->GetAttributeValue("unit") == "DEG") {
target_latitude_unit = 0.017453293;
}
}
- } else
- throw("Target latitude is required for waypoint component: "+Name);
+ } else {
+ cerr << element->ReadFrom() << endl
+ << "Target latitude is required for waypoint component: " << Name
+ << endl;
+ throw("Malformed waypoint definition");
+ }
if (element->FindElement("target_longitude") ) {
- target_longitude_pNode = PropertyManager->GetNode(element->FindElementValue("target_longitude"));
+ target_longitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("target_longitude"));
if (element->FindElement("target_longitude")->HasAttribute("unit")) {
if (element->FindElement("target_longitude")->GetAttributeValue("unit") == "DEG") {
target_longitude_unit = 0.017453293;
}
}
- } else
- throw("Target longitude is required for waypoint component: "+Name);
+ } else {
+ cerr << element->ReadFrom() << endl
+ << "Target longitude is required for waypoint component: " << Name
+ << endl;
+ throw("Malformed waypoint definition");
+ }
if (element->FindElement("source_latitude") ) {
- source_latitude_pNode = PropertyManager->GetNode(element->FindElementValue("source_latitude"));
+ source_latitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("source_latitude"));
if (element->FindElement("source_latitude")->HasAttribute("unit")) {
if (element->FindElement("source_latitude")->GetAttributeValue("unit") == "DEG") {
source_latitude_unit = 0.017453293;
}
}
- } else
- throw("Source latitude is required for waypoint component: "+Name);
+ } else {
+ cerr << element->ReadFrom() << endl
+ << "Source latitude is required for waypoint component: " << Name
+ << endl;
+ throw("Malformed waypoint definition");
+ }
if (element->FindElement("source_longitude") ) {
- source_longitude_pNode = PropertyManager->GetNode(element->FindElementValue("source_longitude"));
+ source_longitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("source_longitude"));
if (element->FindElement("source_longitude")->HasAttribute("unit")) {
if (element->FindElement("source_longitude")->GetAttributeValue("unit") == "DEG") {
source_longitude_unit = 0.017453293;
}
}
- } else
- throw("Source longitude is required for waypoint component: "+Name);
+ } else {
+ cerr << element->ReadFrom() << endl
+ << "Source longitude is required for waypoint component: " << Name
+ << endl;
+ throw("Malformed waypoint definition");
+ }
if (element->FindElement("radius"))
radius = element->FindElementValueAsNumberConvertTo("radius", "FT");
- else
- radius = 21144000; // Radius of Earth in feet.
+ else {
+ FGLocation source(source_longitude * source_latitude_unit,
+ source_latitude * source_longitude_unit, 1.0);
+ radius = source.GetSeaLevelRadius(); // Radius of Earth in feet.
+ }
unit = element->GetAttributeValue("unit");
if (WaypointType == eHeading) {
if (!unit.empty()) {
if (unit == "DEG") eUnit = eDeg;
else if (unit == "RAD") eUnit = eRad;
- else throw("Unknown unit "+unit+" in HEADING waypoint component, "+Name);
+ else {
+ cerr << element->ReadFrom() << endl
+ << "Unknown unit " << unit << " in HEADING waypoint component, "
+ << Name << endl;
+ throw("Malformed waypoint definition");
+ }
} else {
eUnit = eRad; // Default is radians if unspecified
}
if (!unit.empty()) {
if (unit == "FT") eUnit = eFeet;
else if (unit == "M") eUnit = eMeters;
- else throw("Unknown unit "+unit+" in DISTANCE waypoint component, "+Name);
+ else {
+ cerr << element->ReadFrom() << endl
+ << "Unknown unit " << unit << " in DISTANCE waypoint component, "
+ << Name << endl;
+ throw("Malformed waypoint definition");
+ }
} else {
eUnit = eFeet; // Default is feet if unspecified
}
bool FGWaypoint::Run(void )
{
- double target_latitude = target_latitude_pNode->getDoubleValue() * target_latitude_unit;
- double target_longitude = target_longitude_pNode->getDoubleValue() * target_longitude_unit;
- double source_latitude = source_latitude_pNode->getDoubleValue() * source_latitude_unit;
- double source_longitude = source_longitude_pNode->getDoubleValue() * source_longitude_unit;
- FGLocation source(source_longitude, source_latitude, radius);
+ double target_latitude_rad = target_latitude * target_latitude_unit;
+ double target_longitude_rad = target_longitude * target_longitude_unit;
+ FGLocation source(source_longitude * source_latitude_unit,
+ source_latitude * source_longitude_unit, radius);
if (WaypointType == eHeading) { // Calculate Heading
- double heading_to_waypoint_rad = source.GetHeadingTo(target_longitude,
- target_latitude);
+ double heading_to_waypoint_rad = source.GetHeadingTo(target_longitude_rad,
+ target_latitude_rad);
- double heading_to_waypoint = 0;
- if (eUnit == eDeg) heading_to_waypoint = heading_to_waypoint_rad * radtodeg;
- else heading_to_waypoint = heading_to_waypoint_rad;
-
- Output = heading_to_waypoint;
+ if (eUnit == eDeg) Output = heading_to_waypoint_rad * radtodeg;
+ else Output = heading_to_waypoint_rad;
} else { // Calculate Distance
- double wp_distance = source.GetDistanceTo(target_longitude, target_latitude);
+ double wp_distance = source.GetDistanceTo(target_longitude_rad,
+ target_latitude_rad);
- if (eUnit == eMeters) {
- Output = FeetToMeters(wp_distance);
- } else {
- Output = wp_distance;
- }
+ if (eUnit == eMeters) Output = FeetToMeters(wp_distance);
+ else Output = wp_distance;
}
Clip();
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <string>
+#include "simgear/props/propertyObject.hxx"
#include "FGFCSComponent.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_WAYPOINT "$Id: FGWaypoint.h,v 1.3 2015/09/20 20:53:13 bcoconni Exp $"
+#define ID_WAYPOINT "$Id: FGWaypoint.h,v 1.4 2016/04/17 13:19:39 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@endcode
@author Jon S. Berndt
- @version $Id: FGWaypoint.h,v 1.3 2015/09/20 20:53:13 bcoconni Exp $
+ @version $Id: FGWaypoint.h,v 1.4 2016/04/17 13:19:39 bcoconni Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool Run(void);
private:
- FGPropertyNode_ptr target_latitude_pNode;
- FGPropertyNode_ptr target_longitude_pNode;
- FGPropertyNode_ptr source_latitude_pNode;
- FGPropertyNode_ptr source_longitude_pNode;
+ simgear::PropertyObject<double> target_latitude;
+ simgear::PropertyObject<double> target_longitude;
+ simgear::PropertyObject<double> source_latitude;
+ simgear::PropertyObject<double> source_longitude;
double target_latitude_unit;
double target_longitude_unit;
double source_latitude_unit;
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGTank.cpp,v 1.44 2015/12/02 04:23:26 dpculp Exp $");
+IDENT(IdSrc,"$Id: FGTank.cpp,v 1.45 2016/05/05 17:23:10 bcoconni Exp $");
IDENT(IdHdr,ID_TANK);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
element = el->FindElement("location");
if (element) vXYZ = element->FindElementTripletConvertTo("IN");
- else cerr << "No location found for this tank." << endl;
+ else cerr << el->ReadFrom() << "No location found for this tank."
+ << endl;
vXYZ_drain = vXYZ; // Set initial drain location to initial tank CG
SetPriority( InitialPriority ); // this will also set the Selected flag
if (Capacity == 0) {
- cerr << "Tank capacity must not be zero. Reset to 0.00001 lbs!" << endl;
+ cerr << el->ReadFrom()
+ << "Tank capacity must not be zero. Reset to 0.00001 lbs!" << endl;
Capacity = 0.00001;
Contents = 0.0;
}
if (Contents > Capacity) {
- cerr << "Tank content (" << Contents << " lbs) is greater than tank capacity ("
- << Capacity << " lbs) for tank " << tank_number
+ cerr << el->ReadFrom() << "Tank content (" << Contents
+ << " lbs) is greater than tank capacity (" << Capacity
+ << " lbs) for tank " << tank_number
<< "! Did you accidentally swap contents and capacity?" << endl;
throw("tank definition error");
}
throw("For tank "+to_string(TankNumber)+" and when grain_config is specified an izz must be specified when the FUNCTION grain type is specified.");
}
}
- else cerr << "Unknown propellant grain type specified" << endl;
+ else
+ cerr << el->ReadFrom() << "Unknown propellant grain type specified"
+ << endl;
if (element_Grain->FindElement("length"))
Length = element_Grain->FindElementValueAsNumberConvertTo("length", "IN");
switch (grainType) {
case gtCYLINDRICAL:
if (Radius <= InnerRadius) {
- cerr << "The bore diameter should be smaller than the total grain diameter!" << endl;
+ cerr << element_Grain->ReadFrom()
+ << "The bore diameter should be smaller than the total grain diameter!"
+ << endl;
exit(-1);
}
Volume = M_PI * Length * (Radius*Radius - InnerRadius*InnerRadius); // cubic inches
Volume = 1; // Volume is irrelevant for the FUNCTION type, but it can't be zero!
break;
case gtUNKNOWN:
- cerr << "Unknown grain type found in this rocket engine definition." << endl;
+ cerr << el->ReadFrom()
+ << "Unknown grain type found in this rocket engine definition."
+ << endl;
exit(-1);
}
- Density = (Contents*lbtoslug)/Volume; // slugs/in^3
+ Density = (Capacity*lbtoslug)/Volume; // slugs/in^3
}
CalculateInertias();