Avionics
Dropship Simulator
FCS.cpp
Go to the documentation of this file.
1 #include "Module.h"
2 #include "../Extensions.h"
3 
4 void Fcs::FrameMove(float fElapsed)
5 {
6  if (*fcsGetFloatPtr <= 48.0f)
7  return;
8 
9 #pragma region Commands
10  for (UINT i = 0; i < bus->commandStream.size(); i++)
11  {
12  Command command = bus->commandStream.at(i);
13  if (command.delay != 0.0f) continue;
14 
15  int location = command.ivalue;
16 
20  if (command.name == "FlightControlPriorityDepress")
21  {
22  if (locations.size() > static_cast<unsigned>(location))
23  {
24  ControlPriorityLocation = location;
25  Command newCommand;
26  newCommand.name = location == 0 ? "FCSPriorityRight" : "FCSPriorityLeft";
27  bus->commandStream.push_back(newCommand);
28  locations.at(location).priorityButtonDown = true;
29  locations.at(location).priorityHeldDownSec = 0.0f;
30  ControlPriorityLatched = false;
31  }
32  bus->commandStream.erase(bus->commandStream.begin() + i);
33  }
35  else if (command.name == "FlightControlPriorityRelease")
36  {
37  if (locations.size() > static_cast<unsigned>(location))
38  {
39  locations.at(location).priorityButtonDown = false;
40  if (ControlPriorityLocation == location && !ControlPriorityLatched) // other pilot may have pressed it after this guy
42  }
43  bus->commandStream.erase(bus->commandStream.begin() + i);
44  }
45  else if (command.name == "PushToTalkDepress")
46  {
47  if (locations.size() > static_cast<unsigned>(location))
48  {
49  Command newCommand;
50  newCommand.name = location == 0 ? "Push To Talk Pilot" : "Push To Talk Gunner";
51  newCommand.ivalue = 1;
52  bus->commandStream.push_back(newCommand);
53  bus->Transmitting.at(location) = true;
54  }
55  bus->commandStream.erase(bus->commandStream.begin() + i);
56  }
57  else if (command.name == "PushToTalkRelease")
58  {
59  if (locations.size() > static_cast<unsigned>(location))
60  {
61  Command newCommand;
62  newCommand.name = location == 0 ? "Push To Talk Pilot" : "Push To Talk Gunner";
63  newCommand.ivalue = 0;
64  bus->commandStream.push_back(newCommand);
65  bus->Transmitting.at(location) = false;
66  }
67  bus->commandStream.erase(bus->commandStream.begin() + i);
68  }
69  }
70 #pragma endregion
71 
72  if (locations.size() > 1)
73  {
74  for (UINT i = 0; i < locations.size(); i++)
75  {
76  if (locations.at(i).priorityButtonDown)
77  {
78  locations.at(i).priorityHeldDownSec += fElapsed;
80  if (locations.at(i).priorityHeldDownSec >= 40.0f && !ControlPriorityLatched)
81  {
84  }
85  }
86  }
87  }
88 
89  bool dualInput = false;
90  if (ControlPriorityLocation == -1)
91  {
93  bus->PitchControl = 0.0f;
94  bus->RollControl = 0.0f;
95  bus->YawControl = 0.0f;
97  {
101  }
102  for (UINT i = 0; i < flightControls.size(); i++)
103  {
104  if (flightControls.at(i)->IsActive())
105  {
109 
110  if (i == 0)
111  *fcsFaultPtr &= ~1;
112  else
113  *fcsFaultPtr &= ~2;
114  }
115  else
116  {
118  if (i == 0)
119  *fcsFaultPtr |= 1;
120  else
121  *fcsFaultPtr |= 2;
122  }
123  }
124 
126  if (bus->PitchControl > 1.0f)
127  {
128  bus->PitchControl = 1.0f;
129  dualInput = true;
130  }
131  if (bus->RollControl > 1.0f)
132  {
133  bus->RollControl = 1.0f;
134  dualInput = true;
135  }
136  if (bus->YawControl > 1.0f)
137  {
138  bus->YawControl = 1.0f;
139  dualInput = true;
140  }
141  if (bus->PitchControl < -1.0f)
142  {
143  bus->PitchControl = -1.0f;
144  dualInput = true;
145  }
146  if (bus->RollControl < -1.0f)
147  {
148  bus->RollControl = -1.0f;
149  dualInput = true;
150  }
151  if (bus->YawControl < -1.0f)
152  {
153  bus->YawControl = -1.0f;
154  dualInput = true;
155  }
156  }
157  else
158  {
160  if (flightControls.at(ControlPriorityLocation)->IsActive())
161  {
165  }
166  }
167 
168  if (dualInput && !bus->IsCommandOnStack("FCSDualInput"))
169  {
170  Command newCommand;
171  newCommand.name = "FCSDualInput";
172  bus->commandStream.push_back(newCommand);
173  }
174 
176  for (UINT i = 0; i < flightControls.size(); i++)
177  {
179  if (flightControls.at(i)->GetButton(6))
180  {
181  bus->PitchTrim -= fElapsed * 0.03f;
183  if (bus->PitchTrim < -0.2618f)
184  bus->PitchTrim = -0.2618f;
187  }
188  if (flightControls.at(i)->GetButton(8))
189  {
190  bus->PitchTrim += fElapsed * 0.03f;
192  if (bus->PitchTrim > 0.2618f)
193  bus->PitchTrim = 0.2618f;
196  }
197  }
198 
200 
202  if (true)
203  {
204  static float oldhdg = 0.0f;
205  float _yaw = (bus->HeadingTrue - oldhdg);
206  if (_yaw < -D3DX_PI) _yaw += D3DX_PI * 2.0f;
207  if (_yaw > D3DX_PI) _yaw -= D3DX_PI * 2.0f;
208  oldhdg = bus->HeadingTrue;
209  _yaw /= fElapsed; // radians per second
210 
213  float desiredyaw = 0.0f;
214  if (bus->IndicatedAirspeed != 0.0f)
215  desiredyaw = 19.041542139258135684237466284211f * tanf(bus->RollAttitude) * cos(bus->PitchAttitude) / (bus->IndicatedAirspeed / sqrtf(bus->AirDensity) * 1943.84449f); // km/s to knots is 1943.84449
216  float yawcorr = desiredyaw - _yaw; // say we are 10 and we want 0 then 0-10 is -10 perfect!
217 
218  float dampen = yawcorr / 0.05235987756f; // Yaw damper
219  dampen = Library::MathUtils::Clamp(dampen, -0.3f, 0.3f);
220  bus->YawControl += dampen;
222  }
223 
224 
226  const float Vs = 0.010f;
227  const float Vne = 0.128f; // Vne at 60km
228  float ifcs = 1.0f - (bus->IndicatedAirspeed - Vs) / (Vne - Vs);
229  if (ifcs > 1) ifcs = 1;
230  if (ifcs < 0) ifcs = 0;
231  ifcs *= ifcs; // velocity squared
232 
233 
235  ZeroMemory(bus->DiscreetSurfacePostion, sizeof(bus->DiscreetSurfacePostion));
236 
237  const float modarea = 31.796473f / 55.824566f; // lower surface is bigger
238  const float modang = 0.739191473f; // the lower surface is less conducive to roll (need to increase) and more conducive to pitch (need to decrease)
239  const float modcg = 0.14285714285714285714285714285714f; // since the top controls are significantly above the CG compared to the lower controls below...
240  const float moddeflect = 0.392699f / 0.5f; // bottom surfaces can deflect further
241  //float r1 = modcg / modarea;
242  //float r2 = 1.0f / modang*moddeflect;
243  //float r3 = modang*moddeflect;
244  const float modusefullrange = 1.0f / 1.06250954f;
245 
247  float pitreq = Library::MathUtils::Clamp(-bus->PitchControl - bus->PitchTrim, -1.0f, 1.0f) * ifcs;
249 
250  bus->DiscreetSurfacePostion[0] -= bus->RollControlSurfacePosition * modcg / modarea * modusefullrange; // top right from rear
251  bus->DiscreetSurfacePostion[1] -= bus->RollControlSurfacePosition / modang * moddeflect * modusefullrange; // lower right from rear
252  bus->DiscreetSurfacePostion[2] += bus->RollControlSurfacePosition / modang * moddeflect * modusefullrange; // lower left from rear
253  bus->DiscreetSurfacePostion[3] += bus->RollControlSurfacePosition * modcg / modarea * modusefullrange; // top left from rear
254 
255  bus->DiscreetSurfacePostion[0] += pitreq * modcg / modarea * modusefullrange;
256  bus->DiscreetSurfacePostion[1] += pitreq * modang * moddeflect * modusefullrange;
257  bus->DiscreetSurfacePostion[2] += pitreq * modang * moddeflect * modusefullrange;
258  bus->DiscreetSurfacePostion[3] += pitreq * modcg / modarea * modusefullrange;
259 
260  bus->DiscreetSurfacePostion[0] -= bus->YawControlSurfacePosition * modcg / modarea * modusefullrange;
261  bus->DiscreetSurfacePostion[1] += bus->YawControlSurfacePosition * modang * moddeflect * modusefullrange * 0.1f;
262  bus->DiscreetSurfacePostion[2] -= bus->YawControlSurfacePosition * modang * moddeflect * modusefullrange * 0.1f;
263  bus->DiscreetSurfacePostion[3] += bus->YawControlSurfacePosition * modcg / modarea * modusefullrange;
264 
265 
267  float max = max(max(max(fabsf(bus->DiscreetSurfacePostion[0]), fabsf(bus->DiscreetSurfacePostion[1])), fabsf(bus->DiscreetSurfacePostion[2])), fabsf(bus->DiscreetSurfacePostion[3]));
268  if (max > 1.0f)
269  max = 1.0f / max;
270  else
271  max = 1.0f;
272 
273  bus->DiscreetSurfacePostion[0] *= max;
274  bus->DiscreetSurfacePostion[1] *= max;
275  bus->DiscreetSurfacePostion[2] *= max;
276  bus->DiscreetSurfacePostion[3] *= max;
277 }
278 
279 Fcs::Fcs(Bus* prmBus, int joysticks) : Module(prmBus)
280 {
281  locations.resize(joysticks);
282  bus->Transmitting.resize(joysticks);
283 }
284 
285 void Fcs::Initialize(Devices::Joystick* prmFlightControl)
286 {
287  flightControls.push_back(prmFlightControl);
288 }
289 
290 void Fcs::ConnectComponent(std::string type, std::string guid)
291 {
292  fcsGetFloatPtr = bus->GetComponentCurrentStatePtr(guid);
293  fcsFaultPtr = reinterpret_cast<DWORD*>(bus->GetComponentFaultStatePtr(guid));
294 }
std::vector< Location > locations
Definition: Module.h:89
int ControlPriorityLocation
Definition: Module.h:91
float occupantPitchControlAuthority
Definition: Bus.h:298
float PitchInput
Definition: Bus.h:127
void ConnectComponent(std::string name, std::string guid)
Definition: FCS.cpp:290
float occupantRollControlAuthority
Definition: Bus.h:299
std::vector< Command > commandStream
Definition: Bus.h:20
float YawControl
Definition: Bus.h:57
Systems::Fault * GetComponentFaultStatePtr(std::string guidStr)
Definition: Bus.cpp:141
float RollControl
Definition: Bus.h:57
void FrameMove(float fElapsedTime) override
Definition: FCS.cpp:4
std::vector< Devices::Joystick * > flightControls
Definition: Module.h:94
float RollControlSurfacePosition
Definition: Bus.h:60
float IndicatedAirspeed
(3) Indicated Airspeed in km per second?
Definition: Bus.h:42
float * fcsGetFloatPtr
Definition: Module.h:97
static float Clamp(float x, float min, float max)
Definition: Extensions.h:37
float PitchAttitude
(6) Pitch attitude;
Definition: Bus.h:49
float PitchControl
Definition: Bus.h:57
Fcs(Bus *prmBus, int joysticks)
Definition: FCS.cpp:279
float HeadingTrue
(4) Heading–primary flight crew reference (if selectable, record discrete, true or magnetic); ...
Definition: Bus.h:44
float PitchTrim
Definition: Bus.h:259
float AirDensity
Definition: Bus.h:276
std::vector< bool > Transmitting
(8) Manual radio transmitter keying, or CVR/DFDR synchronization reference;
Definition: Bus.h:53
float YawInput
Definition: Bus.h:129
Definition: Bus.h:12
std::string name
command name
Definition: Command.h:11
bool ControlPriorityLatched
Definition: Module.h:92
float RollAttitude
(7) Roll attitude;
Definition: Bus.h:51
float DiscreetSurfacePostion[4]
Definition: Bus.h:59
DWORD * fcsFaultPtr
Definition: Module.h:96
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
float RollInput
Definition: Bus.h:128
Definition: Command.h:5
struct Bus::Afcs AFCS
Bus * bus
Definition: Module.h:17
void Initialize(Devices::Joystick *prmFlightControl)
Definition: FCS.cpp:285
float YawControlSurfacePosition
Definition: Bus.h:61
int ivalue
Definition: Command.h:21
bool AutopilotEngaged
Definition: Bus.h:80
bool IsCommandOnStack(std::string commandName)
Definition: Bus.cpp:67
float delay
wait number of seconds before executing command
Definition: Command.h:8
std::vector< Devices::Joystick > joysticks
Definition: Avionics.cpp:32