Skip to content

Commit

Permalink
refactor: declarative msfs aspects (flybywiresim#6427)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidwalschots authored Jan 20, 2022
1 parent e919a7b commit 4869482
Show file tree
Hide file tree
Showing 16 changed files with 1,811 additions and 1,328 deletions.
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions docs/a320-simvars.md
Original file line number Diff line number Diff line change
Expand Up @@ -821,18 +821,13 @@
- Bool
- NW STRG DISC memo indication should show on ecam if true

- A32NX_TILLER_PEDAL_DISCONNECT
- Bool
- True when tiller disconnect button is pressed
Tiller button to be binded on "TOGGLE WATER RUDDER"

- A32NX_NOSE_WHEEL_POSITION
- Percent over 100
- Position of nose steering wheel animation [0;1] 0 left, 0.5 middle

- A32NX_TILLER_HANDLE_POSITION
- Percent over 100
- Position of tiller steering handle animation [0;1] 0 left, 0.5 middle
- Position of tiller steering handle animation [-1;1] -1 left, 0 middle, 1 right

- A32NX_AUTOPILOT_NOSEWHEEL_DEMAND
- Percent over 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,8 @@
<UseTemplate Name="ASOBO_GT_Anim_Code">
<NODE_ID>HANDLE_LEFT_YOKE</NODE_ID>
<ANIM_NAME>HANDLE_LEFT_YOKE</ANIM_NAME>
<ANIM_CODE>(L:A32NX_TILLER_HANDLE_POSITION)</ANIM_CODE>
<!-- Convert a range of -1...1 to 0...1. -->
<ANIM_CODE>(L:A32NX_TILLER_HANDLE_POSITION) 1 + 2 /</ANIM_CODE>
<ANIM_LENGTH>1</ANIM_LENGTH>
</UseTemplate>
</Component>
Expand Down
20 changes: 8 additions & 12 deletions src/systems/a320_systems/src/hydraulic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,7 +1702,7 @@ impl A320HydraulicBrakeSteerComputerUnit {
.get_identifier("RIGHT_BRAKE_PEDAL_INPUT".to_owned()),

ground_speed_id: context.get_identifier("GPS GROUND SPEED".to_owned()),
rudder_pedal_input_id: context.get_identifier("RUDDER_PEDAL_POSITION".to_owned()),
rudder_pedal_input_id: context.get_identifier("RUDDER_PEDAL_POSITION_RATIO".to_owned()),
tiller_handle_input_id: context.get_identifier("TILLER_HANDLE_POSITION".to_owned()),
tiller_pedal_disconnect_id: context
.get_identifier("TILLER_PEDAL_DISCONNECT".to_owned()),
Expand Down Expand Up @@ -1963,9 +1963,9 @@ impl SimulationElement for A320HydraulicBrakeSteerComputerUnit {
self.is_gear_lever_down = reader.read(&self.gear_handle_position_id);
self.anti_skid_activated = reader.read(&self.antiskid_brakes_active_id);
self.left_brake_pilot_input =
Ratio::new::<ratio>(reader.read(&self.left_brake_pedal_input_id));
Ratio::new::<percent>(reader.read(&self.left_brake_pedal_input_id));
self.right_brake_pilot_input =
Ratio::new::<ratio>(reader.read(&self.right_brake_pedal_input_id));
Ratio::new::<percent>(reader.read(&self.right_brake_pedal_input_id));

self.tiller_handle_position =
Ratio::new::<ratio>(reader.read(&self.tiller_handle_input_id));
Expand Down Expand Up @@ -3567,17 +3567,13 @@ mod tests {
.air_press_nominal()
}

fn set_left_brake(self, position_percent: Ratio) -> Self {
self.set_brake("LEFT_BRAKE_PEDAL_INPUT", position_percent)
}

fn set_right_brake(self, position_percent: Ratio) -> Self {
self.set_brake("RIGHT_BRAKE_PEDAL_INPUT", position_percent)
fn set_left_brake(mut self, position: Ratio) -> Self {
self.write_by_name("LEFT_BRAKE_PEDAL_INPUT", position);
self
}

fn set_brake(mut self, name: &str, position_percent: Ratio) -> Self {
let scaled_value = position_percent.get::<ratio>();
self.write_by_name(name, scaled_value.min(1.).max(0.));
fn set_right_brake(mut self, position: Ratio) -> Self {
self.write_by_name("RIGHT_BRAKE_PEDAL_INPUT", position);
self
}

Expand Down
39 changes: 39 additions & 0 deletions src/systems/a320_systems_wasm/src/autobrakes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::error::Error;
use std::time::Duration;
use systems_wasm::aspects::{EventToVariableMapping, EventToVariableOptions, MsfsAspectBuilder};
use systems_wasm::Variable;

pub(super) fn autobrakes(builder: &mut MsfsAspectBuilder) -> Result<(), Box<dyn Error>> {
let options = |options: EventToVariableOptions| {
options
.leading_debounce(Duration::from_millis(1500))
.afterwards_reset_to(0.)
};

builder.event_to_variable(
"AUTOBRAKE_LO_SET",
EventToVariableMapping::Value(1.),
Variable::named("OVHD_AUTOBRK_LOW_ON_IS_PRESSED"),
options,
)?;
builder.event_to_variable(
"AUTOBRAKE_MED_SET",
EventToVariableMapping::Value(1.),
Variable::named("OVHD_AUTOBRK_MED_ON_IS_PRESSED"),
options,
)?;
builder.event_to_variable(
"AUTOBRAKE_HI_SET",
EventToVariableMapping::Value(1.),
Variable::named("OVHD_AUTOBRK_MAX_ON_IS_PRESSED"),
options,
)?;
builder.event_to_variable(
"AUTOBRAKE_DISARM",
EventToVariableMapping::Value(1.),
Variable::named("AUTOBRAKE_DISARM"),
|options| options.afterwards_reset_to(0.),
)?;

Ok(())
}
107 changes: 107 additions & 0 deletions src/systems/a320_systems_wasm/src/brakes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use std::error::Error;
use systems::shared::{from_bool, to_bool};
use systems_wasm::aspects::{
max, EventToVariableMapping, ExecuteOn, MsfsAspectBuilder, VariableToEventMapping,
VariableToEventWriteOn,
};
use systems_wasm::Variable;

pub(super) fn brakes(builder: &mut MsfsAspectBuilder) -> Result<(), Box<dyn Error>> {
builder.event_to_variable(
"PARKING_BRAKES",
EventToVariableMapping::CurrentValueToValue(|current_value| {
from_bool(!to_bool(current_value))
}),
Variable::named("PARK_BRAKE_LEVER_POS"),
|options| options.mask(),
)?;
builder.event_to_variable(
"PARKING_BRAKE_SET",
EventToVariableMapping::EventDataToValue(|event_data| from_bool(event_data == 1)),
Variable::named("PARK_BRAKE_LEVER_POS"),
|options| options.mask(),
)?;

// Controller inputs for the left and right brakes are captured and translated
// to a variable so that it can be used by the simulation.
// After running the simulation, the variable value is written back to the simulator
// through the event.
let axis_left_brake_set_event_id = builder.event_to_variable(
"AXIS_LEFT_BRAKE_SET",
EventToVariableMapping::EventData32kPosition,
Variable::aspect("BRAKES_LEFT_EVENT"),
|options| options.mask(),
)?;
builder.variable_to_event_id(
Variable::aspect("BRAKE LEFT FORCE FACTOR"),
VariableToEventMapping::EventData32kPosition,
VariableToEventWriteOn::EveryTick,
axis_left_brake_set_event_id,
);
let axis_right_brake_set_event_id = builder.event_to_variable(
"AXIS_RIGHT_BRAKE_SET",
EventToVariableMapping::EventData32kPosition,
Variable::aspect("BRAKES_RIGHT_EVENT"),
|options| options.mask(),
)?;
builder.variable_to_event_id(
Variable::aspect("BRAKE RIGHT FORCE FACTOR"),
VariableToEventMapping::EventData32kPosition,
VariableToEventWriteOn::EveryTick,
axis_right_brake_set_event_id,
);

// Inputs for both brakes, left brake, and right brake are captured and
// translated via a smooth press function into a ratio which is written to variables.
const KEYBOARD_PRESS_SPEED: f64 = 0.6;
const KEYBOARD_RELEASE_SPEED: f64 = 0.3;
builder.event_to_variable(
"BRAKES",
EventToVariableMapping::SmoothPress(KEYBOARD_PRESS_SPEED, KEYBOARD_RELEASE_SPEED),
Variable::aspect("BRAKES"),
|options| options.mask(),
)?;
builder.event_to_variable(
"BRAKES_LEFT",
EventToVariableMapping::SmoothPress(KEYBOARD_PRESS_SPEED, KEYBOARD_RELEASE_SPEED),
Variable::aspect("BRAKES_LEFT"),
|options| options.mask(),
)?;
builder.event_to_variable(
"BRAKES_RIGHT",
EventToVariableMapping::SmoothPress(KEYBOARD_PRESS_SPEED, KEYBOARD_RELEASE_SPEED),
Variable::aspect("BRAKES_RIGHT"),
|options| options.mask(),
)?;

// The maximum braking demand of all controller inputs
// is calculated and made available as a percentage.
builder.reduce(
ExecuteOn::PreTick,
vec![
Variable::aspect("BRAKES"),
Variable::aspect("BRAKES_LEFT"),
Variable::aspect("BRAKES_LEFT_EVENT"),
],
0.,
to_percent_max,
Variable::named("LEFT_BRAKE_PEDAL_INPUT"),
);
builder.reduce(
ExecuteOn::PreTick,
vec![
Variable::aspect("BRAKES"),
Variable::aspect("BRAKES_RIGHT"),
Variable::aspect("BRAKES_RIGHT_EVENT"),
],
0.,
to_percent_max,
Variable::named("RIGHT_BRAKE_PEDAL_INPUT"),
);

Ok(())
}

fn to_percent_max(accumulator: f64, item: f64) -> f64 {
max(accumulator, item * 100.)
}
Loading

0 comments on commit 4869482

Please sign in to comment.