FlightGear next
native_structs.cxx
Go to the documentation of this file.
1// native_fdm.cxx -- FGFS "Native" flight dynamics protocal class
2//
3// Written by Curtis Olson, started September 2001.
4//
5// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20//
21// $Id$
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <simgear/io/lowlevel.hxx> // endian tests
28#include <simgear/timing/sg_time.hxx>
29
30#include <Network/net_ctrls.hxx>
31#include <Network/net_fdm.hxx>
32#include <Network/net_gui.hxx>
33#include <Main/fg_props.hxx>
34
35#include "native_structs.hxx"
36
37
38// FreeBSD works better with this included last ... (?)
39#if defined( _MSC_VER )
40# include <windows.h>
41#elif defined( __MINGW32__ )
42# include <winsock2.h>
43#else
44# include <netinet/in.h> // htonl() ntohl()
45#endif
46
47// The function htond is defined this way due to the way some
48// processors and OSes treat floating point values. Some will raise
49// an exception whenever a "bad" floating point value is loaded into a
50// floating point register. Solaris is notorious for this, but then
51// so is LynxOS on the PowerPC. By translating the data in place,
52// there is no need to load a FP register with the "corruped" floating
53// point value. By doing the BIG_ENDIAN test, I can optimize the
54// routine for big-endian processors so it can be as efficient as
55// possible
56static void htond (double &x)
57{
58 if ( sgIsLittleEndian() ) {
59 int *Double_Overlay;
60 int Holding_Buffer;
61
62 Double_Overlay = (int *) &x;
63 Holding_Buffer = Double_Overlay [0];
64
65 Double_Overlay [0] = htonl (Double_Overlay [1]);
66 Double_Overlay [1] = htonl (Holding_Buffer);
67 } else {
68 return;
69 }
70}
71
72// Float version
73static void htonf (float &x)
74{
75 if ( sgIsLittleEndian() ) {
76 int *Float_Overlay;
77 int Holding_Buffer;
78
79 Float_Overlay = (int *) &x;
80 Holding_Buffer = Float_Overlay [0];
81
82 Float_Overlay [0] = htonl (Holding_Buffer);
83 } else {
84 return;
85 }
86}
87
88template<>
89void FGProps2FDM<FGNetFDM>( SGPropertyNode *props, FGNetFDM *net, bool net_byte_order ) {
90 unsigned int i;
91
92 // Version sanity checking
94
95 // Aero parameters
96 net->longitude = props->getDoubleValue("position/longitude-deg")
97 * SG_DEGREES_TO_RADIANS;
98 net->latitude = props->getDoubleValue("position/latitude-deg")
99 * SG_DEGREES_TO_RADIANS;
100 net->altitude = props->getDoubleValue("position/altitude-ft")
101 * SG_FEET_TO_METER;
102 net->agl = props->getDoubleValue("position/altitude-agl-ft")
103 * SG_FEET_TO_METER;
104 net->phi = SGMiscd::deg2rad( props->getDoubleValue("orientation/roll-deg") );
105 net->theta = SGMiscd::deg2rad( props->getDoubleValue("orientation/pitch-deg") );
106 net->psi = SGMiscd::deg2rad( props->getDoubleValue("orientation/heading-deg") );
107 net->alpha = props->getDoubleValue("orientation/alpha-deg")
108 * SG_DEGREES_TO_RADIANS;
109 net->beta = props->getDoubleValue("orientation/beta-deg")
110 * SG_DEGREES_TO_RADIANS;
111 net->phidot = props->getDoubleValue("orientation/roll-rate-degps")
112 * SG_DEGREES_TO_RADIANS;
113 net->thetadot = props->getDoubleValue("orientation/pitch-rate-degps")
114 * SG_DEGREES_TO_RADIANS;
115 net->psidot = props->getDoubleValue("orientation/yaw-rate-degps")
116 * SG_DEGREES_TO_RADIANS;
117
118 net->vcas = props->getDoubleValue("velocities/airspeed-kt");
119 net->climb_rate = props->getDoubleValue("velocities/vertical-speed-fps");
120
121 net->v_north = props->getDoubleValue("velocities/speed-north-fps", 0.0);
122 net->v_east = props->getDoubleValue("velocities/speed-east-fps", 0.0);
123 net->v_down = props->getDoubleValue("velocities/speed-down-fps", 0.0);
124 net->v_body_u = props->getDoubleValue("velocities/uBody-fps", 0.0);
125 net->v_body_v = props->getDoubleValue("velocities/vBody-fps", 0.0);
126 net->v_body_w = props->getDoubleValue("velocities/wBody-fps", 0.0);
127
128 net->A_X_pilot = props->getDoubleValue("accelerations/pilot/x-accel-fps_sec", 0.0);
129 net->A_Y_pilot = props->getDoubleValue("/accelerations/pilot/y-accel-fps_sec", 0.0);
130 net->A_Z_pilot = props->getDoubleValue("/accelerations/pilot/z-accel-fps_sec", 0.0);
131
132 net->stall_warning = props->getDoubleValue("/sim/alarms/stall-warning", 0.0);
133 net->slip_deg
134 = props->getDoubleValue("/instrumentation/slip-skid-ball/indicated-slip-skid");
135
136 // Engine parameters
138 for ( i = 0; i < net->num_engines; ++i ) {
139 SGPropertyNode *node = props->getNode("engines/engine", i, true);
140 if ( node->getBoolValue( "running" ) ) {
141 net->eng_state[i] = 2;
142 } else if ( node->getBoolValue( "cranking" ) ) {
143 net->eng_state[i] = 1;
144 } else {
145 net->eng_state[i] = 0;
146 }
147 net->rpm[i] = node->getDoubleValue( "rpm" );
148 net->fuel_flow[i] = node->getDoubleValue( "fuel-flow-gph" );
149 net->fuel_px[i] = node->getDoubleValue( "fuel-px-psi" );
150 net->egt[i] = node->getDoubleValue( "egt-degf" );
151 // cout << "egt = " << aero->EGT << endl;
152 net->cht[i] = node->getDoubleValue( "cht-degf" );
153 net->mp_osi[i] = node->getDoubleValue( "mp-osi" );
154 net->tit[i] = node->getDoubleValue( "tit" );
155 net->oil_temp[i] = node->getDoubleValue( "oil-temperature-degf" );
156 net->oil_px[i] = node->getDoubleValue( "oil-pressure-psi" );
157 }
158
159 // Consumables
161 for ( i = 0; i < net->num_tanks; ++i ) {
162 SGPropertyNode *node = props->getNode("/consumables/fuel/tank", i, true);
163 net->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
164 }
165
166 // Gear and flaps
168 for (i = 0; i < net->num_wheels; ++i ) {
169 SGPropertyNode *node = props->getNode("/gear/gear", i, true);
170 net->wow[i] = node->getIntValue("wow");
171 net->gear_pos[i] = node->getDoubleValue("position-norm");
172 net->gear_steer[i] = node->getDoubleValue("steering-norm");
173 net->gear_compression[i] = node->getDoubleValue("compression-norm");
174 }
175
176 // the following really aren't used in this context
177 SGTime time;
178 net->cur_time = time.get_cur_time();
179 net->warp = props->getIntValue("/sim/time/warp");
180 net->visibility = props->getDoubleValue("/environment/visibility-m");
181
182 // Control surface positions
183 SGPropertyNode *node = props->getNode("/surface-positions", true);
184 net->elevator = node->getDoubleValue( "elevator-pos-norm" );
186 = node->getDoubleValue( "elevator-trim-tab-pos-norm" );
187 // FIXME: CLO 10/28/04 - This really should be separated out into 2 values
188 net->left_flap = node->getDoubleValue( "flap-pos-norm" );
189 net->right_flap = node->getDoubleValue( "flap-pos-norm" );
190 net->left_aileron = node->getDoubleValue( "left-aileron-pos-norm" );
191 net->right_aileron = node->getDoubleValue( "right-aileron-pos-norm" );
192 net->rudder = node->getDoubleValue( "rudder-pos-norm" );
193 net->nose_wheel = node->getDoubleValue( "nose-wheel-pos-norm" );
194 net->speedbrake = node->getDoubleValue( "speedbrake-pos-norm" );
195 net->spoilers = node->getDoubleValue( "spoilers-pos-norm" );
196
197 if ( net_byte_order ) {
198 // Convert the net buffer to network format
199 net->version = htonl(net->version);
200
201 htond(net->longitude);
202 htond(net->latitude);
203 htond(net->altitude);
204 htonf(net->agl);
205 htonf(net->phi);
206 htonf(net->theta);
207 htonf(net->psi);
208 htonf(net->alpha);
209 htonf(net->beta);
210
211 htonf(net->phidot);
212 htonf(net->thetadot);
213 htonf(net->psidot);
214 htonf(net->vcas);
215 htonf(net->climb_rate);
216 htonf(net->v_north);
217 htonf(net->v_east);
218 htonf(net->v_down);
219 htonf(net->v_body_u);
220 htonf(net->v_body_v);
221 htonf(net->v_body_w);
222
223 htonf(net->A_X_pilot);
224 htonf(net->A_Y_pilot);
225 htonf(net->A_Z_pilot);
226
227 htonf(net->stall_warning);
228 htonf(net->slip_deg);
229
230 for ( i = 0; i < net->num_engines; ++i ) {
231 net->eng_state[i] = htonl(net->eng_state[i]);
232 htonf(net->rpm[i]);
233 htonf(net->fuel_flow[i]);
234 htonf(net->fuel_px[i]);
235 htonf(net->egt[i]);
236 htonf(net->cht[i]);
237 htonf(net->mp_osi[i]);
238 htonf(net->tit[i]);
239 htonf(net->oil_temp[i]);
240 htonf(net->oil_px[i]);
241 }
242 net->num_engines = htonl(net->num_engines);
243
244 for ( i = 0; i < net->num_tanks; ++i ) {
245 htonf(net->fuel_quantity[i]);
246 }
247 net->num_tanks = htonl(net->num_tanks);
248
249 for ( i = 0; i < net->num_wheels; ++i ) {
250 net->wow[i] = htonl(net->wow[i]);
251 htonf(net->gear_pos[i]);
252 htonf(net->gear_steer[i]);
253 htonf(net->gear_compression[i]);
254 }
255 net->num_wheels = htonl(net->num_wheels);
256
257 net->cur_time = htonl( net->cur_time );
258 net->warp = htonl( net->warp );
259 htonf(net->visibility);
260
261 htonf(net->elevator);
263 htonf(net->left_flap);
264 htonf(net->right_flap);
265 htonf(net->left_aileron);
266 htonf(net->right_aileron);
267 htonf(net->rudder);
268 htonf(net->nose_wheel);
269 htonf(net->speedbrake);
270 htonf(net->spoilers);
271 }
272}
273
274template<>
275void FGFDM2Props<FGNetFDM>( SGPropertyNode *props, FGNetFDM *net, bool net_byte_order ) {
276 unsigned int i;
277
278 if ( net_byte_order ) {
279 // Convert to the net buffer from network format
280 net->version = ntohl(net->version);
281
282 htond(net->longitude);
283 htond(net->latitude);
284 htond(net->altitude);
285 htonf(net->agl);
286 htonf(net->phi);
287 htonf(net->theta);
288 htonf(net->psi);
289 htonf(net->alpha);
290 htonf(net->beta);
291
292 htonf(net->phidot);
293 htonf(net->thetadot);
294 htonf(net->psidot);
295 htonf(net->vcas);
296 htonf(net->climb_rate);
297 htonf(net->v_north);
298 htonf(net->v_east);
299 htonf(net->v_down);
300 htonf(net->v_body_u);
301 htonf(net->v_body_v);
302 htonf(net->v_body_w);
303
304 htonf(net->A_X_pilot);
305 htonf(net->A_Y_pilot);
306 htonf(net->A_Z_pilot);
307
308 htonf(net->stall_warning);
309 htonf(net->slip_deg);
310
311 net->num_engines = htonl(net->num_engines);
312 for ( i = 0; i < net->num_engines; ++i ) {
313 net->eng_state[i] = htonl(net->eng_state[i]);
314 htonf(net->rpm[i]);
315 htonf(net->fuel_flow[i]);
316 htonf(net->fuel_px[i]);
317 htonf(net->egt[i]);
318 htonf(net->cht[i]);
319 htonf(net->mp_osi[i]);
320 htonf(net->tit[i]);
321 htonf(net->oil_temp[i]);
322 htonf(net->oil_px[i]);
323 }
324
325 net->num_tanks = htonl(net->num_tanks);
326 for ( i = 0; i < net->num_tanks; ++i ) {
327 htonf(net->fuel_quantity[i]);
328 }
329
330 net->num_wheels = htonl(net->num_wheels);
331 for ( i = 0; i < net->num_wheels; ++i ) {
332 net->wow[i] = htonl(net->wow[i]);
333 htonf(net->gear_pos[i]);
334 htonf(net->gear_steer[i]);
335 htonf(net->gear_compression[i]);
336 }
337
338 net->cur_time = htonl(net->cur_time);
339 net->warp = ntohl(net->warp);
340 htonf(net->visibility);
341
342 htonf(net->elevator);
344 htonf(net->left_flap);
345 htonf(net->right_flap);
346 htonf(net->left_aileron);
347 htonf(net->right_aileron);
348 htonf(net->rudder);
349 htonf(net->nose_wheel);
350 htonf(net->speedbrake);
351 htonf(net->spoilers);
352 }
353
354 if ( net->version == FG_NET_FDM_VERSION ) {
355 // cout << "pos = " << net->longitude << " " << net->latitude << endl;
356 // cout << "sea level rad = " << fdm_state.get_Sea_level_radius()
357 // << endl;
358
359 props->setDoubleValue("position/latitude-deg",
360 net->latitude * SG_RADIANS_TO_DEGREES);
361 props->setDoubleValue("position/longitude-deg",
362 net->longitude* SG_RADIANS_TO_DEGREES);
363 props->setDoubleValue("position/altitude-ft",
364 net->altitude * SG_METER_TO_FEET);
365
366 if ( net->agl > -9000 ) {
367 props->setDoubleValue("position/altitude-agl-ft",
368 net->agl * SG_METER_TO_FEET );
369 } else {
370 double agl_m = net->altitude
371 - props->getDoubleValue("environment/ground-elevation-m");
372 props->setDoubleValue("position/altitude-agl-ft",
373 agl_m * SG_METER_TO_FEET );
374 }
375 props->setDoubleValue("orientation/roll-deg",
376 net->phi * SG_RADIANS_TO_DEGREES);
377 props->setDoubleValue("orientation/pitch-deg",
378 net->theta * SG_RADIANS_TO_DEGREES);
379 props->setDoubleValue("orientation/heading-deg",
380 net->psi * SG_RADIANS_TO_DEGREES);
381 props->setDoubleValue("orientation/alpha-deg",
382 net->alpha * SG_RADIANS_TO_DEGREES );
383 props->setDoubleValue("orientation/side-slip-rad",
384 net->beta * SG_RADIANS_TO_DEGREES );
385 props->setDoubleValue("orientation/roll-rate-degps",
386 net->phidot * SG_RADIANS_TO_DEGREES);
387 props->setDoubleValue("orientation/pitch-rate-degps",
388 net->thetadot * SG_RADIANS_TO_DEGREES);
389 props->setDoubleValue("orientation/yaw-rate-degps",
390 net->psidot * SG_RADIANS_TO_DEGREES);
391 props->setDoubleValue("velocities/airspeed-kt", net->vcas);
392 props->setDoubleValue("velocities/vertical-speed-fps", net->climb_rate);
393 props->setDoubleValue("velocities/speed-north-fps", net->v_north);
394 props->setDoubleValue("velocities/speed-east-fps", net->v_east);
395 props->setDoubleValue("velocities/speed-down-fps", net->v_down);
396 props->setDoubleValue("velocities/uBody-fps", net->v_body_u);
397 props->setDoubleValue("velocities/vBody-fps", net->v_body_v);
398 props->setDoubleValue("velocities/wBody-fps", net->v_body_w);
399 props->setDoubleValue("accelerations/pilot/x-accel-fps_sec",
400 net->A_X_pilot);
401 props->setDoubleValue("accelerations/pilot/y-accel-fps_sec",
402 net->A_Y_pilot);
403 props->setDoubleValue("accelerations/pilot/z-accel-fps_sec",
404 net->A_Z_pilot);
405
406 props->setDoubleValue( "/sim/alarms/stall-warning", net->stall_warning );
407 props->setDoubleValue( "/instrumentation/slip-skid-ball/indicated-slip-skid",
408 net->slip_deg );
409 props->setBoolValue( "/instrumentation/slip-skid-ball/override", true );
410
411 for ( i = 0; i < net->num_engines; ++i ) {
412 SGPropertyNode *node = props->getNode( "engines/engine", i, true );
413
414 // node->setBoolValue("running", t->isRunning());
415 // node->setBoolValue("cranking", t->isCranking());
416
417 // cout << net->eng_state[i] << endl;
418 if ( net->eng_state[i] == 0 ) {
419 node->setBoolValue( "cranking", false );
420 node->setBoolValue( "running", false );
421 } else if ( net->eng_state[i] == 1 ) {
422 node->setBoolValue( "cranking", true );
423 node->setBoolValue( "running", false );
424 } else if ( net->eng_state[i] == 2 ) {
425 node->setBoolValue( "cranking", false );
426 node->setBoolValue( "running", true );
427 }
428
429 node->setDoubleValue( "rpm", net->rpm[i] );
430 node->setDoubleValue( "fuel-flow-gph", net->fuel_flow[i] );
431 node->setDoubleValue( "fuel-px-psi", net->fuel_px[i] );
432 node->setDoubleValue( "egt-degf", net->egt[i] );
433 node->setDoubleValue( "cht-degf", net->cht[i] );
434 node->setDoubleValue( "mp-osi", net->mp_osi[i] );
435 node->setDoubleValue( "tit", net->tit[i] );
436 node->setDoubleValue( "oil-temperature-degf", net->oil_temp[i] );
437 node->setDoubleValue( "oil-pressure-psi", net->oil_px[i] );
438 }
439
440 for (i = 0; i < net->num_tanks; ++i ) {
441 SGPropertyNode * node
442 = props->getNode("/consumables/fuel/tank", i, true);
443 node->setDoubleValue("level-gal_us", net->fuel_quantity[i] );
444 }
445
446 for (i = 0; i < net->num_wheels; ++i ) {
447 SGPropertyNode * node = props->getNode("/gear/gear", i, true);
448 node->setDoubleValue("wow", net->wow[i] );
449 node->setDoubleValue("position-norm", net->gear_pos[i] );
450 node->setDoubleValue("steering-norm", net->gear_steer[i] );
451 node->setDoubleValue("compression-norm", net->gear_compression[i] );
452 }
453
454 /* these are ignored for now ... */
455 /*
456 if ( net->cur_time ) {
457 props->setLongValue("/sim/time/cur-time-override", net->cur_time);
458 }
459
460 props->setIntValue("/sim/time/warp", net->warp);
461 last_warp = net->warp;
462 */
463
464 SGPropertyNode *node = props->getNode("/surface-positions", true);
465 node->setDoubleValue("elevator-pos-norm", net->elevator);
466 node->setDoubleValue("elevator-trim-tab-pos-norm",
467 net->elevator_trim_tab);
468 // FIXME: CLO 10/28/04 - This really should be separated out
469 // into 2 values
470 node->setDoubleValue("flap-pos-norm", net->left_flap);
471 node->setDoubleValue("flap-pos-norm", net->right_flap);
472 node->setDoubleValue("left-aileron-pos-norm", net->left_aileron);
473 node->setDoubleValue("right-aileron-pos-norm", net->right_aileron);
474 node->setDoubleValue("rudder-pos-norm", net->rudder);
475 node->setDoubleValue("nose-wheel-pos-norm", net->nose_wheel);
476 node->setDoubleValue("speedbrake-pos-norm", net->speedbrake);
477 node->setDoubleValue("spoilers-pos-norm", net->spoilers);
478 } else {
479 SG_LOG( SG_IO, SG_ALERT,
480 "Error: version mismatch in Net FGFDM2Props()" );
481 SG_LOG( SG_IO, SG_ALERT,
482 "\tread " << net->version << " need " << FG_NET_FDM_VERSION );
483 SG_LOG( SG_IO, SG_ALERT,
484 "\tNeeds to upgrade net_fdm.hxx and recompile." );
485 }
486}
487
488#if FG_HAVE_DDS
489#include "DDS/dds_fdm.h"
490#include "DDS/dds_gui.h"
491#include "DDS/dds_ctrls.h"
492
493template<>
494void FGProps2FDM<FG_DDS_FDM>( SGPropertyNode *props, FG_DDS_FDM *dds, bool net_byte_order ) {
495 unsigned int i;
496
497 // Version sanity checking
499
500 // Aero parameters
501 dds->longitude = props->getDoubleValue("position/longitude-deg")
502 * SG_DEGREES_TO_RADIANS;
503 dds->latitude = props->getDoubleValue("position/latitude-deg")
504 * SG_DEGREES_TO_RADIANS;
505 dds->altitude = props->getDoubleValue("position/altitude-ft")
506 * SG_FEET_TO_METER;
507 dds->agl = props->getDoubleValue("position/altitude-agl-ft")
508 * SG_FEET_TO_METER;
509 dds->phi = SGMiscd::deg2rad( props->getDoubleValue("orientation/roll-deg") );
510 dds->theta = SGMiscd::deg2rad( props->getDoubleValue("orientation/pitch-deg") );
511 dds->psi = SGMiscd::deg2rad( props->getDoubleValue("orientation/heading-deg") );
512 dds->alpha = props->getDoubleValue("orientation/alpha-deg")
513 * SG_DEGREES_TO_RADIANS;
514 dds->beta = props->getDoubleValue("orientation/beta-deg")
515 * SG_DEGREES_TO_RADIANS;
516 dds->phidot = props->getDoubleValue("orientation/roll-rate-degps")
517 * SG_DEGREES_TO_RADIANS;
518 dds->thetadot = props->getDoubleValue("orientation/pitch-rate-degps")
519 * SG_DEGREES_TO_RADIANS;
520 dds->psidot = props->getDoubleValue("orientation/yaw-rate-degps")
521 * SG_DEGREES_TO_RADIANS;
522
523 dds->vcas = props->getDoubleValue("velocities/airspeed-kt");
524 dds->climb_rate = props->getDoubleValue("velocities/vertical-speed-fps");
525
526 dds->v_north = props->getDoubleValue("velocities/speed-north-fps", 0.0);
527 dds->v_east = props->getDoubleValue("velocities/speed-east-fps", 0.0);
528 dds->v_down = props->getDoubleValue("velocities/speed-down-fps", 0.0);
529 dds->v_body_u = props->getDoubleValue("velocities/uBody-fps", 0.0);
530 dds->v_body_v = props->getDoubleValue("velocities/vBody-fps", 0.0);
531 dds->v_body_w = props->getDoubleValue("velocities/wBody-fps", 0.0);
532
533 dds->A_X_pilot = props->getDoubleValue("accelerations/pilot/x-accel-fps_sec", 0.0);
534 dds->A_Y_pilot = props->getDoubleValue("/accelerations/pilot/y-accel-fps_sec", 0.0);
535 dds->A_Z_pilot = props->getDoubleValue("/accelerations/pilot/z-accel-fps_sec", 0.0);
536
537 dds->stall_warning = props->getDoubleValue("/sim/alarms/stall-warning", 0.0);
538 dds->slip_deg
539 = props->getDoubleValue("/instrumentation/slip-skid-ball/indicated-slip-skid");
540
541 // Engine parameters
543 for ( i = 0; i < dds->num_engines; ++i ) {
544 SGPropertyNode *node = props->getNode("engines/engine", i, true);
545 if ( node->getBoolValue( "running" ) ) {
546 dds->eng_state[i] = 2;
547 } else if ( node->getBoolValue( "cranking" ) ) {
548 dds->eng_state[i] = 1;
549 } else {
550 dds->eng_state[i] = 0;
551 }
552 dds->rpm[i] = node->getDoubleValue( "rpm" );
553 dds->fuel_flow[i] = node->getDoubleValue( "fuel-flow-gph" );
554 dds->fuel_px[i] = node->getDoubleValue( "fuel-px-psi" );
555 dds->egt[i] = node->getDoubleValue( "egt-degf" );
556 // cout << "egt = " << aero->EGT << endl;
557 dds->cht[i] = node->getDoubleValue( "cht-degf" );
558 dds->mp_osi[i] = node->getDoubleValue( "mp-osi" );
559 dds->tit[i] = node->getDoubleValue( "tit" );
560 dds->oil_temp[i] = node->getDoubleValue( "oil-temperature-degf" );
561 dds->oil_px[i] = node->getDoubleValue( "oil-pressure-psi" );
562 }
563
564 // Consumables
566 for ( i = 0; i < dds->num_tanks; ++i ) {
567 SGPropertyNode *node = props->getNode("/consumables/fuel/tank", i, true);
568 dds->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
569 dds->tank_selected[i] = node->getBoolValue("selected");
570 dds->capacity_m3[i] = node->getDoubleValue("capacity-m3");
571 dds->unusable_m3[i] = node->getDoubleValue("unusable-m3");
572 dds->density_kgpm3[i] = node->getDoubleValue("density-kgpm3");
573 dds->level_m3[i] = node->getDoubleValue("level-m3");
574 }
575
576 // Gear and flaps
578 for (i = 0; i < dds->num_wheels; ++i ) {
579 SGPropertyNode *node = props->getNode("/gear/gear", i, true);
580 dds->wow[i] = node->getIntValue("wow");
581 dds->gear_pos[i] = node->getDoubleValue("position-norm");
582 dds->gear_steer[i] = node->getDoubleValue("steering-norm");
583 dds->gear_compression[i] = node->getDoubleValue("compression-norm");
584 }
585
586 // the following really aren't used in this context
587 SGTime time;
588 dds->cur_time = time.get_cur_time();
589 dds->warp = props->getIntValue("/sim/time/warp");
590 dds->visibility = props->getDoubleValue("/environment/visibility-m");
591
592 // Control surface positions
593 SGPropertyNode *node = props->getNode("/surface-positions", true);
594 dds->elevator = node->getDoubleValue( "elevator-pos-norm" );
596 = node->getDoubleValue( "elevator-trim-tab-pos-norm" );
597 // FIXME: CLO 10/28/04 - This really should be separated out into 2 values
598 dds->left_flap = node->getDoubleValue( "flap-pos-norm" );
599 dds->right_flap = node->getDoubleValue( "flap-pos-norm" );
600 dds->left_aileron = node->getDoubleValue( "left-aileron-pos-norm" );
601 dds->right_aileron = node->getDoubleValue( "right-aileron-pos-norm" );
602 dds->rudder = node->getDoubleValue( "rudder-pos-norm" );
603 dds->nose_wheel = node->getDoubleValue( "nose-wheel-pos-norm" );
604 dds->speedbrake = node->getDoubleValue( "speedbrake-pos-norm" );
605 dds->spoilers = node->getDoubleValue( "spoilers-pos-norm" );
606}
607
608template<>
609void FGFDM2Props<FG_DDS_FDM>( SGPropertyNode *props, FG_DDS_FDM *dds, bool net_byte_order ) {
610 unsigned int i;
611
612 if ( dds->version == FG_DDS_FDM_VERSION ) {
613 // cout << "pos = " << dds->longitude << " " << dds->latitude << endl;
614 // cout << "sea level rad = " << fdm_state.get_Sea_level_radius()
615 // << endl;
616
617 props->setDoubleValue("position/latitude-deg",
618 dds->latitude * SG_RADIANS_TO_DEGREES);
619 props->setDoubleValue("position/longitude-deg",
620 dds->longitude* SG_RADIANS_TO_DEGREES);
621 props->setDoubleValue("position/altitude-ft",
622 dds->altitude * SG_METER_TO_FEET);
623
624 if ( dds->agl > -9000 ) {
625 props->setDoubleValue("position/altitude-agl-ft",
626 dds->agl * SG_METER_TO_FEET );
627 } else {
628 double agl_m = dds->altitude
629 - props->getDoubleValue("environment/ground-elevation-m");
630 props->setDoubleValue("position/altitude-agl-ft",
631 agl_m * SG_METER_TO_FEET );
632 }
633 props->setDoubleValue("orientation/roll-deg",
634 dds->phi * SG_RADIANS_TO_DEGREES);
635 props->setDoubleValue("orientation/pitch-deg",
636 dds->theta * SG_RADIANS_TO_DEGREES);
637 props->setDoubleValue("orientation/heading-deg",
638 dds->psi * SG_RADIANS_TO_DEGREES);
639 props->setDoubleValue("orientation/alpha-deg",
640 dds->alpha * SG_RADIANS_TO_DEGREES );
641 props->setDoubleValue("orientation/side-slip-rad",
642 dds->beta * SG_RADIANS_TO_DEGREES );
643 props->setDoubleValue("orientation/roll-rate-degps",
644 dds->phidot * SG_RADIANS_TO_DEGREES);
645 props->setDoubleValue("orientation/pitch-rate-degps",
646 dds->thetadot * SG_RADIANS_TO_DEGREES);
647 props->setDoubleValue("orientation/yaw-rate-degps",
648 dds->psidot * SG_RADIANS_TO_DEGREES);
649 props->setDoubleValue("velocities/airspeed-kt", dds->vcas);
650 props->setDoubleValue("velocities/vertical-speed-fps", dds->climb_rate);
651 props->setDoubleValue("velocities/speed-north-fps", dds->v_north);
652 props->setDoubleValue("velocities/speed-east-fps", dds->v_east);
653 props->setDoubleValue("velocities/speed-down-fps", dds->v_down);
654 props->setDoubleValue("velocities/uBody-fps", dds->v_body_u);
655 props->setDoubleValue("velocities/vBody-fps", dds->v_body_v);
656 props->setDoubleValue("velocities/wBody-fps", dds->v_body_w);
657 props->setDoubleValue("accelerations/pilot/x-accel-fps_sec",
658 dds->A_X_pilot);
659 props->setDoubleValue("accelerations/pilot/y-accel-fps_sec",
660 dds->A_Y_pilot);
661 props->setDoubleValue("accelerations/pilot/z-accel-fps_sec",
662 dds->A_Z_pilot);
663
664 props->setDoubleValue( "/sim/alarms/stall-warning", dds->stall_warning );
665 props->setDoubleValue( "/instrumentation/slip-skid-ball/indicated-slip-skid",
666 dds->slip_deg );
667 props->setBoolValue( "/instrumentation/slip-skid-ball/override", true );
668
669 for ( i = 0; i < dds->num_engines; ++i ) {
670 SGPropertyNode *node = props->getNode( "engines/engine", i, true );
671
672 // node->setBoolValue("running", t->isRunning());
673 // node->setBoolValue("cranking", t->isCranking());
674 // cout << dds->eng_state[i] << endl;
675 if ( dds->eng_state[i] == 0 ) {
676 node->setBoolValue( "cranking", false );
677 node->setBoolValue( "running", false );
678 } else if ( dds->eng_state[i] == 1 ) {
679 node->setBoolValue( "cranking", true );
680 node->setBoolValue( "running", false );
681 } else if ( dds->eng_state[i] == 2 ) {
682 node->setBoolValue( "cranking", false );
683 node->setBoolValue( "running", true );
684 }
685
686 node->setDoubleValue( "rpm", dds->rpm[i] );
687 node->setDoubleValue( "fuel-flow-gph", dds->fuel_flow[i] );
688 node->setDoubleValue( "fuel-px-psi", dds->fuel_px[i] );
689 node->setDoubleValue( "egt-degf", dds->egt[i] );
690 node->setDoubleValue( "cht-degf", dds->cht[i] );
691 node->setDoubleValue( "mp-osi", dds->mp_osi[i] );
692 node->setDoubleValue( "tit", dds->tit[i] );
693 node->setDoubleValue( "oil-temperature-degf", dds->oil_temp[i] );
694 node->setDoubleValue( "oil-pressure-psi", dds->oil_px[i] );
695 }
696
697 for (i = 0; i < dds->num_tanks; ++i ) {
698 SGPropertyNode * node
699 = props->getNode("/consumables/fuel/tank", i, true);
700 node->setDoubleValue("level-gal_us", dds->fuel_quantity[i]);
701 node->setBoolValue("selected", dds->tank_selected[i] > 0);
702 node->setDoubleValue("capacity-m3", dds->capacity_m3[i]);
703 node->setDoubleValue("unusable-m3", dds->unusable_m3[i]);
704 node->setDoubleValue("density-kgpm3", dds->density_kgpm3[i]);
705 node->setDoubleValue("level-m3", dds->level_m3[i]);
706 }
707
708 for (i = 0; i < dds->num_wheels; ++i ) {
709 SGPropertyNode * node = props->getNode("/gear/gear", i, true);
710 node->setDoubleValue("wow", dds->wow[i] );
711 node->setDoubleValue("position-norm", dds->gear_pos[i] );
712 node->setDoubleValue("steering-norm", dds->gear_steer[i] );
713 node->setDoubleValue("compression-norm", dds->gear_compression[i] );
714 }
715
716 /* these are ignored for now ... */
717 /*
718 if ( dds->cur_time ) {
719 props->setLongValue("/sim/time/cur-time-override", dds->cur_time);
720 }
721
722 props->setIntValue("/sim/time/warp", dds->warp);
723 last_warp = dds->warp;
724 */
725 SGPropertyNode *node = props->getNode("/surface-positions", true);
726 node->setDoubleValue("elevator-pos-norm", dds->elevator);
727 node->setDoubleValue("elevator-trim-tab-pos-norm",
728 dds->elevator_trim_tab);
729 // FIXME: CLO 10/28/04 - This really should be separated out
730 // into 2 values
731 node->setDoubleValue("flap-pos-norm", dds->left_flap);
732 node->setDoubleValue("flap-pos-norm", dds->right_flap);
733 node->setDoubleValue("left-aileron-pos-norm", dds->left_aileron);
734 node->setDoubleValue("right-aileron-pos-norm", dds->right_aileron);
735 node->setDoubleValue("rudder-pos-norm", dds->rudder);
736 node->setDoubleValue("nose-wheel-pos-norm", dds->nose_wheel);
737 node->setDoubleValue("speedbrake-pos-norm", dds->speedbrake);
738 node->setDoubleValue("spoilers-pos-norm", dds->spoilers);
739 } else {
740 SG_LOG( SG_IO, SG_ALERT,
741 "Error: version mismatch in DDS FGFDM2Props()" );
742 SG_LOG( SG_IO, SG_ALERT,
743 "\tread " << dds->version << " need " << FG_DDS_FDM_VERSION );
744 SG_LOG( SG_IO, SG_ALERT,
745 "\tNeeds to upgrade DDS/dds_fdm.hxx and recompile." );
746 }
747}
748#endif
749
750
751
752
753
754template<>
755void FGProps2GUI<FGNetGUI>( SGPropertyNode *props, FGNetGUI *net ) {
756 static SGPropertyNode *nav_freq
757 = props->getNode("/instrumentation/nav/frequencies/selected-mhz", true);
758 static SGPropertyNode *nav_target_radial
759 = props->getNode("/instrumentation/nav/radials/target-radial-deg", true);
760 static SGPropertyNode *nav_inrange
761 = props->getNode("/instrumentation/nav/in-range", true);
762 static SGPropertyNode *nav_loc
763 = props->getNode("/instrumentation/nav/nav-loc", true);
764 static SGPropertyNode *nav_gs_dist_signed
765 = props->getNode("/instrumentation/nav/gs-distance", true);
766 static SGPropertyNode *nav_loc_dist
767 = props->getNode("/instrumentation/nav/nav-distance", true);
768 static SGPropertyNode *nav_reciprocal_radial
769 = props->getNode("/instrumentation/nav/radials/reciprocal-radial-deg", true);
770 static SGPropertyNode *nav_gs_deflection
771 = props->getNode("/instrumentation/nav/gs-needle-deflection", true);
772 unsigned int i;
773
774 // Version sanity checking
776
777 // Aero parameters
778 net->longitude = props->getDoubleValue("position/longitude-deg")
779 * SG_DEGREES_TO_RADIANS;
780 net->latitude = props->getDoubleValue("position/latitude-deg")
781 * SG_DEGREES_TO_RADIANS;
782 net->altitude = props->getDoubleValue("position/altitude-ft")
783 * SG_FEET_TO_METER;
784 net->phi = SGMiscd::deg2rad( props->getDoubleValue("orientation/roll-deg") );
785 net->theta = SGMiscd::deg2rad( props->getDoubleValue("orientation/pitch-deg") );
786 net->psi = SGMiscd::deg2rad( props->getDoubleValue("orientation/heading-deg") );
787
788 // Velocities
789 net->vcas = props->getDoubleValue("velocities/airspeed-kt");
790 net->climb_rate = props->getDoubleValue("velocities/vertical-speed-fps");
791
792 // Consumables
794 for ( i = 0; i < net->num_tanks; ++i ) {
795 SGPropertyNode *node = props->getNode("/consumables/fuel/tank", i, true);
796 net->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
797 }
798
799 // Environment
800 SGTime time;
801 net->cur_time = time.get_cur_time();
802 net->warp = props->getIntValue("/sim/time/warp");
803 net->ground_elev = props->getDoubleValue("environment/ground-elevation-m");
804
805 // Approach
806 net->tuned_freq = nav_freq->getDoubleValue();
807 net->nav_radial = nav_target_radial->getDoubleValue();
808 net->in_range = nav_inrange->getBoolValue();
809
810 if ( nav_loc->getBoolValue() ) {
811 // is an ILS
812 net->dist_nm
813 = nav_gs_dist_signed->getDoubleValue()
814 * SG_METER_TO_NM;
815 } else {
816 // is a VOR
817 net->dist_nm = nav_loc_dist->getDoubleValue()
818 * SG_METER_TO_NM;
819 }
820
822 = nav_reciprocal_radial->getDoubleValue()
823 - nav_target_radial->getDoubleValue();
824
825 if ( net->course_deviation_deg < -1000.0
826 || net->course_deviation_deg > 1000.0 )
827 {
828 // Sanity check ...
829 net->course_deviation_deg = 0.0;
830 }
831 while ( net->course_deviation_deg > 180.0 ) {
832 net->course_deviation_deg -= 360.0;
833 }
834 while ( net->course_deviation_deg < -180.0 ) {
835 net->course_deviation_deg += 360.0;
836 }
837 if ( fabs(net->course_deviation_deg) > 90.0 )
839 = ( net->course_deviation_deg<0.0
840 ? -net->course_deviation_deg - 180.0
841 : -net->course_deviation_deg + 180.0 );
842
843 if ( nav_loc->getBoolValue() ) {
844 // is an ILS
846 = nav_gs_deflection->getDoubleValue()
847 / 5.0;
848 } else {
849 // is an ILS
850 net->gs_deviation_deg = -9999.0;
851 }
852
853#if defined( FG_USE_NETWORK_BYTE_ORDER )
854 // Convert the net buffer to network format
855 net->version = htonl(net->version);
856
857 htond(net->longitude);
858 htond(net->latitude);
859 htonf(net->altitude);
860 htonf(net->phi);
861 htonf(net->theta);
862 htonf(net->psi);
863 htonf(net->vcas);
864 htonf(net->climb_rate);
865
866 for ( i = 0; i < net->num_tanks; ++i ) {
867 htonf(net->fuel_quantity[i]);
868 }
869 net->num_tanks = htonl(net->num_tanks);
870
871 net->cur_time = htonl( net->cur_time );
872 net->warp = htonl( net->warp );
873 net->ground_elev = htonl( net->ground_elev );
874
875 htonf(net->tuned_freq);
876 htonf(net->nav_radial);
877 net->in_range = htonl( net->in_range );
878 htonf(net->dist_nm);
881#endif
882}
883
884template<>
885void FGGUI2Props<FGNetGUI>( SGPropertyNode *props, FGNetGUI *net ) {
886 unsigned int i;
887
888#if defined( FG_USE_NETWORK_BYTE_ORDER )
889 // Convert to the net buffer from network format
890 net->version = ntohl(net->version);
891
892 htond(net->longitude);
893 htond(net->latitude);
894 htonf(net->altitude);
895 htonf(net->phi);
896 htonf(net->theta);
897 htonf(net->psi);
898 htonf(net->vcas);
899 htonf(net->climb_rate);
900
901 net->num_tanks = htonl(net->num_tanks);
902 for ( i = 0; i < net->num_tanks; ++i ) {
903 htonf(net->fuel_quantity[i]);
904 }
905
906 net->cur_time = ntohl(net->cur_time);
907 net->warp = ntohl(net->warp);
908 net->ground_elev = htonl( net->ground_elev );
909
910 htonf(net->tuned_freq);
911 htonf(net->nav_radial);
912 net->in_range = htonl( net->in_range );
913 htonf(net->dist_nm);
916#endif
917
918 if ( net->version == FG_NET_GUI_VERSION ) {
919
920 // cout << "pos = " << net->longitude << " " << net->latitude << endl;
921 // cout << "sea level rad = " << fdm_state->get_Sea_level_radius()
922 // << endl;
923
924 props->setDoubleValue("position/latitude-deg",
925 net->latitude * SG_RADIANS_TO_DEGREES);
926 props->setDoubleValue("position/longitude-deg",
927 net->longitude* SG_RADIANS_TO_DEGREES);
928 props->setDoubleValue("position/altitude-ft",
929 net->altitude * SG_METER_TO_FEET);
930
931 props->setDoubleValue("orientation/roll-deg",
932 net->phi * SG_RADIANS_TO_DEGREES);
933 props->setDoubleValue("orientation/pitch-deg",
934 net->theta * SG_RADIANS_TO_DEGREES);
935 props->setDoubleValue("orientation/heading-deg",
936 net->psi * SG_RADIANS_TO_DEGREES);
937
938 props->setDoubleValue("velocities/airspeed-kt", net->vcas);
939 props->setDoubleValue("velocities/vertical-speed-fps", net->climb_rate);
940
941 for (i = 0; i < net->num_tanks; ++i ) {
942 SGPropertyNode * node
943 = props->getNode("/consumables/fuel/tank", i, true);
944 node->setDoubleValue("level-gal_us", net->fuel_quantity[i] );
945 }
946
947 if ( net->cur_time ) {
948 props->setLongValue("/sim/time/cur-time-override", net->cur_time);
949 }
950
951 props->setIntValue("/sim/time/warp", net->warp);
952
953 // Approach
954 props->setDoubleValue( "/instrumentation/nav[0]/frequencies/selected-mhz",
955 net->tuned_freq );
956 props->setBoolValue( "/instrumentation/nav[0]/in-range", net->in_range > 0);
957 props->setDoubleValue( "/instrumentation/dme/indicated-distance-nm", net->dist_nm );
958 props->setDoubleValue( "/instrumentation/nav[0]/heading-needle-deflection",
960 props->setDoubleValue( "/instrumentation/nav[0]/gs-needle-deflection",
961 net->gs_deviation_deg );
962 } else {
963 SG_LOG( SG_IO, SG_ALERT,
964 "Error: version mismatch in FGNetNativeGUI2Props()" );
965 SG_LOG( SG_IO, SG_ALERT,
966 "\tread " << net->version << " need " << FG_NET_GUI_VERSION );
967 SG_LOG( SG_IO, SG_ALERT,
968 "\tNeed to upgrade net_fdm.hxx and recompile." );
969 }
970}
971
972#if FG_HAVE_DDS
973template<>
974void FGProps2GUI<FG_DDS_GUI>( SGPropertyNode *props, FG_DDS_GUI *dds ) {
975 static SGPropertyNode *nav_freq
976 = props->getNode("/instrumentation/nav/frequencies/selected-mhz", true);
977 static SGPropertyNode *nav_target_radial
978 = props->getNode("/instrumentation/nav/radials/target-radial-deg", true);
979 static SGPropertyNode *nav_inrange
980 = props->getNode("/instrumentation/nav/in-range", true);
981 static SGPropertyNode *nav_loc
982 = props->getNode("/instrumentation/nav/nav-loc", true);
983 static SGPropertyNode *nav_gs_dist_signed
984 = props->getNode("/instrumentation/nav/gs-distance", true);
985 static SGPropertyNode *nav_loc_dist
986 = props->getNode("/instrumentation/nav/nav-distance", true);
987 static SGPropertyNode *nav_reciprocal_radial
988 = props->getNode("/instrumentation/nav/radials/reciprocal-radial-deg", true);
989 static SGPropertyNode *nav_gs_deflection
990 = props->getNode("/instrumentation/nav/gs-needle-deflection", true);
991 unsigned int i;
992
993 // Version sanity checking
995
996 // Aero parameters
997 dds->longitude = props->getDoubleValue("position/longitude-deg")
998 * SG_DEGREES_TO_RADIANS;
999 dds->latitude = props->getDoubleValue("position/latitude-deg")
1000 * SG_DEGREES_TO_RADIANS;
1001 dds->altitude = props->getDoubleValue("position/altitude-ft")
1002 * SG_FEET_TO_METER;
1003 dds->phi = SGMiscd::deg2rad( props->getDoubleValue("orientation/roll-deg") );
1004 dds->theta = SGMiscd::deg2rad( props->getDoubleValue("orientation/pitch-deg") );
1005 dds->psi = SGMiscd::deg2rad( props->getDoubleValue("orientation/heading-deg") );
1006
1007 // Velocities
1008 dds->vcas = props->getDoubleValue("velocities/airspeed-kt");
1009 dds->climb_rate = props->getDoubleValue("velocities/vertical-speed-fps");
1010
1011 // Consumables
1013 for ( i = 0; i < dds->num_tanks; ++i ) {
1014 SGPropertyNode *node = props->getNode("/consumables/fuel/tank", i, true);
1015 dds->fuel_quantity[i] = node->getDoubleValue("level-gal_us");
1016 }
1017
1018 // Environment
1019 SGTime time;
1020 dds->cur_time = time.get_cur_time();
1021 dds->warp = props->getIntValue("/sim/time/warp");
1022 dds->ground_elev = props->getDoubleValue("environment/ground-elevation-m");
1023
1024 // Approach
1025 dds->tuned_freq = nav_freq->getDoubleValue();
1026 dds->nav_radial = nav_target_radial->getDoubleValue();
1027 dds->in_range = nav_inrange->getBoolValue();
1028
1029 if ( nav_loc->getBoolValue() ) {
1030 // is an ILS
1031 dds->dist_nm
1032 = nav_gs_dist_signed->getDoubleValue()
1033 * SG_METER_TO_NM;
1034 } else {
1035 // is a VOR
1036 dds->dist_nm = nav_loc_dist->getDoubleValue()
1037 * SG_METER_TO_NM;
1038 }
1039
1041 = nav_reciprocal_radial->getDoubleValue()
1042 - nav_target_radial->getDoubleValue();
1043
1044 if ( dds->course_deviation_deg < -1000.0
1045 || dds->course_deviation_deg > 1000.0 )
1046 {
1047 // Sanity check ...
1048 dds->course_deviation_deg = 0.0;
1049 }
1050 while ( dds->course_deviation_deg > 180.0 ) {
1051 dds->course_deviation_deg -= 360.0;
1052 }
1053 while ( dds->course_deviation_deg > 180.0 ) {
1054 dds->course_deviation_deg -= 360.0;
1055 }
1056 while ( dds->course_deviation_deg < -180.0 ) {
1057 dds->course_deviation_deg += 360.0;
1058 }
1059 if ( fabs(dds->course_deviation_deg) > 90.0 )
1061 = ( dds->course_deviation_deg<0.0
1062 ? -dds->course_deviation_deg - 180.0
1063 : -dds->course_deviation_deg + 180.0 );
1064
1065 if ( nav_loc->getBoolValue() ) {
1066 // is an ILS
1067 dds->gs_deviation_deg
1068 = nav_gs_deflection->getDoubleValue()
1069 / 5.0;
1070 } else {
1071 // is an ILS
1072 dds->gs_deviation_deg = -9999.0;
1073 }
1074}
1075
1076template<>
1077void FGGUI2Props<FG_DDS_GUI>( SGPropertyNode *props, FG_DDS_GUI *dds ) {
1078 unsigned int i;
1079
1080 if ( dds->version == FG_DDS_GUI_VERSION ) {
1081
1082 // cout << "pos = " << dds->longitude << " " << dds->latitude << endl;
1083 // cout << "sea level rad = " << fdm_state->get_Sea_level_radius()
1084 // << endl;
1085
1086 props->setDoubleValue("position/latitude-deg",
1087 dds->latitude * SG_RADIANS_TO_DEGREES);
1088 props->setDoubleValue("position/longitude-deg",
1089 dds->longitude* SG_RADIANS_TO_DEGREES);
1090 props->setDoubleValue("position/altitude-ft",
1091 dds->altitude * SG_METER_TO_FEET);
1092
1093 props->setDoubleValue("orientation/roll-deg",
1094 dds->phi * SG_RADIANS_TO_DEGREES);
1095 props->setDoubleValue("orientation/pitch-deg",
1096 dds->theta * SG_RADIANS_TO_DEGREES);
1097 props->setDoubleValue("orientation/heading-deg",
1098 dds->psi * SG_RADIANS_TO_DEGREES);
1099
1100 props->setDoubleValue("velocities/airspeed-kt", dds->vcas);
1101 props->setDoubleValue("velocities/vertical-speed-fps", dds->climb_rate);
1102
1103 for (i = 0; i < dds->num_tanks; ++i ) {
1104 SGPropertyNode * node
1105 = props->getNode("/consumables/fuel/tank", i, true);
1106 node->setDoubleValue("level-gal_us", dds->fuel_quantity[i] );
1107 }
1108
1109 if ( dds->cur_time ) {
1110 props->setLongValue("/sim/time/cur-time-override", dds->cur_time);
1111 }
1112
1113 props->setIntValue("/sim/time/warp", dds->warp );
1114
1115 // Approach
1116 props->setDoubleValue( "/instrumentation/nav[0]/frequencies/selected-mhz",
1117 dds->tuned_freq );
1118 props->setBoolValue( "/instrumentation/nav[0]/in-range", dds->in_range > 0);
1119 props->setDoubleValue( "/instrumentation/dme/indicated-distance-nm", dds->dist_nm );
1120 props->setDoubleValue( "/instrumentation/nav[0]/heading-needle-deflection",
1121 dds->course_deviation_deg );
1122 props->setDoubleValue( "/instrumentation/nav[0]/gs-needle-deflection",
1123 dds->gs_deviation_deg );
1124 } else {
1125 SG_LOG( SG_IO, SG_ALERT,
1126 "Error: version mismatch in FGNetNativeGUI2Props()" );
1127 SG_LOG( SG_IO, SG_ALERT,
1128 "\tread " << dds->version << " need " << FG_DDS_GUI_VERSION );
1129 SG_LOG( SG_IO, SG_ALERT,
1130 "\tNeed to upgrade net_fdm.hxx and recompile." );
1131 }
1132}
1133#endif
1134
1135
1136// Populate the FGNetCtrls structure from the property tree.
1137template<>
1138void FGProps2Ctrls<FGNetCtrls>( SGPropertyNode *props, FGNetCtrls *net, bool honor_freezes,
1139 bool net_byte_order )
1140{
1141 int i;
1142 SGPropertyNode *node;
1143 SGPropertyNode *fuelpump;
1144 SGPropertyNode *tempnode;
1145
1146 // fill in values
1147 node = props->getNode("/controls/flight", true);
1149 net->aileron = node->getDoubleValue( "aileron" );
1150 net->elevator = node->getDoubleValue( "elevator" );
1151 net->rudder = node->getDoubleValue( "rudder" );
1152 net->aileron_trim = node->getDoubleValue( "aileron-trim" );
1153 net->elevator_trim = node->getDoubleValue( "elevator-trim" );
1154 net->rudder_trim = node->getDoubleValue( "rudder-trim" );
1155 net->flaps = node->getDoubleValue( "flaps" );
1156 net->speedbrake = node->getDoubleValue( "speedbrake" );
1157 net->spoilers = node->getDoubleValue( "spoilers" );
1158 net->flaps_power
1159 = props->getDoubleValue( "/systems/electrical/outputs/flaps", 1.0 ) >= 1.0;
1160 net->flap_motor_ok = node->getBoolValue( "flaps-serviceable" );
1161
1163 for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
1164 // Controls
1165 node = props->getNode("/controls/engines/engine", i );
1166 fuelpump = props->getNode("/systems/electrical/outputs/fuel-pump", i );
1167
1168 tempnode = node->getChild("starter");
1169 if ( tempnode != NULL ) {
1170 net->starter_power[i] = ( tempnode->getDoubleValue() >= 1.0 );
1171 }
1172 tempnode = node->getChild("master-bat");
1173 if ( tempnode != NULL ) {
1174 net->master_bat[i] = tempnode->getBoolValue();
1175 }
1176 tempnode = node->getChild("master-alt");
1177 if ( tempnode != NULL ) {
1178 net->master_alt[i] = tempnode->getBoolValue();
1179 }
1180
1181 net->throttle[i] = node->getDoubleValue( "throttle", 0.0 );
1182 net->mixture[i] = node->getDoubleValue( "mixture", 0.0 );
1183 net->prop_advance[i] = node->getDoubleValue( "propeller-pitch", 0.0 );
1184 net->condition[i] = node->getDoubleValue( "condition", 0.0 );
1185 net->magnetos[i] = node->getIntValue( "magnetos", 0 );
1186 if ( i == 0 ) {
1187 // cout << "Magnetos -> " << node->getIntValue( "magnetos", 0 );
1188 }
1189 if ( i == 0 ) {
1190 // cout << "Starter -> " << node->getIntValue( "starter", false )
1191 // << endl;
1192 }
1193
1194 if ( fuelpump != NULL ) {
1195 net->fuel_pump_power[i] = ( fuelpump->getDoubleValue() >= 1.0 );
1196 } else {
1197 net->fuel_pump_power[i] = 0;
1198 }
1199
1200 // Faults
1201 SGPropertyNode *faults = node->getChild( "faults", 0, true );
1202 net->engine_ok[i] = faults->getBoolValue( "serviceable", true );
1203 net->mag_left_ok[i]
1204 = faults->getBoolValue( "left-magneto-serviceable", true );
1205 net->mag_right_ok[i]
1206 = faults->getBoolValue( "right-magneto-serviceable", true);
1207 net->spark_plugs_ok[i]
1208 = faults->getBoolValue( "spark-plugs-serviceable", true );
1209 net->oil_press_status[i]
1210 = faults->getIntValue( "oil-pressure-status", 0 );
1211 net->fuel_pump_ok[i]
1212 = faults->getBoolValue( "fuel-pump-serviceable", true );
1213 }
1215 for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
1216 node = props->getNode("/controls/fuel/tank", i);
1217 if ( node->getChild("fuel_selector") != 0 ) {
1218 net->fuel_selector[i]
1219 = node->getChild("fuel_selector")->getBoolValue();
1220 } else {
1221 net->fuel_selector[i] = false;
1222 }
1223 }
1224 node = props->getNode("/controls/gear", true);
1225 net->brake_left = node->getChild("brake-left")->getDoubleValue();
1226 net->brake_right = node->getChild("brake-right")->getDoubleValue();
1228 = node->getChild("copilot-brake-left")->getDoubleValue();
1230 = node->getChild("copilot-brake-right")->getDoubleValue();
1231 net->brake_parking = node->getChild("brake-parking")->getDoubleValue();
1232
1233 net->gear_handle = props->getBoolValue( "/controls/gear/gear-down" );
1234
1235 net->master_avionics = props->getBoolValue("/controls/switches/master-avionics");
1236
1237 net->wind_speed_kt = props->getDoubleValue("/environment/wind-speed-kt");
1238 net->wind_dir_deg = props->getDoubleValue("/environment/wind-from-heading-deg");
1239 net->turbulence_norm =
1240 props->getDoubleValue("/environment/turbulence/magnitude-norm");
1241
1242 net->temp_c = props->getDoubleValue("/environment/temperature-degc");
1243 net->press_inhg = props->getDoubleValue("/environment/pressure-sea-level-inhg");
1244
1245 net->hground = props->getDoubleValue("/position/ground-elev-m");
1246 net->magvar = props->getDoubleValue("/environment/magnetic-variation-deg");
1247
1248 net->icing = props->getBoolValue("/hazards/icing/wing");
1249
1250 net->speedup = props->getIntValue("/sim/speed-up");
1251 net->freeze = 0;
1252 if ( honor_freezes ) {
1253 if ( props->getBoolValue("/sim/freeze/master") ) {
1254 net->freeze |= 0x01;
1255 }
1256 if ( props->getBoolValue("/sim/freeze/position") ) {
1257 net->freeze |= 0x02;
1258 }
1259 if ( props->getBoolValue("/sim/freeze/fuel") ) {
1260 net->freeze |= 0x04;
1261 }
1262 }
1263
1264 if ( net_byte_order ) {
1265 // convert to network byte order
1266 net->version = htonl(net->version);
1267 htond(net->aileron);
1268 htond(net->elevator);
1269 htond(net->rudder);
1270 htond(net->aileron_trim);
1271 htond(net->elevator_trim);
1272 htond(net->rudder_trim);
1273 htond(net->flaps);
1274 htond(net->speedbrake);
1275 htond(net->spoilers);
1276 net->flaps_power = htonl(net->flaps_power);
1277 net->flap_motor_ok = htonl(net->flap_motor_ok);
1278
1279 net->num_engines = htonl(net->num_engines);
1280 for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
1281 net->master_bat[i] = htonl(net->master_bat[i]);
1282 net->master_alt[i] = htonl(net->master_alt[i]);
1283 net->magnetos[i] = htonl(net->magnetos[i]);
1284 net->starter_power[i] = htonl(net->starter_power[i]);
1285 htond(net->throttle[i]);
1286 htond(net->mixture[i]);
1287 net->fuel_pump_power[i] = htonl(net->fuel_pump_power[i]);
1288 htond(net->prop_advance[i]);
1289 htond(net->condition[i]);
1290 net->engine_ok[i] = htonl(net->engine_ok[i]);
1291 net->mag_left_ok[i] = htonl(net->mag_left_ok[i]);
1292 net->mag_right_ok[i] = htonl(net->mag_right_ok[i]);
1293 net->spark_plugs_ok[i] = htonl(net->spark_plugs_ok[i]);
1294 net->oil_press_status[i] = htonl(net->oil_press_status[i]);
1295 net->fuel_pump_ok[i] = htonl(net->fuel_pump_ok[i]);
1296 }
1297
1298 net->num_tanks = htonl(net->num_tanks);
1299 for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
1300 net->fuel_selector[i] = htonl(net->fuel_selector[i]);
1301 }
1302
1303 net->cross_feed = htonl(net->cross_feed);
1304 htond(net->brake_left);
1305 htond(net->brake_right);
1308 htond(net->brake_parking);
1309 net->gear_handle = htonl(net->gear_handle);
1310 net->master_avionics = htonl(net->master_avionics);
1311 htond(net->wind_speed_kt);
1312 htond(net->wind_dir_deg);
1313 htond(net->turbulence_norm);
1314 htond(net->temp_c);
1315 htond(net->press_inhg);
1316 htond(net->hground);
1317 htond(net->magvar);
1318 net->icing = htonl(net->icing);
1319 net->speedup = htonl(net->speedup);
1320 net->freeze = htonl(net->freeze);
1321 }
1322}
1323
1324
1325// Update the property tree from the FGNetCtrls structure.
1326template<>
1327void FGCtrls2Props<FGNetCtrls>( SGPropertyNode *props, FGNetCtrls *net, bool honor_freezes,
1328 bool net_byte_order )
1329{
1330 int i;
1331
1332 SGPropertyNode * node;
1333
1334 if ( net_byte_order ) {
1335 // convert from network byte order
1336 net->version = htonl(net->version);
1337 htond(net->aileron);
1338 htond(net->elevator);
1339 htond(net->rudder);
1340 htond(net->aileron_trim);
1341 htond(net->elevator_trim);
1342 htond(net->rudder_trim);
1343 htond(net->flaps);
1344 htond(net->speedbrake);
1345 htond(net->spoilers);
1346 net->flaps_power = htonl(net->flaps_power);
1347 net->flap_motor_ok = htonl(net->flap_motor_ok);
1348
1349 net->num_engines = htonl(net->num_engines);
1350 for ( i = 0; i < (int)net->num_engines; ++i ) {
1351 net->master_bat[i] = htonl(net->master_bat[i]);
1352 net->master_alt[i] = htonl(net->master_alt[i]);
1353 net->magnetos[i] = htonl(net->magnetos[i]);
1354 net->starter_power[i] = htonl(net->starter_power[i]);
1355 htond(net->throttle[i]);
1356 htond(net->mixture[i]);
1357 net->fuel_pump_power[i] = htonl(net->fuel_pump_power[i]);
1358 htond(net->prop_advance[i]);
1359 htond(net->condition[i]);
1360 net->engine_ok[i] = htonl(net->engine_ok[i]);
1361 net->mag_left_ok[i] = htonl(net->mag_left_ok[i]);
1362 net->mag_right_ok[i] = htonl(net->mag_right_ok[i]);
1363 net->spark_plugs_ok[i] = htonl(net->spark_plugs_ok[i]);
1364 net->oil_press_status[i] = htonl(net->oil_press_status[i]);
1365 net->fuel_pump_ok[i] = htonl(net->fuel_pump_ok[i]);
1366 }
1367
1368 net->num_tanks = htonl(net->num_tanks);
1369 for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
1370 net->fuel_selector[i] = htonl(net->fuel_selector[i]);
1371 }
1372
1373 net->cross_feed = htonl(net->cross_feed);
1374 htond(net->brake_left);
1375 htond(net->brake_right);
1378 htond(net->brake_parking);
1379 net->gear_handle = htonl(net->gear_handle);
1380 net->master_avionics = htonl(net->master_avionics);
1381 htond(net->wind_speed_kt);
1382 htond(net->wind_dir_deg);
1383 htond(net->turbulence_norm);
1384 htond(net->temp_c);
1385 htond(net->press_inhg);
1386 htond(net->hground);
1387 htond(net->magvar);
1388 net->icing = htonl(net->icing);
1389 net->speedup = htonl(net->speedup);
1390 net->freeze = htonl(net->freeze);
1391 }
1392
1393 if ( net->version != FG_NET_CTRLS_VERSION ) {
1394 SG_LOG( SG_IO, SG_ALERT,
1395 "Version mismatch with raw controls packet format." );
1396 SG_LOG( SG_IO, SG_ALERT,
1397 "FlightGear needs version = " << FG_NET_CTRLS_VERSION
1398 << " but is receiving version = " << net->version );
1399 }
1400 node = props->getNode("/controls/flight", true);
1401 node->setDoubleValue( "aileron", net->aileron );
1402 node->setDoubleValue( "elevator", net->elevator );
1403 node->setDoubleValue( "rudder", net->rudder );
1404 node->setDoubleValue( "aileron-trim", net->aileron_trim );
1405 node->setDoubleValue( "elevator-trim", net->elevator_trim );
1406 node->setDoubleValue( "rudder-trim", net->rudder_trim );
1407 node->setDoubleValue( "flaps", net->flaps );
1408 node->setDoubleValue( "speedbrake", net->speedbrake ); //JWW
1409 // or
1410 node->setDoubleValue( "spoilers", net->spoilers ); //JWW
1411// cout << "NET->Spoilers: " << net->spoilers << endl;
1412 props->setBoolValue( "/systems/electrical/outputs/flaps", net->flaps_power > 0 );
1413 node->setBoolValue( "flaps-serviceable", net->flap_motor_ok > 0 );
1414
1415 for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
1416 // Controls
1417 node = props->getNode("/controls/engines/engine", i);
1418 node->getChild( "throttle" )->setDoubleValue( net->throttle[i] );
1419 node->getChild( "mixture" )->setDoubleValue( net->mixture[i] );
1420 node->getChild( "propeller-pitch" )
1421 ->setDoubleValue( net->prop_advance[i] );
1422 node->getChild( "condition" )
1423 ->setDoubleValue( net->condition[i] );
1424 node->getChild( "magnetos" )->setDoubleValue( net->magnetos[i] );
1425 node->getChild( "starter" )->setDoubleValue( net->starter_power[i] );
1426 node->getChild( "feed_tank" )->setIntValue( net->feed_tank_to[i] );
1427 node->getChild( "reverser" )->setBoolValue( net->reverse[i] > 0 );
1428 // Faults
1429 SGPropertyNode *faults = node->getNode( "faults", true );
1430 faults->setBoolValue( "serviceable", net->engine_ok[i] > 0 );
1431 faults->setBoolValue( "left-magneto-serviceable",
1432 net->mag_left_ok[i] > 0 );
1433 faults->setBoolValue( "right-magneto-serviceable",
1434 net->mag_right_ok[i] > 0);
1435 faults->setBoolValue( "spark-plugs-serviceable",
1436 net->spark_plugs_ok[i] > 0);
1437 faults->setIntValue( "oil-pressure-status", net->oil_press_status[i] );
1438 faults->setBoolValue( "fuel-pump-serviceable", net->fuel_pump_ok[i] > 0);
1439 }
1440
1441 props->setBoolValue( "/systems/electrical/outputs/fuel-pump",
1442 net->fuel_pump_power[0] > 0);
1443
1444 for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
1445 node = props->getNode( "/controls/fuel/tank", i );
1446 node->getChild( "fuel_selector" )
1447 ->setBoolValue( net->fuel_selector[i] > 0 );
1448// node->getChild( "to_tank" )->xfer_tank( i, net->xfer_to[i] );
1449 }
1450 node = props->getNode( "/controls/gear" );
1451 if ( node != NULL ) {
1452 node->getChild( "brake-left" )->setDoubleValue( net->brake_left );
1453 node->getChild( "brake-right" )->setDoubleValue( net->brake_right );
1454 node->getChild( "copilot-brake-left" )
1455 ->setDoubleValue( net->copilot_brake_left );
1456 node->getChild( "copilot-brake-right" )
1457 ->setDoubleValue( net->copilot_brake_right );
1458 node->getChild( "brake-parking" )->setDoubleValue( net->brake_parking );
1459 }
1460
1461 node = props->getNode( "/controls/gear", true );
1462 node->setBoolValue( "gear-down", net->gear_handle > 0 );
1463// node->setDoubleValue( "brake-parking", net->brake_parking );
1464// node->setDoubleValue( net->brake_left );
1465// node->setDoubleValue( net->brake_right );
1466
1467 node = props->getNode( "/controls/switches", true );
1468 node->setBoolValue( "master-bat", net->master_bat[0] != 0 );
1469 node->setBoolValue( "master-alt", net->master_alt[0] != 0 );
1470 node->setBoolValue( "master-avionics", net->master_avionics > 0 );
1471
1472 node = props->getNode( "/environment", true );
1473 node->setDoubleValue( "wind-speed-kt", net->wind_speed_kt );
1474 node->setDoubleValue( "wind-from-heading-deg", net->wind_dir_deg );
1475 node->setDoubleValue( "turbulence/magnitude-norm", net->turbulence_norm );
1476 node->setDoubleValue( "magnetic-variation-deg", net->magvar );
1477
1478 node->setDoubleValue( "/environment/temperature-degc",
1479 net->temp_c );
1480 node->setDoubleValue( "/environment/pressure-sea-level-inhg",
1481 net->press_inhg );
1482
1483 // ground elevation ???
1484
1485 props->setDoubleValue("/hazards/icing/wing", net->icing);
1486
1487 node = props->getNode( "/radios", true );
1488 node->setDoubleValue( "comm/frequencies/selected-mhz[0]", net->comm_1 );
1489 node->setDoubleValue( "nav/frequencies/selected-mhz[0]", net->nav_1 );
1490 node->setDoubleValue( "nav[1]/frequencies/selected-mhz[0]", net->nav_2 );
1491
1492 props->setDoubleValue( "/sim/speed-up", net->speedup );
1493
1494 if ( honor_freezes ) {
1495 node = props->getNode( "/sim/freeze", true );
1496 node->setBoolValue( "master", (net->freeze & 0x01) > 0 );
1497 node->setBoolValue( "position", (net->freeze & 0x02) > 0 );
1498 node->setBoolValue( "fuel", (net->freeze & 0x04) > 0 );
1499 }
1500}
1501
1502#if FG_HAVE_DDS
1503// Populate the FG_DDS_Ctrls structure from the property tree.
1504template<>
1505void FGProps2Ctrls<FG_DDS_Ctrls>( SGPropertyNode *props, FG_DDS_Ctrls *dds, bool honor_freezes, bool net_byte_order )
1506{
1507 int i;
1508 SGPropertyNode *node;
1509 SGPropertyNode *fuelpump;
1510 SGPropertyNode *tempnode;
1511
1512 // fill in values
1513 node = props->getNode("/controls/flight", true);
1515 dds->aileron = node->getDoubleValue( "aileron" );
1516 dds->elevator = node->getDoubleValue( "elevator" );
1517 dds->rudder = node->getDoubleValue( "rudder" );
1518 dds->aileron_trim = node->getDoubleValue( "aileron-trim" );
1519 dds->elevator_trim = node->getDoubleValue( "elevator-trim" );
1520 dds->rudder_trim = node->getDoubleValue( "rudder-trim" );
1521 dds->flaps = node->getDoubleValue( "flaps" );
1522 dds->speedbrake = node->getDoubleValue( "speedbrake" );
1523 dds->spoilers = node->getDoubleValue( "spoilers" );
1524 dds->flaps_power
1525 = props->getDoubleValue( "/systems/electrical/outputs/flaps", 1.0 ) >= 1.0;
1526 dds->flap_motor_ok = node->getBoolValue( "flaps-serviceable" );
1527
1529 for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
1530 // Controls
1531 node = props->getNode("/controls/engines/engine", i );
1532 fuelpump = props->getNode("/systems/electrical/outputs/fuel-pump", i );
1533
1534 tempnode = node->getChild("starter");
1535 if ( tempnode != NULL ) {
1536 dds->starter_power[i] = ( tempnode->getDoubleValue() >= 1.0 );
1537 }
1538 tempnode = node->getChild("master-bat");
1539 if ( tempnode != NULL ) {
1540 dds->master_bat[i] = tempnode->getBoolValue();
1541 }
1542 tempnode = node->getChild("master-alt");
1543 if ( tempnode != NULL ) {
1544 dds->master_alt[i] = tempnode->getBoolValue();
1545 }
1546
1547 dds->throttle[i] = node->getDoubleValue( "throttle", 0.0 );
1548 dds->mixture[i] = node->getDoubleValue( "mixture", 0.0 );
1549 dds->prop_advance[i] = node->getDoubleValue( "propeller-pitch", 0.0 );
1550 dds->condition[i] = node->getDoubleValue( "condition", 0.0 );
1551 dds->magnetos[i] = node->getIntValue( "magnetos", 0 );
1552 if ( i == 0 ) {
1553 // cout << "Magnetos -> " << node->getIntValue( "magnetos", 0 );
1554 }
1555 if ( i == 0 ) {
1556 // cout << "Starter -> " << node->getIntValue( "starter", false )
1557 // << endl;
1558 }
1559
1560 if ( fuelpump != NULL ) {
1561 dds->fuel_pump_power[i] = ( fuelpump->getDoubleValue() >= 1.0 );
1562 } else {
1563 dds->fuel_pump_power[i] = 0;
1564 }
1565
1566 // Faults
1567 SGPropertyNode *faults = node->getChild( "faults", 0, true );
1568 dds->engine_ok[i] = faults->getBoolValue( "serviceable", true );
1569 dds->mag_left_ok[i]
1570 = faults->getBoolValue( "left-magneto-serviceable", true );
1571 dds->mag_right_ok[i]
1572 = faults->getBoolValue( "right-magneto-serviceable", true);
1573 dds->spark_plugs_ok[i]
1574 = faults->getBoolValue( "spark-plugs-serviceable", true );
1575 dds->oil_press_status[i]
1576 = faults->getIntValue( "oil-pressure-status", 0 );
1577 dds->fuel_pump_ok[i]
1578 = faults->getBoolValue( "fuel-pump-serviceable", true );
1579 }
1581 for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
1582 node = props->getNode("/controls/fuel/tank", i);
1583 if ( node->getChild("fuel_selector") != 0 ) {
1584 dds->fuel_selector[i]
1585 = node->getChild("fuel_selector")->getBoolValue();
1586 } else {
1587 dds->fuel_selector[i] = false;
1588 }
1589 }
1590 node = props->getNode("/controls/gear", true);
1591 dds->brake_left = node->getChild("brake-left")->getDoubleValue();
1592 dds->brake_right = node->getChild("brake-right")->getDoubleValue();
1594 = node->getChild("copilot-brake-left")->getDoubleValue();
1596 = node->getChild("copilot-brake-right")->getDoubleValue();
1597 dds->brake_parking = node->getChild("brake-parking")->getDoubleValue();
1598
1599 dds->gear_handle = props->getBoolValue( "/controls/gear/gear-down" );
1600
1601 dds->master_avionics = props->getBoolValue("/controls/switches/master-avionics");
1602
1603 dds->wind_speed_kt = props->getDoubleValue("/environment/wind-speed-kt");
1604 dds->wind_dir_deg = props->getDoubleValue("/environment/wind-from-heading-deg");
1605 dds->turbulence_norm =
1606 props->getDoubleValue("/environment/turbulence/magnitude-norm");
1607
1608 dds->temp_c = props->getDoubleValue("/environment/temperature-degc");
1609 dds->press_inhg = props->getDoubleValue("/environment/pressure-sea-level-inhg");
1610
1611 dds->hground = props->getDoubleValue("/position/ground-elev-m");
1612 dds->magvar = props->getDoubleValue("/environment/magnetic-variation-deg");
1613
1614 dds->icing = props->getBoolValue("/hazards/icing/wing");
1615
1616 dds->speedup = props->getIntValue("/sim/speed-up");
1617 dds->freeze = 0;
1618 if ( honor_freezes ) {
1619 if ( props->getBoolValue("/sim/freeze/master") ) {
1620 dds->freeze |= 0x01;
1621 }
1622 if ( props->getBoolValue("/sim/freeze/position") ) {
1623 dds->freeze |= 0x02;
1624 }
1625 if ( props->getBoolValue("/sim/freeze/fuel") ) {
1626 dds->freeze |= 0x04;
1627 }
1628 }
1629}
1630
1631// Update the property tree from the FG_DDS_Ctrls structure.
1632template<>
1633void FGCtrls2Props<FG_DDS_Ctrls>( SGPropertyNode *props, FG_DDS_Ctrls *dds, bool honor_freezes, bool net_byte_order )
1634{
1635 int i;
1636
1637 SGPropertyNode * node;
1638
1639 if ( dds->version != FG_DDS_CTRLS_VERSION ) {
1640 SG_LOG( SG_IO, SG_ALERT,
1641 "Version mismatch with raw controls packet format." );
1642 SG_LOG( SG_IO, SG_ALERT,
1643 "FlightGear needs version = " << FG_DDS_CTRLS_VERSION
1644 << " but is receiving version = " << dds->version );
1645 }
1646 node = props->getNode("/controls/flight", true);
1647 node->setDoubleValue( "aileron", dds->aileron );
1648 node->setDoubleValue( "elevator", dds->elevator );
1649 node->setDoubleValue( "rudder", dds->rudder );
1650 node->setDoubleValue( "aileron-trim", dds->aileron_trim );
1651 node->setDoubleValue( "elevator-trim", dds->elevator_trim );
1652 node->setDoubleValue( "rudder-trim", dds->rudder_trim );
1653 node->setDoubleValue( "flaps", dds->flaps );
1654 node->setDoubleValue( "speedbrake", dds->speedbrake ); //JWW
1655 // or
1656 node->setDoubleValue( "spoilers", dds->spoilers ); //JWW
1657// cout << "NET->Spoilers: " << dds->spoilers << endl;
1658 props->setBoolValue( "/systems/electrical/outputs/flaps", dds->flaps_power > 0 );
1659 node->setBoolValue( "flaps-serviceable", dds->flap_motor_ok > 0 );
1660
1661 for ( i = 0; i < FGNetCtrls::FG_MAX_ENGINES; ++i ) {
1662 // Controls
1663 node = props->getNode("/controls/engines/engine", i);
1664 node->getChild( "throttle" )->setDoubleValue( dds->throttle[i] );
1665 node->getChild( "mixture" )->setDoubleValue( dds->mixture[i] );
1666 node->getChild( "propeller-pitch" )
1667 ->setDoubleValue( dds->prop_advance[i] );
1668 node->getChild( "condition" )
1669 ->setDoubleValue( dds->condition[i] );
1670 node->getChild( "magnetos" )->setDoubleValue( dds->magnetos[i] );
1671 node->getChild( "starter" )->setDoubleValue( dds->starter_power[i] );
1672 node->getChild( "feed_tank" )->setIntValue( dds->feed_tank_to[i] );
1673 node->getChild( "reverser" )->setBoolValue( dds->reverse[i] > 0 );
1674 // Faults
1675 SGPropertyNode *faults = node->getNode( "faults", true );
1676 faults->setBoolValue( "serviceable", dds->engine_ok[i] > 0 );
1677 faults->setBoolValue( "left-magneto-serviceable",
1678 dds->mag_left_ok[i] > 0 );
1679 faults->setBoolValue( "right-magneto-serviceable",
1680 dds->mag_right_ok[i] > 0);
1681 faults->setBoolValue( "spark-plugs-serviceable",
1682 dds->spark_plugs_ok[i] > 0);
1683 faults->setIntValue( "oil-pressure-status", dds->oil_press_status[i] );
1684 faults->setBoolValue( "fuel-pump-serviceable", dds->fuel_pump_ok[i] > 0);
1685 }
1686
1687 props->setBoolValue( "/systems/electrical/outputs/fuel-pump",
1688 dds->fuel_pump_power[0] > 0);
1689
1690 for ( i = 0; i < FGNetCtrls::FG_MAX_TANKS; ++i ) {
1691 node = props->getNode( "/controls/fuel/tank", i );
1692 node->getChild( "fuel_selector" )
1693 ->setBoolValue( dds->fuel_selector[i] > 0 );
1694// node->getChild( "to_tank" )->xfer_tank( i, dds->xfer_to[i] );
1695 }
1696 node = props->getNode( "/controls/gear" );
1697 if ( node != NULL ) {
1698 node->getChild( "brake-left" )->setDoubleValue( dds->brake_left );
1699 node->getChild( "brake-right" )->setDoubleValue( dds->brake_right );
1700 node->getChild( "copilot-brake-left" )
1701 ->setDoubleValue( dds->copilot_brake_left );
1702 node->getChild( "copilot-brake-right" )
1703 ->setDoubleValue( dds->copilot_brake_right );
1704 node->getChild( "brake-parking" )->setDoubleValue( dds->brake_parking );
1705 }
1706
1707 node = props->getNode( "/controls/gear", true );
1708 node->setBoolValue( "gear-down", dds->gear_handle > 0 );
1709// node->setDoubleValue( "brake-parking", dds->brake_parking );
1710// node->setDoubleValue( dds->brake_left );
1711// node->setDoubleValue( dds->brake_right );
1712
1713 node = props->getNode( "/controls/switches", true );
1714 node->setBoolValue( "master-bat", dds->master_bat[0] != 0 );
1715 node->setBoolValue( "master-alt", dds->master_alt[0] != 0 );
1716 node->setBoolValue( "master-avionics", dds->master_avionics > 0 );
1717
1718 node = props->getNode( "/environment", true );
1719 node->setDoubleValue( "wind-speed-kt", dds->wind_speed_kt );
1720 node->setDoubleValue( "wind-from-heading-deg", dds->wind_dir_deg );
1721 node->setDoubleValue( "turbulence/magnitude-norm", dds->turbulence_norm );
1722 node->setDoubleValue( "magnetic-variation-deg", dds->magvar );
1723
1724 node->setDoubleValue( "/environment/temperature-degc",
1725 dds->temp_c );
1726 node->setDoubleValue( "/environment/pressure-sea-level-inhg",
1727 dds->press_inhg );
1728
1729 // ground elevation ???
1730
1731 props->setDoubleValue("/hazards/icing/wing", dds->icing);
1732
1733 node = props->getNode( "/radios", true );
1734 node->setDoubleValue( "comm/frequencies/selected-mhz[0]", dds->comm_1 );
1735 node->setDoubleValue( "nav/frequencies/selected-mhz[0]", dds->nav_1 );
1736 node->setDoubleValue( "nav[1]/frequencies/selected-mhz[0]", dds->nav_2 );
1737
1738 props->setDoubleValue( "/sim/speed-up", dds->speedup );
1739
1740 if ( honor_freezes ) {
1741 node = props->getNode( "/sim/freeze", true );
1742 node->setBoolValue( "master", (dds->freeze & 0x01) > 0 );
1743 node->setBoolValue( "position", (dds->freeze & 0x02) > 0 );
1744 node->setBoolValue( "fuel", (dds->freeze & 0x04) > 0 );
1745 }
1746}
1747#endif
1748
const uint32_t FG_NET_FDM_VERSION
#define i(x)
double copilot_brake_left
uint32_t flaps_power
Definition net_ctrls.hxx:63
uint32_t fuel_pump_ok[FG_MAX_ENGINES]
Definition net_ctrls.hxx:87
double brake_left
Definition net_ctrls.hxx:98
uint32_t freeze
double flaps
Definition net_ctrls.hxx:58
uint32_t reverse[4]
Definition net_ctrls.hxx:78
double speedbrake
Definition net_ctrls.hxx:60
uint32_t starter_power[FG_MAX_ENGINES]
Definition net_ctrls.hxx:71
double mixture[FG_MAX_ENGINES]
Definition net_ctrls.hxx:73
double copilot_brake_right
double prop_advance[FG_MAX_ENGINES]
Definition net_ctrls.hxx:76
uint32_t master_bat[FG_MAX_ENGINES]
Definition net_ctrls.hxx:68
double wind_dir_deg
uint32_t master_avionics
double wind_speed_kt
uint32_t cross_feed
Definition net_ctrls.hxx:95
double elevator_trim
Definition net_ctrls.hxx:56
uint32_t feed_tank_to[4]
Definition net_ctrls.hxx:77
double condition[FG_MAX_ENGINES]
Definition net_ctrls.hxx:74
double rudder
Definition net_ctrls.hxx:54
double aileron
Definition net_ctrls.hxx:52
uint32_t flap_motor_ok
Definition net_ctrls.hxx:64
double magvar
double turbulence_norm
uint32_t master_alt[FG_MAX_ENGINES]
Definition net_ctrls.hxx:69
uint32_t mag_left_ok[FG_MAX_ENGINES]
Definition net_ctrls.hxx:83
uint32_t engine_ok[FG_MAX_ENGINES]
Definition net_ctrls.hxx:82
double press_inhg
uint32_t num_engines
Definition net_ctrls.hxx:67
uint32_t fuel_selector[FG_MAX_TANKS]
Definition net_ctrls.hxx:91
double comm_1
double temp_c
uint32_t mag_right_ok[FG_MAX_ENGINES]
Definition net_ctrls.hxx:84
double hground
double nav_2
uint32_t spark_plugs_ok[FG_MAX_ENGINES]
Definition net_ctrls.hxx:85
uint32_t gear_handle
double spoilers
Definition net_ctrls.hxx:59
uint32_t num_tanks
Definition net_ctrls.hxx:90
double nav_1
double throttle[FG_MAX_ENGINES]
Definition net_ctrls.hxx:72
uint32_t oil_press_status[FG_MAX_ENGINES]
Definition net_ctrls.hxx:86
uint32_t speedup
double aileron_trim
Definition net_ctrls.hxx:55
uint32_t icing
double elevator
Definition net_ctrls.hxx:53
uint32_t version
Definition net_ctrls.hxx:49
uint32_t fuel_pump_power[FG_MAX_ENGINES]
Definition net_ctrls.hxx:75
double rudder_trim
Definition net_ctrls.hxx:57
double brake_parking
uint32_t magnetos[FG_MAX_ENGINES]
Definition net_ctrls.hxx:70
double brake_right
Definition net_ctrls.hxx:99
uint32_t wow[FG_MAX_WHEELS]
float cht[FG_MAX_ENGINES]
float fuel_flow[FG_MAX_ENGINES]
float mp_osi[FG_MAX_ENGINES]
float gear_steer[FG_MAX_WHEELS]
float gear_pos[FG_MAX_WHEELS]
float tit[FG_MAX_ENGINES]
float egt[FG_MAX_ENGINES]
float oil_temp[FG_MAX_ENGINES]
float rpm[FG_MAX_ENGINES]
uint32_t eng_state[FG_MAX_ENGINES]
float gear_compression[FG_MAX_WHEELS]
float fuel_quantity[FG_MAX_TANKS]
float fuel_px[FG_MAX_ENGINES]
float oil_px[FG_MAX_ENGINES]
double latitude
Definition net_gui.hxx:52
float climb_rate
Definition net_gui.hxx:62
float phi
Definition net_gui.hxx:56
float course_deviation_deg
Definition net_gui.hxx:79
float fuel_quantity[FG_MAX_TANKS]
Definition net_gui.hxx:66
uint32_t warp
Definition net_gui.hxx:71
float ground_elev
Definition net_gui.hxx:72
uint32_t num_tanks
Definition net_gui.hxx:65
uint32_t version
Definition net_gui.hxx:47
float dist_nm
Definition net_gui.hxx:78
float psi
Definition net_gui.hxx:58
float altitude
Definition net_gui.hxx:54
double longitude
Definition net_gui.hxx:51
@ FG_MAX_TANKS
Definition net_gui.hxx:36
float theta
Definition net_gui.hxx:57
float vcas
Definition net_gui.hxx:61
float nav_radial
Definition net_gui.hxx:76
uint32_t cur_time
Definition net_gui.hxx:69
float gs_deviation_deg
Definition net_gui.hxx:80
float tuned_freq
Definition net_gui.hxx:75
uint32_t in_range
Definition net_gui.hxx:77
#define FG_DDS_CTRLS_VERSION
Definition dds_ctrls.h:20
#define FG_DDS_FDM_VERSION
Definition dds_fdm.h:20
#define FG_DDS_GUI_VERSION
Definition dds_gui.h:20
void FGGUI2Props< FGNetGUI >(SGPropertyNode *props, FGNetGUI *net)
void FGProps2Ctrls< FGNetCtrls >(SGPropertyNode *props, FGNetCtrls *net, bool honor_freezes, bool net_byte_order)
void FGCtrls2Props< FGNetCtrls >(SGPropertyNode *props, FGNetCtrls *net, bool honor_freezes, bool net_byte_order)
static void htond(double &x)
void FGFDM2Props< FGNetFDM >(SGPropertyNode *props, FGNetFDM *net, bool net_byte_order)
void FGProps2GUI< FGNetGUI >(SGPropertyNode *props, FGNetGUI *net)
void FGProps2FDM< FGNetFDM >(SGPropertyNode *props, FGNetFDM *net, bool net_byte_order)
static void htonf(float &x)
void FGCtrls2Props(SGPropertyNode *props, T *net, bool honor_freezes, bool net_byte_order)
void FGGUI2Props(SGPropertyNode *props, T *net)
void FGProps2GUI(SGPropertyNode *props, T *net)
void FGProps2Ctrls(SGPropertyNode *props, T *net, bool honor_freezes, bool net_byte_order)
void FGProps2FDM(SGPropertyNode *props, T *net, bool net_byte_order=true)
void FGFDM2Props(SGPropertyNode *props, T *net, bool net_byte_order=true)
const uint32_t FG_NET_CTRLS_VERSION
Definition net_ctrls.hxx:34
const uint32_t FG_NET_GUI_VERSION
Definition net_gui.hxx:23
float magvar
Definition dds_ctrls.h:79
uint16_t freeze
Definition dds_ctrls.h:82
uint32_t magnetos[4]
Definition dds_ctrls.h:44
float mixture[4]
Definition dds_ctrls.h:47
uint16_t fuel_selector[8]
Definition dds_ctrls.h:60
char flaps_power
Definition dds_ctrls.h:39
float copilot_brake_right
Definition dds_ctrls.h:65
float brake_left
Definition dds_ctrls.h:62
float turbulence_norm
Definition dds_ctrls.h:75
char master_bat[4]
Definition dds_ctrls.h:42
float condition[4]
Definition dds_ctrls.h:48
char master_avionics
Definition dds_ctrls.h:68
float throttle[4]
Definition dds_ctrls.h:46
float elevator
Definition dds_ctrls.h:31
float comm_1
Definition dds_ctrls.h:69
float wind_speed_kt
Definition dds_ctrls.h:73
float spoilers
Definition dds_ctrls.h:37
char fuel_pump_ok[4]
Definition dds_ctrls.h:58
float prop_advance[4]
Definition dds_ctrls.h:50
float nav_1
Definition dds_ctrls.h:71
float brake_right
Definition dds_ctrls.h:63
float aileron_trim
Definition dds_ctrls.h:33
float copilot_brake_left
Definition dds_ctrls.h:64
uint16_t num_engines
Definition dds_ctrls.h:41
float flaps
Definition dds_ctrls.h:36
float nav_2
Definition dds_ctrls.h:72
uint16_t oil_press_status[4]
Definition dds_ctrls.h:57
char master_alt[4]
Definition dds_ctrls.h:43
char gear_handle
Definition dds_ctrls.h:67
uint32_t speedup
Definition dds_ctrls.h:81
char reverse[4]
Definition dds_ctrls.h:52
char mag_left_ok[4]
Definition dds_ctrls.h:54
float aileron
Definition dds_ctrls.h:30
uint32_t starter_power[4]
Definition dds_ctrls.h:45
float press_inhg
Definition dds_ctrls.h:77
int16_t version
Definition dds_ctrls.h:29
float elevator_trim
Definition dds_ctrls.h:34
float hground
Definition dds_ctrls.h:78
float speedbrake
Definition dds_ctrls.h:38
char flap_motor_ok
Definition dds_ctrls.h:40
float rudder
Definition dds_ctrls.h:32
float wind_dir_deg
Definition dds_ctrls.h:74
float brake_parking
Definition dds_ctrls.h:66
char spark_plugs_ok[4]
Definition dds_ctrls.h:56
uint16_t feed_tank_to[4]
Definition dds_ctrls.h:51
float rudder_trim
Definition dds_ctrls.h:35
uint32_t fuel_pump_power[4]
Definition dds_ctrls.h:49
float temp_c
Definition dds_ctrls.h:76
uint16_t num_tanks
Definition dds_ctrls.h:59
char engine_ok[4]
Definition dds_ctrls.h:53
char mag_right_ok[4]
Definition dds_ctrls.h:55
float elevator
Definition dds_fdm.h:81
float oil_px[4]
Definition dds_fdm.h:65
float unusable_m3[8]
Definition dds_fdm.h:70
float rpm[4]
Definition dds_fdm.h:57
float tit[4]
Definition dds_fdm.h:63
float spoilers
Definition dds_fdm.h:90
float gear_compression[16]
Definition dds_fdm.h:77
float density_kgpm3[8]
Definition dds_fdm.h:71
float cht[4]
Definition dds_fdm.h:61
float A_Z_pilot
Definition dds_fdm.h:52
float beta
Definition dds_fdm.h:38
float nose_wheel
Definition dds_fdm.h:88
char tank_selected[8]
Definition dds_fdm.h:68
float thetadot
Definition dds_fdm.h:40
float gear_steer[16]
Definition dds_fdm.h:76
float egt[4]
Definition dds_fdm.h:60
float phi
Definition dds_fdm.h:34
float alpha
Definition dds_fdm.h:37
uint16_t num_engines
Definition dds_fdm.h:55
float level_m3[8]
Definition dds_fdm.h:72
float climb_rate
Definition dds_fdm.h:43
float fuel_quantity[8]
Definition dds_fdm.h:67
float oil_temp[4]
Definition dds_fdm.h:64
float slip_deg
Definition dds_fdm.h:54
float theta
Definition dds_fdm.h:35
float vcas
Definition dds_fdm.h:42
float A_X_pilot
Definition dds_fdm.h:50
float v_north
Definition dds_fdm.h:44
float psi
Definition dds_fdm.h:36
uint16_t eng_state[4]
Definition dds_fdm.h:56
float mp_osi[4]
Definition dds_fdm.h:62
uint16_t num_wheels
Definition dds_fdm.h:73
float speedbrake
Definition dds_fdm.h:89
float capacity_m3[8]
Definition dds_fdm.h:69
float phidot
Definition dds_fdm.h:39
double longitude
Definition dds_fdm.h:30
float left_aileron
Definition dds_fdm.h:85
uint64_t warp
Definition dds_fdm.h:79
float agl
Definition dds_fdm.h:33
int16_t version
Definition dds_fdm.h:29
float left_flap
Definition dds_fdm.h:83
float gear_pos[16]
Definition dds_fdm.h:75
uint64_t cur_time
Definition dds_fdm.h:78
float rudder
Definition dds_fdm.h:87
float v_east
Definition dds_fdm.h:45
uint16_t wow[16]
Definition dds_fdm.h:74
float A_Y_pilot
Definition dds_fdm.h:51
uint16_t num_tanks
Definition dds_fdm.h:66
float v_body_w
Definition dds_fdm.h:49
float v_body_u
Definition dds_fdm.h:47
double altitude
Definition dds_fdm.h:32
float fuel_px[4]
Definition dds_fdm.h:59
float fuel_flow[4]
Definition dds_fdm.h:58
float stall_warning
Definition dds_fdm.h:53
float psidot
Definition dds_fdm.h:41
double latitude
Definition dds_fdm.h:31
float right_flap
Definition dds_fdm.h:84
float visibility
Definition dds_fdm.h:80
float v_down
Definition dds_fdm.h:46
float elevator_trim_tab
Definition dds_fdm.h:82
float right_aileron
Definition dds_fdm.h:86
float v_body_v
Definition dds_fdm.h:48
float nav_radial
Definition dds_gui.h:43
uint64_t cur_time
Definition dds_gui.h:39
float theta
Definition dds_gui.h:33
float gs_deviation_deg
Definition dds_gui.h:47
float altitude
Definition dds_gui.h:30
float course_deviation_deg
Definition dds_gui.h:46
float dist_nm
Definition dds_gui.h:45
uint16_t num_tanks
Definition dds_gui.h:37
float ground_elev
Definition dds_gui.h:41
float fuel_quantity[8]
Definition dds_gui.h:38
char in_range
Definition dds_gui.h:44
double latitude
Definition dds_gui.h:29
float phi
Definition dds_gui.h:32
double longitude
Definition dds_gui.h:28
float vcas
Definition dds_gui.h:35
float tuned_freq
Definition dds_gui.h:42
uint64_t warp
Definition dds_gui.h:40
float climb_rate
Definition dds_gui.h:36
float psi
Definition dds_gui.h:34
int16_t version
Definition dds_gui.h:27