Skip to content

Commit

Permalink
feat(a380-efcs): various updates (#8513)
Browse files Browse the repository at this point in the history
* feat(fbw): integrate pause/spawn handling improvements from A32NX

* feat(a380-efcs): add roll precontrol, correct A380 flare law

* fix(a380-efcs): use correct sign for elevator position inputs

* feat(a380-efcs): add manual trim mode, and auto reset to 0deg at 30kts
  • Loading branch information
lukecologne authored Mar 10, 2024
1 parent 1744552 commit 6f3245c
Show file tree
Hide file tree
Showing 29 changed files with 3,313 additions and 3,780 deletions.
53 changes: 37 additions & 16 deletions fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ bool FlyByWireInterface::connect() {
flightDataRecorder.initialize();

// connect to sim connect
bool success = simConnectInterface.connect(clientDataEnabled, autopilotStateMachineEnabled, autopilotLawsEnabled, flyByWireEnabled, primDisabled,
secDisabled, facDisabled, throttleAxis, spoilersHandler, flightControlsKeyChangeAileron,
flightControlsKeyChangeElevator, flightControlsKeyChangeRudder,
disableXboxCompatibilityRudderAxisPlusMinus, enableRudder2AxisMode, idMinimumSimulationRate->get(),
idMaximumSimulationRate->get(), limitSimulationRateByPerformance);
bool success = simConnectInterface.connect(
clientDataEnabled, autopilotStateMachineEnabled, autopilotLawsEnabled, flyByWireEnabled, primDisabled, secDisabled, facDisabled,
throttleAxis, spoilersHandler, flightControlsKeyChangeAileron, flightControlsKeyChangeElevator, flightControlsKeyChangeRudder,
disableXboxCompatibilityRudderAxisPlusMinus, enableRudder2AxisMode, idMinimumSimulationRate->get(), idMaximumSimulationRate->get(),
limitSimulationRateByPerformance);
// request data
if (!simConnectInterface.requestData()) {
std::cout << "WASM: Request data failed!" << std::endl;
Expand Down Expand Up @@ -73,6 +73,9 @@ bool FlyByWireInterface::update(double sampleTime) {
// get data & inputs
result &= readDataAndLocalVariables(sampleTime);

// get sim data
SimData simData = simConnectInterface.getSimData();

// update performance monitoring
result &= updatePerformanceMonitoring(sampleTime);

Expand All @@ -86,10 +89,10 @@ bool FlyByWireInterface::update(double sampleTime) {
result &= handleFcuInitialization(calculatedSampleTime);

// do not process laws in pause or slew
if (simConnectInterface.getSimData().slew_on) {
if (simData.slew_on) {
wasInSlew = true;
return result;
} else if (pauseDetected || simConnectInterface.getSimData().cameraState >= 10.0) {
} else if (pauseDetected || simData.cameraState >= 10.0 || !idIsReady->get() || simData.simulationTime < 2) {
return result;
}

Expand Down Expand Up @@ -154,11 +157,14 @@ bool FlyByWireInterface::update(double sampleTime) {
// update FO side with FO Sync ON
result &= updateFoSide(calculatedSampleTime);

// update flight data recorder
flightDataRecorder.update(&autopilotStateMachine, &autopilotLaws, &autoThrust, engineData, additionalData);
// do not further process when active pause is on
if (!simConnectInterface.isSimInActivePause()) {
// update flight data recorder
flightDataRecorder.update(&autopilotStateMachine, &autopilotLaws, &autoThrust, engineData, additionalData);
}

// if default AP is on -> disconnect it
if (simConnectInterface.getSimData().autopilot_master_on) {
if (simData.autopilot_master_on) {
simConnectInterface.sendEvent(SimConnectInterface::Events::AUTOPILOT_OFF);
}

Expand Down Expand Up @@ -1265,6 +1271,11 @@ bool FlyByWireInterface::updateAdirs(int adirsIndex) {
}

bool FlyByWireInterface::updatePrim(double sampleTime, int primIndex) {
// do not further process when active pause is on
if (simConnectInterface.isSimInActivePause()) {
return true;
}

SimData simData = simConnectInterface.getSimData();
SimInput simInput = simConnectInterface.getSimInput();
SimInputPitchTrim pitchTrimInput = simConnectInterface.getSimInputPitchTrim();
Expand Down Expand Up @@ -1383,9 +1394,9 @@ bool FlyByWireInterface::updatePrim(double sampleTime, int primIndex) {
prims[primIndex].modelInputs.in.analog_inputs.thr_lever_2_pos = thrustLeverAngle_2->get();
prims[primIndex].modelInputs.in.analog_inputs.thr_lever_3_pos = thrustLeverAngle_3->get();
prims[primIndex].modelInputs.in.analog_inputs.thr_lever_4_pos = thrustLeverAngle_4->get();
prims[primIndex].modelInputs.in.analog_inputs.elevator_1_pos_deg = 30. * elevator1Position;
prims[primIndex].modelInputs.in.analog_inputs.elevator_2_pos_deg = 30. * elevator2Position;
prims[primIndex].modelInputs.in.analog_inputs.elevator_3_pos_deg = 30. * elevator3Position;
prims[primIndex].modelInputs.in.analog_inputs.elevator_1_pos_deg = -30. * elevator1Position;
prims[primIndex].modelInputs.in.analog_inputs.elevator_2_pos_deg = -30. * elevator2Position;
prims[primIndex].modelInputs.in.analog_inputs.elevator_3_pos_deg = -30. * elevator3Position;
prims[primIndex].modelInputs.in.analog_inputs.ths_pos_deg = thsPosition;
prims[primIndex].modelInputs.in.analog_inputs.left_aileron_1_pos_deg = 30. * leftAileron1Position;
prims[primIndex].modelInputs.in.analog_inputs.left_aileron_2_pos_deg = 30. * leftAileron2Position;
Expand Down Expand Up @@ -1485,6 +1496,11 @@ bool FlyByWireInterface::updatePrim(double sampleTime, int primIndex) {
}

bool FlyByWireInterface::updateSec(double sampleTime, int secIndex) {
// do not further process when active pause is on
if (simConnectInterface.isSimInActivePause()) {
return true;
}

const int oppSecIndex = secIndex == 0 ? 1 : 0;
SimData simData = simConnectInterface.getSimData();
SimInput simInput = simConnectInterface.getSimInput();
Expand Down Expand Up @@ -1592,9 +1608,9 @@ bool FlyByWireInterface::updateSec(double sampleTime, int secIndex) {
secs[secIndex].modelInputs.in.analog_inputs.fo_pitch_stick_pos = 0;
secs[secIndex].modelInputs.in.analog_inputs.capt_roll_stick_pos = -simInput.inputs[1];
secs[secIndex].modelInputs.in.analog_inputs.fo_roll_stick_pos = 0;
secs[secIndex].modelInputs.in.analog_inputs.elevator_1_pos_deg = 30. * elevator1Position;
secs[secIndex].modelInputs.in.analog_inputs.elevator_2_pos_deg = 30. * elevator2Position;
secs[secIndex].modelInputs.in.analog_inputs.elevator_3_pos_deg = 30. * elevator3Position;
secs[secIndex].modelInputs.in.analog_inputs.elevator_1_pos_deg = -30. * elevator1Position;
secs[secIndex].modelInputs.in.analog_inputs.elevator_2_pos_deg = -30. * elevator2Position;
secs[secIndex].modelInputs.in.analog_inputs.elevator_3_pos_deg = -30. * elevator3Position;
secs[secIndex].modelInputs.in.analog_inputs.ths_pos_deg = thsPosition;
secs[secIndex].modelInputs.in.analog_inputs.left_aileron_1_pos_deg = 30. * leftAileron1Position;
secs[secIndex].modelInputs.in.analog_inputs.left_aileron_2_pos_deg = 30. * leftAileron2Position;
Expand Down Expand Up @@ -1745,6 +1761,11 @@ bool FlyByWireInterface::updateSec(double sampleTime, int secIndex) {
// }

bool FlyByWireInterface::updateFac(double sampleTime, int facIndex) {
// do not further process when active pause is on
if (simConnectInterface.isSimInActivePause()) {
return true;
}

const int oppFacIndex = facIndex == 0 ? 1 : 0;
SimData simData = simConnectInterface.getSimData();
SimInputRudderTrim trimInput = simConnectInterface.getSimInputRudderTrim();
Expand Down
24 changes: 24 additions & 0 deletions fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ bool SimConnectInterface::connect(bool clientDataEnabled,
// register key event handler
// remove when aileron events can be processed via SimConnect
register_key_event_handler_EX1(static_cast<GAUGE_KEY_EVENT_HANDLER_EX1>(processKeyEvent), NULL);
// register for pause event
SimConnect_SubscribeToSystemEvent(hSimConnect, Events::SYSTEM_EVENT_PAUSE, "Pause_EX1");
// send initial event to FCU to force HDG mode
execute_calculator_code("(>H:A320_Neo_FCU_HDG_PULL)", nullptr, nullptr, nullptr);
// success
Expand All @@ -94,6 +96,8 @@ void SimConnectInterface::disconnect() {
// unregister key event handler
// remove when aileron events can be processed via SimConnect
unregister_key_event_handler_EX1(static_cast<GAUGE_KEY_EVENT_HANDLER_EX1>(processKeyEvent), NULL);
// unregister from pause events
SimConnect_UnsubscribeFromSystemEvent(hSimConnect, Events::SYSTEM_EVENT_PAUSE);
// info message
std::cout << "WASM: Disconnecting..." << std::endl;
// close connection
Expand All @@ -116,6 +120,18 @@ void SimConnectInterface::updateSimulationRateLimits(double minSimulationRate, d
this->maxSimulationRate = maxSimulationRate;
}

bool SimConnectInterface::isSimInAnyPause() {
return (pauseState > 0);
}

bool SimConnectInterface::isSimInActivePause() {
return (pauseState == 4);
}

bool SimConnectInterface::isSimInPause() {
return (pauseState == 8);
}

bool SimConnectInterface::prepareSimDataSimConnectDataDefinitions() {
bool result = true;

Expand Down Expand Up @@ -1507,6 +1523,14 @@ void SimConnectInterface::simConnectProcessEvent_EX1(const SIMCONNECT_RECV_EVENT
void SimConnectInterface::processEventWithOneParam(const DWORD eventId, const DWORD data0) {
// process depending on event id
switch (eventId) {
case Events::SYSTEM_EVENT_PAUSE: {
pauseState = static_cast<long>(data0);
std::cout << "WASM: SYSTEM_EVENT_PAUSE: ";
std::cout << static_cast<long>(data0);
std::cout << std::endl;
break;
}

case Events::AXIS_ELEVATOR_SET: {
simInput.inputs[AXIS_ELEVATOR_SET] = static_cast<long>(data0) / 16384.0;
if (loggingFlightControlsEnabled) {
Expand Down
22 changes: 15 additions & 7 deletions fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ class SimConnectInterface {
SIM_RATE_INCR,
SIM_RATE_DECR,
SIM_RATE_SET,
SYSTEM_EVENT_PAUSE
};

SimConnectInterface() = default;
Expand Down Expand Up @@ -322,6 +323,10 @@ class SimConnectInterface {

void updateSimulationRateLimits(double minSimulationRate, double maxSimulationRate);

bool isSimInAnyPause();
bool isSimInActivePause();
bool isSimInPause();

private:
enum ClientData {
AUTOPILOT_STATE_MACHINE,
Expand Down Expand Up @@ -380,6 +385,8 @@ class SimConnectInterface {
int secDisabled = -1;
int facDisabled = -1;

long pauseState = 0;

// change to non-static when aileron events can be processed via SimConnect
static bool loggingFlightControlsEnabled;
bool loggingThrottlesEnabled = false;
Expand Down Expand Up @@ -447,7 +454,8 @@ class SimConnectInterface {
* in the event->dwData field of the SIMCONNECT_RECV_EVENT struct.
*
* @param event The pointer to the corresponding event data
* @see https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent.htm
* @see
* https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent.htm
*/
void simConnectProcessEvent(const SIMCONNECT_RECV_EVENT* event);

Expand All @@ -464,7 +472,8 @@ class SimConnectInterface {
* all other parameters.
*
* @param event The pointer to the corresponding event data
* @see https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent_EX1.htm
* @see
* https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent_EX1.htm
*/
void simConnectProcessEvent_EX1(const SIMCONNECT_RECV_EVENT_EX1* event);

Expand All @@ -491,12 +500,11 @@ class SimConnectInterface {

static std::string getSimConnectExceptionString(SIMCONNECT_EXCEPTION exception);

private:

/**
private:
/**
* @brief Process a SimConnect event with one parameter.
* @param eventId Specifies the ID of the client event.
* @param data0 Double word containing any additional number required by the event.
*/
void processEventWithOneParam(const DWORD eventId, const DWORD data0);
*/
void processEventWithOneParam(const DWORD eventId, const DWORD data0);
};
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,4 @@ A380LateralDirectLaw::A380LateralDirectLaw():
{
}

A380LateralDirectLaw::~A380LateralDirectLaw()
{
}
A380LateralDirectLaw::~A380LateralDirectLaw() = default;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef RTW_HEADER_A380LateralDirectLaw_private_h_
#define RTW_HEADER_A380LateralDirectLaw_private_h_
#include "rtwtypes.h"
#include "A380LateralDirectLaw_types.h"
#endif

52 changes: 0 additions & 52 deletions fbw-a380x/src/wasm/fbw_a380/src/model/A380LateralDirectLaw_types.h
Original file line number Diff line number Diff line change
@@ -1,56 +1,4 @@
#ifndef RTW_HEADER_A380LateralDirectLaw_types_h_
#define RTW_HEADER_A380LateralDirectLaw_types_h_
#include "rtwtypes.h"

#ifndef DEFINED_TYPEDEF_FOR_base_time_
#define DEFINED_TYPEDEF_FOR_base_time_

struct base_time
{
real_T dt;
real_T simulation_time;
real_T monotonic_time;
};

#endif

#ifndef DEFINED_TYPEDEF_FOR_lateral_direct_input_
#define DEFINED_TYPEDEF_FOR_lateral_direct_input_

struct lateral_direct_input
{
base_time time;
real_T delta_xi_pos;
real_T delta_zeta_pos;
boolean_T tracking_mode_on;
};

#endif

#ifndef DEFINED_TYPEDEF_FOR_base_roll_output_
#define DEFINED_TYPEDEF_FOR_base_roll_output_

struct base_roll_output
{
real_T xi_inboard_deg;
real_T xi_midboard_deg;
real_T xi_outboard_deg;
real_T xi_spoiler_deg;
real_T zeta_upper_deg;
real_T zeta_lower_deg;
};

#endif

#ifndef DEFINED_TYPEDEF_FOR_lateral_direct_output_
#define DEFINED_TYPEDEF_FOR_lateral_direct_output_

struct lateral_direct_output
{
lateral_direct_input input;
base_roll_output output;
};

#endif
#endif

Loading

0 comments on commit 6f3245c

Please sign in to comment.