04/03/99 JSB Changed Aero() method to correct body axis force calculation
from wind vector. Fix provided by Tony Peden.
05/03/99 JSB Changed (for the better?) the way configurations are read in.
+9/17/99 TP Combined force and moment functions. Added aero reference
+ point to config file. Added calculations for moments due to
+ difference in cg and aero reference point
********************************************************************************
COMMENTS, REFERENCES, and NOTES
int axis;
string axis_descript;
- axis = -1;
+ axis = -1;
aircraftDef = aircraft_path + "/" + fname + "/" + fname + ".cfg";
ifstream aircraftfile(aircraftDef.c_str());
cout << "Reading Aircraft Configuration File: " << aircraftDef << endl;
+ Output->SocketStatusOutput("Reading Aircraft Configuration File: " + aircraftDef);
numTanks = numEngines = 0;
numSelectedOxiTanks = numSelectedFuelTanks = 0;
while (!aircraftfile.fail()) {
- holding_string.erase();
+ holding_string.erase();
aircraftfile >> holding_string;
#if defined(__BORLANDC__) || defined(FG_HAVE_NATIVE_SGI_COMPILERS) || defined(_MSC_VER)
if (holding_string.compare(0, 2, "//") != 0) {
if (holding_string.compare("//",0,2) != 0) {
#endif
if (holding_string == "AIRCRAFT") {
- cout << "Reading in Aircraft parameters ..." << endl;
+ cout << "Reading in Aircraft parameters ..." << endl;
} else if (holding_string == "AERODYNAMICS") {
- cout << "Reading in Aerodynamic parameters ..." << endl;
- } else if (holding_string == "AC_NAME") {
- aircraftfile >> AircraftName; // String with no embedded spaces
- cout << "Aircraft Name: " << AircraftName << endl;
- } else if (holding_string == "AC_WINGAREA") {
- aircraftfile >> WingArea;
- cout << "Aircraft Wing Area: " << WingArea << endl;
- } else if (holding_string == "AC_WINGSPAN") {
- aircraftfile >> WingSpan;
- cout << "Aircraft WingSpan: " << WingSpan << endl;
- } else if (holding_string == "AC_CHORD") {
- aircraftfile >> cbar;
- cout << "Aircraft Chord: " << cbar << endl;
- } else if (holding_string == "AC_IXX") {
- aircraftfile >> baseIxx;
- cout << "Aircraft Base Ixx: " << baseIxx << endl;
- } else if (holding_string == "AC_IYY") {
- aircraftfile >> baseIyy;
- cout << "Aircraft Base Iyy: " << baseIyy << endl;
- } else if (holding_string == "AC_IZZ") {
- aircraftfile >> baseIzz;
- cout << "Aircraft Base Izz: " << baseIzz << endl;
- } else if (holding_string == "AC_IXZ") {
- aircraftfile >> baseIxz;
- cout << "Aircraft Base Ixz: " << baseIxz << endl;
- } else if (holding_string == "AC_EMPTYWT") {
- aircraftfile >> EmptyWeight;
- EmptyMass = EmptyWeight / GRAVITY;
- cout << "Aircraft Empty Weight: " << EmptyWeight << endl;
- } else if (holding_string == "AC_CGLOC") {
- aircraftfile >> baseXcg >> baseYcg >> baseZcg;
- cout << "Aircraft Base C.G.: " << baseXcg << " " << baseYcg << " " << baseZcg << endl;
- } else if (holding_string == "AC_EYEPTLOC") {
- aircraftfile >> Xep >> Yep >> Zep;
- cout << "Pilot Eyepoint: " << Xep << " " << Yep << " " << Zep << endl;
- } else if (holding_string == "AC_TANK") {
+ cout << "Reading in Aerodynamic parameters ..." << endl;
+ } else if (holding_string == "AC_NAME") {
+ aircraftfile >> AircraftName; // String with no embedded spaces
+ cout << "Aircraft Name: " << AircraftName << endl;
+ } else if (holding_string == "AC_WINGAREA") {
+ aircraftfile >> WingArea;
+ cout << "Aircraft Wing Area: " << WingArea << endl;
+ } else if (holding_string == "AC_WINGSPAN") {
+ aircraftfile >> WingSpan;
+ cout << "Aircraft WingSpan: " << WingSpan << endl;
+ } else if (holding_string == "AC_CHORD") {
+ aircraftfile >> cbar;
+ cout << "Aircraft Chord: " << cbar << endl;
+ } else if (holding_string == "AC_IXX") {
+ aircraftfile >> baseIxx;
+ cout << "Aircraft Base Ixx: " << baseIxx << endl;
+ } else if (holding_string == "AC_IYY") {
+ aircraftfile >> baseIyy;
+ cout << "Aircraft Base Iyy: " << baseIyy << endl;
+ } else if (holding_string == "AC_IZZ") {
+ aircraftfile >> baseIzz;
+ cout << "Aircraft Base Izz: " << baseIzz << endl;
+ } else if (holding_string == "AC_IXZ") {
+ aircraftfile >> baseIxz;
+ cout << "Aircraft Base Ixz: " << baseIxz << endl;
+ } else if (holding_string == "AC_EMPTYWT") {
+ aircraftfile >> EmptyWeight;
+ EmptyMass = EmptyWeight / GRAVITY;
+ cout << "Aircraft Empty Weight: " << EmptyWeight << endl;
+ } else if (holding_string == "AC_AERORP") {
+ aircraftfile >> Xrp >> Yrp >> Zrp;
+ cout << "Aerodynamic Reference Point: " << Xrp << " " << Yrp << " " << Zrp << endl;
+ } else if (holding_string == "AC_CGLOC") {
+ aircraftfile >> baseXcg >> baseYcg >> baseZcg;
+ cout << "Aircraft Base C.G.: " << baseXcg << " " << baseYcg << " " << baseZcg << endl;
+ } else if (holding_string == "AC_EYEPTLOC") {
+ aircraftfile >> Xep >> Yep >> Zep;
+ cout << "Pilot Eyepoint: " << Xep << " " << Yep << " " << Zep << endl;
+ } else if (holding_string == "AC_TANK") {
Tank[numTanks] = new FGTank(aircraftfile);
switch(Tank[numTanks]->GetType()) {
case FGTank::ttFUEL:
numSelectedFuelTanks++;
- cout << "Reading in Fuel Tank #" << numSelectedFuelTanks << " parameters ..." << endl;
+ cout << "Reading in Fuel Tank #" << numSelectedFuelTanks << " parameters ..." << endl;
break;
case FGTank::ttOXIDIZER:
numSelectedOxiTanks++;
- cout << "Reading in Oxidizer Tank #" << numSelectedOxiTanks << " parameters ..." << endl;
+ cout << "Reading in Oxidizer Tank #" << numSelectedOxiTanks << " parameters ..." << endl;
break;
}
numTanks++;
- } else if (holding_string == "AC_ENGINE") {
+ } else if (holding_string == "AC_GEAR") {
+
+ lGear.push_back(new FGLGear(aircraftfile));
+
+ } else if (holding_string == "AC_ENGINE") {
aircraftfile >> tag;
- cout << "Reading in " << tag << " Engine parameters ..." << endl;
+ cout << "Reading in " << tag << " Engine parameters ..." << endl;
Engine[numEngines] = new FGEngine(FDMExec, engine_path, tag, numEngines);
numEngines++;
- } else if (holding_string == "}") {
+ } else if (holding_string == "}") {
+
+ } else if (holding_string == "{") {
- } else if (holding_string == "{") {
+ } else if (holding_string == "LIFT") {
- } else if (holding_string == "LIFT") {
+ axis_descript = " Lift Coefficients ...";
+ axis = LiftCoeff;
- axis_descript = " Lift Coefficients ...";
- axis = LiftCoeff;
-
- } else if (holding_string == "DRAG") {
+ } else if (holding_string == "DRAG") {
- axis_descript = " Drag Coefficients ...";
- axis = DragCoeff;
+ axis_descript = " Drag Coefficients ...";
+ axis = DragCoeff;
- } else if (holding_string == "SIDE") {
+ } else if (holding_string == "SIDE") {
- axis_descript = " Side Coefficients ...";
- axis = SideCoeff;
+ axis_descript = " Side Coefficients ...";
+ axis = SideCoeff;
- } else if (holding_string == "ROLL") {
+ } else if (holding_string == "ROLL") {
- axis_descript = " Roll Coefficients ...";
- axis = RollCoeff;
+ axis_descript = " Roll Coefficients ...";
+ axis = RollCoeff;
- } else if (holding_string == "PITCH") {
+ } else if (holding_string == "PITCH") {
- axis_descript = " Pitch Coefficients ...";
- axis = PitchCoeff;
+ axis_descript = " Pitch Coefficients ...";
+ axis = PitchCoeff;
- } else if (holding_string == "YAW") {
+ } else if (holding_string == "YAW") {
- axis_descript = " Yaw Coefficients ...";
- axis = YawCoeff;
+ axis_descript = " Yaw Coefficients ...";
+ axis = YawCoeff;
- }
+ }
+
+ if (axis >= 0) {
+ cout << axis_descript << endl;
+ aircraftfile >> tag;
+ gpos = aircraftfile.tellg();
+ aircraftfile >> tag;
+ if ( !(tag == "}") ) {
+ while ( !(tag == "}") ) {
+ aircraftfile.seekg(gpos);
+ Coeff[axis][coeff_ctr[axis]] = new FGCoefficient(FDMExec, aircraftfile);
+ coeff_ctr[axis]++;
+ aircraftfile >> tag;
+ gpos = aircraftfile.tellg();
+ aircraftfile >> tag;
+ }
+ } else {
+ cout << " None found ..." << endl;
+ }
+ }
+ axis = -1;
- if (axis >= 0) {
- cout << axis_descript << endl;
- aircraftfile >> tag;
- gpos = aircraftfile.tellg();
- aircraftfile >> tag;
- if ( !(tag == "}") ) {
- while ( !(tag == "}") ) {
- aircraftfile.seekg(gpos);
- Coeff[axis][coeff_ctr[axis]] = new FGCoefficient(FDMExec, aircraftfile);
- coeff_ctr[axis]++;
- aircraftfile >> tag;
- gpos = aircraftfile.tellg();
- aircraftfile >> tag;
- }
- } else {
- cout << " None found ..." << endl;
- }
- }
- axis = -1;
-
} else {
- aircraftfile.getline(scratch, 127);
+ aircraftfile.getline(scratch, 127);
}
}
- cout << "End of Configuration File Parsing." << endl;
+ cout << "End of Configuration File Parsing." << endl;
return true;
}
MassChange();
- FProp(); FAero(); FGear(); FMass();
- MProp(); MAero(); MGear(); MMass();
+ FMProp(); FMAero(); FMGear(); FMMass();
PutState();
} else { // skip Run() execution this time
case FGTank::ttFUEL:
if (Tank[t]->GetSelected()) {
Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
- numSelectedFuelTanks)*(dt*rate) + Fshortage);
+ numSelectedFuelTanks)*(dt*rate) + Fshortage);
}
break;
case FGTank::ttOXIDIZER:
if (Tank[t]->GetSelected()) {
Oshortage = Tank[t]->Reduce((Engine[e]->CalcOxidizerNeed()/
- numSelectedOxiTanks)*(dt*rate) + Oshortage);
+ numSelectedOxiTanks)*(dt*rate) + Oshortage);
}
break;
}
if (Tank[t]->GetSelected()) {
Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
- numSelectedFuelTanks)*(dt*rate) + Fshortage);
+ numSelectedFuelTanks)*(dt*rate) + Fshortage);
}
break;
}
// Calculate new CG here.
- Xt = Yt = Zt = 0;
+ Xt = Yt = Zt = Tw = 0;
Xw = Yw = Zw = 0;
for (t=0; t<numTanks; t++) {
Xt += Tank[t]->GetX()*Tank[t]->GetContents();
}
-void FGAircraft::FAero(void)
+void FGAircraft::FMAero(void)
{
float F[3];
-
+ float Fxaero,Fyaero,Fzaero;
+ float dxcg,dycg,dzcg;
+ int axis_ctr,ctr;
F[0] = F[1] = F[2] = 0.0;
- for (int axis_ctr = 0; axis_ctr < 3; axis_ctr++)
- for (int ctr=0; ctr < coeff_ctr[axis_ctr]; ctr++)
+ for (axis_ctr = 0; axis_ctr < 3; axis_ctr++)
+ for (ctr=0; ctr < coeff_ctr[axis_ctr]; ctr++)
F[axis_ctr] += Coeff[axis_ctr][ctr]->TotalValue();
+ Fxaero = - F[DragCoeff]*cos(alpha)*cos(beta)
+ - F[SideCoeff]*cos(alpha)*sin(beta)
+ + F[LiftCoeff]*sin(alpha);
+ Fyaero = F[DragCoeff]*sin(beta)
+ + F[SideCoeff]*cos(beta);
+ Fzaero = - F[DragCoeff]*sin(alpha)*cos(beta)
+ - F[SideCoeff]*sin(alpha)*sin(beta)
+ - F[LiftCoeff]*cos(alpha);
+
Forces[0] += - F[DragCoeff]*cos(alpha)*cos(beta)
- F[SideCoeff]*cos(alpha)*sin(beta)
+ F[LiftCoeff]*sin(alpha);
Forces[1] += F[DragCoeff]*sin(beta)
- + F[SideCoeff]*cos(beta);
+ + F[SideCoeff]*cos(beta);
Forces[2] += - F[DragCoeff]*sin(alpha)*cos(beta)
- F[SideCoeff]*sin(alpha)*sin(beta)
- F[LiftCoeff]*cos(alpha);
-}
-
-
-void FGAircraft::FGear(void)
-{
- if (GearUp) {
- // crash routine
- } else {
-
- }
-}
-
-void FGAircraft::FMass(void)
-{
- Forces[0] += -GRAVITY*sin(tht) * Mass;
- Forces[1] += GRAVITY*sin(phi)*cos(tht) * Mass;
- Forces[2] += GRAVITY*cos(phi)*cos(tht) * Mass;
-}
-
-
-void FGAircraft::FProp(void)
-{
- for (int i=0;i<numEngines;i++) {
- Forces[0] += Engine[i]->CalcThrust();
- }
-}
+ dxcg = (Xcg - Xrp)/12; //cg and rp values are in inches
+ dycg = (Ycg - Yrp)/12;
+ dzcg = (Zcg - Zrp)/12;
+ Moments[0] += -Fzaero*dycg - Fyaero*dzcg; //rolling moment
+ Moments[1] += Fxaero*dzcg - Fzaero*dxcg; //pitching moment
+ Moments[2] += Fxaero*dycg + Fyaero*dxcg; //yawing moment
-void FGAircraft::MAero(void)
-{
- int axis_ctr, ctr;
-
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr = 0; ctr < coeff_ctr[axis_ctr+3]; ctr++) {
Moments[axis_ctr] += Coeff[axis_ctr+3][ctr]->TotalValue();
}
-void FGAircraft::MGear(void)
+void FGAircraft::FMGear(void)
{
if (GearUp) {
+ // crash routine
} else {
+ for (int i=0;i<lGear.size();i++) {
+ // lGear[i].
+ }
}
}
-void FGAircraft::MMass(void)
+void FGAircraft::FMMass(void)
{
+ Forces[0] += -GRAVITY*sin(tht) * Mass;
+ Forces[1] += GRAVITY*sin(phi)*cos(tht) * Mass;
+ Forces[2] += GRAVITY*cos(phi)*cos(tht) * Mass;
}
-void FGAircraft::MProp(void)
+void FGAircraft::FMProp(void)
{
+ for (int i=0;i<numEngines;i++) {
+ Forces[0] += Engine[i]->CalcThrust();
+ }
}
-
void FGAircraft::GetState(void)
{
dt = State->Getdt();
FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGOutput";
- FirstPass = true;
+ sFirstPass = dFirstPass = true;
+
+#ifdef FG_WITH_JSBSIM_SOCKET
+ socket = new FGfdmSocket("localhost",1138);
+#endif
}
FGOutput::~FGOutput(void)
{
+ if (socket) delete socket;
}
bool FGOutput::Run(void)
{
if (!FGModel::Run()) {
- DelimitedOutput("JSBSimData.csv");
+ SocketOutput();
+// DelimitedOutput("JSBSimData.csv");
} else {
}
return false;
void FGOutput::DelimitedOutput(void)
{
- if (FirstPass) {
+ if (dFirstPass) {
cout << "Time,";
cout << "Altitude,";
cout << "Phi,";
cout << "M,";
cout << "N";
cout << endl;
- FirstPass = false;
+ dFirstPass = false;
}
cout << State->Getsim_time() << ",";
void FGOutput::DelimitedOutput(string fname)
{
- if (FirstPass) {
+ if (sFirstPass) {
datafile.open(fname.c_str());
datafile << "Time,";
datafile << "Altitude,";
datafile << "M,";
datafile << "N";
datafile << endl;
- FirstPass = false;
+ sFirstPass = false;
}
datafile << State->Getsim_time() << ",";
datafile.flush();
}
+void FGOutput::SocketOutput(void)
+{
+ string asciiData;
+
+ if (socket <= 0) return;
+
+ socket->Clear();
+ if (sFirstPass) {
+ socket->Append("<LABELS>");
+ socket->Append("Time");
+ socket->Append("Altitude");
+ socket->Append("Phi");
+ socket->Append("Tht");
+ socket->Append("Psi");
+ socket->Append("Rho");
+ socket->Append("Vtotal");
+ socket->Append("U");
+ socket->Append("V");
+ socket->Append("W");
+ socket->Append("Vn");
+ socket->Append("Ve");
+ socket->Append("Vd");
+ socket->Append("Udot");
+ socket->Append("Vdot");
+ socket->Append("Wdot");
+ socket->Append("P");
+ socket->Append("Q");
+ socket->Append("R");
+ socket->Append("PDot");
+ socket->Append("QDot");
+ socket->Append("RDot");
+ socket->Append("Fx");
+ socket->Append("Fy");
+ socket->Append("Fz");
+ socket->Append("Latitude");
+ socket->Append("Longitude");
+ socket->Append("QBar");
+ socket->Append("Alpha");
+ socket->Append("L");
+ socket->Append("M");
+ socket->Append("N");
+ sFirstPass = false;
+ socket->Send();
+ }
+
+ socket->Clear();
+ socket->Append(State->Getsim_time());
+ socket->Append(State->Geth());
+ socket->Append(Rotation->Getphi());
+ socket->Append(Rotation->Gettht());
+ socket->Append(Rotation->Getpsi());
+ socket->Append(Atmosphere->GetDensity());
+ socket->Append(State->GetVt());
+ socket->Append(Translation->GetU());
+ socket->Append(Translation->GetV());
+ socket->Append(Translation->GetW());
+ socket->Append(Position->GetVn());
+ socket->Append(Position->GetVe());
+ socket->Append(Position->GetVd());
+ socket->Append(Translation->GetUdot());
+ socket->Append(Translation->GetVdot());
+ socket->Append(Translation->GetWdot());
+ socket->Append(Rotation->GetP());
+ socket->Append(Rotation->GetQ());
+ socket->Append(Rotation->GetR());
+ socket->Append(Rotation->GetPdot());
+ socket->Append(Rotation->GetQdot());
+ socket->Append(Rotation->GetRdot());
+ socket->Append(Aircraft->GetFx());
+ socket->Append(Aircraft->GetFy());
+ socket->Append(Aircraft->GetFz());
+ socket->Append(State->Getlatitude());
+ socket->Append(State->Getlongitude());
+ socket->Append(State->Getqbar());
+ socket->Append(Translation->Getalpha());
+ socket->Append(Aircraft->GetL());
+ socket->Append(Aircraft->GetM());
+ socket->Append(Aircraft->GetN());
+ socket->Send();
+}
+
+
+void FGOutput::SocketStatusOutput(string out_str)
+{
+ string asciiData;
+
+ if (socket <= 0) return;
+
+ socket->Clear();
+ asciiData = string("<STATUS>") + out_str;
+ socket->Append(asciiData.c_str());
+ socket->Send();
+}
+