44 #include "FGOutputFG.h"
45 #include "FGXMLElement.h"
46 #include "models/FGAuxiliary.h"
47 #include "models/FGPropulsion.h"
48 #include "models/FGFCS.h"
49 #include "models/propulsion/FGPiston.h"
50 #include "models/propulsion/FGElectric.h"
51 #include "models/propulsion/FGTank.h"
53 #if defined(WIN32) && !defined(__CYGWIN__)
56 # include <netinet/in.h>
60 # define min(X,Y) X<Y?X:Y
63 static const int endianTest = 1;
64 #define isLittleEndian (*((char *) &endianTest ) != 0)
80 static void htond (
double &x)
82 if ( isLittleEndian ) {
86 Double_Overlay = (
int *) &x;
87 Holding_Buffer = Double_Overlay [0];
89 Double_Overlay [0] = htonl (Double_Overlay [1]);
90 Double_Overlay [1] = htonl (Holding_Buffer);
97 static void htonf (
float &x)
99 if ( isLittleEndian ) {
103 Float_Overlay = (
int *) &x;
104 Holding_Buffer = Float_Overlay [0];
106 Float_Overlay [0] = htonl (Holding_Buffer);
120 memset(&fgSockBuf, 0x0,
sizeof(fgSockBuf));
122 if (fdmex->GetDebugLevel() > 0) {
124 if (Propulsion->GetNumEngines() > FGNetFDM::FG_MAX_ENGINES)
125 cerr <<
"This vehicle has " << Propulsion->GetNumEngines() <<
" engines, but the current " << endl
126 <<
"version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_ENGINES <<
" engines." << endl
127 <<
"Only the first " << FGNetFDM::FG_MAX_ENGINES <<
" engines will be used." << endl;
130 if (Propulsion->GetNumTanks() > FGNetFDM::FG_MAX_TANKS)
131 cerr <<
"This vehicle has " << Propulsion->GetNumTanks() <<
" tanks, but the current " << endl
132 <<
"version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_TANKS <<
" tanks." << endl
133 <<
"Only the first " << FGNetFDM::FG_MAX_TANKS <<
" tanks will be used." << endl;
136 if (GroundReactions->GetNumGearUnits() > FGNetFDM::FG_MAX_WHEELS)
137 cerr <<
"This vehicle has " << GroundReactions->GetNumGearUnits() <<
" bogeys, but the current " << endl
138 <<
"version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_WHEELS <<
" bogeys." << endl
139 <<
"Only the first " << FGNetFDM::FG_MAX_WHEELS <<
" bogeys will be used." << endl;
156 outputOptions.useSimTime =
true;
174 void FGOutputFG::SocketDataFill(FGNetFDM* net)
179 net->version = FG_NET_FDM_VERSION;
182 net->longitude = Propagate->GetLongitude();
183 net->latitude = Propagate->GetGeodLatitudeRad();
185 net->agl = (float)(Propagate->GetDistanceAGL()*0.3048);
187 net->phi = (float)(Propagate->
GetEuler(ePhi));
188 net->theta = (float)(Propagate->
GetEuler(eTht));
189 net->psi = (float)(Propagate->
GetEuler(ePsi));
191 net->alpha = (float)(Auxiliary->Getalpha());
192 net->beta = (float)(Auxiliary->Getbeta());
195 net->phidot = (float)(Auxiliary->GetEulerRates(ePhi));
196 net->thetadot = (float)(Auxiliary->GetEulerRates(eTht));
197 net->psidot = (float)(Auxiliary->GetEulerRates(ePsi));
199 net->climb_rate = (float)(Propagate->
Gethdot());
200 net->v_north = (float)(Propagate->
GetVel(eNorth));
201 net->v_east = (float)(Propagate->
GetVel(eEast));
202 net->v_down = (float)(Propagate->
GetVel(eDown));
204 net->v_body_u = (float)(Propagate->
GetUVW(1));
205 net->v_body_v = (float)(Propagate->
GetUVW(2));
206 net->v_body_w = (float)(Propagate->
GetUVW(3));
209 net->A_X_pilot = (float)(Auxiliary->GetPilotAccel(1));
210 net->A_Y_pilot = (float)(Auxiliary->GetPilotAccel(2));
211 net->A_Z_pilot = (float)(Auxiliary->GetPilotAccel(3));
214 net->stall_warning = 0.0;
215 net->slip_deg = (float)(Auxiliary->Getbeta(inDegrees));
217 net->num_engines = min(FGNetFDM::FG_MAX_ENGINES,Propulsion->
GetNumEngines());
219 for (i=0; i<net->num_engines; i++) {
221 if (engine->GetRunning())
222 net->eng_state[i] = 2;
223 else if (engine->GetCranking())
224 net->eng_state[i] = 1;
226 net->eng_state[i] = 0;
228 switch (engine->GetType()) {
229 case (FGEngine::etRocket):
231 case (FGEngine::etPiston):
234 net->rpm[i] = (float)(piston_engine->getRPM());
235 net->fuel_flow[i] = (float)(piston_engine->getFuelFlow_gph());
237 net->egt[i] = (float)(piston_engine->GetEGT());
238 net->cht[i] = (float)(piston_engine->getCylinderHeadTemp_degF());
239 net->mp_osi[i] = (float)(piston_engine->getManifoldPressure_inHg());
240 net->oil_temp[i] = (float)(piston_engine->getOilTemp_degF());
241 net->oil_px[i] = (float)(piston_engine->getOilPressure_psi());
245 case (FGEngine::etTurbine):
247 case (FGEngine::etTurboprop):
249 case (FGEngine::etElectric):
250 net->rpm[i] =
static_cast<float>(
static_cast<FGElectric*
>(engine)->getRPM());
252 case (FGEngine::etUnknown):
257 net->num_tanks = min(FGNetFDM::FG_MAX_TANKS, Propulsion->
GetNumTanks());
259 for (i=0; i<net->num_tanks; i++) {
260 net->fuel_quantity[i] = (float)(((FGTank *)Propulsion->
GetTank(i))->GetContents());
263 net->num_wheels = min(FGNetFDM::FG_MAX_WHEELS, GroundReactions->
GetNumGearUnits());
265 for (i=0; i<net->num_wheels; i++) {
267 if (GroundReactions->
GetGearUnit(i)->GetGearUnitDown())
268 net->gear_pos[i] = 1;
270 net->gear_pos[i] = 0;
271 net->gear_steer[i] = (float)(GroundReactions->
GetGearUnit(i)->GetSteerNorm());
276 if (outputOptions.useSimTime) {
278 net->cur_time =
static_cast<uint32_t
>(FDMExec->
GetSimTime()*outputOptions.timeFactor);
281 net->cur_time = 1234567890u;
285 net->visibility = 25000.0;
288 net->elevator = (float)(FCS->
GetDePos(ofNorm));
290 net->left_flap = (float)(FCS->
GetDfPos(ofNorm));
291 net->right_flap = (float)(FCS->
GetDfPos(ofNorm));
292 net->left_aileron = (float)(FCS->
GetDaLPos(ofNorm));
293 net->right_aileron = (float)(FCS->
GetDaRPos(ofNorm));
294 net->rudder = (float)(FCS->
GetDrPos(ofNorm));
295 net->nose_wheel = (float)(FCS->
GetDrPos(ofNorm));
296 net->speedbrake = (float)(FCS->
GetDsbPos(ofNorm));
297 net->spoilers = (float)(FCS->
GetDspPos(ofNorm));
300 if ( isLittleEndian ) {
301 net->version = htonl(net->version);
303 htond(net->longitude);
304 htond(net->latitude);
305 htond(net->altitude);
314 htonf(net->thetadot);
317 htonf(net->climb_rate);
321 htonf(net->v_body_u);
322 htonf(net->v_body_v);
323 htonf(net->v_body_w);
325 htonf(net->A_X_pilot);
326 htonf(net->A_Y_pilot);
327 htonf(net->A_Z_pilot);
329 htonf(net->stall_warning);
330 htonf(net->slip_deg);
332 for (i=0; i<net->num_engines; ++i ) {
333 net->eng_state[i] = htonl(net->eng_state[i]);
335 htonf(net->fuel_flow[i]);
336 htonf(net->fuel_px[i]);
339 htonf(net->mp_osi[i]);
341 htonf(net->oil_temp[i]);
342 htonf(net->oil_px[i]);
344 net->num_engines = htonl(net->num_engines);
346 for (i=0; i<net->num_tanks; ++i ) {
347 htonf(net->fuel_quantity[i]);
349 net->num_tanks = htonl(net->num_tanks);
351 for (i=0; i<net->num_wheels; ++i ) {
352 net->wow[i] = htonl(net->wow[i]);
353 htonf(net->gear_pos[i]);
354 htonf(net->gear_steer[i]);
355 htonf(net->gear_compression[i]);
357 net->num_wheels = htonl(net->num_wheels);
359 net->cur_time = htonl( net->cur_time );
360 net->warp = htonl( net->warp );
361 htonf(net->visibility);
363 htonf(net->elevator);
364 htonf(net->elevator_trim_tab);
365 htonf(net->left_flap);
366 htonf(net->right_flap);
367 htonf(net->left_aileron);
368 htonf(net->right_aileron);
370 htonf(net->nose_wheel);
371 htonf(net->speedbrake);
372 htonf(net->spoilers);
380 int length =
sizeof(fgSockBuf);
382 if (socket == 0)
return;
383 if (!socket->GetConnectStatus())
return;
385 SocketDataFill(&fgSockBuf);
386 socket->Send((
char *)&fgSockBuf, length);