]> git.mxchange.org Git - flightgear.git/blob - src/Network/multiplay.cxx
Vivian Meazza:
[flightgear.git] / src / Network / multiplay.cxx
1 // multiplay.cxx -- protocol object for multiplay in Flightgear
2 //
3 // Written by Diarmuid Tyson, started February 2003.
4 // diarmuid.tyson@airservicesaustralia.com
5 //
6 // With addtions by Vivian Meazza, January 2006
7 //
8 // Copyright (C) 2003  Airservices Australia
9 //
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License as
12 // published by the Free Software Foundation; either version 2 of the
13 // License, or (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 //
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <simgear/compiler.h>
30
31 #include STL_STRING
32
33 #include <iostream>
34 #include <map>
35 #include <string>
36
37 #include <simgear/debug/logstream.hxx>
38 #include <simgear/scene/model/placement.hxx>
39 #include <simgear/scene/model/placementtrans.hxx>
40
41 #include <Scenery/scenery.hxx>
42
43 #include "multiplay.hxx"
44
45 SG_USING_STD(string);
46
47
48 // These constants are provided so that the ident command can list file versions.
49 const char sFG_MULTIPLAY_BID[] = "$Id$";
50 const char sFG_MULTIPLAY_HID[] = FG_MULTIPLAY_HID;
51
52
53 /******************************************************************
54 * Name: FGMultiplay
55 * Description: Constructor.  Initialises the protocol and stores
56 * host and port information.
57 ******************************************************************/
58 FGMultiplay::FGMultiplay (const string &dir, const int rate, const string &host, const int port) {
59
60     last_time = 0;
61     last_speedN = last_speedE = last_speedD = 0;
62     calcaccN = calcaccE = calcaccD = 0;
63     set_hz(rate);
64
65     set_direction(dir);
66
67     if (get_direction() == SG_IO_IN) {
68
69         fgSetInt("/sim/multiplay/rxport", port);
70         fgSetString("/sim/multiplay/rxhost", host.c_str());
71
72     } else if (get_direction() == SG_IO_OUT) {
73
74         fgSetInt("/sim/multiplay/txport", port);
75         fgSetString("/sim/multiplay/txhost", host.c_str());
76
77     }
78
79     lat_n = fgGetNode("/position/latitude-deg", true);
80     lon_n = fgGetNode("/position/longitude-deg", true);
81     alt_n = fgGetNode("/position/altitude-ft", true);
82     heading_n = fgGetNode("/orientation/heading-deg", true);
83     roll_n = fgGetNode("/orientation/roll-deg", true);
84     pitch_n = fgGetNode("/orientation/pitch-deg", true);
85     speedN_n = fgGetNode("/velocities/speed-north-fps", true);
86     speedE_n = fgGetNode("/velocities/speed-east-fps", true);
87     speedD_n = fgGetNode("/velocities/speed-down-fps", true);
88     left_aileron_n = fgGetNode("/surface-positions/left-aileron-pos-norm", true);
89     right_aileron_n = fgGetNode("/surface-positions/right-aileron-pos-norm", true);
90     elevator_n = fgGetNode("/surface-positions/elevator-pos-norm", true);
91     rudder_n = fgGetNode("/surface-positions/rudder-pos-norm", true);
92     /*rpms_n[0] = fgGetNode("/engines/engine/rpm", true);
93     rpms_n[1] = fgGetNode("/engines/engine[1]/rpm", true);
94     rpms_n[2] = fgGetNode("/engines/engine[2]/rpm", true);
95     rpms_n[3] = fgGetNode("/engines/engine[3]/rpm", true);
96     rpms_n[4] = fgGetNode("/engines/engine[4]/rpm", true);
97     rpms_n[5] = fgGetNode("/engines/engine[5]/rpm", true);*/
98     rateH_n = fgGetNode("/orientation/yaw-rate-degps", true);
99     rateR_n = fgGetNode("/orientation/roll-rate-degps", true);
100     rateP_n = fgGetNode("/orientation/pitch-rate-degps", true);
101
102     SGPropertyNode_ptr n = fgGetNode("/controls/flight/slats",true);
103     _node_cache *c = new _node_cache( n->getDoubleValue(), n );
104     props["controls/flight/slats"] = c;
105
106     n = fgGetNode("/controls/flight/speedbrake", true);
107     c = new _node_cache( n->getDoubleValue(), n );
108     props["controls/flight/speedbrake"] = c;
109
110     n = fgGetNode("/controls/flight/spoilers", true);
111     c = new _node_cache( n->getDoubleValue(), n );
112     props["controls/flight/spoilers"] = c;
113
114     n = fgGetNode("/controls/gear/gear-down", true);
115     c = new _node_cache( n->getDoubleValue(), n );
116     props["controls/gear/gear-down"] = c;
117
118     n = fgGetNode("/controls/lighting/nav-lights", true);
119     c = new _node_cache( n->getDoubleValue(), n );
120     props["controls/lighting/nav-lights"] = c;
121
122     n = fgGetNode("/surface-positions/flap-pos-norm", true);
123     c = new _node_cache( n->getDoubleValue(), n );
124     props["surface-positions/flap-pos-norm"] = c;
125
126     n = fgGetNode("/surface-positions/speedbrake-pos-norm", true);
127     c = new _node_cache( n->getDoubleValue(), n );
128     props["surface-positions/speedbrake-pos-norm"] = c;
129
130     for (int i = 0; i < 6; i++)
131     {
132         char *s = new char[32];
133
134         snprintf(s, 32, "engines/engine[%i]/n1", i);
135         n = fgGetNode(s, true);
136         c = new _node_cache( n->getDoubleValue(), n );
137         props["s"] = c;
138
139         snprintf(s, 32, "engines/engine[%i]/n2", i);
140         n = fgGetNode(s, true);
141         c = new _node_cache( n->getDoubleValue(), n );
142         props[s] = c;
143
144         snprintf(s, 32, "engines/engine[%i]/rpm", i);
145         n = fgGetNode(s, true);
146         c = new _node_cache( n->getDoubleValue(), n );
147         props[s] = c;
148
149         delete [] s;
150     }
151
152     for (int j = 0; j < 5; j++)
153     {
154         char *s = new char[32];
155     
156         snprintf(s, 32, "gear/gear[%i]/compression-norm", j);
157         n = fgGetNode(s, true);
158         c = new _node_cache( n->getDoubleValue(), n );
159         props["s"] = c;
160
161         snprintf(s, 32, "gear/gear[%i]/position-norm", j);
162         n = fgGetNode(s, true);
163         c = new _node_cache( n->getDoubleValue(), n );
164         props[s] = c;
165 #if 0
166         snprintf(s, 32, "gear/gear[%i]/rollspeed-ms", j);
167         n = fgGetNode(s, true);
168         c = new _node_cache( n->getDoubleValue(), n );
169         props[s] = c;
170 #endif
171         delete [] s;
172     }
173
174     n = fgGetNode("gear/tailhook/position-norm", true);
175     c = new _node_cache( n->getDoubleValue(), n );
176     props["gear/tailhook/position-norm"] = c;
177 }
178
179
180 /******************************************************************
181 * Name: ~FGMultiplay
182 * Description: Destructor.
183 ******************************************************************/
184 FGMultiplay::~FGMultiplay () {
185     props.clear();
186 }
187
188
189 /******************************************************************
190 * Name: open
191 * Description: Enables the protocol.
192 ******************************************************************/
193 bool FGMultiplay::open() {
194
195     if ( is_enabled() ) {
196     SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel "
197         << "is already in use, ignoring" );
198     return false;
199     }
200
201     set_enabled(true);
202
203     return is_enabled();
204 }
205
206
207 /******************************************************************
208 * Name: process
209 * Description: Prompts the multiplayer mgr to either send
210 * or receive data over the network
211 ******************************************************************/
212 bool FGMultiplay::process() {
213
214   if (get_direction() == SG_IO_IN) {
215
216     globals->get_multiplayer_mgr()->ProcessData();
217
218   } else if (get_direction() == SG_IO_OUT) {
219
220     double accN, accE, accD;
221     string fdm = fgGetString("/sim/flight-model");
222
223     if(fdm == "jsb"){
224         calcAcc(speedN_n->getDoubleValue(),
225                 speedE_n->getDoubleValue(),
226                 speedD_n->getDoubleValue());
227         accN = calcaccN;
228         accE = calcaccE;
229         accD = calcaccD;
230     }else{
231         SG_LOG(SG_GENERAL, SG_DEBUG," not doing acc calc" << fdm);
232         accN = fgGetDouble("/accelerations/ned/north-accel-fps_sec");
233         accE = fgGetDouble("/accelerations/ned/east-accel-fps_sec");
234         accD = fgGetDouble("/accelerations/ned/down-accel-fps_sec");
235     }
236
237     globals->get_multiplayer_mgr()->SendMyPosition(
238                                      lat_n->getDoubleValue(),
239                                      lon_n->getDoubleValue(),
240                                      alt_n->getDoubleValue(),
241                                      heading_n->getDoubleValue(),
242                                      roll_n->getDoubleValue(),
243                                      pitch_n->getDoubleValue(),
244                                      speedN_n->getDoubleValue(),
245                                      speedE_n->getDoubleValue(),
246                                      speedD_n->getDoubleValue(),
247                                      left_aileron_n->getDoubleValue(),
248                                      right_aileron_n->getDoubleValue(),
249                                      elevator_n->getDoubleValue(),
250                                      rudder_n->getDoubleValue(),
251                                      rateH_n->getDoubleValue(),
252                                      rateR_n->getDoubleValue(),
253                                      rateP_n->getDoubleValue(),
254                                      accN, accE, accD);
255     
256     // check for changes
257     for (propit = props.begin(); propit != props.end(); propit++)
258     {
259       double val = propit->second->val;
260       double curr_val = propit->second->node->getDoubleValue();
261       if (curr_val < val * 0.99 || curr_val > val * 1.01 )
262       {
263         SGPropertyNode::Type type = propit->second->node->getType();
264         propit->second->val = val = curr_val;
265         globals->get_multiplayer_mgr()->SendPropMessage(propit->first, type, val);
266         //cout << "Prop " << propit->first <<" type " << type << " val " << val << endl;
267       } else {
268           //  cout << "no change" << endl;
269       }
270     }
271
272     // send all properties when necessary
273     // FGMultiplayMgr::getSendAllProps();
274     bool send_all = globals->get_multiplayer_mgr()->getSendAllProps();
275     //cout << "send_all in " << send;
276     if (send_all){
277         SG_LOG( SG_NETWORK, SG_ALERT,
278           "FGMultiplay::sending ALL property messages" );
279           for (propit = props.begin(); propit != props.end(); propit++) {
280               SGPropertyNode::Type type = propit->second->node->getType();
281               double val = propit->second->val;
282               globals->get_multiplayer_mgr()->SendPropMessage(propit->first, type, val);
283           }
284         send_all = false;
285         globals->get_multiplayer_mgr()->setSendAllProps(send_all);
286     }
287     //cout << " send_all out " << s << endl;
288   }
289
290     return true;
291 }
292
293
294 /******************************************************************
295 * Name: close
296 * Description:  Closes the multiplayer mgrs to stop any further
297 * network processing
298 ******************************************************************/
299 bool FGMultiplay::close() {
300
301   if (get_direction() == SG_IO_IN) {
302
303     globals->get_multiplayer_mgr()->Close();
304
305   } else if (get_direction() == SG_IO_OUT) {
306
307 //    globals->get_multiplayer_mgr()->Close();
308
309   }
310
311     return true;
312 }
313
314 /******************************************************************
315  * Name: CalcAcc
316  * Description: Calculate accelerations given speedN, speedE, speedD
317  ******************************************************************/
318 void FGMultiplay::calcAcc(double speedN, double speedE, double speedD)
319 {
320     double time, dt;                        //secs
321     /*double accN, accE, accD;    */            //fps2
322
323     dt = 0;
324
325     time = fgGetDouble("/sim/time/elapsed-sec");
326
327     dt = time-last_time;
328     
329     SG_LOG(SG_GENERAL, SG_DEBUG," doing acc calc"
330     <<"time: "<< time << " last " << last_time << " dt " << dt );
331                                 
332     //calculate the accelerations  
333     calcaccN = (speedN - last_speedN)/dt;
334     calcaccE = (speedE - last_speedE)/dt;
335     calcaccD = (speedD - last_speedD)/dt;
336
337     //set the properties
338     /*fgSetDouble("/accelerations/ned/north-accel-fps_sec",accN);
339     fgSetDouble("/accelerations/ned/east-accel-fps_sec",accE);
340     fgSetDouble("/accelerations/ned/down-accel-fps_sec",accN);*/
341     
342     //save the values
343     last_time = time;
344     last_speedN = speedN;
345     last_speedE = speedE;
346     last_speedD = speedD;
347     
348 }// end calcAcc
349