#pragma once #include "FluidSim/AudioProcessing.hpp" #include "FluidSim/Crankcase.hpp" #include "FluidSim/Carburetor.hpp" #include "FluidSim/Fluid.hpp" #include "FluidSim/OutdoorAudio.hpp" #include "FluidSim/Ecu.hpp" #include "FluidSim/ReedValve.hpp" #include "FluidSim/MotorcycleTest.hpp" #include "FluidSim/Solver.hpp" #include "FluidSim/TwoStrokeCylinder.hpp" #include "FluidSim/TwoStrokeConfig.hpp" #include #include namespace fluidsim::port { struct TwoStrokeSnapshot { float rpm{}, cylinder_pressure{}, crankcase_pressure{}, intake_pressure{}; float throttle{}, transfer_area{}, exhaust_area{}; bool reed_open{}, fuel_cut{}, ignition_cut{}; float pedal{}; OutdoorScene audio_scene{OutdoorScene::Wall}; }; // Port of the C# 125 cc crankcase-scavenged two-stroke scenario. It retains // the plenum / reed / crankcase / transfer / cylinder / exhaust topology. class TwoStrokeScenario : public MotorcycleTest { public: void set_listener(AudioListener listener) { audio_.set_listener(listener); } explicit TwoStrokeScenario(int sample_rate = 44100, TwoStrokeConfig config = {}); AudioFrame process(); void set_throttle(float value); void set_controls(float pedal, float load_value, float clutch_value); void shift_up() { vehicle.shift_up(); } void shift_down() { vehicle.shift_down(); } void set_neutral() { vehicle.set_neutral(); } void set_pipe_solver(PipeSolver solver) { for(auto& pipe : pipes) pipe.solver=solver; } void set_audio_scene(OutdoorScene scene) { audio_.set_scene(scene); } void set_monitor_filter(bool enabled) { audio_.set_monitor_filter(enabled); } AudioFrame dry_audio() const { return audio_.dry_frame(); } AudioFrame unfiltered_audio() const { return audio_.unfiltered_frame(); } TwoStrokeSnapshot snapshot() const; float throttle{}; const TwoStrokeConfig configuration; Ecu ecu{}; Carburetor carburetor; ReedValve reed{}; float intake_flow{}, exhaust_flow{}; Crankshaft crankshaft{}; TwoStrokeCylinder cylinder; Crankcase crankcase; Volume0D intake_plenum{0.5e-3f, 101325.0f, 300.0f}; std::vector pipes; private: float dt_{}, max_throttle_area_{}; float reed_in_area_{}, reed_out_area_{}, transfer_pipe_area_{}, transfer_valve_area_{}, exhaust_valve_area_{}; bool reed_open_{}; std::uint64_t step_count_{}; Port* plenum_inlet_{}; Port* plenum_outlet_{}; BoundarySystem boundaries_; Solver solver_; OutdoorAudio audio_; static float area_for_diameter(float diameter); static float slide_area(float diameter, float opening); static std::vector create_pipes(const TwoStrokeConfig& config); }; } // namespace fluidsim::port