Avionics
Dropship Simulator
MCU.cpp
Go to the documentation of this file.
1 #include "Module.h"
2 
3 #include <io.h>
4 #include <fcntl.h>
5 #include <share.h>
6 #include <sys/stat.h>
7 
8 Mcu::Mcu(Bus* prmBus, Logger* prmLogger) : Module(prmBus)
9 {
10  logger = prmLogger;
11 
12  // load config
13  int f;
14  if (_sopen_s(&f, "motion.dat", _O_RDONLY | _O_BINARY, _SH_DENYNO, _S_IREAD) != 0)
15  {
16  logger->Log("Module::MCU could not load motion.dat", Logger::Level::Fatal, errno);
17  }
18  else
19  {
20  _lseek(f, SEEK_SET, 0L);
21  _read(f, &Locations, sizeof(Locations));
22  _close(f);
23  }
24  current = {0, 0, 0, 0};
25 
27  emergencyStopGetPtr = bus->GetComponentCurrentStatePtr("CE4DED74-F759-484F-B5AD-69C03AB7A8BD");
28 }
29 
30 void Mcu::FrameMove(float fElapsedTime)
31 {
32  // 0 is off, safe
33  // 1 is caution lights on, wait 5 seconds
34  // 2 is motion power on, wait 5 seconds
35  // 3 is load mid-level, wait 5 seconds
36  // 4 is motion running, watch emer stop
37  // 5 is load mid-level, wait 5 seconds
38  // 6 is load off-level, wait 5 seconds
39  // 7 is motion power off, wait 5 seconds
40  // 8 is caution lights off, set back to 0
41 
42  Command command;
43  for (UINT i = 0; i < bus->commandStream.size(); i++)
44  {
45  command = bus->commandStream.at(i);
46  if (command.delay != 0.0f) continue;
47 
48  if (command.name == "MotionStartStop")
49  {
50  if (sequencer == 0 && *emergencyStopGetPtr == 1.0f)
51  {
52  sequencer = 1;
53  timer = 0.0f;
54  }
55  else if (sequencer <= 4)
56  {
57  sequencer = 5;
58  timer = 0.0f;
59  }
60  bus->commandStream.erase(bus->commandStream.begin() + i);
61  }
62  else if (command.name == "MotionStart")
63  {
64  if (sequencer == 0 && *emergencyStopGetPtr == 1.0f)
65  {
66  sequencer = 1;
67  timer = 0.0f;
68  }
69  bus->commandStream.erase(bus->commandStream.begin() + i);
70  }
71  else if (command.name == "MotionStop")
72  {
73  if (sequencer <= 4)
74  {
75  sequencer = 5;
76  timer = 0.0f;
77  }
78  bus->commandStream.erase(bus->commandStream.begin() + i);
79  }
80  else if (command.name == "MotionTest")
81  {
82  testmode = command.ivalue;
83  if (testmode == 0)
84  {
85  bus->NormalAcceleration = D3DXVECTOR3(0, 0, 0);
86  }
87  bus->commandStream.erase(bus->commandStream.begin() + i);
88  }
89  }
90 
92  if (*emergencyStopGetPtr != 1.0f && sequencer && sequencer < 5)
93  {
94  // play cool sound effect
95  command.name = "MCURideHalted";
96  bus->commandStream.push_back(command);
97  sequencer = 5;
98  timer = 0.0f; // shut it down;
99  }
100 
101  if (testmode == 1) // heave UP 4G
102  {
103  bus->NormalAcceleration = D3DXVECTOR3(0, -0.03922660011455540164454186719264f, 0);
104  }
105  else if (testmode == 2) // tilt left 4G
106  {
107  bus->NormalAcceleration = D3DXVECTOR3(-0.03922660011455540164454186719264f, 0, 0);
108  }
109  else if (testmode == 3) // tilt forward 4G
110  {
111  bus->NormalAcceleration = D3DXVECTOR3(0, 0, 0.03922660011455540164454186719264f);
112  }
113 
114 
116  //float roll = powf(bus->RollControl, 4.0f);
117  //if (bus->RollControl > 0) roll = -roll;
118  //float pitch = powf(bus->PitchControl, 4.0f);
119  //if (bus->PitchControl < 0) pitch = -pitch;
120 
122  //static float roll=0.0f;
123  //static float pitch=0.0f;
124  //static float timeSinceLastChange = 0.0f;
125  //timeSinceLastChange += fElapsedTime;
126  //if (timeSinceLastChange > 15.0f)
127  //{
128  // timeSinceLastChange -= 15.0f;
129  // roll = (float)rand() / (float)RAND_MAX - 0.5f; // 0 to 1 becomes -.5 to +.5
130  // pitch = (float)rand() / (float)RAND_MAX - 0.5f; // 0 to 1 becomes -.5 to +.5
131  //}
132 
133 #pragma region Platform Responds to NormalAccelleration
134  static float counteri = 0.0f, counterj = 0.0f, counterk = 0.0f; // this is the
135  D3DXVECTOR3 limitacc = bus->NormalAcceleration * 101.971621f; // convert km/s to g's
136  limitacc.y -= 1.0f; // we always get 1g for free!
137 
138  // set up for 4G's based on http://msis.jsc.nasa.gov/images/section03/image106.gif
140  if (limitacc.x > 4.0f)
141  limitacc.x = 4.0f;
142  else if (limitacc.x < -4.0f)
143  limitacc.x = -4.0f;
144  if (limitacc.y < -4.0f)
145  limitacc.y = -4.0f;
146  else if (limitacc.y > 4.0f) // quarter travel into seat
147  limitacc.y = 4.0f;
148  if (limitacc.z > 4.0f) // quarter travel into headrest
149  limitacc.z = 4.0f;
150  else if (limitacc.z < -4.0f)
151  limitacc.z = -4.0f;
152 
153  float igs = limitacc.x - counteri;
154  float jgs = limitacc.y - counterj;
155  float kgs = limitacc.z - counterk;
156 
157  if (!testmode)
158  {
159  counteri += igs * fElapsedTime * 0.1f;
160  counterj += jgs * fElapsedTime * 0.1f;
161  counterk += kgs * fElapsedTime * 0.1f;
162  }
163 
164  igs *= 0.25f; // scale to 1
165  jgs *= 0.25f; // scale to 1
166  kgs *= 0.25f; // scale to 1
167 
168  float roll = igs;
169  float pitch = -kgs;
170  float heave = -jgs; // -1.0f to 1.0f is -4.0G to +4.0G
171 
173  float currentPressure = 0.0f;
174  Nullable<float> pneumaticPressure = bus->GetComponentStateFloat("0E1C068F-F901-4C1A-AC12-10F53E894579");
175  if (pneumaticPressure.is_set())
176  currentPressure = pneumaticPressure.get();
177  float modulate = currentPressure / 50.0f - 1.0f; // 100/50 is 1, 50/50 is 0
178  if (modulate > 1.0f) modulate = 1.0f;
179  else if (modulate < 0.0f) modulate = 0.0f;
180  roll *= modulate;
181  pitch *= modulate;
182  heave *= modulate;
183 
184 #pragma endregion
185 
186 
187  timer -= fElapsedTime;
188  if (timer <= 0.0f)
189  {
190  timer = 0.0f;
191  switch (sequencer)
192  {
193  case 1: // caution lights, wait 5 seconds
194  logger->Log("Module::MCU Sequencer 1");
195  command.name = "MotionPlatformCautionLights";
196  command.ivalue = 1;
197  command.delay = 0.0f;
198  bus->commandStream.push_back(command);
199  timer = 5.0f;
200  sequencer++;
201  // load off before we engage motion power
202  current.fl = current.fr = current.bl = current.br = 0.0f; // off-level
203  break;
204  case 2: // motion power, wait 5 seconds
205  logger->Log("Module::MCU Sequencer 2");
206  command.name = "Motion Power";
207  command.ivalue = 1;
208  command.delay = 0.0f;
209  bus->commandStream.push_back(command);
210  timer = 5.0f;
211  sequencer++;
212  break;
213  case 3: // load mid-level, wait 5 seconds
214  logger->Log("Module::MCU Sequencer 3");
215  current = Locations[5]; // mid-level
216  timer = 10.0f;
217  sequencer++;
218  break;
219  case 4: // operating
220  // -1 and -1 is FL, -1 and 0 is FF, -1 and 1 is FR
221  // 0 and -1 is LL, 0 and 0 is MID, 0 and 1 is RR
222  // 1 and -1 is BL, 1 and 0 is BB, 1 and 1 is BR
223  if (roll <= 0.0f && pitch <= 0.0f)
224  {
225  float newflF = 0.0f, newfrF = 0.0f, newblF = 0.0f, newbrF = 0.0f;
226  // left and right of zone 1 front side
227  newflF += Locations[1].fl * fabs(roll); // was -1 to 0, now 1 to 0, FL
228  newfrF += Locations[1].fr * fabs(roll);
229  newblF += Locations[1].bl * fabs(roll);
230  newbrF += Locations[1].br * fabs(roll);
231  newflF += Locations[2].fl * (roll + 1.0f); // was -1 to 0, now 0 to 1, FF
232  newfrF += Locations[2].fr * (roll + 1.0f);
233  newblF += Locations[2].bl * (roll + 1.0f);
234  newbrF += Locations[2].br * (roll + 1.0f);
235  float newflM = 0.0f, newfrM = 0.0f, newblM = 0.0f, newbrM = 0.0f;
236  // left and right of zone mid-line
237  newflM += Locations[4].fl * fabs(roll); // was -1 to 0, now 1 to 0, LL
238  newfrM += Locations[4].fr * fabs(roll);
239  newblM += Locations[4].bl * fabs(roll);
240  newbrM += Locations[4].br * fabs(roll);
241  newflM += Locations[5].fl * (roll + 1.0f); // was -1 to 0, now 0 to 1, MID
242  newfrM += Locations[5].fr * (roll + 1.0f);
243  newblM += Locations[5].bl * (roll + 1.0f);
244  newbrM += Locations[5].br * (roll + 1.0f);
245  // front and back of zone
246  current.fl = newflF * fabs(pitch) + newflM * (pitch + 1.0f);
247  current.fr = newfrF * fabs(pitch) + newfrM * (pitch + 1.0f);
248  current.bl = newblF * fabs(pitch) + newblM * (pitch + 1.0f);
249  current.br = newbrF * fabs(pitch) + newbrM * (pitch + 1.0f);
250  }
251  else if (roll >= 0.0f && pitch <= 0.0f)
252  {
253  float newflF = 0.0f, newfrF = 0.0f, newblF = 0.0f, newbrF = 0.0f;
254  // left and right of zone 2 front side
255  newflF += Locations[3].fl * roll; // was 0 to 1 FR
256  newfrF += Locations[3].fr * roll;
257  newblF += Locations[3].bl * roll;
258  newbrF += Locations[3].br * roll;
259  newflF += Locations[2].fl * 1.0f - roll; // was 0 to 1, now 1 to 0, FF
260  newfrF += Locations[2].fr * 1.0f - roll;
261  newblF += Locations[2].bl * 1.0f - roll;
262  newbrF += Locations[2].br * 1.0f - roll;
263  float newflM = 0.0f, newfrM = 0.0f, newblM = 0.0f, newbrM = 0.0f;
264  // left and right of zone mid-line
265  newflM += Locations[6].fl * roll; // was 0 to 1, RR
266  newfrM += Locations[6].fr * roll;
267  newblM += Locations[6].bl * roll;
268  newbrM += Locations[6].br * roll;
269  newflM += Locations[5].fl * 1.0f - roll; // was 0 to 1, now 1 to 0, MID
270  newfrM += Locations[5].fr * 1.0f - roll;
271  newblM += Locations[5].bl * 1.0f - roll;
272  newbrM += Locations[5].br * 1.0f - roll;
273  // front and back of zone
274  current.fl = newflF * fabs(pitch) + newflM * (pitch + 1.0f);
275  current.fr = newfrF * fabs(pitch) + newfrM * (pitch + 1.0f);
276  current.bl = newblF * fabs(pitch) + newblM * (pitch + 1.0f);
277  current.br = newbrF * fabs(pitch) + newbrM * (pitch + 1.0f);
278  }
279  else if (roll <= 0.0f && pitch >= 0.0f)
280  {
281  float newflF = 0.0f, newfrF = 0.0f, newblF = 0.0f, newbrF = 0.0f;
282  // left and right of zone 3 back side
283  newflF += Locations[7].fl * fabs(roll); // was -1 to 0, now 1 to 0, FL
284  newfrF += Locations[7].fr * fabs(roll);
285  newblF += Locations[7].bl * fabs(roll);
286  newbrF += Locations[7].br * fabs(roll);
287  newflF += Locations[8].fl * (roll + 1.0f); // was -1 to 0, now 0 to 1, FF
288  newfrF += Locations[8].fr * (roll + 1.0f);
289  newblF += Locations[8].bl * (roll + 1.0f);
290  newbrF += Locations[8].br * (roll + 1.0f);
291  float newflM = 0.0f, newfrM = 0.0f, newblM = 0.0f, newbrM = 0.0f;
292  // left and right of zone mid-line
293  newflM += Locations[4].fl * fabs(roll); // was -1 to 0, now 1 to 0, LL
294  newfrM += Locations[4].fr * fabs(roll);
295  newblM += Locations[4].bl * fabs(roll);
296  newbrM += Locations[4].br * fabs(roll);
297  newflM += Locations[5].fl * (roll + 1.0f); // was -1 to 0, now 0 to 1, MID
298  newfrM += Locations[5].fr * (roll + 1.0f);
299  newblM += Locations[5].bl * (roll + 1.0f);
300  newbrM += Locations[5].br * (roll + 1.0f);
301  // front and back of zone
302  current.fl = newflF * pitch + newflM * (1.0f - pitch);
303  current.fr = newfrF * pitch + newfrM * (1.0f - pitch);
304  current.bl = newblF * pitch + newblM * (1.0f - pitch);
305  current.br = newbrF * pitch + newbrM * (1.0f - pitch);
306  }
307  else if (roll >= 0.0f && pitch >= 0.0f)
308  {
309  float newflF = 0.0f, newfrF = 0.0f, newblF = 0.0f, newbrF = 0.0f;
310  // left and right of zone 4 back side
311  newflF += Locations[9].fl * roll; // was 0 to 1 FR
312  newfrF += Locations[9].fr * roll;
313  newblF += Locations[9].bl * roll;
314  newbrF += Locations[9].br * roll;
315  newflF += Locations[8].fl * 1.0f - roll; // was 0 to 1, now 1 to 0, FF
316  newfrF += Locations[8].fr * 1.0f - roll;
317  newblF += Locations[8].bl * 1.0f - roll;
318  newbrF += Locations[8].br * 1.0f - roll;
319  float newflM = 0.0f, newfrM = 0.0f, newblM = 0.0f, newbrM = 0.0f;
320  // left and right of zone mid-line
321  newflM += Locations[6].fl * roll; // was 0 to 1, RR
322  newfrM += Locations[6].fr * roll;
323  newblM += Locations[6].bl * roll;
324  newbrM += Locations[6].br * roll;
325  newflM += Locations[5].fl * 1.0f - roll; // was 0 to 1, now 1 to 0, MID
326  newfrM += Locations[5].fr * 1.0f - roll;
327  newblM += Locations[5].bl * 1.0f - roll;
328  newbrM += Locations[5].br * 1.0f - roll;
329  // front and back of zone
330  current.fl = newflF * pitch + newflM * (1.0f - pitch);
331  current.fr = newfrF * pitch + newfrM * (1.0f - pitch);
332  current.bl = newblF * pitch + newblM * (1.0f - pitch);
333  current.br = newbrF * pitch + newbrM * (1.0f - pitch);
334  }
339  {
340  float mag = max(fabsf(pitch), fabsf(roll)); // say pitch is 0.0f, roll is -0.9f, mag is 0.9f
341  if (mag < 1.0f)
342  {
343  heave *= (1.0f - mag); // so if we have 0.1 avail 1.0f-0.9f = 0.1f available
344  if (heave > 0)
345  {
346  // high - mid is how much room we have...
347  current.fl += (Locations[10].fl - Locations[5].fl) * heave;
348  current.fr += (Locations[10].fr - Locations[5].fr) * heave;
349  current.bl += (Locations[10].bl - Locations[5].bl) * heave;
350  current.br += (Locations[10].br - Locations[5].br) * heave;
351  }
352  else
353  {
354  // FL was 0.5
355  // (0.5 - 0.0) = 0.5 to go
356  // 0.5 * -1.0 = -0.5
357  current.fl += (Locations[5].fl - Locations[0].fl) * heave * 0.75f;
358  current.fr += (Locations[5].fr - Locations[0].fr) * heave * 0.75f;
359  current.bl += (Locations[5].bl - Locations[0].bl) * heave * 0.75f;
360  current.br += (Locations[5].br - Locations[0].br) * heave * 0.75f;
361  }
362  }
363  }
364 
365  break;
366  case 5: // load mid-level, wait 5 seconds
367  logger->Log("Module::MCU Sequencer 5");
368  current = Locations[5]; // mid-level
369  timer = 10.0f;
370  sequencer++;
371  break;
372  case 6: // load off-level, wait 5 seconds
373  logger->Log("Module::MCU Sequencer 6");
374  current.fl = current.fr = current.bl = current.br = 0.0f; // off-level
375  timer = 10.0f;
376  sequencer++;
377  break;
378  case 7: // motion power, wait 5 seconds
379  logger->Log("Module::MCU Sequencer 7");
380  command.name = "Motion Power";
381  command.ivalue = 0;
382  command.delay = 0.0f;
383  bus->commandStream.push_back(command);
384  timer = 5.0f;
385  sequencer++;
386  break;
387  case 8: // caution lights, wait 5 seconds
388  logger->Log("Module::MCU Sequencer 8");
389  command.name = "MotionPlatformCautionLights";
390  command.ivalue = 0;
391  command.delay = 0.0f;
392  bus->commandStream.push_back(command);
393  sequencer = 0;
394  break;
395  }
396  }
397 
403 }
int testmode
Definition: Module.h:198
double PlatformFrontRightBellow
Definition: Bus.h:32
float * emergencyStopGetPtr
Definition: Module.h:199
std::vector< Command > commandStream
Definition: Bus.h:20
double PlatformFrontLeftBellow
Definition: Bus.h:33
Definition: Logger.h:5
float timer
Definition: Module.h:197
Definition: Bus.h:12
std::string name
command name
Definition: Command.h:11
D3DXVECTOR3 NormalAcceleration
(5) vertical (11) longitudinal (18) lateral
Definition: Bus.h:47
SSnap current
Definition: Module.h:207
Abstract base class for modules By definition, instruments don&#39;t do any of the work (they don&#39;t modif...
Definition: Module.h:11
Mcu(Bus *prmBus, Logger *prmLogger)
Definition: MCU.cpp:8
Definition: Command.h:5
double PlatformBackLeftBellow
Definition: Bus.h:31
float fl
Definition: Module.h:203
Logger * logger
Definition: Module.h:209
void Log(const char *msg, Level level=Info, int errorCode=0)
These have to be in this order.
Definition: Logger.cpp:16
Bus * bus
Definition: Module.h:17
float fr
Definition: Module.h:203
int PlatformMotionSequencer
Definition: Bus.h:34
bool is_set() const
Definition: Nullable.h:86
void FrameMove(float fElapsedTime) override
Definition: MCU.cpp:30
int ivalue
Definition: Command.h:21
SSnap Locations[11]
Definition: Module.h:206
float br
Definition: Module.h:203
float delay
wait number of seconds before executing command
Definition: Command.h:8
float bl
Definition: Module.h:203
double PlatformBackRightBellow
Definition: Bus.h:30
int sequencer
Definition: Module.h:187
T get() const
Definition: Nullable.h:79