From 1ecd1769acf7b6c04d1e2c43c079b3f73ebbb5c0 Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Wed, 19 Oct 2022 23:01:41 -0400 Subject: [PATCH 1/8] Added display rotation for no reason in particular --- include/engine_sim_application.h | 1 + include/shaders.h | 3 ++- include/units.h | 1 - src/engine_sim_application.cpp | 17 +++++++++++++++-- src/gas_system.cpp | 5 ----- src/shaders.cpp | 8 ++++++-- 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/include/engine_sim_application.h b/include/engine_sim_application.h index e5d019ab..a81dad38 100644 --- a/include/engine_sim_application.h +++ b/include/engine_sim_application.h @@ -108,6 +108,7 @@ class EngineSimApplication { virtual void process(float dt); virtual void render(); + float m_displayAngle; float m_displayHeight; int m_gameWindowHeight; int m_screenWidth; diff --git a/include/shaders.h b/include/shaders.h index e737cb40..7b4445ea 100644 --- a/include/shaders.h +++ b/include/shaders.h @@ -31,7 +31,8 @@ class Shaders : public dbasic::ShaderBase { float height, const Bounds &cameraBounds, float screenWidth, - float screenHeight); + float screenHeight, + float angle = 0.0f); void CalculateUiCamera(float screenWidth, float screenHeight); void SetClearColor(const ysVector &col); diff --git a/include/units.h b/include/units.h index d513abcd..291e3caf 100644 --- a/include/units.h +++ b/include/units.h @@ -24,7 +24,6 @@ namespace units { extern constexpr double inch = cm * 2.54; extern constexpr double foot = inch * 12.0; extern constexpr double thou = inch / 1000.0; - extern constexpr double mile = m * 1609.344; // Time diff --git a/src/engine_sim_application.cpp b/src/engine_sim_application.cpp index c964f460..f83a1fcf 100644 --- a/src/engine_sim_application.cpp +++ b/src/engine_sim_application.cpp @@ -79,6 +79,8 @@ EngineSimApplication::EngineSimApplication() { m_screen = 0; m_viewParameters.Layer0 = 0; m_viewParameters.Layer1 = 0; + + m_displayAngle = 0.0f; } EngineSimApplication::~EngineSimApplication() { @@ -105,7 +107,7 @@ void EngineSimApplication::initialize(void *instance, ysContextObject::DeviceAPI m_engine.GetConsole()->SetDefaultFontDirectory(enginePath + "/fonts/"); const std::string shaderPath = enginePath + "/shaders/"; - std::string winTitle = "Engine Sim | AngeTheGreat | v" + s_buildVersion; + const std::string winTitle = "Engine Sim | AngeTheGreat | v" + s_buildVersion; dbasic::DeltaEngine::GameEngineSettings settings; settings.API = api; settings.DepthBuffer = false; @@ -216,6 +218,16 @@ void EngineSimApplication::process(float frame_dt) { speed = 1 / 1000.0; } + if (m_engine.IsKeyDown(ysKey::Code::F1)) { + m_displayAngle += frame_dt * 1.0f; + } + else if (m_engine.IsKeyDown(ysKey::Code::F2)) { + m_displayAngle -= frame_dt * 1.0f; + } + else if (m_engine.ProcessKeyDown(ysKey::Code::F3)) { + m_displayAngle = 0.0f; + } + m_simulator.setSimulationSpeed(speed); const double avgFramerate = clamp(m_engine.GetAverageFramerate(), 30.0f, 1000.0f); @@ -1015,7 +1027,8 @@ void EngineSimApplication::renderScene() { m_displayHeight / m_engineView->m_zoom, m_engineView->m_bounds, m_screenWidth, - m_screenHeight); + m_screenHeight, + m_displayAngle); m_geometryGenerator.reset(); diff --git a/src/gas_system.cpp b/src/gas_system.cpp index fd37df98..746f3743 100644 --- a/src/gas_system.cpp +++ b/src/gas_system.cpp @@ -278,10 +278,6 @@ void GasSystem::dissipateExcessVelocity() { m_state.E_k += 0.5 * mass() * (v_squared - c_squared); if (m_state.E_k < 0) m_state.E_k = 0; - - if (std::isnan(m_state.momentum[0]) || std::isnan(m_state.E_k)) { - int a = 0; - } } void GasSystem::updateVelocity(double dt, double beta) { @@ -402,7 +398,6 @@ double GasSystem::flow(const FlowParameters ¶ms) { const double maxFlow = source->pressureEquilibriumMaxFlow(sink); flow = clamp(flow, 0.0, 0.9 * source->n()); - //flow = clamp(flow, 0.0, maxFlow); const double fraction = flow / source->n(); const double fractionVolume = fraction * source->volume(); diff --git a/src/shaders.cpp b/src/shaders.cpp index 2eab38d9..07e7d86a 100644 --- a/src/shaders.cpp +++ b/src/shaders.cpp @@ -113,7 +113,8 @@ void Shaders::CalculateCamera( float height, const Bounds &cameraBounds, float screenWidth, - float screenHeight) + float screenHeight, + float angle) { const ysMatrix projection = ysMath::OrthographicProjection( width, @@ -140,9 +141,12 @@ void Shaders::CalculateCamera( m_screenVariables.Projection = ysMath::Transpose(projection); + const float sinAngle = std::sin(angle); + const float cosAngle = std::cos(angle); + const ysVector cameraEye = ysMath::Add( - ysMath::LoadVector(0.0f, 0.0f, 10.0f, 1.0f), + ysMath::LoadVector(10.0f * sinAngle, 0.0f, 10.0f * cosAngle, 1.0f), m_cameraPosition); const ysVector cameraTarget = ysMath::Add( From 4f7b915a24d02fde1ea0d49e67dec5420b20cc6a Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Thu, 20 Oct 2022 01:12:01 -0400 Subject: [PATCH 2/8] Added dyno min/max speed and hold step --- es/objects/objects.mr | 9 +++++++++ include/delay_filter.h | 2 +- include/engine.h | 27 ++++++++++++++++++--------- scripting/include/engine_node.h | 29 ++++++++++++++++------------- src/engine.cpp | 24 +++++++++++++++--------- src/engine_sim_application.cpp | 13 +++++++------ 6 files changed, 66 insertions(+), 38 deletions(-) diff --git a/es/objects/objects.mr b/es/objects/objects.mr index c6dade81..46c5211b 100644 --- a/es/objects/objects.mr +++ b/es/objects/objects.mr @@ -79,6 +79,9 @@ private node _engine => __engine_sim__engine { input redline [float]; input starter_speed [float]; input starter_torque [float]; + input dyno_min_speed [float]; + input dyno_max_speed [float]; + input dyno_hold_step [float]; input fuel [fuel]; input throttle [throttle_channel]; @@ -98,6 +101,9 @@ public node engine { input redline: params.redline; input starter_speed: params.starter_speed; input starter_torque: params.starter_torque; + input dyno_min_speed: 1000 * units.rpm; + input dyno_max_speed: redline; + input dyno_hold_step: 100 * units.rpm; input fuel: params.fuel; input throttle_gamma: 1.0; @@ -116,6 +122,9 @@ public node engine { redline: redline, starter_speed: starter_speed, starter_torque: starter_torque, + dyno_min_speed: dyno_min_speed, + dyno_max_speed: dyno_max_speed, + dyno_hold_step: dyno_hold_step, fuel: fuel, throttle: throttle, diff --git a/include/delay_filter.h b/include/delay_filter.h index 8101473e..805b1854 100644 --- a/include/delay_filter.h +++ b/include/delay_filter.h @@ -26,7 +26,7 @@ class DelayFilter : public Filter { } virtual float f(float sample) override { - return fast_f(static_cast(sample)); + return static_cast(fast_f(static_cast(sample))); } inline double fast_f(double sample) { diff --git a/include/engine.h b/include/engine.h index 88b29df9..559c5cac 100644 --- a/include/engine.h +++ b/include/engine.h @@ -20,17 +20,20 @@ class Engine : public Part { public: struct Parameters { - int CylinderBanks; - int CylinderCount; - int CrankshaftCount; - int ExhaustSystemCount; - int IntakeCount; + int cylinderBanks; + int cylinderCount; + int crankshaftCount; + int exhaustSystemCount; + int intakeCount; - std::string Name; + std::string name; - double StarterTorque = units::torque(90.0, units::ft_lb); - double StarterSpeed = units::rpm(200); - double Redline = units::rpm(6500); + double starterTorque = units::torque(90.0, units::ft_lb); + double starterSpeed = units::rpm(200); + double redline = units::rpm(6500); + double dynoMinSpeed = units::rpm(1000); + double dynoMaxSpeed = units::rpm(6500); + double dynoHoldStep = units::rpm(100); Throttle *throttle; @@ -74,6 +77,9 @@ class Engine : public Part { inline double getStarterTorque() const { return m_starterTorque; } inline double getStarterSpeed() const { return m_starterSpeed; } inline double getRedline() const { return m_redline; } + inline double getDynoMinSpeed() const { return m_dynoMinSpeed; } + inline double getDynoMaxSpeed() const { return m_dynoMaxSpeed; } + inline double getDynoHoldStep() const { return m_dynoHoldStep; } int getCylinderBankCount() const { return m_cylinderBankCount; } int getCylinderCount() const { return m_cylinderCount; } @@ -116,6 +122,9 @@ class Engine : public Part { double m_starterTorque; double m_starterSpeed; double m_redline; + double m_dynoMinSpeed; + double m_dynoMaxSpeed; + double m_dynoHoldStep; double m_initialSimulationFrequency; double m_initialHighFrequencyGain; diff --git a/scripting/include/engine_node.h b/scripting/include/engine_node.h index 21f43828..fa3b6fbf 100644 --- a/scripting/include/engine_node.h +++ b/scripting/include/engine_node.h @@ -42,11 +42,11 @@ namespace es_script { context.setEngine(engine); Engine::Parameters parameters = m_parameters; - parameters.CrankshaftCount = (int)m_crankshafts.size(); - parameters.CylinderBanks = (int)m_cylinderBanks.size(); - parameters.CylinderCount = cylinderCount; - parameters.ExhaustSystemCount = (int)exhaustSystems.size(); - parameters.IntakeCount = (int)intakes.size(); + parameters.crankshaftCount = (int)m_crankshafts.size(); + parameters.cylinderBanks = (int)m_cylinderBanks.size(); + parameters.cylinderCount = cylinderCount; + parameters.exhaustSystemCount = (int)exhaustSystems.size(); + parameters.intakeCount = (int)intakes.size(); parameters.throttle = m_throttle->generate(); engine->initialize(parameters); @@ -81,16 +81,16 @@ namespace es_script { } } - for (int i = 0; i < parameters.CrankshaftCount; ++i) { + for (int i = 0; i < parameters.crankshaftCount; ++i) { m_crankshafts[i]->generate(engine->getCrankshaft(i), &context); } - for (int i = 0; i < parameters.CylinderBanks; ++i) { + for (int i = 0; i < parameters.cylinderBanks; ++i) { m_cylinderBanks[i]->indexSlaveJournals(&context); } int cylinderIndex = 0; - for (int i = 0; i < parameters.CylinderBanks; ++i) { + for (int i = 0; i < parameters.cylinderBanks; ++i) { m_cylinderBanks[i]->generate( i, cylinderIndex, @@ -101,7 +101,7 @@ namespace es_script { cylinderIndex += m_cylinderBanks[i]->getCylinderCount(); } - for (int i = 0; i < parameters.CylinderBanks; ++i) { + for (int i = 0; i < parameters.cylinderBanks; ++i) { m_cylinderBanks[i]->connectRodAssemblies(&context); } @@ -151,10 +151,13 @@ namespace es_script { protected: virtual void registerInputs() { - addInput("name", &m_parameters.Name); - addInput("starter_torque", &m_parameters.StarterTorque); - addInput("starter_speed", &m_parameters.StarterSpeed); - addInput("redline", &m_parameters.Redline); + addInput("name", &m_parameters.name); + addInput("starter_torque", &m_parameters.starterTorque); + addInput("starter_speed", &m_parameters.starterSpeed); + addInput("dyno_min_speed", &m_parameters.dynoMinSpeed); + addInput("dyno_max_speed", &m_parameters.dynoMaxSpeed); + addInput("dyno_hold_step", &m_parameters.dynoHoldStep); + addInput("redline", &m_parameters.redline); addInput("fuel", &m_fuel, InputTarget::Type::Object); addInput("throttle", &m_throttle, InputTarget::Type::Object); addInput("simulation_frequency", &m_parameters.initialSimulationFrequency); diff --git a/src/engine.cpp b/src/engine.cpp index 2e9dd9e2..1914ba4c 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -28,6 +28,9 @@ Engine::Engine() { m_exhaustSystemCount = 0; m_starterSpeed = 0; m_starterTorque = 0; + m_dynoMinSpeed = 0; + m_dynoMaxSpeed = 0; + m_dynoHoldStep = 0; m_redline = 0; m_throttle = nullptr; @@ -51,15 +54,18 @@ Engine::~Engine() { } void Engine::initialize(const Parameters ¶ms) { - m_crankshaftCount = params.CrankshaftCount; - m_cylinderCount = params.CylinderCount; - m_cylinderBankCount = params.CylinderBanks; - m_exhaustSystemCount = params.ExhaustSystemCount; - m_intakeCount = params.IntakeCount; - m_starterTorque = params.StarterTorque; - m_starterSpeed = params.StarterSpeed; - m_redline = params.Redline; - m_name = params.Name; + m_crankshaftCount = params.crankshaftCount; + m_cylinderCount = params.cylinderCount; + m_cylinderBankCount = params.cylinderBanks; + m_exhaustSystemCount = params.exhaustSystemCount; + m_intakeCount = params.intakeCount; + m_starterTorque = params.starterTorque; + m_starterSpeed = params.starterSpeed; + m_dynoMinSpeed = params.dynoMinSpeed; + m_dynoMaxSpeed = params.dynoMaxSpeed; + m_dynoHoldStep = params.dynoHoldStep; + m_redline = params.redline; + m_name = params.name; m_throttle = params.throttle; m_initialHighFrequencyGain = params.initialHighFrequencyGain; m_initialSimulationFrequency = params.initialSimulationFrequency; diff --git a/src/engine_sim_application.cpp b/src/engine_sim_application.cpp index f83a1fcf..f9d3bb7e 100644 --- a/src/engine_sim_application.cpp +++ b/src/engine_sim_application.cpp @@ -760,15 +760,15 @@ void EngineSimApplication::processEngineInput() { } else if (m_engine.IsKeyDown(ysKey::Code::G) && m_simulator.m_dyno.m_hold) { if (mouseWheelDelta > 0) { - m_dynoSpeed += units::rpm(100.0); + m_dynoSpeed += m_iceEngine->getDynoHoldStep(); } else if (mouseWheelDelta < 0) { - m_dynoSpeed -= units::rpm(100.0); + m_dynoSpeed -= m_iceEngine->getDynoHoldStep(); } - m_dynoSpeed = clamp(m_dynoSpeed, units::rpm(0), DBL_MAX); + m_dynoSpeed = clamp(m_dynoSpeed, m_iceEngine->getDynoMinSpeed(), m_iceEngine->getDynoMaxSpeed()); - m_infoCluster->setLogMessage("[G] - Set dyno speed to " + std::to_string(m_dynoSpeed)); + m_infoCluster->setLogMessage("[G] - Set dyno speed to " + std::to_string(units::toRpm(m_dynoSpeed))); fineControlInUse = true; } @@ -840,7 +840,7 @@ void EngineSimApplication::processEngineInput() { m_dynoSpeed *= (1 / (1 + dt)); } - if ((m_dynoSpeed + units::rpm(1000)) > m_iceEngine->getRedline()) { + if (m_dynoSpeed > m_iceEngine->getRedline()) { m_simulator.m_dyno.m_enabled = false; m_dynoSpeed = units::rpm(0); } @@ -852,7 +852,8 @@ void EngineSimApplication::processEngineInput() { } } - m_simulator.m_dyno.m_rotationSpeed = m_dynoSpeed + units::rpm(1000); + m_dynoSpeed = clamp(m_dynoSpeed, m_iceEngine->getDynoMinSpeed(), m_iceEngine->getDynoMaxSpeed()); + m_simulator.m_dyno.m_rotationSpeed = m_dynoSpeed; const bool prevStarterEnabled = m_simulator.m_starterMotor.m_enabled; if (m_engine.IsKeyDown(ysKey::Code::S)) { From 0ec734c8178a03b47a163ddb70c966eb77fd27bd Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Thu, 20 Oct 2022 01:12:31 -0400 Subject: [PATCH 3/8] Bump version --- src/engine_sim_application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine_sim_application.cpp b/src/engine_sim_application.cpp index f9d3bb7e..3f679cfa 100644 --- a/src/engine_sim_application.cpp +++ b/src/engine_sim_application.cpp @@ -24,7 +24,7 @@ #include "../discord/Discord.h" #endif -std::string EngineSimApplication::s_buildVersion = "0.1.11a"; +std::string EngineSimApplication::s_buildVersion = "0.1.12a"; EngineSimApplication::EngineSimApplication() { m_assetPath = ""; From 5be5fd47fbb334a938356ed9cbb229754ec2ec8d Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Thu, 20 Oct 2022 01:43:40 -0400 Subject: [PATCH 4/8] Updated Patron list --- README.md | 219 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 114 insertions(+), 105 deletions(-) diff --git a/README.md b/README.md index 46e00c4b..962b2980 100644 --- a/README.md +++ b/README.md @@ -89,55 +89,61 @@ This project was made possible by the generous donations of the following indivi |||||| |-|-|-|-|-| -|Devin@Hondatuningsuite|nut|Devin C Martinez|WelcomeCat|Ida 8858| -|Emily|Steelorse |Kruddy|Sgt. Fluff|darcuter| -|FatFluffyFox|Benton1234|Jim C K Flaten|The Zuck|Blade Skydancer| -|Ye' old apple|Hayden Henderson|AlphaX|Lucas Martins Bündchen|Jay Dog| -|Shaqalito|damo|IBS-IS-CRAP|Snowy|Noah Greenberg| -|Eisberg|Brendan M.|Kevin Nowald|poklijn|Alex Layton| -|Lukas Bartee|Thibaut Dubuisson|The Cheeze Ity|JoeJimTom|MichaelB450| -|Björn|Bartdavy|sasha bandelier|Caleb Black|COOKIES| -|Andrew Cooper|asimo3089|Vim Wizard|Kevin Arsenault|Carl Linden| -|Kele Tappi|Kroklethon|Blobby McBlob|labourateur|viperfan7| -|SlimmyJimmy|Jason Becker|malek george haddad|Sascha Kamp|ves| -|Supernalboot |BeamNG|Paul Harrison|Tyler Russell (Nytelife26)|nicholas jacobs| -|DrDotMadness|AVeryPlainTyler|Zach Perez|Paul Schaefer|Clay Bauer| -|CR33DYM0N14|julien nadeau|Patt313|Philip Edwards|rotary media| -|James L Plummer|RegularRuby670|Mateusz Ładosz|FémLol Stúdió|Crazy Yany| -|Elden|Tristan Walker|Matthew McDonald|Jan-Sander Huiting|Mitchell Almstedt| -|Dylan Lebiedz|Name Here|LoganBoi FNAF|Epic Randomness|cole newcomb| -|MrPiThon|mike |dung|Alvaro ArroyoZamora|vincie.net| -|Skinna Godwin||||| +|Devin@Hondatuningsuite|nut|Devin C Martinez|WelcomeCat|Saints Sasha| +|Ida 8858|Emily|Steelorse |Kruddy|Sgt. Fluff| +|darcuter|FatFluffyFox|Benton1234|Jim C K Flaten|The Zuck| +|Blade Skydancer|Ye' old apple|Hayden Henderson|AlphaX|Lucas Martins Bündchen| +|Jay Dog|damo|IBS-IS-CRAP|Snowy|Noah Greenberg| +|Eisberg|Brendan M.|Alex Layton|Lukas Bartee|Thibaut Dubuisson| +|The Cheeze Ity|JoeJimTom|MichaelB450|Björn|Bartdavy| +|sasha bandelier|Caleb Black|COOKIES|Andrew Cooper|asimo3089| +|Vim Wizard|Kevin Arsenault|Carl Linden|Kele Tappi|Kroklethon| +|labourateur|viperfan7|SlimmyJimmy|Jason Becker|Sascha Kamp| +|ves|Supernalboot |BeamNG|Paul Harrison|Tyler Russell (Nytelife26)| +|nicholas jacobs|DrDotMadness|AVeryPlainTyler|Zach Perez|Paul Schaefer| +|Clay Bauer|CR33DYM0N14|julien nadeau|Patt313|Philip Edwards| +|RegularRuby670|Mateusz Ładosz|FémLol Stúdió|Crazy Yany|Elden| +|Tristan Walker|Matthew McDonald|Jan-Sander Huiting|Mitchell Almstedt|Dylan Lebiedz| +|Name Here|LoganBoi FNAF|Epic Randomness|MrPiThon|mike | +|dung|Alvaro ArroyoZamora|Skinna Godwin|BeppoBarone|レナVA| +|Sabata |Brady Fulham|Powerpuncher |NK10K|Gavin Osowski| +|Orbitstrider|Steven Doyle|Jaksu2696|Toni |Devin Abolins| ### Tuners |||||| |-|-|-|-|-| |Boosted Media|Matthew McLennan|Venican|Lyan le Golmuth|Alberto R.| |BetaToaster|Akira Takemoto|J Anderson|Apolly007|LexLuther| -|Saints Sasha|xilophor|Robert K|viktor lind|Adrian Kucinski| -|sarowie .|Chris Fischer|Marlod|Chase Hansen|Aidan Szalanski| -|Andrew Taylor|Jason Hwang|Juuso Natunen|MoonOperator|Ian Moss| -|PickleRick |Beljim46|RSOFT92|UCD|Sped| -|OldManJenkins|James Hart|Kalle Nilsson|XxBrasta455xX |Colin Sandage| -|Dakota Mackinnon|Carter Kopp|george |Jakub Kozak|CJ Plessas| -|Loizeau|Charles Mills|YellowLight|Didrik Esbjug|Alessandro Dal Pino| -|Carter Williams|Robert D|Cadence Plume|zach kettering|BLANK| -|Provenance EMU|rommi5000|Dylan Engler|Nathan Rojas|Cornelius| +|xilophor|Robert K|viktor lind|Adrian Kucinski|sarowie .| +|Chris Fischer|Marlod|Chase Hansen|Aidan Szalanski|Andrew Taylor| +|Jason Hwang|Juuso Natunen|Ian Moss|PickleRick |Beljim46| +|RSOFT92|UCD|Sped|OldManJenkins|James Hart| +|Kalle Nilsson|XxBrasta455xX |Colin Sandage|Dakota Mackinnon|Carter Kopp| +|Jakub Kozak|CJ Plessas|Loizeau|Charles Mills|YellowLight| +|Didrik Esbjug|Alessandro Dal Pino|Carter Williams|Robert D|Cadence Plume| +|BLANK|Provenance EMU|Dylan Engler|Nathan Rojas|Cornelius| |Acid|larsloveslegos|Maxime Desages|GM|BreadForMen| |Devin Freeman|Lieven RYCKEBOER|Amelia Taylor|Jelle Plukker|sodmo | -|Maurice Matos|Jimmy Briscoe|Cirithor|Martin .K|DMartland| -|Lucas Diem|Richard Budíček|Jack Sheppeard|Meemen|Anderson Huynh| -|NPException|Mattia Villa|Austin King|C|AIDAN POWELL| -|Brenn_the_Otter|Lane Mosier|Ceze |oranjest1|POPA ALBERT| -|Jw|ISON |Mathew Graham|John Crowell|Asher Blythe| -|Joe Worm|Kuiper|Cronos Skies|Matt Amott|Simon Krayer| -|József Gulyás|Caleb Bek|Monster Man25|GeneralMoineau|EsuKurimu| -|Caleb Sartin|JoshuaTheGreat |Prono_Wolfie|Jared L.|Hunter Wood| -|Ben Poole|Steven Victoria|Jordan Zondlak|Agelessgod|Christopher Fahs| -|Jonathan Vincent|Dalton Guillot|Simon Stojanovic|Andrew Urbanczyk|Daniel| -|vPam |Justin Kruithof|Zavier Studios|Curtis C Coomber|Sawyer Clark| -|Mike Hart|Ciro Rancourt|Miles Guo|Michael Lesslie`|Rewind | -|E=mc^2|Keaton Call|1|Jeremy B|Chance Hall| +|Jimmy Briscoe|Cirithor|Martin .K|DMartland|Lucas Diem| +|Richard Budíček|Jack Sheppeard|Meemen|Anderson Huynh|NPException| +|Mattia Villa|C|AIDAN POWELL|Brenn_the_Otter|Lane Mosier| +|Ceze |oranjest1|Jw|ISON |Mathew Graham| +|MACHINA|John Crowell|Asher Blythe|Cronos Skies|Matt Amott| +|CpTKugelHagel|Simon Krayer|Caleb Bek|Monster Man25|GeneralMoineau| +|EsuKurimu|Caleb Sartin|Jared L.|Hunter Wood|Ben Poole| +|Steven Victoria|Jordan Zondlak|Agelessgod|Christopher Fahs|Jonathan Vincent| +|Dalton Guillot|Simon Stojanovic|Andrew Urbanczyk|deniaL|Tyler Hughes| +|vPam |Justin Kruithof|Curtis C Coomber|Sawyer Clark|Mike Hart| +|Ciro Rancourt|Miles Guo|Rewind |E=mc^2|Keaton Call| +|J.Es|Jeremy B|Chance Hall|Jack Tompkins|Race Sim Studio| +|Quentin ZAOUI|Floyd Henderson|James Haylow|Milkshiekh |Wyatt Todd| +|User 2820|Leon Schutte|CYBERBUG_JR|sebiii|Keegan| +|Victor Cosiuga|Rolly !|Elias Pettersson|Tyson Makovec|Bill McDermott| +|Phontonic|Simon Armstrong|avec |KidozyGAME (Dead)|Stephan Cote| +|Justin Biggerstaff|Jabba Jubba|notD34THNIGHT|Inventor|Wesley Bear| +|Supersonic2510|Pixel|Simon Bernhardt|Bas Vangermeersch|ToyotaCipra| +|kyle crawford|ApatheticWood|Ben Vaughn|Erich Westhoven|Zack Myers| +|Tbjoern|Vetle Høgås|Derek Thom|Aaron Beck|| ### Junior Mechanics |||||| @@ -147,79 +153,82 @@ This project was made possible by the generous donations of the following indivi |Marius Becker|Cedric Wille|infernap12 |Julian Dinges|Wamuthas| |Alex Mason|Hawar Karem|Melonenstrauch|Jacek Dębski|Alex Eastman| |Darren Taing|Po Wang|Giorgio Iannucci|Levis|Eden| -|Alin Chiparatu|Arjun Mandakath|A.M. |BrickTheBassist|Dylan Ryan| -|Noah Entrekin|Josh D|generic|Henrik Cohrs|Nic Yetter| +|Alin Chiparatu|Arjun Mandakath|A.M. |Dylan Ryan|Noah Entrekin| +|GT130|Josh D|generic|Henrik Cohrs|Nic Yetter| |Dan Fredriksen|153AN1MJ|Rasmus|EpicEcho|Kaur Hendrikson| |Maddox Partridge|L33TIFY_|Zack Fletcher|teiiio|Mike Zaite| |Evan Sonin|Christopher Zimmerman|PrefacedVase |funtomr|Triton Alabaster| -|appelpie|Samuel Plante|Julien Ferluc|AnomalousFerret_|Miles Orozco| -|Spencer Teeter|ThatCanadian|Harry Prabowo|Dylan Rogerson|Jaedyn Allen| -|Zephyr Sefira|Alexander Stone|Mason Little|Wojciech Czop|ryzen5 | -|Kosta Diamantis|Karol Stodolak|Tim van der Linde|Loïc Ruttner|jonthefuzz| -|AsgarK|James Morgan|Elijah |1ntl|Tobias Johansson| -|Mome |P|SOPA_|Shingekuro|Sean King| -|REMI VIGOUROUX|Russell Marsh|Alyx Ranas|Naters305 |ChrisakaMrXD | -|Nic |BeaminYo|sean|Zach Hagedorn|Jhon lenon| -|Everett Butts|Kyan|ranger Nation|Hiago Oliveira|Texi| -|MrRhody|cat|Inglorious Bastard|Marty Mitchell|Justin Chao| -|ManuelS|Cornelius Rössing|Michał Szyszkowski|Pedro Freire|Anthony Stuart| +|appelpie|Julien Ferluc|AnomalousFerret_|Miles Orozco|Spencer Teeter| +|ThatCanadian|Harry Prabowo|Dylan Rogerson|Jaedyn Allen|Zephyr Sefira| +|Alexander Stone|Mason Little|Wojciech Czop|ryzen5 |Kosta Diamantis| +|Karol Stodolak|Tim van der Linde|Loïc Ruttner|jonthefuzz|AsgarK| +|James Morgan|Elijah |1ntl|Tobias Johansson|Mome | +|P|SOPA_|Shingekuro|Sean King|Russell Marsh| +|Alyx Ranas|Naters305 |ChrisakaMrXD |Nic |sean| +|Zach Hagedorn|Jhon lenon|Everett Butts|Kyan|ranger Nation| +|Hiago Oliveira|Texi|MrRhody|Inglorious Bastard|Marty Mitchell| +|Justin Chao|ManuelS|Cornelius Rössing|Pedro Freire|Anthony Stuart| |Hubba Nubba|Skychii|Joe Underwood|Xander_|Notbigdank| |Sander D.|Lars Joosten|Danksa|Metrostation |Myles Wommack| |Derrick Sampson|Corey Hannen|Matteo La Corte|Octothorp Obelus|David Baril| -|Antonino Arenas|Soyuz Kafire|Ivan Coha|BigElbowski|Apolepth| -|Julian Krad|David Soulieres|Eric Huang|Léo Vias|Riccardo Mariani| -|Vic Viper|Shinkaaaa|Mumaransa |Michael Banovsky|Hendrik Voss| -|Inverted Blackhat|Rafael Morais|Sandu Denis|skipyC |Tobias Moor| -|jaky3 .|Clément LEGRAND|Ian C. Simpson|Challier|Jan Przemysław Drabik| -|Dsand23|Tim Doherty|Smooth DLX|The German Dude|CrazyEagle | -|Jordon Goodman|HenryWithaG .|Oscar Krula|Brayden Moore|Steven| -|Nall Wolfert|papajonk|Andrew|Ben Kingston|Julian Vogl| -|Maxime Lubrano|foxy foxfoxy|zero3growlithe |MrMekouil|Doudimme| -|Elliott Towlson|Jacob Hultberg|Nolan Orloff|Mike|tobi9899 | -|Eda Misař|Danila Frolkin|Xecotcovach|Jumbobaco|Rastus| +|Soyuz Kafire|Ivan Coha|BigElbowski|Apolepth|Julian Krad| +|David Soulieres|Eric Huang|Léo Vias|Riccardo Mariani|Vic Viper| +|Shinkaaaa|Mumaransa |Michael Banovsky|Hendrik Voss|Inverted Blackhat| +|skipyC |Tobias Moor|jaky3 .|Clément LEGRAND|Ian C. Simpson| +|Challier|Jan Przemysław Drabik|Dsand23|Smooth DLX|The German Dude| +|CrazyEagle |Jordon Goodman|HenryWithaG .|Oscar Krula|Brayden Moore| +|Steven|Nall Wolfert|papajonk|Andrew|Ben Kingston| +|Julian Vogl|Maxime Lubrano|MrMekouil|Doudimme|Jacob Hultberg| +|Nolan Orloff|Mike|tobi9899 |Danila Frolkin|Xecotcovach| |Aj|Carcar404|John Martin|Dominik Greinert|Lukas Stadler| |Oliver Yang|sonax51|Marcel Kliment|Chris|David Rush| -|LethalVenom13|Dave Osterhoff|JC Estacio|Anto1709|Ben| -|Morgan Munroe|Ivor Forrest|Hayden Nance|Sam Hopkins|Mr. Chilz Live| -|Atte |Dax |William Bergström|homelessmeme|Thanleft| -|Zaxerg |Robeloox|Maximilian-Lukas Marz|Morgn|Seth Monteleone| -|playfulmean videos|Lanimations LA|Bram G|Benoit Fournier|Nexorio| -|Bernar Lepiller|Nicolas Baur|the |Snekers|Darkmount| -|HITMAN|Tobiasz Michalik|Aidas Ri|Daniel Postler|Skim_Beeblez| -|PurpleToaster|Impetus|Thunderbird324|Fred Joss|Krzysztof Radowski| -|Azerrty|Harrison Speck|Matt Baker|BigLynch|Markus Pelto| -|Duke Boreham|IMBIBE|MACHINA|Rose Giles|Jonas Brekka| -|HASTRX|Lepoucehumain|Az |Bluetn |Naomi Humin| -|qkrrudgks|Lociel|Johann Gross|Janis Knappich|WhatTheDuck| +|LethalVenom13|Dave Osterhoff|Anto1709|Ben|Morgan Munroe| +|Ivor Forrest|Sam Hopkins|Atte |Dax |William Bergström| +|homelessmeme|Thanleft|Zaxerg |Robeloox|Maximilian-Lukas Marz| +|Morgn|Seth Monteleone|playfulmean videos|Lanimations LA|Bram G| +|Benoit Fournier|Bernar Lepiller|Nicolas Baur|the |Snekers| +|Darkmount|Tobiasz Michalik|Aidas Ri|Daniel Postler|Skim_Beeblez| +|Impetus|Thunderbird324|Fred Joss|Krzysztof Radowski|Azerrty| +|Harrison Speck|Matt Baker|BigLynch|Markus Pelto|IMBIBE| +|James L Plummer|Rose Giles|Jonas Brekka|HASTRX|Lepoucehumain| +|Naomi Humin|qkrrudgks|Johann Gross|Janis Knappich|WhatTheDuck| |테루|Glimple Bort|Jacob Tudisco|Tanner|Julian kaspi| -|nathan gould|Mr nobody|Randal Rainis Kruus|Beppierre|Brennan Huff| -|CpTKugelHagel|mix gaming|Craig Martin|Thomas Bukovsky|Colaxe| -|Robert Oram|Matsuy15 L|Aleksander Dzwonkowski|Kacpe|Alex Sedlic| +|nathan gould|Randal Rainis Kruus|Beppierre|Craig Martin|Thomas Bukovsky| +|Colaxe|Robert Oram|Matsuy15 L|Kacpe|Alex Sedlic| |Mark Benson|Mhenn!|Anders Nelson|Dingus|Rustle| |Marco Schulz|stratum |brochier gabriel|Thomas|brody of hillcountry| -|cree|Thomas Afford|Brody Blaskie|Martien Gaming|Adrien MC| -|William A Grubbs|Trevo Ph.D.|Donovan Gibson|Polish R3t4rd|Keith Price| -|LAWL CAKE|Rhien Schultz|Cody Cox|FireThrow13|Landon Barnes| -|Seraphim|Titus Standing|Matt Miklos|Sean Ramey|B Dub| -|Jonathan Ekman|Al Pomeroy|Vestii|Wil|adrian| -|Airatise|night the wolf|TJ Sinkoski|Shotts SilverStone|Reagan Carbaugh| -|Jayden Turner|WarAestheticsRebooted|Aidan Case|Casey Bryant Goodwin|Konrad| -|Stephanie Summers|Bananensmoothie 56|Adam Larcher|Kazar Xin Xiao|Riccardo Marcaccio| -|William S.|Francis Filion|Loïc |Kenny Deane|Blackspots| -|mike |MXT|Joshua Gibson|milky boi|Hagen| -|gunmaster929 |jgvan |Benny 282|Sean Wehner|Christian Poole| -|Ethan|josh|Tsukiyama Shuu|Ooof_uhhh_haah|sano ken ch| -|Diego Martinez|Chuck|GalaxyFrogs|Danial Thomas Cairns|Leaked Night| -|Sivear|Marco Hernandez|Bacon baconbacon|TheGeForce |Leander Mengel| -|Tripplex2112 Sub plz|Chriphost|Carthage|Greg L|Chipskate| -|Muhammed Mehmood|Hamilton Sjoberg|Amina Moh|vSiiFT|Jeremy Wren| -|Esteban Acosta|John A Ullenberg|Michael Morozov|Andrew Webberley|Nathaniel Lim| -|Aaron Ksicinski|Apocalypt|Josh batuzich|Ed|Tyler Hughes| -|Hunter |Gene Brockoff|Redheadspellslinger.|Pablo Magariños|Nilz| -|Jose Manuel Silva Calvo|AJ|Ethan Wille |Aurora|DILLY| -|Derek Shunia|Jan|Crimcy Productions|Nope Mircea|Giancarlo Cestari| -|Tanner Edge|brad.|Connor Merrick|Zurpy Dood|Martin Scholer| +|Thomas Afford|Brody Blaskie|Martien Gaming|Adrien MC|William A Grubbs| +|Trevo Ph.D.|Donovan Gibson|Polish R3t4rd|Keith Price|LAWL CAKE| +|Rhien Schultz|FireThrow13|Seraphim|Titus Standing|Matt Miklos| +|B Dub|Jonathan Ekman|Al Pomeroy|Vestii|Wil| +|adrian|Airatise|TJ Sinkoski|Shotts SilverStone|Reagan Carbaugh| +|WarAestheticsRebooted|Aidan Case|Casey Bryant Goodwin|Konrad|Adam Larcher| +|Kazar Xin Xiao|Riccardo Marcaccio|William S.|Francis Filion|Loïc | +|Kenny Deane|Blackspots|mike |MXT|Joshua Gibson| +|milky boi|Hagen|gunmaster929 |jgvan |Benny 282| +|Sean Wehner|Christian Poole|Ethan|Tsukiyama Shuu|Ooof_uhhh_haah| +|sano ken ch|Diego Martinez|Chuck|GalaxyFrogs|TheGeForce | +|Chriphost|Carthage|Greg L|Chipskate|Muhammed Mehmood| +|Hamilton Sjoberg|Amina Moh|vSiiFT|Jeremy Wren|Esteban Acosta| +|John A Ullenberg|Michael Morozov|Andrew Webberley|Nathaniel Lim|Aaron Ksicinski| +|Apocalypt|Josh batuzich|Ed|Hunter |Gene Brockoff| +|Redheadspellslinger.|Pablo Magariños|Nilz|Jose Manuel Silva Calvo|AJ| +|Ethan Wille |Aurora|Derek Shunia|Jan|Nope Mircea| +|Giancarlo Cestari|Tanner Edge|brad.|Connor Merrick|Martin Scholer| |Deppy|Dan Smith|Tyson |Jac Comeau|Itemfinder | -|Tischer Games|Pedro Henrique|Jonathon Owens|BeenWashedUp|martin wolff| -|Kurt Houben||||| - +|Tischer Games|Pedro Henrique|BeenWashedUp|martin wolff|Kurt Houben| +|Thomas Onslow|Brendan Puglisi|Kai Anquetil|Rudolph Ignatenko|CloudHackIX| +|Zach Carreau|Jonathan Vanderlyn|Krobivnov|ienergy|Leifster| +|Mikael Kaaronen|Glen|H.Helsing|ange|The Nobles| +|Johnathan Johnson|Juha Merentie|Jim Fares|Tom Marshall|Superferrariman| +|Zakary Zisa|JustTy|晟道 杜|Dnialibr Williams|Takumi Fujiwara| +|Koen van Hal|Jonathan Hill|Marco Siciliano|Kevindosenfutter|Angry Prawn| +|Natharic 67|Rafael Monteiro|Jacob Ashline|ChironTheFloof|Caleb Dauphinee| +|Tony |Zac L|AlainMoto FPV|eirik johan johnsen|Elderet| +|Miles Longmore|lemon head|Viccy|Casey|Kajetan Cupa| +|Conejero00|Bill Gricko|A cow wearing a turban|Danni Nowicki|Udo Schmidt| +|Tyler Swords|Constellation Gaming|Manimo|valentine|Jules Schattenberg| +|Brandon Crotts|Philipp Popetschnigg|Tiziano Della Fazia|goodgamer1109|Joshua Thomas| +|Jeff Testa|Avery Snyder|Josh Kern|Triptagram|Bayon Antoine| +|Iván Juárez Núñez|Amery Martinat|ElArGee|Cory Green|lucas Di lorenzo| +|Caleb Sandersier||||| From 0c901ed9660f4b7fea3e62c81a0532c44d8a3fc3 Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Sun, 20 Nov 2022 18:50:21 -0500 Subject: [PATCH 5/8] Refactored simulator to support non-piston engines for no reason in particular --- CMakeLists.txt | 2 + assets/main.mr | 2 +- include/camshaft.h | 10 +- include/connecting_rod.h | 20 +- include/crankshaft.h | 18 +- include/engine.h | 5 + include/engine_sim_application.h | 4 +- include/fuel.h | 22 +- include/ignition_module.h | 16 +- include/intake.h | 2 +- include/piston.h | 2 +- include/piston_engine_simulator.h | 73 +++ include/simulation_object.h | 3 +- include/simulator.h | 161 +++--- include/standard_valvetrain.h | 4 +- include/synthesizer.h | 46 +- include/vtec_valvetrain.h | 18 +- scripting/include/camshaft_node.h | 14 +- scripting/include/connecting_rod_node.h | 26 +- scripting/include/crankshaft_node.h | 22 +- scripting/include/fuel_node.h | 22 +- scripting/include/ignition_module_node.h | 12 +- scripting/include/intake_node.h | 2 +- scripting/include/piston_node.h | 2 +- scripting/include/standard_valvetrain_node.h | 4 +- scripting/include/vtec_valvetrain_node.h | 26 +- src/camshaft.cpp | 16 +- src/connecting_rod.cpp | 22 +- src/crankshaft.cpp | 18 +- src/engine.cpp | 14 +- src/engine_sim_application.cpp | 157 +++--- src/fuel.cpp | 20 +- src/ignition_module.cpp | 24 +- src/intake.cpp | 4 +- src/mixer_cluster.cpp | 14 +- src/piston.cpp | 2 +- src/piston_engine_simulator.cpp | 413 ++++++++++++++++ src/simulation_object.cpp | 5 +- src/simulator.cpp | 488 +++---------------- src/standard_valvetrain.cpp | 4 +- src/synthesizer.cpp | 96 ++-- src/vtec_valvetrain.cpp | 18 +- test/synthesizer_tests.cpp | 40 +- 43 files changed, 1007 insertions(+), 886 deletions(-) create mode 100644 include/piston_engine_simulator.h create mode 100644 src/piston_engine_simulator.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index faa5a0bf..9421ab42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ add_library(engine-sim STATIC src/low_pass_filter.cpp src/part.cpp src/piston.cpp + src/piston_engine_simulator.cpp src/simulator.cpp src/standard_valvetrain.cpp src/starter_motor.cpp @@ -118,6 +119,7 @@ add_library(engine-sim STATIC include/low_pass_filter.h include/part.h include/piston.h + include/piston_engine_simulator.h include/simulator.h include/standard_valvetrain.h include/starter_motor.h diff --git a/assets/main.mr b/assets/main.mr index 0dc7be4d..c792d27c 100644 --- a/assets/main.mr +++ b/assets/main.mr @@ -1,6 +1,6 @@ import "engine_sim.mr" import "themes/default.mr" -import "engines/atg-video-2/01_subaru_ej25_eh.mr" +import "C:\\Users\\ange_\\Downloads\\Nissan L28E.mr" use_default_theme() main() diff --git a/include/camshaft.h b/include/camshaft.h index 73e0ed95..7acd90cb 100644 --- a/include/camshaft.h +++ b/include/camshaft.h @@ -11,19 +11,19 @@ class Camshaft : public Part { public: struct Parameters { // Number of lobes - int Lobes; + int lobes; // Camshaft advance in camshaft degrees - double Advance = 0; + double advance = 0; // Corresponding crankshaft - Crankshaft *Crankshaft; + Crankshaft *crankshaft; // Lobe profile - Function *LobeProfile; + Function *lobeProfile; // Base radius - double BaseRadius = units::distance(600, units::thou); + double baseRadius = units::distance(600, units::thou); }; public: diff --git a/include/connecting_rod.h b/include/connecting_rod.h index 50390099..9e26c3c7 100644 --- a/include/connecting_rod.h +++ b/include/connecting_rod.h @@ -9,19 +9,19 @@ class Piston; class ConnectingRod : public Part { public: struct Parameters { - double Mass = 0.0; - double MomentOfInertia = 0.0; - double CenterOfMass = 0.0; - double Length = 0.0; + double mass = 0.0; + double momentOfInertia = 0.0; + double centerOfMass = 0.0; + double length = 0.0; - int RodJournals = 0; - double SlaveThrow = 0; + int rodJournals = 0; + double slaveThrow = 0; - Piston *Piston = nullptr; + Piston *piston = nullptr; - Crankshaft *Crankshaft = nullptr; - ConnectingRod *Master = nullptr; - int Journal = 0; + Crankshaft *crankshaft = nullptr; + ConnectingRod *master = nullptr; + int journal = 0; }; public: diff --git a/include/crankshaft.h b/include/crankshaft.h index 8e8db3fe..fe99e02a 100644 --- a/include/crankshaft.h +++ b/include/crankshaft.h @@ -6,15 +6,15 @@ class Crankshaft : public Part { public: struct Parameters { - double Mass; - double FlywheelMass; - double MomentOfInertia; - double CrankThrow; - double Pos_x = 0; - double Pos_y = 0; - double TDC = 0; - double FrictionTorque = 0; - int RodJournals; + double mass; + double flywheelMass; + double momentOfInertia; + double crankThrow; + double pos_x = 0; + double pos_y = 0; + double tdc = 0; + double frictionTorque = 0; + int rodJournals; }; public: diff --git a/include/engine.h b/include/engine.h index 559c5cac..ef18ac7d 100644 --- a/include/engine.h +++ b/include/engine.h @@ -17,6 +17,9 @@ #include +class Simulator; +class Vehicle; +class Transmission; class Engine : public Part { public: struct Parameters { @@ -104,6 +107,8 @@ class Engine : public Part { double getInitialNoise() const { return m_initialNoise; } double getInitialJitter() const { return m_initialJitter; } + virtual Simulator *createSimulator(Vehicle *vehicle, Transmission *transmission); + protected: std::string m_name; diff --git a/include/engine_sim_application.h b/include/engine_sim_application.h index a81dad38..d7462cd5 100644 --- a/include/engine_sim_application.h +++ b/include/engine_sim_application.h @@ -84,7 +84,7 @@ class EngineSimApplication { int getScreenWidth() const { return m_screenWidth; } int getScreenHeight() const { return m_screenHeight; } - Simulator *getSimulator() { return &m_simulator; } + Simulator *getSimulator() { return m_simulator; } InfoCluster *getInfoCluster() { return m_infoCluster; } ApplicationSettings* getAppSettings() { return &m_applicationSettings; } @@ -134,7 +134,7 @@ class EngineSimApplication { Engine *m_iceEngine; Vehicle *m_vehicle; Transmission *m_transmission; - Simulator m_simulator; + Simulator *m_simulator; double m_dynoSpeed; double m_torque; diff --git a/include/fuel.h b/include/fuel.h index 0dfe3d04..4addf76a 100644 --- a/include/fuel.h +++ b/include/fuel.h @@ -10,20 +10,20 @@ class Fuel { public: struct Parameters { - std::string Name = "Gasoline"; - double MolecularMass = + std::string name = "Gasoline"; + double molecularMass = units::mass(100.0, units::g); - double EnergyDensity = + double energyDensity = units::energy(48.1, units::kJ) / units::mass(1.0, units::g); - double Density = + double density = units::mass(0.755, units::kg) / units::volume(1.0, units::L); - double MolecularAfr = 25 / 2.0; - double BurningEfficiencyRandomness = 0.5; - double LowEfficiencyAttenuation = 0.6; - double MaxBurningEfficiency = 0.8; - double MaxTurbulenceEffect = 2.0; - double MaxDilutionEffect = 50.0; - Function *TurbulenceToFlameSpeedRatio = nullptr; + double molecularAfr = 25 / 2.0; + double burningEfficiencyRandomness = 0.5; + double lowEfficiencyAttenuation = 0.6; + double maxBurningEfficiency = 0.8; + double maxTurbulenceEffect = 2.0; + double maxDilutionEffect = 50.0; + Function *turbulenceToFlameSpeedRatio = nullptr; }; Fuel(); diff --git a/include/ignition_module.h b/include/ignition_module.h index 7647262f..7fa7df96 100644 --- a/include/ignition_module.h +++ b/include/ignition_module.h @@ -10,17 +10,17 @@ class IgnitionModule : public Part { public: struct Parameters { - int CylinderCount; - Crankshaft *Crankshaft; - Function *TimingCurve; - double RevLimit = units::rpm(6000.0); - double LimiterDuration = 0.5 * units::sec; + int cylinderCount; + Crankshaft *crankshaft; + Function *timingCurve; + double revLimit = units::rpm(6000.0); + double limiterDuration = 0.5 * units::sec; }; struct SparkPlug { - double Angle = 0; - bool IgnitionEvent = false; - bool Enabled = false; + double angle = 0; + bool ignitionEvent = false; + bool enabled = false; }; public: diff --git a/include/intake.h b/include/intake.h index 4555a116..1646faac 100644 --- a/include/intake.h +++ b/include/intake.h @@ -9,7 +9,7 @@ class Intake : public Part { public: struct Parameters { // Plenum volume - double Volume; + double volume; // Plenum dimensions double CrossSectionArea; diff --git a/include/piston.h b/include/piston.h index fa51385e..730b4d47 100644 --- a/include/piston.h +++ b/include/piston.h @@ -16,7 +16,7 @@ class Piston : public Part { double CompressionHeight; double WristPinPosition; double Displacement; - double Mass; + double mass; }; public: diff --git a/include/piston_engine_simulator.h b/include/piston_engine_simulator.h new file mode 100644 index 00000000..43792487 --- /dev/null +++ b/include/piston_engine_simulator.h @@ -0,0 +1,73 @@ +#ifndef ATG_ENGINE_SIM_PISTON_ENGINE_SIMULATOR_H +#define ATG_ENGINE_SIM_PISTON_ENGINE_SIMULATOR_H + +#include "simulator.h" + +#include "engine.h" +#include "transmission.h" +#include "combustion_chamber.h" +#include "vehicle.h" +#include "synthesizer.h" +#include "dynamometer.h" +#include "starter_motor.h" +#include "derivative_filter.h" +#include "vehicle_drag_constraint.h" +#include "delay_filter.h" + +#include "scs.h" + +#include + +class PistonEngineSimulator : public Simulator { + public: + PistonEngineSimulator(); + virtual ~PistonEngineSimulator() override; + + void loadSimulation(Engine *engine, Vehicle *vehicle, Transmission *transmission); + + virtual double getTotalExhaustFlow() const; + void endFrame(); + virtual void destroy() override; + + void setFluidSimulationSteps(int steps) { m_fluidSimulationSteps = steps; } + int getFluidSimulationSteps() const { return m_fluidSimulationSteps; } + int getFluidSimulationFrequency() const { return m_fluidSimulationSteps * getSimulationFrequency(); } + + virtual double getAverageOutputSignal() const override; + + DerivativeFilter m_derivativeFilter; + + protected: + virtual void simulateStep_() override; + + protected: + void placeAndInitialize(); + void placeCylinder(int i); + + protected: + virtual void writeToSynthesizer() override; + + protected: + DelayFilter *m_delayFilters; + + atg_scs::FixedPositionConstraint *m_crankConstraints; + atg_scs::ClutchConstraint *m_crankshaftLinks; + atg_scs::RotationFrictionConstraint *m_crankshaftFrictionConstraints; + atg_scs::LineConstraint *m_cylinderWallConstraints; + atg_scs::LinkConstraint *m_linkConstraints; + atg_scs::RigidBody m_vehicleMass; + VehicleDragConstraint m_vehicleDrag; + + std::chrono::steady_clock::time_point m_simulationStart; + std::chrono::steady_clock::time_point m_simulationEnd; + + Engine *m_engine; + Transmission *m_transmission; + Vehicle *m_vehicle; + + double *m_exhaustFlowStagingBuffer; + + int m_fluidSimulationSteps; +}; + +#endif /* ATG_ENGINE_SIM_PISTON_ENGINE_SIMULATOR_H */ diff --git a/include/simulation_object.h b/include/simulation_object.h index 112441cf..f3479cce 100644 --- a/include/simulation_object.h +++ b/include/simulation_object.h @@ -34,7 +34,8 @@ class SimulationObject { float scale = 1.0f, float lx = 0.0f, float ly = 0.0f, - float theta = 0.0f); + float theta = 0.0f, + float z = 0.0f); ysVector tintByLayer(const ysVector &col, int layers) const; EngineSimApplication *m_app; diff --git a/include/simulator.h b/include/simulator.h index b6ce381b..0517246d 100644 --- a/include/simulator.h +++ b/include/simulator.h @@ -3,7 +3,6 @@ #include "engine.h" #include "transmission.h" -#include "combustion_chamber.h" #include "vehicle.h" #include "synthesizer.h" #include "dynamometer.h" @@ -11,125 +10,113 @@ #include "derivative_filter.h" #include "vehicle_drag_constraint.h" #include "delay_filter.h" - -#include "scs.h" +#include "engine.h" #include class Simulator { - public: - enum class SystemType { - NsvOptimized, - Generic - }; +public: + enum class SystemType { + NsvOptimized, + Generic + }; + + struct Parameters { + SystemType systemType = SystemType::NsvOptimized; + }; - struct Parameters { - SystemType SystemType = SystemType::NsvOptimized; - }; + static constexpr int DynoTorqueSamples = 512; - static constexpr int DynoTorqueSamples = 512; +public: + Simulator(); + virtual ~Simulator(); - public: - Simulator(); - ~Simulator(); + virtual void initialize(const Parameters ¶ms); + void loadSimulation(Engine *engine, Vehicle *vehicle, Transmission *transmission); + void releaseSimulation(); - void initialize(const Parameters ¶ms); - void loadSimulation(Engine *engine, Vehicle *vehicle, Transmission *transmission); - void releaseSimulation(); + virtual void startFrame(double dt); + bool simulateStep(); + virtual double getTotalExhaustFlow() const; + int readAudioOutput(int samples, int16_t *target); + virtual void endFrame(); + virtual void destroy(); - void startFrame(double dt); - bool simulateStep(); - double getTotalExhaustFlow() const; - int readAudioOutput(int samples, int16_t *target); - int getFrameIterationCount() const { return i_steps; } - void endFrame(); - void destroy(); + void startAudioRenderingThread(); + void endAudioRenderingThread(); - void startAudioRenderingThread(); - void endAudioRenderingThread(); + int getFrameIterationCount() const { return m_steps; } - double getSynthesizerInputLatency() const { return m_synthesizer.getLatency(); } - double getSynthesizerInputLatencyTarget() const; + Synthesizer &synthesizer() { return m_synthesizer; } - int getCurrentIteration() const { return m_currentIteration; } + Engine *getEngine() const { return m_engine; } + Transmission *getTransmission() const { return m_transmission; } + Vehicle *getVehicle() const { return m_vehicle; } + atg_scs::RigidBodySystem *getSystem() { return m_system; } - int i_steps; + void setSimulationFrequency(int frequency) { m_simulationFrequency = frequency; } + int getSimulationFrequency() const { return m_simulationFrequency; } - double getAverageProcessingTime() const { return m_physicsProcessingTime; } + double getTimestep() const { return 1.0 / m_simulationFrequency; } - Engine *getEngine() const { return m_engine; } - Transmission *getTransmission() const { return m_transmission; } - Vehicle *getVehicle() const { return m_vehicle; } - atg_scs::RigidBodySystem *getSystem() { return m_system; } + void setTargetSynthesizerLatency(double latency) { m_targetSynthesizerLatency = latency; } + double getTargetSynthesizerLatency() const { return m_targetSynthesizerLatency; } + double getSynthesizerInputLatency() const { return m_synthesizer.getLatency(); } + double getSynthesizerInputLatencyTarget() const; - void setSimulationFrequency(int frequency) { m_simulationFrequency = frequency; } - int getSimulationFrequency() const { return m_simulationFrequency; } + void setSimulationSpeed(double simSpeed) { m_simulationSpeed = simSpeed; } + double getSimulationSpeed() const { return m_simulationSpeed; } + int getCurrentIteration() const { return m_currentIteration; } + double getAverageProcessingTime() const { return m_physicsProcessingTime; } - void setFluidSimulationSteps(int steps) { m_fluidSimulationSteps = steps; } - int getFluidSimulationSteps() const { return m_fluidSimulationSteps; } - int getFluidSimulationFrequency() const { return m_fluidSimulationSteps * m_simulationFrequency; } + int simulationSteps() const { return m_steps; } - double getTimestep() const { return 1.0 / m_simulationFrequency; } + virtual double getFilteredDynoTorque() const; + virtual double getDynoPower() const; + virtual double getAverageOutputSignal() const; - void setTargetSynthesizerLatency(double latency) { m_targetSynthesizerLatency = latency; } - double getTargetSynthesizerLatency() const { return m_targetSynthesizerLatency; } + double filteredEngineSpeed() const { return m_filteredEngineSpeed; } - void setSimulationSpeed(double simSpeed) { m_simulationSpeed = simSpeed; } - double getSimulationSpeed() const { return m_simulationSpeed; } + Dynamometer m_dyno; + StarterMotor m_starterMotor; - double getFilteredDynoTorque() const; - double getDynoPower() const; - double getAverageOutputSignal() const; +protected: + void initializeSynthesizer(); + virtual void simulateStep_(); + virtual void writeToSynthesizer() = 0; - Synthesizer *getSynthesizer() { return &m_synthesizer; } + atg_scs::RigidBodySystem *m_system; - Dynamometer m_dyno; - StarterMotor m_starterMotor; - DerivativeFilter m_derivativeFilter; +private: + void updateFilteredEngineSpeed(double dt); - protected: - void placeAndInitialize(); - void placeCylinder(int i); - void initializeSynthesizer(); - - protected: - void updateFilteredEngineSpeed(double dt); - void writeToSynthesizer(); +private: + atg_scs::RigidBody m_vehicleMass; + VehicleDragConstraint m_vehicleDrag; - protected: - atg_scs::RigidBodySystem *m_system; - Synthesizer m_synthesizer; + Synthesizer m_synthesizer; - DelayFilter *m_delayFilters; + std::chrono::steady_clock::time_point m_simulationStart; + std::chrono::steady_clock::time_point m_simulationEnd; + int m_currentIteration; - atg_scs::FixedPositionConstraint *m_crankConstraints; - atg_scs::ClutchConstraint *m_crankshaftLinks; - atg_scs::RotationFrictionConstraint *m_crankshaftFrictionConstraints; - atg_scs::LineConstraint *m_cylinderWallConstraints; - atg_scs::LinkConstraint *m_linkConstraints; - atg_scs::RigidBody m_vehicleMass; - VehicleDragConstraint m_vehicleDrag; + Engine *m_engine; + Transmission *m_transmission; + Vehicle *m_vehicle; - std::chrono::steady_clock::time_point m_simulationStart; - std::chrono::steady_clock::time_point m_simulationEnd; - int m_currentIteration; + double m_physicsProcessingTime; - Engine *m_engine; - Transmission *m_transmission; - Vehicle *m_vehicle; + int m_simulationFrequency; - double m_physicsProcessingTime; + double m_targetSynthesizerLatency; + double m_simulationSpeed; - int m_simulationFrequency; - int m_fluidSimulationSteps; + double *m_dynoTorqueSamples; + int m_lastDynoTorqueSample; - double m_targetSynthesizerLatency; - double m_simulationSpeed; - double *m_exhaustFlowStagingBuffer; - double m_filteredEngineSpeed; + double m_filteredEngineSpeed; - double *m_dynoTorqueSamples; - int m_lastDynoTorqueSample; + int m_steps; }; #endif /* ATG_ENGINE_SIM_SIMULATOR_H */ diff --git a/include/standard_valvetrain.h b/include/standard_valvetrain.h index 78ead798..1ed3536e 100644 --- a/include/standard_valvetrain.h +++ b/include/standard_valvetrain.h @@ -6,8 +6,8 @@ class StandardValvetrain : public Valvetrain { public: struct Parameters { - Camshaft *IntakeCamshaft; - Camshaft *ExhaustCamshaft; + Camshaft *intakeCamshaft; + Camshaft *exhaustCamshaft; }; public: diff --git a/include/synthesizer.h b/include/synthesizer.h index 7c871b1c..ffbf4a22 100644 --- a/include/synthesizer.h +++ b/include/synthesizer.h @@ -18,39 +18,39 @@ class Synthesizer { public: struct AudioParameters { - float Volume = 1.0f; - float Convolution = 1.0f; + float volume = 1.0f; + float convolution = 1.0f; float dF_F_mix = 0.01f; - float InputSampleNoise = 0.5f; - float InputSampleNoiseFrequencyCutoff = 10000.0f; - float AirNoise = 1.0f; - float AirNoiseFrequencyCutoff = 2000.0f; - float LevelerTarget = 30000.0f; - float LevelerMaxGain = 1.9f; - float LevelerMinGain = 0.00001f; + float inputSampleNoise = 0.5f; + float inputSampleNoiseFrequencyCutoff = 10000.0f; + float airNoise = 1.0f; + float airNoiseFrequencyCutoff = 2000.0f; + float levelerTarget = 30000.0f; + float levelerMaxGain = 1.9f; + float levelerMinGain = 0.00001f; }; struct Parameters { - int InputChannelCount = 1; - int InputBufferSize = 1024; - int AudioBufferSize = 44100; - float InputSampleRate = 10000; - float AudioSampleRate = 44100; - AudioParameters InitialAudioParameters; + int inputChannelCount = 1; + int inputBufferSize = 1024; + int audioBufferSize = 44100; + float inputSampleRate = 10000; + float audioSampleRate = 44100; + AudioParameters initialAudioParameters; }; struct InputChannel { - RingBuffer Data; - float *TransferBuffer = nullptr; - double LastInputSample = 0.0f; + RingBuffer data; + float *transferBuffer = nullptr; + double lastInputSample = 0.0f; }; struct ProcessingFilters { - ConvolutionFilter Convolution; - DerivativeFilter Derivative; - JitterFilter JitterFilter; - ButterworthLowPassFilter AirNoiseLowPass; - LowPassFilter InputDcFilter; + ConvolutionFilter convolution; + DerivativeFilter derivative; + JitterFilter jitterFilter; + ButterworthLowPassFilter airNoiseLowPass; + LowPassFilter inputDcFilter; ButterworthLowPassFilter antialiasing; }; diff --git a/include/vtec_valvetrain.h b/include/vtec_valvetrain.h index 12cb9a8b..8b731ba6 100644 --- a/include/vtec_valvetrain.h +++ b/include/vtec_valvetrain.h @@ -7,18 +7,18 @@ class Engine; class VtecValvetrain : public Valvetrain { public: struct Parameters { - double MinRpm; - double MinSpeed; - double ManifoldVacuum; - double MinThrottlePosition; + double minRpm; + double minSpeed; + double manifoldVacuum; + double minThrottlePosition; - Camshaft *IntakeCamshaft; - Camshaft *ExhaustCamshaft; + Camshaft *intakeCamshaft; + Camshaft *exhaustCamshaft; - Camshaft *VtecIntakeCamshaft; - Camshaft *VtexExhaustCamshaft; + Camshaft *vtecIntakeCamshaft; + Camshaft *vtexExhaustCamshaft; - Engine *Engine; + Engine *engine; }; public: diff --git a/scripting/include/camshaft_node.h b/scripting/include/camshaft_node.h index f4e20371..8bca5401 100644 --- a/scripting/include/camshaft_node.h +++ b/scripting/include/camshaft_node.h @@ -24,13 +24,13 @@ namespace es_script { EngineContext *context) const { Camshaft::Parameters parameters = m_parameters; - parameters.Crankshaft = crankshaft; - parameters.Lobes = (int)m_lobes.size(); - parameters.LobeProfile = m_lobeProfile->generate(context); + parameters.crankshaft = crankshaft; + parameters.lobes = (int)m_lobes.size(); + parameters.lobeProfile = m_lobeProfile->generate(context); camshaft->initialize(parameters); - for (int i = 0; i < parameters.Lobes; ++i) { + for (int i = 0; i < parameters.lobes; ++i) { camshaft->setLobeCenterline(i, m_lobes[i]); } } @@ -41,8 +41,8 @@ namespace es_script { protected: virtual void registerInputs() { - addInput("advance", &m_parameters.Advance); - addInput("base_radius", &m_parameters.BaseRadius); + addInput("advance", &m_parameters.advance); + addInput("base_radius", &m_parameters.baseRadius); addInput("lobe_profile", &m_lobeProfile); ObjectReferenceNode::registerInputs(); @@ -54,7 +54,7 @@ namespace es_script { // Read inputs readAllInputs(); - m_parameters.Crankshaft = nullptr; + m_parameters.crankshaft = nullptr; } Camshaft::Parameters m_parameters; diff --git a/scripting/include/connecting_rod_node.h b/scripting/include/connecting_rod_node.h index 64c25118..e1e1bcf2 100644 --- a/scripting/include/connecting_rod_node.h +++ b/scripting/include/connecting_rod_node.h @@ -40,26 +40,26 @@ namespace es_script { int rodJournal) const { ConnectingRod::Parameters params = m_parameters; - params.Crankshaft = crankshaft; - params.Journal = rodJournal; - params.Piston = piston; - params.RodJournals = static_cast(m_rodJournals.size()); - params.Master = nullptr; + params.crankshaft = crankshaft; + params.journal = rodJournal; + params.piston = piston; + params.rodJournals = static_cast(m_rodJournals.size()); + params.master = nullptr; connectingRod->initialize(params); - for (int i = 0; i < params.RodJournals; ++i) { + for (int i = 0; i < params.rodJournals; ++i) { connectingRod->setRodJournalAngle(i, m_rodJournals[i]->getAngle() + constants::pi / 2); } } protected: virtual void registerInputs() { - addInput("mass", &m_parameters.Mass); - addInput("moment_of_inertia", &m_parameters.MomentOfInertia); - addInput("center_of_mass", &m_parameters.CenterOfMass); - addInput("length", &m_parameters.Length); - addInput("slave_throw", &m_parameters.SlaveThrow); + addInput("mass", &m_parameters.mass); + addInput("moment_of_inertia", &m_parameters.momentOfInertia); + addInput("center_of_mass", &m_parameters.centerOfMass); + addInput("length", &m_parameters.length); + addInput("slave_throw", &m_parameters.slaveThrow); ObjectReferenceNode::registerInputs(); } @@ -70,8 +70,8 @@ namespace es_script { // Read inputs readAllInputs(); - m_parameters.Crankshaft = nullptr; - m_parameters.Piston = nullptr; + m_parameters.crankshaft = nullptr; + m_parameters.piston = nullptr; } ConnectingRod::Parameters m_parameters; diff --git a/scripting/include/crankshaft_node.h b/scripting/include/crankshaft_node.h index 1fecb555..9439e7d1 100644 --- a/scripting/include/crankshaft_node.h +++ b/scripting/include/crankshaft_node.h @@ -25,10 +25,10 @@ namespace es_script { void generate(Crankshaft *crankshaft, EngineContext *context) { Crankshaft::Parameters params = m_parameters; - params.RodJournals = (int)m_rodJournals.size(); + params.rodJournals = (int)m_rodJournals.size(); crankshaft->initialize(params); - for (int i = 0; i < params.RodJournals; ++i) { + for (int i = 0; i < params.rodJournals; ++i) { RodJournalNode *rodJournal = m_rodJournals[i]; crankshaft->setRodJournalAngle( i, @@ -42,14 +42,14 @@ namespace es_script { protected: virtual void registerInputs() { - addInput("throw", &m_parameters.CrankThrow); - addInput("flywheel_mass", &m_parameters.FlywheelMass); - addInput("mass", &m_parameters.Mass); - addInput("friction_torque", &m_parameters.FrictionTorque); - addInput("moment_of_inertia", &m_parameters.MomentOfInertia); - addInput("position_x", &m_parameters.Pos_x); - addInput("position_y", &m_parameters.Pos_y); - addInput("tdc", &m_parameters.TDC); + addInput("throw", &m_parameters.crankThrow); + addInput("flywheel_mass", &m_parameters.flywheelMass); + addInput("mass", &m_parameters.mass); + addInput("friction_torque", &m_parameters.frictionTorque); + addInput("moment_of_inertia", &m_parameters.momentOfInertia); + addInput("position_x", &m_parameters.pos_x); + addInput("position_y", &m_parameters.pos_y); + addInput("tdc", &m_parameters.tdc); ObjectReferenceNode::registerInputs(); } @@ -60,7 +60,7 @@ namespace es_script { // Read inputs readAllInputs(); - m_parameters.RodJournals = 0; + m_parameters.rodJournals = 0; } Crankshaft::Parameters m_parameters; diff --git a/scripting/include/fuel_node.h b/scripting/include/fuel_node.h index 95f67a93..d698ba54 100644 --- a/scripting/include/fuel_node.h +++ b/scripting/include/fuel_node.h @@ -20,7 +20,7 @@ namespace es_script { void generate(Fuel *fuel, EngineContext *context) const { Fuel::Parameters params = m_parameters; - params.TurbulenceToFlameSpeedRatio = + params.turbulenceToFlameSpeedRatio = m_turbulenceToFlameSpeedRatio->generate(context); fuel->initialize(params); @@ -32,16 +32,16 @@ namespace es_script { "turbulence_to_flame_speed_ratio", &m_turbulenceToFlameSpeedRatio, InputTarget::Type::Object); - addInput("name", &m_parameters.Name); - addInput("molecular_mass", &m_parameters.MolecularMass); - addInput("energy_density", &m_parameters.EnergyDensity); - addInput("density", &m_parameters.Density); - addInput("molecular_afr", &m_parameters.MolecularAfr); - addInput("max_burning_efficiency", &m_parameters.MaxBurningEfficiency); - addInput("burning_efficiency_randomness", &m_parameters.BurningEfficiencyRandomness); - addInput("low_efficiency_attenuation", &m_parameters.LowEfficiencyAttenuation); - addInput("max_turbulence_effect", &m_parameters.MaxTurbulenceEffect); - addInput("max_dilution_effect", &m_parameters.MaxDilutionEffect); + addInput("name", &m_parameters.name); + addInput("molecular_mass", &m_parameters.molecularMass); + addInput("energy_density", &m_parameters.energyDensity); + addInput("density", &m_parameters.density); + addInput("molecular_afr", &m_parameters.molecularAfr); + addInput("max_burning_efficiency", &m_parameters.maxBurningEfficiency); + addInput("burning_efficiency_randomness", &m_parameters.burningEfficiencyRandomness); + addInput("low_efficiency_attenuation", &m_parameters.lowEfficiencyAttenuation); + addInput("max_turbulence_effect", &m_parameters.maxTurbulenceEffect); + addInput("max_dilution_effect", &m_parameters.maxDilutionEffect); ObjectReferenceNode::registerInputs(); } diff --git a/scripting/include/ignition_module_node.h b/scripting/include/ignition_module_node.h index 26c17223..0b4e0e98 100644 --- a/scripting/include/ignition_module_node.h +++ b/scripting/include/ignition_module_node.h @@ -25,12 +25,12 @@ namespace es_script { void generate(Engine *engine, EngineContext *context) const { IgnitionModule::Parameters params; - params.Crankshaft = engine->getCrankshaft(0); - params.CylinderCount = engine->getCylinderCount(); - params.RevLimit = m_revLimit; - params.TimingCurve = m_timingCurve->generate(context); - params.CylinderCount = engine->getCylinderCount(); - params.LimiterDuration = m_limiterDuration; + params.crankshaft = engine->getCrankshaft(0); + params.cylinderCount = engine->getCylinderCount(); + params.revLimit = m_revLimit; + params.timingCurve = m_timingCurve->generate(context); + params.cylinderCount = engine->getCylinderCount(); + params.limiterDuration = m_limiterDuration; engine->getIgnitionModule()->initialize(params); for (const Post &post : m_posts) { diff --git a/scripting/include/intake_node.h b/scripting/include/intake_node.h index d92f9dc7..ae433ead 100644 --- a/scripting/include/intake_node.h +++ b/scripting/include/intake_node.h @@ -28,7 +28,7 @@ namespace es_script { protected: virtual void registerInputs() { - addInput("plenum_volume", &m_parameters.Volume); + addInput("plenum_volume", &m_parameters.volume); addInput("plenum_cross_section_area", &m_parameters.CrossSectionArea); addInput("intake_flow_rate", &m_parameters.InputFlowK); addInput("idle_flow_rate", &m_parameters.IdleFlowK); diff --git a/scripting/include/piston_node.h b/scripting/include/piston_node.h index 263147f2..c05db448 100644 --- a/scripting/include/piston_node.h +++ b/scripting/include/piston_node.h @@ -34,7 +34,7 @@ namespace es_script { protected: virtual void registerInputs() { - addInput("mass", &m_parameters.Mass); + addInput("mass", &m_parameters.mass); addInput("blowby", &m_parameters.BlowbyFlowCoefficient); addInput("compression_height", &m_parameters.CompressionHeight); addInput("wrist_pin_position", &m_parameters.WristPinPosition); diff --git a/scripting/include/standard_valvetrain_node.h b/scripting/include/standard_valvetrain_node.h index a95273f0..3c80bb60 100644 --- a/scripting/include/standard_valvetrain_node.h +++ b/scripting/include/standard_valvetrain_node.h @@ -28,8 +28,8 @@ namespace es_script { m_exhaustCamshaft->generate(exhaustCam, crank, context); StandardValvetrain::Parameters params; - params.IntakeCamshaft = intakeCam; - params.ExhaustCamshaft = exhaustCam; + params.intakeCamshaft = intakeCam; + params.exhaustCamshaft = exhaustCam; valvetrain->initialize(params); return valvetrain; diff --git a/scripting/include/vtec_valvetrain_node.h b/scripting/include/vtec_valvetrain_node.h index 3953c15f..15b49ce0 100644 --- a/scripting/include/vtec_valvetrain_node.h +++ b/scripting/include/vtec_valvetrain_node.h @@ -31,15 +31,15 @@ namespace es_script { m_vtecExhaustCamshaft->generate(vtecExhaustCam, crank, context); VtecValvetrain::Parameters params; - params.IntakeCamshaft = intakeCam; - params.ExhaustCamshaft = exhaustCam; - params.VtecIntakeCamshaft = vtecIntakeCam; - params.VtexExhaustCamshaft = vtecExhaustCam; - params.MinRpm = m_parameters.MinRpm; - params.MinSpeed = m_parameters.MinSpeed; - params.MinThrottlePosition = m_parameters.MinThrottlePosition; - params.ManifoldVacuum = m_parameters.ManifoldVacuum; - params.Engine = context->getEngine(); + params.intakeCamshaft = intakeCam; + params.exhaustCamshaft = exhaustCam; + params.vtecIntakeCamshaft = vtecIntakeCam; + params.vtexExhaustCamshaft = vtecExhaustCam; + params.minRpm = m_parameters.minRpm; + params.minSpeed = m_parameters.minSpeed; + params.minThrottlePosition = m_parameters.minThrottlePosition; + params.manifoldVacuum = m_parameters.manifoldVacuum; + params.engine = context->getEngine(); valvetrain->initialize(params); return valvetrain; @@ -52,10 +52,10 @@ namespace es_script { addInput("intake_camshaft", &m_intakeCamshaft, InputTarget::Type::Object); addInput("exhaust_camshaft", &m_exhaustCamshaft, InputTarget::Type::Object); - addInput("min_rpm", &m_parameters.MinRpm); - addInput("min_speed", &m_parameters.MinSpeed); - addInput("manifold_vacuum", &m_parameters.ManifoldVacuum); - addInput("min_throttle_position", &m_parameters.MinThrottlePosition); + addInput("min_rpm", &m_parameters.minRpm); + addInput("min_speed", &m_parameters.minSpeed); + addInput("manifold_vacuum", &m_parameters.manifoldVacuum); + addInput("min_throttle_position", &m_parameters.minThrottlePosition); ValvetrainNode::registerInputs(); } diff --git a/src/camshaft.cpp b/src/camshaft.cpp index 47365b04..f03f3414 100644 --- a/src/camshaft.cpp +++ b/src/camshaft.cpp @@ -21,14 +21,14 @@ Camshaft::~Camshaft() { } void Camshaft::initialize(const Parameters ¶ms) { - m_lobeAngles = new double[params.Lobes]; - memset(m_lobeAngles, 0, sizeof(double) * params.Lobes); - - m_lobes = params.Lobes; - m_crankshaft = params.Crankshaft; - m_lobeProfile = params.LobeProfile; - m_advance = params.Advance; - m_baseRadius = params.BaseRadius; + m_lobeAngles = new double[params.lobes]; + memset(m_lobeAngles, 0, sizeof(double) * params.lobes); + + m_lobes = params.lobes; + m_crankshaft = params.crankshaft; + m_lobeProfile = params.lobeProfile; + m_advance = params.advance; + m_baseRadius = params.baseRadius; } void Camshaft::destroy() { diff --git a/src/connecting_rod.cpp b/src/connecting_rod.cpp index 01195be3..7474bcd3 100644 --- a/src/connecting_rod.cpp +++ b/src/connecting_rod.cpp @@ -23,18 +23,18 @@ ConnectingRod::~ConnectingRod() { } void ConnectingRod::initialize(const Parameters ¶ms) { - m_centerOfMass = params.CenterOfMass; - m_length = params.Length; - m_m = params.Mass; - m_I = params.MomentOfInertia; - m_journal = params.Journal; - m_crankshaft = params.Crankshaft; - m_piston = params.Piston; + m_centerOfMass = params.centerOfMass; + m_length = params.length; + m_m = params.mass; + m_I = params.momentOfInertia; + m_journal = params.journal; + m_crankshaft = params.crankshaft; + m_piston = params.piston; - m_rodJournalAngles = new double[params.RodJournals]; - m_rodJournalCount = params.RodJournals; - m_slaveThrow = params.SlaveThrow; - m_master = params.Master; + m_rodJournalAngles = new double[params.rodJournals]; + m_rodJournalCount = params.rodJournals; + m_slaveThrow = params.slaveThrow; + m_master = params.master; } double ConnectingRod::getBigEndLocal() const { diff --git a/src/crankshaft.cpp b/src/crankshaft.cpp index 6bafad47..47b4d54c 100644 --- a/src/crankshaft.cpp +++ b/src/crankshaft.cpp @@ -22,16 +22,16 @@ Crankshaft::~Crankshaft() { } void Crankshaft::initialize(const Parameters ¶ms) { - m_m = params.Mass; - m_flywheelMass = params.FlywheelMass; - m_I = params.MomentOfInertia; - m_throw = params.CrankThrow; - m_rodJournalCount = params.RodJournals; + m_m = params.mass; + m_flywheelMass = params.flywheelMass; + m_I = params.momentOfInertia; + m_throw = params.crankThrow; + m_rodJournalCount = params.rodJournals; m_rodJournalAngles = new double[m_rodJournalCount]; - m_p_x = params.Pos_x; - m_p_y = params.Pos_y; - m_tdc = params.TDC; - m_frictionTorque = params.FrictionTorque; + m_p_x = params.pos_x; + m_p_y = params.pos_y; + m_tdc = params.tdc; + m_frictionTorque = params.frictionTorque; } void Crankshaft::destroy() { diff --git a/src/engine.cpp b/src/engine.cpp index 1914ba4c..15e326d5 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,10 +1,10 @@ #include "..\include\engine.h" -#include "..\include\engine.h" #include "../include/engine.h" #include "../include/constants.h" #include "../include/units.h" #include "../include/fuel.h" +#include "../include/piston_engine_simulator.h" #include #include @@ -383,6 +383,18 @@ int Engine::getMaxDepth() const { return maxDepth; } +Simulator *Engine::createSimulator(Vehicle *vehicle, Transmission *transmission) { + PistonEngineSimulator *simulator = new PistonEngineSimulator; + Simulator::Parameters simulatorParams; + simulatorParams.systemType = Simulator::SystemType::NsvOptimized; + simulator->initialize(simulatorParams); + + simulator->loadSimulation(this, vehicle, transmission); + simulator->setFluidSimulationSteps(8); + + return static_cast(simulator); +} + double Engine::getRpm() const { if (m_crankshaftCount == 0) return 0; else return std::abs(units::toRpm(getCrankshaft(0)->m_body.v_theta)); diff --git a/src/engine_sim_application.cpp b/src/engine_sim_application.cpp index 3f679cfa..3a47b339 100644 --- a/src/engine_sim_application.cpp +++ b/src/engine_sim_application.cpp @@ -58,6 +58,7 @@ EngineSimApplication::EngineSimApplication() { m_torque = 0; m_dynoSpeed = 0; + m_simulator = nullptr; m_engineView = nullptr; m_rightGaugeCluster = nullptr; m_temperatureGauge = nullptr; @@ -176,7 +177,7 @@ void EngineSimApplication::initialize() { m_engine.GetAudioDevice()->CreateBuffer(¶ms, 44100); m_audioSource = m_engine.GetAudioDevice()->CreateSource(m_outputAudioBuffer); - m_audioSource->SetMode((m_simulator.getEngine() != nullptr) + m_audioSource->SetMode((m_simulator->getEngine() != nullptr) ? ysAudioSource::Mode::Loop : ysAudioSource::Mode::Stop); m_audioSource->SetPan(0.0f); @@ -228,20 +229,20 @@ void EngineSimApplication::process(float frame_dt) { m_displayAngle = 0.0f; } - m_simulator.setSimulationSpeed(speed); + m_simulator->setSimulationSpeed(speed); const double avgFramerate = clamp(m_engine.GetAverageFramerate(), 30.0f, 1000.0f); - m_simulator.startFrame(1 / avgFramerate); + m_simulator->startFrame(1 / avgFramerate); auto proc_t0 = std::chrono::steady_clock::now(); - const int iterationCount = m_simulator.getFrameIterationCount(); - while (m_simulator.simulateStep()) { + const int iterationCount = m_simulator->getFrameIterationCount(); + while (m_simulator->simulateStep()) { m_oscCluster->sample(); } auto proc_t1 = std::chrono::steady_clock::now(); - m_simulator.endFrame(); + m_simulator->endFrame(); auto duration = proc_t1 - proc_t0; if (iterationCount > 0) { @@ -270,7 +271,7 @@ void EngineSimApplication::process(float frame_dt) { } int16_t *samples = new int16_t[maxWrite]; - const int readSamples = m_simulator.readAudioOutput(maxWrite, samples); + const int readSamples = m_simulator->readAudioOutput(maxWrite, samples); for (SampleOffset i = 0; i < (SampleOffset)readSamples && i < maxWrite; ++i) { const int16_t sample = samples[i]; @@ -305,7 +306,7 @@ void EngineSimApplication::process(float frame_dt) { } m_performanceCluster->addInputBufferUsageSample( - (double)m_simulator.getSynthesizerInputLatency() / m_simulator.getSynthesizerInputLatencyTarget()); + (double)m_simulator->getSynthesizerInputLatency() / m_simulator->getSynthesizerInputLatencyTarget()); m_performanceCluster->addAudioLatencySample( m_audioBuffer.offsetDelta(m_audioSource->GetCurrentWritePosition(), m_audioBuffer.m_writePointer) / (44100 * 0.1)); } @@ -355,7 +356,7 @@ void EngineSimApplication::run() { if (m_engine.ProcessKeyDown(ysKey::Code::Return)) { m_audioSource->SetMode(ysAudioSource::Mode::Stop); loadScript(); - if (m_simulator.getEngine() != nullptr) { + if (m_simulator->getEngine() != nullptr) { m_audioSource->SetMode(ysAudioSource::Mode::Loop); } } @@ -417,7 +418,7 @@ void EngineSimApplication::run() { stopRecording(); } - m_simulator.endAudioRenderingThread(); + m_simulator->endAudioRenderingThread(); } void EngineSimApplication::destroy() { @@ -429,7 +430,7 @@ void EngineSimApplication::destroy() { m_assetManager.Destroy(); m_engine.Destroy(); - m_simulator.destroy(); + m_simulator->destroy(); m_audioBuffer.destroy(); } @@ -438,6 +439,13 @@ void EngineSimApplication::loadEngine( Vehicle *vehicle, Transmission *transmission) { + destroyObjects(); + + if (m_simulator != nullptr) { + m_simulator->releaseSimulation(); + delete m_simulator; + } + if (m_vehicle != nullptr) { delete m_vehicle; m_vehicle = nullptr; @@ -457,8 +465,7 @@ void EngineSimApplication::loadEngine( m_vehicle = vehicle; m_transmission = transmission; - destroyObjects(); - m_simulator.releaseSimulation(); + m_simulator = engine->createSimulator(vehicle, transmission); if (engine == nullptr || vehicle == nullptr || transmission == nullptr) { m_iceEngine = nullptr; @@ -472,19 +479,13 @@ void EngineSimApplication::loadEngine( m_viewParameters.Layer1 = engine->getMaxDepth(); engine->calculateDisplacement(); - m_simulator.setFluidSimulationSteps(8); - m_simulator.setSimulationFrequency(engine->getSimulationFrequency()); - - Simulator::Parameters simulatorParams; - simulatorParams.SystemType = Simulator::SystemType::NsvOptimized; - m_simulator.initialize(simulatorParams); - m_simulator.loadSimulation(engine, vehicle, transmission); + m_simulator->setSimulationFrequency(engine->getSimulationFrequency()); - Synthesizer::AudioParameters audioParams = m_simulator.getSynthesizer()->getAudioParameters(); - audioParams.InputSampleNoise = static_cast(engine->getInitialJitter()); - audioParams.AirNoise = static_cast(engine->getInitialNoise()); + Synthesizer::AudioParameters audioParams = m_simulator->synthesizer().getAudioParameters(); + audioParams.inputSampleNoise = static_cast(engine->getInitialJitter()); + audioParams.airNoise = static_cast(engine->getInitialNoise()); audioParams.dF_F_mix = static_cast(engine->getInitialHighFrequencyGain()); - m_simulator.getSynthesizer()->setAudioParameters(audioParams); + m_simulator->synthesizer().setAudioParameters(audioParams); for (int i = 0; i < engine->getExhaustSystemCount(); ++i) { ImpulseResponse *response = engine->getExhaustSystem(i)->getImpulseResponse(); @@ -495,7 +496,7 @@ void EngineSimApplication::loadEngine( waveFile.FillBuffer(0); waveFile.CloseFile(); - m_simulator.getSynthesizer()->initializeImpulseResponse( + m_simulator->synthesizer().initializeImpulseResponse( reinterpret_cast(waveFile.GetBuffer()), waveFile.GetSampleCount(), response->getVolume(), @@ -505,7 +506,7 @@ void EngineSimApplication::loadEngine( waveFile.DestroyInternalBuffer(); } - m_simulator.startAudioRenderingThread(); + m_simulator->startAudioRenderingThread(); } void EngineSimApplication::drawGenerated( @@ -684,36 +685,36 @@ void EngineSimApplication::processEngineInput() { ? 0.001 : 0.01; - Synthesizer::AudioParameters audioParams = m_simulator.getSynthesizer()->getAudioParameters(); - audioParams.Volume = clamp(audioParams.Volume + mouseWheelDelta * rate * dt); + Synthesizer::AudioParameters audioParams = m_simulator->synthesizer().getAudioParameters(); + audioParams.volume = clamp(audioParams.volume + mouseWheelDelta * rate * dt); - m_simulator.getSynthesizer()->setAudioParameters(audioParams); + m_simulator->synthesizer().setAudioParameters(audioParams); fineControlInUse = true; - m_infoCluster->setLogMessage("[Z] - Set volume to " + std::to_string(audioParams.Volume)); + m_infoCluster->setLogMessage("[Z] - Set volume to " + std::to_string(audioParams.volume)); } else if (m_engine.IsKeyDown(ysKey::Code::X)) { const double rate = fineControlMode ? 0.001 : 0.01; - Synthesizer::AudioParameters audioParams = m_simulator.getSynthesizer()->getAudioParameters(); - audioParams.Convolution = clamp(audioParams.Convolution + mouseWheelDelta * rate * dt); + Synthesizer::AudioParameters audioParams = m_simulator->synthesizer().getAudioParameters(); + audioParams.convolution = clamp(audioParams.convolution + mouseWheelDelta * rate * dt); - m_simulator.getSynthesizer()->setAudioParameters(audioParams); + m_simulator->synthesizer().setAudioParameters(audioParams); fineControlInUse = true; - m_infoCluster->setLogMessage("[X] - Set convolution level to " + std::to_string(audioParams.Convolution)); + m_infoCluster->setLogMessage("[X] - Set convolution level to " + std::to_string(audioParams.convolution)); } else if (m_engine.IsKeyDown(ysKey::Code::C)) { const double rate = fineControlMode ? 0.00001 : 0.001; - Synthesizer::AudioParameters audioParams = m_simulator.getSynthesizer()->getAudioParameters(); + Synthesizer::AudioParameters audioParams = m_simulator->synthesizer().getAudioParameters(); audioParams.dF_F_mix = clamp(audioParams.dF_F_mix + mouseWheelDelta * rate * dt); - m_simulator.getSynthesizer()->setAudioParameters(audioParams); + m_simulator->synthesizer().setAudioParameters(audioParams); fineControlInUse = true; m_infoCluster->setLogMessage("[C] - Set high freq. gain to " + std::to_string(audioParams.dF_F_mix)); @@ -723,26 +724,26 @@ void EngineSimApplication::processEngineInput() { ? 0.001 : 0.01; - Synthesizer::AudioParameters audioParams = m_simulator.getSynthesizer()->getAudioParameters(); - audioParams.AirNoise = clamp(audioParams.AirNoise + mouseWheelDelta * rate * dt); + Synthesizer::AudioParameters audioParams = m_simulator->synthesizer().getAudioParameters(); + audioParams.airNoise = clamp(audioParams.airNoise + mouseWheelDelta * rate * dt); - m_simulator.getSynthesizer()->setAudioParameters(audioParams); + m_simulator->synthesizer().setAudioParameters(audioParams); fineControlInUse = true; - m_infoCluster->setLogMessage("[V] - Set low freq. noise to " + std::to_string(audioParams.AirNoise)); + m_infoCluster->setLogMessage("[V] - Set low freq. noise to " + std::to_string(audioParams.airNoise)); } else if (m_engine.IsKeyDown(ysKey::Code::B)) { const double rate = fineControlMode ? 0.001 : 0.01; - Synthesizer::AudioParameters audioParams = m_simulator.getSynthesizer()->getAudioParameters(); - audioParams.InputSampleNoise = clamp(audioParams.InputSampleNoise + mouseWheelDelta * rate * dt); + Synthesizer::AudioParameters audioParams = m_simulator->synthesizer().getAudioParameters(); + audioParams.inputSampleNoise = clamp(audioParams.inputSampleNoise + mouseWheelDelta * rate * dt); - m_simulator.getSynthesizer()->setAudioParameters(audioParams); + m_simulator->synthesizer().setAudioParameters(audioParams); fineControlInUse = true; - m_infoCluster->setLogMessage("[B] - Set high freq. noise to " + std::to_string(audioParams.InputSampleNoise)); + m_infoCluster->setLogMessage("[B] - Set high freq. noise to " + std::to_string(audioParams.inputSampleNoise)); } else if (m_engine.IsKeyDown(ysKey::Code::N)) { const double rate = fineControlMode @@ -750,15 +751,15 @@ void EngineSimApplication::processEngineInput() { : 100.0; const double newSimulationFrequency = clamp( - m_simulator.getSimulationFrequency() + mouseWheelDelta * rate * dt, + m_simulator->getSimulationFrequency() + mouseWheelDelta * rate * dt, 400.0, 400000.0); - m_simulator.setSimulationFrequency(newSimulationFrequency); + m_simulator->setSimulationFrequency(newSimulationFrequency); fineControlInUse = true; - m_infoCluster->setLogMessage("[N] - Set simulation freq to " + std::to_string(m_simulator.getSimulationFrequency())); + m_infoCluster->setLogMessage("[N] - Set simulation freq to " + std::to_string(m_simulator->getSimulationFrequency())); } - else if (m_engine.IsKeyDown(ysKey::Code::G) && m_simulator.m_dyno.m_hold) { + else if (m_engine.IsKeyDown(ysKey::Code::G) && m_simulator->m_dyno.m_hold) { if (mouseWheelDelta > 0) { m_dynoSpeed += m_iceEngine->getDynoHoldStep(); } @@ -814,26 +815,26 @@ void EngineSimApplication::processEngineInput() { } if (m_engine.ProcessKeyDown(ysKey::Code::D)) { - m_simulator.m_dyno.m_enabled = !m_simulator.m_dyno.m_enabled; + m_simulator->m_dyno.m_enabled = !m_simulator->m_dyno.m_enabled; - const std::string msg = m_simulator.m_dyno.m_enabled + const std::string msg = m_simulator->m_dyno.m_enabled ? "DYNOMOMETER ENABLED" : "DYNOMOMETER DISABLED"; m_infoCluster->setLogMessage(msg); } if (m_engine.ProcessKeyDown(ysKey::Code::H)) { - m_simulator.m_dyno.m_hold = !m_simulator.m_dyno.m_hold; + m_simulator->m_dyno.m_hold = !m_simulator->m_dyno.m_hold; - const std::string msg = m_simulator.m_dyno.m_hold - ? m_simulator.m_dyno.m_enabled ? "HOLD ENABLED" : "HOLD ON STANDBY [ENABLE DYNO. FOR HOLD]" + const std::string msg = m_simulator->m_dyno.m_hold + ? m_simulator->m_dyno.m_enabled ? "HOLD ENABLED" : "HOLD ON STANDBY [ENABLE DYNO. FOR HOLD]" : "HOLD DISABLED"; m_infoCluster->setLogMessage(msg); } - if (m_simulator.m_dyno.m_enabled) { - if (!m_simulator.m_dyno.m_hold) { - if (m_simulator.getFilteredDynoTorque() > units::torque(1.0, units::ft_lb)) { + if (m_simulator->m_dyno.m_enabled) { + if (!m_simulator->m_dyno.m_hold) { + if (m_simulator->getFilteredDynoTorque() > units::torque(1.0, units::ft_lb)) { m_dynoSpeed += units::rpm(500) * dt; } else { @@ -841,57 +842,57 @@ void EngineSimApplication::processEngineInput() { } if (m_dynoSpeed > m_iceEngine->getRedline()) { - m_simulator.m_dyno.m_enabled = false; + m_simulator->m_dyno.m_enabled = false; m_dynoSpeed = units::rpm(0); } } } else { - if (!m_simulator.m_dyno.m_hold) { + if (!m_simulator->m_dyno.m_hold) { m_dynoSpeed = units::rpm(0); } } m_dynoSpeed = clamp(m_dynoSpeed, m_iceEngine->getDynoMinSpeed(), m_iceEngine->getDynoMaxSpeed()); - m_simulator.m_dyno.m_rotationSpeed = m_dynoSpeed; + m_simulator->m_dyno.m_rotationSpeed = m_dynoSpeed; - const bool prevStarterEnabled = m_simulator.m_starterMotor.m_enabled; + const bool prevStarterEnabled = m_simulator->m_starterMotor.m_enabled; if (m_engine.IsKeyDown(ysKey::Code::S)) { - m_simulator.m_starterMotor.m_enabled = true; + m_simulator->m_starterMotor.m_enabled = true; } else { - m_simulator.m_starterMotor.m_enabled = false; + m_simulator->m_starterMotor.m_enabled = false; } - if (prevStarterEnabled != m_simulator.m_starterMotor.m_enabled) { - const std::string msg = m_simulator.m_starterMotor.m_enabled + if (prevStarterEnabled != m_simulator->m_starterMotor.m_enabled) { + const std::string msg = m_simulator->m_starterMotor.m_enabled ? "STARTER ENABLED" : "STARTER DISABLED"; m_infoCluster->setLogMessage(msg); } if (m_engine.ProcessKeyDown(ysKey::Code::A)) { - m_simulator.getEngine()->getIgnitionModule()->m_enabled = - !m_simulator.getEngine()->getIgnitionModule()->m_enabled; + m_simulator->getEngine()->getIgnitionModule()->m_enabled = + !m_simulator->getEngine()->getIgnitionModule()->m_enabled; - const std::string msg = m_simulator.getEngine()->getIgnitionModule()->m_enabled + const std::string msg = m_simulator->getEngine()->getIgnitionModule()->m_enabled ? "IGNITION ENABLED" : "IGNITION DISABLED"; m_infoCluster->setLogMessage(msg); } if (m_engine.ProcessKeyDown(ysKey::Code::Up)) { - m_simulator.getTransmission()->changeGear(m_simulator.getTransmission()->getGear() + 1); + m_simulator->getTransmission()->changeGear(m_simulator->getTransmission()->getGear() + 1); m_infoCluster->setLogMessage( - "UPSHIFTED TO " + std::to_string(m_simulator.getTransmission()->getGear() + 1)); + "UPSHIFTED TO " + std::to_string(m_simulator->getTransmission()->getGear() + 1)); } else if (m_engine.ProcessKeyDown(ysKey::Code::Down)) { - m_simulator.getTransmission()->changeGear(m_simulator.getTransmission()->getGear() - 1); + m_simulator->getTransmission()->changeGear(m_simulator->getTransmission()->getGear() - 1); - if (m_simulator.getTransmission()->getGear() != -1) { + if (m_simulator->getTransmission()->getGear() != -1) { m_infoCluster->setLogMessage( - "DOWNSHIFTED TO " + std::to_string(m_simulator.getTransmission()->getGear() + 1)); + "DOWNSHIFTED TO " + std::to_string(m_simulator->getTransmission()->getGear() + 1)); } else { m_infoCluster->setLogMessage("SHIFTED TO NEUTRAL"); @@ -921,7 +922,7 @@ void EngineSimApplication::processEngineInput() { const double clutch_s = dt / (dt + clutchRC); m_clutchPressure = m_clutchPressure * (1 - clutch_s) + m_targetClutchPressure * clutch_s; - m_simulator.getTransmission()->setClutchPressure(m_clutchPressure); + m_simulator->getTransmission()->setClutchPressure(m_clutchPressure); } void EngineSimApplication::renderScene() { @@ -1061,15 +1062,15 @@ void EngineSimApplication::refreshUserInterface() { m_infoCluster = m_uiManager.getRoot()->addElement(); m_infoCluster->setEngine(m_iceEngine); - m_rightGaugeCluster->m_simulator = &m_simulator; + m_rightGaugeCluster->m_simulator = m_simulator; m_rightGaugeCluster->setEngine(m_iceEngine); - m_oscCluster->setSimulator(&m_simulator); + m_oscCluster->setSimulator(m_simulator); if (m_iceEngine != nullptr) { m_oscCluster->setDynoMaxRange(units::toRpm(m_iceEngine->getRedline())); } - m_performanceCluster->setSimulator(&m_simulator); - m_loadSimulationCluster->setSimulator(&m_simulator); - m_mixerCluster->setSimulator(&m_simulator); + m_performanceCluster->setSimulator(m_simulator); + m_loadSimulationCluster->setSimulator(m_simulator); + m_mixerCluster->setSimulator(m_simulator); } void EngineSimApplication::startRecording() { diff --git a/src/fuel.cpp b/src/fuel.cpp index 08557f16..aa404ed0 100644 --- a/src/fuel.cpp +++ b/src/fuel.cpp @@ -22,16 +22,16 @@ Fuel::~Fuel() { } void Fuel::initialize(const Parameters ¶ms) { - m_molecularMass = params.MolecularMass; - m_energyDensity = params.EnergyDensity; - m_density = params.Density; - m_turbulenceToFlameSpeedRatio = params.TurbulenceToFlameSpeedRatio; - m_molecularAfr = params.MolecularAfr; - m_burningEfficiencyRandomness = params.BurningEfficiencyRandomness; - m_maxBurningEfficiency = params.MaxBurningEfficiency; - m_maxDilutionEffect = params.MaxDilutionEffect; - m_maxTurbulenceEffect = params.MaxTurbulenceEffect; - m_lowEfficiencyAttenuation = params.LowEfficiencyAttenuation; + m_molecularMass = params.molecularMass; + m_energyDensity = params.energyDensity; + m_density = params.density; + m_turbulenceToFlameSpeedRatio = params.turbulenceToFlameSpeedRatio; + m_molecularAfr = params.molecularAfr; + m_burningEfficiencyRandomness = params.burningEfficiencyRandomness; + m_maxBurningEfficiency = params.maxBurningEfficiency; + m_maxDilutionEffect = params.maxDilutionEffect; + m_maxTurbulenceEffect = params.maxTurbulenceEffect; + m_lowEfficiencyAttenuation = params.lowEfficiencyAttenuation; } double Fuel::flameSpeed( diff --git a/src/ignition_module.cpp b/src/ignition_module.cpp index e3642e46..968925cd 100644 --- a/src/ignition_module.cpp +++ b/src/ignition_module.cpp @@ -30,19 +30,19 @@ void IgnitionModule::destroy() { } void IgnitionModule::initialize(const Parameters ¶ms) { - m_cylinderCount = params.CylinderCount; + m_cylinderCount = params.cylinderCount; m_plugs = new SparkPlug[m_cylinderCount]; - m_crankshaft = params.Crankshaft; - m_timingCurve = params.TimingCurve; - m_revLimit = params.RevLimit; - m_limiterDuration = params.LimiterDuration; + m_crankshaft = params.crankshaft; + m_timingCurve = params.timingCurve; + m_revLimit = params.revLimit; + m_limiterDuration = params.limiterDuration; } void IgnitionModule::setFiringOrder(int cylinderIndex, double angle) { assert(cylinderIndex < m_cylinderCount); - m_plugs[cylinderIndex].Angle = angle; - m_plugs[cylinderIndex].Enabled = true; + m_plugs[cylinderIndex].angle = angle; + m_plugs[cylinderIndex].enabled = true; } void IgnitionModule::reset() { @@ -58,7 +58,7 @@ void IgnitionModule::update(double dt) { const double advance = getTimingAdvance(); for (int i = 0; i < m_cylinderCount; ++i) { - double adjustedAngle = positiveMod(m_plugs[i].Angle - advance, fourPi); + double adjustedAngle = positiveMod(m_plugs[i].angle - advance, fourPi); const double r0 = m_lastCrankshaftAngle; double r1 = cycleAngle; @@ -69,7 +69,7 @@ void IgnitionModule::update(double dt) { } if (adjustedAngle >= r0 && adjustedAngle < r1) { - m_plugs[i].IgnitionEvent = m_plugs[i].Enabled; + m_plugs[i].ignitionEvent = m_plugs[i].enabled; } } else { @@ -79,7 +79,7 @@ void IgnitionModule::update(double dt) { } if (adjustedAngle >= r1 && adjustedAngle < r0) { - m_plugs[i].IgnitionEvent = m_plugs[i].Enabled; + m_plugs[i].ignitionEvent = m_plugs[i].enabled; } } } @@ -98,12 +98,12 @@ void IgnitionModule::update(double dt) { } bool IgnitionModule::getIgnitionEvent(int index) const { - return m_plugs[index].IgnitionEvent; + return m_plugs[index].ignitionEvent; } void IgnitionModule::resetIgnitionEvents() { for (int i = 0; i < m_cylinderCount; ++i) { - m_plugs[i].IgnitionEvent = false; + m_plugs[i].ignitionEvent = false; } } diff --git a/src/intake.cpp b/src/intake.cpp index a3546ee3..56f2d63b 100644 --- a/src/intake.cpp +++ b/src/intake.cpp @@ -25,11 +25,11 @@ void Intake::initialize(Parameters ¶ms) { const double width = std::sqrt(params.CrossSectionArea); m_system.initialize( units::pressure(1.0, units::atm), - params.Volume, + params.volume, units::celcius(25.0)); m_system.setGeometry( width, - params.Volume / params.CrossSectionArea, + params.volume / params.CrossSectionArea, 1.0, 0.0); diff --git a/src/mixer_cluster.cpp b/src/mixer_cluster.cpp index e5359413..5dd89634 100644 --- a/src/mixer_cluster.cpp +++ b/src/mixer_cluster.cpp @@ -148,27 +148,27 @@ void MixerCluster::render() { grid.h_cells = 6; grid.v_cells = 1; - Synthesizer::AudioParameters parameters = m_simulator->getSynthesizer()->getAudioParameters(); + Synthesizer::AudioParameters parameters = m_simulator->synthesizer().getAudioParameters(); m_volumeGauge->m_bounds = grid.get(m_bounds, 0, 0); - m_volumeGauge->m_gauge->m_value = (float)parameters.Volume * 100.0f; + m_volumeGauge->m_gauge->m_value = (float)parameters.volume * 100.0f; m_convolutionGauge->m_bounds = grid.get(m_bounds, 1, 0); - m_convolutionGauge->m_gauge->m_value = (float)parameters.Convolution * 100.0f; + m_convolutionGauge->m_gauge->m_value = (float)parameters.convolution * 100.0f; m_highFreqFilterGauge->m_bounds = grid.get(m_bounds, 2, 0); m_highFreqFilterGauge->m_gauge->m_value = (float)parameters.dF_F_mix * 1000.0f; m_noise0Gauge->m_bounds = grid.get(m_bounds, 3, 0); - m_noise0Gauge->m_gauge->m_value = (float)parameters.AirNoise * 100.0f; + m_noise0Gauge->m_gauge->m_value = (float)parameters.airNoise * 100.0f; m_noise1Gauge->m_bounds = grid.get(m_bounds, 4, 0); - m_noise1Gauge->m_gauge->m_value = (float)parameters.InputSampleNoise * 100.0f; + m_noise1Gauge->m_gauge->m_value = (float)parameters.inputSampleNoise * 100.0f; - const double gain = m_simulator->getSynthesizer()->getLevelerGain(); + const double gain = m_simulator->synthesizer().getLevelerGain(); m_levelerGauge->m_bounds = grid.get(m_bounds, 5, 0); m_levelerGauge->m_gauge->m_value = - 100.0f * (float)((gain - parameters.LevelerMinGain) / parameters.LevelerMaxGain); + 100.0f * (float)((gain - parameters.levelerMinGain) / parameters.levelerMaxGain); UiElement::render(); } diff --git a/src/piston.cpp b/src/piston.cpp index a69b8bd9..13fac389 100644 --- a/src/piston.cpp +++ b/src/piston.cpp @@ -29,7 +29,7 @@ void Piston::initialize(const Parameters ¶ms) { m_compressionHeight = params.CompressionHeight; m_displacement = params.Displacement; m_wristPinLocation = params.WristPinPosition; - m_mass = params.Mass; + m_mass = params.mass; m_blowby_k = params.BlowbyFlowCoefficient; } diff --git a/src/piston_engine_simulator.cpp b/src/piston_engine_simulator.cpp new file mode 100644 index 00000000..c0a2e3ed --- /dev/null +++ b/src/piston_engine_simulator.cpp @@ -0,0 +1,413 @@ +#include "../include/piston_engine_simulator.h" + +#include "../include/constants.h" +#include "../include/units.h" + +#include +#include +#include +#include + +PistonEngineSimulator::PistonEngineSimulator() { + m_engine = nullptr; + m_transmission = nullptr; + m_vehicle = nullptr; + m_delayFilters = nullptr; + + m_crankConstraints = nullptr; + m_cylinderWallConstraints = nullptr; + m_linkConstraints = nullptr; + m_crankshaftFrictionConstraints = nullptr; + m_crankshaftLinks = nullptr; + + m_exhaustFlowStagingBuffer = nullptr; + + m_derivativeFilter.m_dt = 1.0; + m_fluidSimulationSteps = 8; +} + +PistonEngineSimulator::~PistonEngineSimulator() { + assert(m_crankConstraints == nullptr); + assert(m_cylinderWallConstraints == nullptr); + assert(m_linkConstraints == nullptr); + assert(m_crankshaftFrictionConstraints == nullptr); + assert(m_exhaustFlowStagingBuffer == nullptr); + assert(m_delayFilters == nullptr); + assert(m_antialiasingFilters == nullptr); +} + +void PistonEngineSimulator::loadSimulation(Engine *engine, Vehicle *vehicle, Transmission *transmission) { + Simulator::loadSimulation(engine, vehicle, transmission); + + m_engine = engine; + m_vehicle = vehicle; + m_transmission = transmission; + + const int crankCount = m_engine->getCrankshaftCount(); + const int cylinderCount = m_engine->getCylinderCount(); + const int linkCount = cylinderCount * 2; + + if (crankCount <= 0) return; + + m_crankConstraints = new atg_scs::FixedPositionConstraint[crankCount]; + m_cylinderWallConstraints = new atg_scs::LineConstraint[cylinderCount]; + m_linkConstraints = new atg_scs::LinkConstraint[linkCount]; + m_crankshaftFrictionConstraints = new atg_scs::RotationFrictionConstraint[crankCount]; + m_crankshaftLinks = new atg_scs::ClutchConstraint[crankCount - 1]; + m_delayFilters = new DelayFilter[cylinderCount]; + + const double ks = 5000; + const double kd = 10; + + for (int i = 0; i < crankCount; ++i) { + Crankshaft *outputShaft = m_engine->getCrankshaft(0); + Crankshaft *crankshaft = m_engine->getCrankshaft(i); + + m_crankConstraints[i].setBody(&crankshaft->m_body); + m_crankConstraints[i].setWorldPosition( + crankshaft->getPosX(), + crankshaft->getPosY()); + m_crankConstraints[i].setLocalPosition(0.0, 0.0); + m_crankConstraints[i].m_kd = kd; + m_crankConstraints[i].m_ks = ks; + + crankshaft->m_body.p_x = crankshaft->getPosX(); + crankshaft->m_body.p_y = crankshaft->getPosY(); + crankshaft->m_body.theta = 0; + crankshaft->m_body.m = + crankshaft->getMass() + crankshaft->getFlywheelMass(); + crankshaft->m_body.I = crankshaft->getMomentOfInertia(); + + m_crankshaftFrictionConstraints[i].m_minTorque = -crankshaft->getFrictionTorque(); + m_crankshaftFrictionConstraints[i].m_maxTorque = crankshaft->getFrictionTorque(); + m_crankshaftFrictionConstraints[i].setBody(&m_engine->getCrankshaft(i)->m_body); + + m_system->addRigidBody(&m_engine->getCrankshaft(i)->m_body); + m_system->addConstraint(&m_crankConstraints[i]); + m_system->addConstraint(&m_crankshaftFrictionConstraints[i]); + + if (crankshaft != outputShaft) { + atg_scs::ClutchConstraint *crankLink = &m_crankshaftLinks[i - 1]; + crankLink->setBody1(&outputShaft->m_body); + crankLink->setBody2(&crankshaft->m_body); + + m_system->addConstraint(crankLink); + } + } + + m_transmission->addToSystem(m_system, &m_vehicleMass, m_vehicle, m_engine); + m_vehicle->addToSystem(m_system, &m_vehicleMass); + + m_vehicleDrag.initialize(&m_vehicleMass, m_vehicle); + m_system->addConstraint(&m_vehicleDrag); + + m_vehicleMass.reset(); + m_vehicleMass.m = 1.0; + m_vehicleMass.I = 1.0; + m_system->addRigidBody(&m_vehicleMass); + + for (int i = 0; i < cylinderCount; ++i) { + Piston *piston = m_engine->getPiston(i); + ConnectingRod *connectingRod = piston->getRod(); + + CylinderBank *bank = piston->getCylinderBank(); + const double dx = std::cos(bank->getAngle() + constants::pi / 2); + const double dy = std::sin(bank->getAngle() + constants::pi / 2); + + m_cylinderWallConstraints[i].setBody(&piston->m_body); + m_cylinderWallConstraints[i].m_dx = dx; + m_cylinderWallConstraints[i].m_dy = dy; + m_cylinderWallConstraints[i].m_local_x = 0.0; + m_cylinderWallConstraints[i].m_local_y = piston->getWristPinLocation(); + m_cylinderWallConstraints[i].m_p0_x = bank->getX(); + m_cylinderWallConstraints[i].m_p0_y = bank->getY(); + m_cylinderWallConstraints[i].m_ks = ks; + m_cylinderWallConstraints[i].m_kd = kd; + + piston->setCylinderConstraint(&m_cylinderWallConstraints[i]); + + m_linkConstraints[i * 2 + 0].setBody1(&connectingRod->m_body); + m_linkConstraints[i * 2 + 0].setBody2(&piston->m_body); + m_linkConstraints[i * 2 + 0] + .setLocalPosition1(0.0, connectingRod->getLittleEndLocal()); + m_linkConstraints[i * 2 + 0].setLocalPosition2(0.0, piston->getWristPinLocation()); + m_linkConstraints[i * 2 + 0].m_ks = ks; + m_linkConstraints[i * 2 + 0].m_kd = kd; + + double journal_x = 0.0, journal_y = 0.0; + if (connectingRod->getMasterRod() == nullptr) { + Crankshaft *crankshaft = connectingRod->getCrankshaft(); + crankshaft->getRodJournalPositionLocal( + connectingRod->getJournal(), + &journal_x, + &journal_y); + m_linkConstraints[i * 2 + 1].setBody2(&crankshaft->m_body); + } + else { + connectingRod->getMasterRod()->getRodJournalPositionLocal( + connectingRod->getJournal(), + &journal_x, + &journal_y); + m_linkConstraints[i * 2 + 1].setBody2(&connectingRod->getMasterRod()->m_body); + } + + m_linkConstraints[i * 2 + 1].setBody1(&connectingRod->m_body); + m_linkConstraints[i * 2 + 1] + .setLocalPosition1(0.0, connectingRod->getBigEndLocal()); + m_linkConstraints[i * 2 + 1] + .setLocalPosition2(journal_x, journal_y); + m_linkConstraints[i * 2 + 1].m_ks = ks; + m_linkConstraints[i * 2 + 0].m_kd = kd; + + piston->m_body.m = piston->getMass(); + piston->m_body.I = 1.0; + + connectingRod->m_body.m = connectingRod->getMass(); + connectingRod->m_body.I = connectingRod->getMomentOfInertia(); + + m_system->addRigidBody(&piston->m_body); + m_system->addRigidBody(&connectingRod->m_body); + m_system->addConstraint(&m_linkConstraints[i * 2 + 0]); + m_system->addConstraint(&m_linkConstraints[i * 2 + 1]); + m_system->addConstraint(&m_cylinderWallConstraints[i]); + m_system->addForceGenerator(m_engine->getChamber(i)); + } + + m_dyno.connectCrankshaft(m_engine->getOutputCrankshaft()); + m_system->addConstraint(&m_dyno); + + m_starterMotor.connectCrankshaft(m_engine->getOutputCrankshaft()); + m_starterMotor.m_maxTorque = m_engine->getStarterTorque(); + m_starterMotor.m_rotationSpeed = -m_engine->getStarterSpeed(); + m_system->addConstraint(&m_starterMotor); + + placeAndInitialize(); + initializeSynthesizer(); +} + +double PistonEngineSimulator::getAverageOutputSignal() const { + double sum = 0.0; + for (int i = 0; i < m_engine->getExhaustSystemCount(); ++i) { + sum += m_engine->getExhaustSystem(i)->getSystem()->pressure(); + } + + return sum / m_engine->getExhaustSystemCount(); +} + +void PistonEngineSimulator::placeAndInitialize() { + const int cylinderCount = m_engine->getCylinderCount(); + for (int i = 0; i < cylinderCount; ++i) { + ConnectingRod *rod = m_engine->getConnectingRod(i); + + if (rod->getRodJournalCount() != 0) { + placeCylinder(i); + } + } + + for (int i = 0; i < cylinderCount; ++i) { + placeCylinder(i); + } + + for (int i = 0; i < cylinderCount; ++i) { + m_engine->getChamber(i)->m_system.initialize( + units::pressure(1.0, units::atm), + m_engine->getChamber(i)->getVolume(), + units::celcius(25.0) + ); + + Piston *piston = m_engine->getChamber(i)->getPiston(); + CylinderHead *head = m_engine->getChamber(i)->getCylinderHead(); + ExhaustSystem *exhaust = head->getExhaustSystem(piston->getCylinderIndex()); + const double exhaustLength = + head->getHeaderPrimaryLength(piston->getCylinderIndex()) + + exhaust->getLength(); + const double speedOfSound = 343.0 * units::m / units::sec; + const double delay = exhaustLength / speedOfSound; + m_delayFilters[i].initialize(delay, 10000.0); + } + + m_engine->getIgnitionModule()->reset(); + + m_exhaustFlowStagingBuffer = new double[m_engine->getExhaustSystemCount()]; +} + +void PistonEngineSimulator::placeCylinder(int i) { + ConnectingRod *rod = m_engine->getConnectingRod(i); + Piston *piston = m_engine->getPiston(i); + CylinderBank *bank = piston->getCylinderBank(); + + double p_x, p_y; + if (rod->getMasterRod() != nullptr) { + rod->getMasterRod()->getRodJournalPositionGlobal(rod->getJournal(), &p_x, &p_y); + } + else { + rod->getCrankshaft()->getRodJournalPositionGlobal(rod->getJournal(), &p_x, &p_y); + } + + // (bank->m_x + bank->m_dx * s - p_x)^2 + (bank->m_y + bank->m_dy * s - p_y)^2 = (rod->m_length)^2 + const double a = bank->getDx() * bank->getDx() + bank->getDy() * bank->getDy(); + const double b = -2 * bank->getDx() * (p_x - bank->getX()) - 2 * bank->getDy() * (p_y - bank->getY()); + const double c = + (p_x - bank->getX()) * (p_x - bank->getX()) + + (p_y - bank->getY()) * (p_y - bank->getY()) + - rod->getLength() * rod->getLength(); + + const double det = b * b - 4 * a * c; + if (det < 0) return; + + const double sqrt_det = std::sqrt(det); + const double s0 = (-b + sqrt_det) / (2 * a); + const double s1 = (-b - sqrt_det) / (2 * a); + + const double s = std::max(s0, s1); + if (s < 0) return; + + const double e_x = s * bank->getDx() + bank->getX(); + const double e_y = s * bank->getDy() + bank->getY(); + + const double theta = ((e_y - p_y) > 0) + ? std::acos((e_x - p_x) / rod->getLength()) + : 2 * constants::pi - std::acos((e_x - p_x) / rod->getLength()); + rod->m_body.theta = theta - constants::pi / 2; + + double cl_x, cl_y; + rod->m_body.localToWorld(0, rod->getBigEndLocal(), &cl_x, &cl_y); + rod->m_body.p_x += p_x - cl_x; + rod->m_body.p_y += p_y - cl_y; + + piston->m_body.p_x = e_x; + piston->m_body.p_y = e_y; + piston->m_body.theta = bank->getAngle() + constants::pi; +} + +void PistonEngineSimulator::simulateStep_() { + const double timestep = getTimestep(); + IgnitionModule *im = m_engine->getIgnitionModule(); + im->update(timestep); + + const int cylinderCount = m_engine->getCylinderCount(); + for (int i = 0; i < cylinderCount; ++i) { + if (im->getIgnitionEvent(i)) { + m_engine->getChamber(i)->ignite(); + } + + m_engine->getChamber(i)->update(timestep); + } + + for (int i = 0; i < cylinderCount; ++i) { + m_engine->getChamber(i)->resetLastTimestepExhaustFlow(); + m_engine->getChamber(i)->resetLastTimestepIntakeFlow(); + } + + const int exhaustSystemCount = m_engine->getExhaustSystemCount(); + const int intakeCount = m_engine->getIntakeCount(); + const double fluidTimestep = timestep / m_fluidSimulationSteps; + for (int i = 0; i < m_fluidSimulationSteps; ++i) { + for (int j = 0; j < exhaustSystemCount; ++j) { + m_engine->getExhaustSystem(j)->process(fluidTimestep); + } + + for (int j = 0; j < intakeCount; ++j) { + m_engine->getIntake(j)->process(fluidTimestep); + m_engine->getIntake(j)->m_flowRate += m_engine->getIntake(j)->m_flow; + } + + for (int j = 0; j < cylinderCount; ++j) { + m_engine->getChamber(j)->flow(fluidTimestep); + } + } + + im->resetIgnitionEvents(); +} + +double PistonEngineSimulator::getTotalExhaustFlow() const { + double totalFlow = 0.0; + for (int i = 0; i < m_engine->getCylinderCount(); ++i) { + totalFlow += m_engine->getChamber(i)->getLastTimestepExhaustFlow(); + } + + return totalFlow; +} + +void PistonEngineSimulator::endFrame() { + Simulator::endFrame(); + + if (m_engine == nullptr) { + return; + } + + const double frameTimestep = simulationSteps() * getTimestep(); + const int cylinderCount = m_engine->getCylinderCount(); + for (int i = 0; i < m_engine->getIntakeCount(); ++i) { + m_engine->getIntake(i)->m_flowRate /= frameTimestep; + } +} + +void PistonEngineSimulator::destroy() { + if (m_system != nullptr) m_system->reset(); + + if (m_crankConstraints != nullptr) delete[] m_crankConstraints; + if (m_cylinderWallConstraints != nullptr) delete[] m_cylinderWallConstraints; + if (m_linkConstraints != nullptr) delete[] m_linkConstraints; + if (m_crankshaftFrictionConstraints != nullptr) delete[] m_crankshaftFrictionConstraints; + if (m_exhaustFlowStagingBuffer != nullptr) delete[] m_exhaustFlowStagingBuffer; + if (m_system != nullptr) delete m_system; + if (m_delayFilters != nullptr) delete[] m_delayFilters; + + m_crankConstraints = nullptr; + m_cylinderWallConstraints = nullptr; + m_linkConstraints = nullptr; + m_crankshaftFrictionConstraints = nullptr; + m_exhaustFlowStagingBuffer = nullptr; + m_system = nullptr; + + m_vehicle = nullptr; + m_transmission = nullptr; + m_engine = nullptr; + m_delayFilters = nullptr; +} + +void PistonEngineSimulator::writeToSynthesizer() { + const int exhaustSystemCount = m_engine->getExhaustSystemCount(); + for (int i = 0; i < exhaustSystemCount; ++i) { + m_exhaustFlowStagingBuffer[i] = 0; + } + + const double attenuation = std::min(std::abs(filteredEngineSpeed()), 40.0) / 40.0; + const double attenuation_3 = attenuation * attenuation * attenuation; + + static double lastValveLift[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + const double timestep = getTimestep(); + const int cylinderCount = m_engine->getCylinderCount(); + for (int i = 0; i < cylinderCount; ++i) { + Piston *piston = m_engine->getPiston(i); + CylinderBank *bank = piston->getCylinderBank(); + CylinderHead *head = m_engine->getHead(bank->getIndex()); + ExhaustSystem *exhaust = head->getExhaustSystem(piston->getCylinderIndex()); + CombustionChamber *chamber = m_engine->getChamber(i); + + const double exhaustLength = + head->getHeaderPrimaryLength(piston->getCylinderIndex()) + + exhaust->getLength(); + + double exhaustFlow = + attenuation_3 * 1600 * ( + 1.0 * (chamber->m_exhaustRunnerAndPrimary.pressure() - units::pressure(1.0, units::atm)) + + 0.1 * chamber->m_exhaustRunnerAndPrimary.dynamicPressure(1.0, 0.0) + + 0.1 * chamber->m_exhaustRunnerAndPrimary.dynamicPressure(-1.0, 0.0)); + + lastValveLift[i] = head->exhaustValveLift(piston->getCylinderIndex()); + + const double delayedExhaustPulse = + m_delayFilters[i].fast_f(exhaustFlow); + + ExhaustSystem *exhaustSystem = head->getExhaustSystem(piston->getCylinderIndex()); + m_exhaustFlowStagingBuffer[exhaustSystem->getIndex()] += + head->getSoundAttenuation(piston->getCylinderIndex()) + * (exhaustSystem->getAudioVolume() * delayedExhaustPulse / cylinderCount) + * (1 / (exhaustLength * exhaustLength)); + } + + synthesizer().writeInput(m_exhaustFlowStagingBuffer); +} diff --git a/src/simulation_object.cpp b/src/simulation_object.cpp index 9843dd8d..80f5d6e7 100644 --- a/src/simulation_object.cpp +++ b/src/simulation_object.cpp @@ -62,7 +62,8 @@ void SimulationObject::setTransform( float scale, float lx, float ly, - float angle) + float angle, + float z) { double p_x, p_y; rigidBody->localToWorld(lx, ly, &p_x, &p_y); @@ -71,7 +72,7 @@ void SimulationObject::setTransform( ysMath::Constants::ZAxis, (float)rigidBody->theta + angle); const ysMatrix trans = ysMath::TranslationTransform( - ysMath::LoadVector((float)p_x, (float)p_y, 0.0f)); + ysMath::LoadVector((float)p_x, (float)p_y, z)); const ysMatrix scaleTransform = ysMath::ScaleTransform(ysMath::LoadScalar(scale)); m_app->getShaders()->SetObjectTransform( diff --git a/src/simulator.cpp b/src/simulator.cpp index 5d021e5a..a6cfa13f 100644 --- a/src/simulator.cpp +++ b/src/simulator.cpp @@ -1,59 +1,32 @@ -#include "..\include\simulator.h" -#include "..\include\simulator.h" #include "../include/simulator.h" -#include "../include/constants.h" -#include "../include/units.h" - -#include -#include -#include -#include - Simulator::Simulator() { m_engine = nullptr; - m_transmission = nullptr; m_vehicle = nullptr; - m_delayFilters = nullptr; + m_transmission = nullptr; + m_system = nullptr; + + m_physicsProcessingTime = 0; - i_steps = 0; - m_currentIteration = 0; m_simulationSpeed = 1.0; m_targetSynthesizerLatency = 0.1; m_simulationFrequency = 10000; - m_fluidSimulationSteps = 8; + m_steps = 0; - m_crankConstraints = nullptr; - m_cylinderWallConstraints = nullptr; - m_linkConstraints = nullptr; - m_crankshaftFrictionConstraints = nullptr; - m_crankshaftLinks = nullptr; - m_system = nullptr; - - m_physicsProcessingTime = 0.0; - m_exhaustFlowStagingBuffer = nullptr; + m_currentIteration = 0; m_filteredEngineSpeed = 0.0; m_dynoTorqueSamples = nullptr; m_lastDynoTorqueSample = 0; - - m_derivativeFilter.m_dt = 1.0; } Simulator::~Simulator() { - assert(m_crankConstraints == nullptr); - assert(m_cylinderWallConstraints == nullptr); - assert(m_linkConstraints == nullptr); - assert(m_crankshaftFrictionConstraints == nullptr); assert(m_system == nullptr); - assert(m_exhaustFlowStagingBuffer == nullptr); - assert(m_delayFilters == nullptr); - assert(m_antialiasingFilters == nullptr); assert(m_dynoTorqueSamples == nullptr); } void Simulator::initialize(const Parameters ¶ms) { - if (params.SystemType == SystemType::NsvOptimized) { + if (params.systemType == SystemType::NsvOptimized) { atg_scs::OptimizedNsvRigidBodySystem *system = new atg_scs::OptimizedNsvRigidBodySystem; system->initialize( @@ -79,147 +52,6 @@ void Simulator::loadSimulation(Engine *engine, Vehicle *vehicle, Transmission *t m_engine = engine; m_vehicle = vehicle; m_transmission = transmission; - - const int crankCount = m_engine->getCrankshaftCount(); - const int cylinderCount = m_engine->getCylinderCount(); - const int linkCount = cylinderCount * 2; - - if (crankCount <= 0) return; - - m_crankConstraints = new atg_scs::FixedPositionConstraint[crankCount]; - m_cylinderWallConstraints = new atg_scs::LineConstraint[cylinderCount]; - m_linkConstraints = new atg_scs::LinkConstraint[linkCount]; - m_crankshaftFrictionConstraints = new atg_scs::RotationFrictionConstraint[crankCount]; - m_crankshaftLinks = new atg_scs::ClutchConstraint[crankCount - 1]; - m_delayFilters = new DelayFilter[cylinderCount]; - - const double ks = 5000; - const double kd = 10; - - for (int i = 0; i < crankCount; ++i) { - Crankshaft *outputShaft = m_engine->getCrankshaft(0); - Crankshaft *crankshaft = m_engine->getCrankshaft(i); - - m_crankConstraints[i].setBody(&crankshaft->m_body); - m_crankConstraints[i].setWorldPosition( - crankshaft->getPosX(), - crankshaft->getPosY()); - m_crankConstraints[i].setLocalPosition(0.0, 0.0); - m_crankConstraints[i].m_kd = kd; - m_crankConstraints[i].m_ks = ks; - - crankshaft->m_body.p_x = crankshaft->getPosX(); - crankshaft->m_body.p_y = crankshaft->getPosY(); - crankshaft->m_body.theta = 0; - crankshaft->m_body.m = - crankshaft->getMass() + crankshaft->getFlywheelMass(); - crankshaft->m_body.I = crankshaft->getMomentOfInertia(); - - m_crankshaftFrictionConstraints[i].m_minTorque = -crankshaft->getFrictionTorque(); - m_crankshaftFrictionConstraints[i].m_maxTorque = crankshaft->getFrictionTorque(); - m_crankshaftFrictionConstraints[i].setBody(&m_engine->getCrankshaft(i)->m_body); - - m_system->addRigidBody(&m_engine->getCrankshaft(i)->m_body); - m_system->addConstraint(&m_crankConstraints[i]); - m_system->addConstraint(&m_crankshaftFrictionConstraints[i]); - - if (crankshaft != outputShaft) { - atg_scs::ClutchConstraint *crankLink = &m_crankshaftLinks[i - 1]; - crankLink->setBody1(&outputShaft->m_body); - crankLink->setBody2(&crankshaft->m_body); - - m_system->addConstraint(crankLink); - } - } - - m_transmission->addToSystem(m_system, &m_vehicleMass, m_vehicle, m_engine); - m_vehicle->addToSystem(m_system, &m_vehicleMass); - - m_vehicleDrag.initialize(&m_vehicleMass, m_vehicle); - m_system->addConstraint(&m_vehicleDrag); - - m_vehicleMass.reset(); - m_vehicleMass.m = 1.0; - m_vehicleMass.I = 1.0; - m_system->addRigidBody(&m_vehicleMass); - - for (int i = 0; i < cylinderCount; ++i) { - Piston *piston = m_engine->getPiston(i); - ConnectingRod *connectingRod = piston->getRod(); - - CylinderBank *bank = piston->getCylinderBank(); - const double dx = std::cos(bank->getAngle() + constants::pi / 2); - const double dy = std::sin(bank->getAngle() + constants::pi / 2); - - m_cylinderWallConstraints[i].setBody(&piston->m_body); - m_cylinderWallConstraints[i].m_dx = dx; - m_cylinderWallConstraints[i].m_dy = dy; - m_cylinderWallConstraints[i].m_local_x = 0.0; - m_cylinderWallConstraints[i].m_local_y = piston->getWristPinLocation(); - m_cylinderWallConstraints[i].m_p0_x = bank->getX(); - m_cylinderWallConstraints[i].m_p0_y = bank->getY(); - m_cylinderWallConstraints[i].m_ks = ks; - m_cylinderWallConstraints[i].m_kd = kd; - - piston->setCylinderConstraint(&m_cylinderWallConstraints[i]); - - m_linkConstraints[i * 2 + 0].setBody1(&connectingRod->m_body); - m_linkConstraints[i * 2 + 0].setBody2(&piston->m_body); - m_linkConstraints[i * 2 + 0] - .setLocalPosition1(0.0, connectingRod->getLittleEndLocal()); - m_linkConstraints[i * 2 + 0].setLocalPosition2(0.0, piston->getWristPinLocation()); - m_linkConstraints[i * 2 + 0].m_ks = ks; - m_linkConstraints[i * 2 + 0].m_kd = kd; - - double journal_x = 0.0, journal_y = 0.0; - if (connectingRod->getMasterRod() == nullptr) { - Crankshaft *crankshaft = connectingRod->getCrankshaft(); - crankshaft->getRodJournalPositionLocal( - connectingRod->getJournal(), - &journal_x, - &journal_y); - m_linkConstraints[i * 2 + 1].setBody2(&crankshaft->m_body); - } - else { - connectingRod->getMasterRod()->getRodJournalPositionLocal( - connectingRod->getJournal(), - &journal_x, - &journal_y); - m_linkConstraints[i * 2 + 1].setBody2(&connectingRod->getMasterRod()->m_body); - } - - m_linkConstraints[i * 2 + 1].setBody1(&connectingRod->m_body); - m_linkConstraints[i * 2 + 1] - .setLocalPosition1(0.0, connectingRod->getBigEndLocal()); - m_linkConstraints[i * 2 + 1] - .setLocalPosition2(journal_x, journal_y); - m_linkConstraints[i * 2 + 1].m_ks = ks; - m_linkConstraints[i * 2 + 0].m_kd = kd; - - piston->m_body.m = piston->getMass(); - piston->m_body.I = 1.0; - - connectingRod->m_body.m = connectingRod->getMass(); - connectingRod->m_body.I = connectingRod->getMomentOfInertia(); - - m_system->addRigidBody(&piston->m_body); - m_system->addRigidBody(&connectingRod->m_body); - m_system->addConstraint(&m_linkConstraints[i * 2 + 0]); - m_system->addConstraint(&m_linkConstraints[i * 2 + 1]); - m_system->addConstraint(&m_cylinderWallConstraints[i]); - m_system->addForceGenerator(m_engine->getChamber(i)); - } - - m_dyno.connectCrankshaft(m_engine->getOutputCrankshaft()); - m_system->addConstraint(&m_dyno); - - m_starterMotor.connectCrankshaft(m_engine->getOutputCrankshaft()); - m_starterMotor.m_maxTorque = m_engine->getStarterTorque(); - m_starterMotor.m_rotationSpeed = -m_engine->getStarterSpeed(); - m_system->addConstraint(&m_starterMotor); - - placeAndInitialize(); - initializeSynthesizer(); } void Simulator::releaseSimulation() { @@ -229,119 +61,9 @@ void Simulator::releaseSimulation() { destroy(); } -double Simulator::getFilteredDynoTorque() const { - if (m_dynoTorqueSamples == nullptr) return 0; - - double averageTorque = 0; - for (int i = 0; i < DynoTorqueSamples; ++i) { - averageTorque += m_dynoTorqueSamples[i]; - } - - return averageTorque / DynoTorqueSamples; -} - -double Simulator::getDynoPower() const { - return (m_engine != nullptr) - ? getFilteredDynoTorque() * m_engine->getSpeed() - : 0; -} - -double Simulator::getAverageOutputSignal() const { - double sum = 0.0; - for (int i = 0; i < m_engine->getExhaustSystemCount(); ++i) { - sum += m_engine->getExhaustSystem(i)->getSystem()->pressure(); - } - - return sum / m_engine->getExhaustSystemCount(); -} - -void Simulator::placeAndInitialize() { - const int cylinderCount = m_engine->getCylinderCount(); - for (int i = 0; i < cylinderCount; ++i) { - ConnectingRod *rod = m_engine->getConnectingRod(i); - - if (rod->getRodJournalCount() != 0) { - placeCylinder(i); - } - } - - for (int i = 0; i < cylinderCount; ++i) { - placeCylinder(i); - } - - for (int i = 0; i < cylinderCount; ++i) { - m_engine->getChamber(i)->m_system.initialize( - units::pressure(1.0, units::atm), - m_engine->getChamber(i)->getVolume(), - units::celcius(25.0) - ); - - Piston *piston = m_engine->getChamber(i)->getPiston(); - CylinderHead *head = m_engine->getChamber(i)->getCylinderHead(); - ExhaustSystem *exhaust = head->getExhaustSystem(piston->getCylinderIndex()); - const double exhaustLength = - head->getHeaderPrimaryLength(piston->getCylinderIndex()) - + exhaust->getLength(); - const double speedOfSound = 343.0 * units::m / units::sec; - const double delay = exhaustLength / speedOfSound; - m_delayFilters[i].initialize(delay, 10000.0); - } - - m_engine->getIgnitionModule()->reset(); -} - -void Simulator::placeCylinder(int i) { - ConnectingRod *rod = m_engine->getConnectingRod(i); - Piston *piston = m_engine->getPiston(i); - CylinderBank *bank = piston->getCylinderBank(); - - double p_x, p_y; - if (rod->getMasterRod() != nullptr) { - rod->getMasterRod()->getRodJournalPositionGlobal(rod->getJournal(), &p_x, &p_y); - } - else { - rod->getCrankshaft()->getRodJournalPositionGlobal(rod->getJournal(), &p_x, &p_y); - } - - // (bank->m_x + bank->m_dx * s - p_x)^2 + (bank->m_y + bank->m_dy * s - p_y)^2 = (rod->m_length)^2 - const double a = bank->getDx() * bank->getDx() + bank->getDy() * bank->getDy(); - const double b = -2 * bank->getDx() * (p_x - bank->getX()) - 2 * bank->getDy() * (p_y - bank->getY()); - const double c = - (p_x - bank->getX()) * (p_x - bank->getX()) - + (p_y - bank->getY()) * (p_y - bank->getY()) - - rod->getLength() * rod->getLength(); - - const double det = b * b - 4 * a * c; - if (det < 0) return; - - const double sqrt_det = std::sqrt(det); - const double s0 = (-b + sqrt_det) / (2 * a); - const double s1 = (-b - sqrt_det) / (2 * a); - - const double s = std::max(s0, s1); - if (s < 0) return; - - const double e_x = s * bank->getDx() + bank->getX(); - const double e_y = s * bank->getDy() + bank->getY(); - - const double theta = ((e_y - p_y) > 0) - ? std::acos((e_x - p_x) / rod->getLength()) - : 2 * constants::pi - std::acos((e_x - p_x) / rod->getLength()); - rod->m_body.theta = theta - constants::pi / 2; - - double cl_x, cl_y; - rod->m_body.localToWorld(0, rod->getBigEndLocal(), &cl_x, &cl_y); - rod->m_body.p_x += p_x - cl_x; - rod->m_body.p_y += p_y - cl_y; - - piston->m_body.p_x = e_x; - piston->m_body.p_y = e_y; - piston->m_body.theta = bank->getAngle() + constants::pi; -} - void Simulator::startFrame(double dt) { if (m_engine == nullptr) { - i_steps = 0; + m_steps = 0; return; } @@ -350,40 +72,28 @@ void Simulator::startFrame(double dt) { m_synthesizer.setInputSampleRate(m_simulationFrequency * m_simulationSpeed); const double timestep = getTimestep(); - i_steps = (int)std::round((dt * m_simulationSpeed) / timestep); + m_steps = (int)std::round((dt * m_simulationSpeed) / timestep); - const double targetLatency = getSynthesizerInputLatencyTarget(); + const double targetLatency = getSynthesizerInputLatencyTarget(); if (m_synthesizer.getLatency() < targetLatency) { - i_steps = static_cast((i_steps + 1) * 1.1); + m_steps = static_cast((m_steps + 1) * 1.1); } else if (m_synthesizer.getLatency() > targetLatency) { - i_steps = static_cast((i_steps - 1) * 0.9); - if (i_steps < 0) { - i_steps = 0; + m_steps = static_cast((m_steps - 1) * 0.9); + if (m_steps < 0) { + m_steps = 0; } } - if (i_steps > 0) { + if (m_steps > 0) { for (int i = 0; i < m_engine->getIntakeCount(); ++i) { m_engine->getIntake(i)->m_flowRate = 0; } } } -void Simulator::startAudioRenderingThread() { - m_synthesizer.startAudioRenderingThread(); -} - -void Simulator::endAudioRenderingThread() { - m_synthesizer.endAudioRenderingThread(); -} - -double Simulator::getSynthesizerInputLatencyTarget() const { - return m_targetSynthesizerLatency; -} - bool Simulator::simulateStep() { - if (m_currentIteration >= i_steps) { + if (getCurrentIteration() >= simulationSteps()) { auto s1 = std::chrono::steady_clock::now(); const long long lastFrame = @@ -393,7 +103,7 @@ bool Simulator::simulateStep() { return false; } - const double timestep = 1.0 / m_simulationFrequency; + const double timestep = getTimestep(); m_system->process(timestep, 1); m_engine->update(timestep); @@ -434,57 +144,16 @@ bool Simulator::simulateStep() { m_lastDynoTorqueSample = index; } - IgnitionModule *im = m_engine->getIgnitionModule(); - im->update(timestep); - - const int cylinderCount = m_engine->getCylinderCount(); - for (int i = 0; i < cylinderCount; ++i) { - if (im->getIgnitionEvent(i)) { - m_engine->getChamber(i)->ignite(); - } - - m_engine->getChamber(i)->update(timestep); - } - - for (int i = 0; i < cylinderCount; ++i) { - m_engine->getChamber(i)->resetLastTimestepExhaustFlow(); - m_engine->getChamber(i)->resetLastTimestepIntakeFlow(); - } - - const int exhaustSystemCount = m_engine->getExhaustSystemCount(); - const int intakeCount = m_engine->getIntakeCount(); - const double fluidTimestep = timestep / m_fluidSimulationSteps; - for (int i = 0; i < m_fluidSimulationSteps; ++i) { - for (int j = 0; j < exhaustSystemCount; ++j) { - m_engine->getExhaustSystem(j)->process(fluidTimestep); - } - - for (int j = 0; j < intakeCount; ++j) { - m_engine->getIntake(j)->process(fluidTimestep); - m_engine->getIntake(j)->m_flowRate += m_engine->getIntake(j)->m_flow; - } - - for (int j = 0; j < cylinderCount; ++j) { - m_engine->getChamber(j)->flow(fluidTimestep); - } - } - - im->resetIgnitionEvents(); + simulateStep_(); writeToSynthesizer(); ++m_currentIteration; - return true; } double Simulator::getTotalExhaustFlow() const { - double totalFlow = 0.0; - for (int i = 0; i < m_engine->getCylinderCount(); ++i) { - totalFlow += m_engine->getChamber(i)->getLastTimestepExhaustFlow(); - } - - return totalFlow; + return 0.0; } int Simulator::readAudioOutput(int samples, int16_t *target) { @@ -492,103 +161,60 @@ int Simulator::readAudioOutput(int samples, int16_t *target) { } void Simulator::endFrame() { - if (m_engine == nullptr) { - return; - } - - const double frameTimestep = i_steps * getTimestep(); - const int cylinderCount = m_engine->getCylinderCount(); - for (int i = 0; i < m_engine->getIntakeCount(); ++i) { - m_engine->getIntake(i)->m_flowRate /= frameTimestep; - } - m_synthesizer.endInputBlock(); } void Simulator::destroy() { - if (m_system != nullptr) m_system->reset(); + m_synthesizer.destroy(); +} - if (m_crankConstraints != nullptr) delete[] m_crankConstraints; - if (m_cylinderWallConstraints != nullptr) delete[] m_cylinderWallConstraints; - if (m_linkConstraints != nullptr) delete[] m_linkConstraints; - if (m_crankshaftFrictionConstraints != nullptr) delete[] m_crankshaftFrictionConstraints; - if (m_exhaustFlowStagingBuffer != nullptr) delete[] m_exhaustFlowStagingBuffer; - if (m_system != nullptr) delete m_system; - if (m_delayFilters != nullptr) delete[] m_delayFilters; - - m_crankConstraints = nullptr; - m_cylinderWallConstraints = nullptr; - m_linkConstraints = nullptr; - m_crankshaftFrictionConstraints = nullptr; - m_exhaustFlowStagingBuffer = nullptr; - m_system = nullptr; +void Simulator::startAudioRenderingThread() { + m_synthesizer.startAudioRenderingThread(); +} - m_vehicle = nullptr; - m_transmission = nullptr; - m_engine = nullptr; - m_delayFilters = nullptr; +void Simulator::endAudioRenderingThread() { + m_synthesizer.endAudioRenderingThread(); +} - m_synthesizer.destroy(); +double Simulator::getSynthesizerInputLatencyTarget() const { + return m_targetSynthesizerLatency; +} + +double Simulator::getFilteredDynoTorque() const { + if (m_dynoTorqueSamples == nullptr) return 0; + + double averageTorque = 0; + for (int i = 0; i < DynoTorqueSamples; ++i) { + averageTorque += m_dynoTorqueSamples[i]; + } + + return averageTorque / DynoTorqueSamples; +} + +double Simulator::getDynoPower() const { + return (m_engine != nullptr) + ? getFilteredDynoTorque() * m_engine->getSpeed() + : 0; +} + +double Simulator::getAverageOutputSignal() const { + return 0.0; } void Simulator::initializeSynthesizer() { Synthesizer::Parameters synthParams; - synthParams.AudioBufferSize = 44100; - synthParams.AudioSampleRate = 44100; - synthParams.InputBufferSize = 44100; - synthParams.InputChannelCount = m_engine->getExhaustSystemCount(); - synthParams.InputSampleRate = static_cast(m_simulationFrequency); + synthParams.audioBufferSize = 44100; + synthParams.audioSampleRate = 44100; + synthParams.inputBufferSize = 44100; + synthParams.inputChannelCount = m_engine->getExhaustSystemCount(); + synthParams.inputSampleRate = static_cast(getSimulationFrequency()); m_synthesizer.initialize(synthParams); +} - m_exhaustFlowStagingBuffer = new double[m_engine->getExhaustSystemCount()]; +void Simulator::simulateStep_() { } void Simulator::updateFilteredEngineSpeed(double dt) { const double alpha = dt / (100 + dt); m_filteredEngineSpeed = alpha * m_filteredEngineSpeed + (1 - alpha) * m_engine->getRpm(); } - -void Simulator::writeToSynthesizer() { - const int exhaustSystemCount = m_engine->getExhaustSystemCount(); - for (int i = 0; i < exhaustSystemCount; ++i) { - m_exhaustFlowStagingBuffer[i] = 0; - } - - const double attenuation = std::min(std::abs(m_filteredEngineSpeed), 40.0) / 40.0; - const double attenuation_3 = attenuation * attenuation * attenuation; - - static double lastValveLift[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - const double timestep = getTimestep(); - const int cylinderCount = m_engine->getCylinderCount(); - for (int i = 0; i < cylinderCount; ++i) { - Piston *piston = m_engine->getPiston(i); - CylinderBank *bank = piston->getCylinderBank(); - CylinderHead *head = m_engine->getHead(bank->getIndex()); - ExhaustSystem *exhaust = head->getExhaustSystem(piston->getCylinderIndex()); - CombustionChamber *chamber = m_engine->getChamber(i); - - const double exhaustLength = - head->getHeaderPrimaryLength(piston->getCylinderIndex()) - + exhaust->getLength(); - - double exhaustFlow = - attenuation_3 * 1600 * ( - 1.0 * (chamber->m_exhaustRunnerAndPrimary.pressure() - units::pressure(1.0, units::atm)) - + 0.1 * chamber->m_exhaustRunnerAndPrimary.dynamicPressure(1.0, 0.0) - + 0.1 * chamber->m_exhaustRunnerAndPrimary.dynamicPressure(-1.0, 0.0)); - - lastValveLift[i] = head->exhaustValveLift(piston->getCylinderIndex()); - - const double delayedExhaustPulse = - m_delayFilters[i].fast_f(exhaustFlow); - - ExhaustSystem *exhaustSystem = head->getExhaustSystem(piston->getCylinderIndex()); - m_exhaustFlowStagingBuffer[exhaustSystem->getIndex()] += - head->getSoundAttenuation(piston->getCylinderIndex()) - * (exhaustSystem->getAudioVolume() * delayedExhaustPulse / cylinderCount) - * (1 / (exhaustLength * exhaustLength)); - } - - m_synthesizer.writeInput(m_exhaustFlowStagingBuffer); -} diff --git a/src/standard_valvetrain.cpp b/src/standard_valvetrain.cpp index fe68c940..edc05da7 100644 --- a/src/standard_valvetrain.cpp +++ b/src/standard_valvetrain.cpp @@ -12,8 +12,8 @@ StandardValvetrain::~StandardValvetrain() { } void StandardValvetrain::initialize(const Parameters ¶ms) { - m_intakeCamshaft = params.IntakeCamshaft; - m_exhaustCamshaft = params.ExhaustCamshaft; + m_intakeCamshaft = params.intakeCamshaft; + m_exhaustCamshaft = params.exhaustCamshaft; } double StandardValvetrain::intakeValveLift(int cylinder) { diff --git a/src/synthesizer.cpp b/src/synthesizer.cpp index da541ba3..8cf6d74a 100644 --- a/src/synthesizer.cpp +++ b/src/synthesizer.cpp @@ -35,47 +35,47 @@ Synthesizer::~Synthesizer() { } void Synthesizer::initialize(const Parameters &p) { - m_inputChannelCount = p.InputChannelCount; - m_inputBufferSize = p.InputBufferSize; - m_inputWriteOffset = p.InputBufferSize; - m_audioBufferSize = p.AudioBufferSize; - m_inputSampleRate = p.InputSampleRate; - m_audioSampleRate = p.AudioSampleRate; - m_audioParameters = p.InitialAudioParameters; + m_inputChannelCount = p.inputChannelCount; + m_inputBufferSize = p.inputBufferSize; + m_inputWriteOffset = p.inputBufferSize; + m_audioBufferSize = p.audioBufferSize; + m_inputSampleRate = p.inputSampleRate; + m_audioSampleRate = p.audioSampleRate; + m_audioParameters = p.initialAudioParameters; m_inputSamplesRead = 0; m_inputWriteOffset = 0; m_processed = true; - m_audioBuffer.initialize(p.AudioBufferSize); - m_inputChannels = new InputChannel[p.InputChannelCount]; - for (int i = 0; i < p.InputChannelCount; ++i) { - m_inputChannels[i].TransferBuffer = new float[p.InputBufferSize]; - m_inputChannels[i].Data.initialize(p.InputBufferSize); + m_audioBuffer.initialize(p.audioBufferSize); + m_inputChannels = new InputChannel[p.inputChannelCount]; + for (int i = 0; i < p.inputChannelCount; ++i) { + m_inputChannels[i].transferBuffer = new float[p.inputBufferSize]; + m_inputChannels[i].data.initialize(p.inputBufferSize); } - m_filters = new ProcessingFilters[p.InputChannelCount]; - for (int i = 0; i < p.InputChannelCount; ++i) { - m_filters[i].AirNoiseLowPass.setCutoffFrequency( - m_audioParameters.AirNoiseFrequencyCutoff, m_audioSampleRate); + m_filters = new ProcessingFilters[p.inputChannelCount]; + for (int i = 0; i < p.inputChannelCount; ++i) { + m_filters[i].airNoiseLowPass.setCutoffFrequency( + m_audioParameters.airNoiseFrequencyCutoff, m_audioSampleRate); - m_filters[i].Derivative.m_dt = 1 / m_audioSampleRate; + m_filters[i].derivative.m_dt = 1 / m_audioSampleRate; - m_filters[i].InputDcFilter.setCutoffFrequency(10.0); - m_filters[i].InputDcFilter.m_dt = 1 / m_audioSampleRate; + m_filters[i].inputDcFilter.setCutoffFrequency(10.0); + m_filters[i].inputDcFilter.m_dt = 1 / m_audioSampleRate; - m_filters[i].JitterFilter.initialize( + m_filters[i].jitterFilter.initialize( 10, - m_audioParameters.InputSampleNoiseFrequencyCutoff, + m_audioParameters.inputSampleNoiseFrequencyCutoff, m_audioSampleRate); m_filters[i].antialiasing.setCutoffFrequency(1900.0f, m_audioSampleRate); } - m_levelingFilter.p_target = m_audioParameters.LevelerTarget; - m_levelingFilter.p_maxLevel = m_audioParameters.LevelerMaxGain; - m_levelingFilter.p_minLevel = m_audioParameters.LevelerMinGain; + m_levelingFilter.p_target = m_audioParameters.levelerTarget; + m_levelingFilter.p_maxLevel = m_audioParameters.levelerMaxGain; + m_levelingFilter.p_minLevel = m_audioParameters.levelerMinGain; m_antialiasing.setCutoffFrequency(m_audioSampleRate * 0.45f, m_audioSampleRate); for (int i = 0; i < m_audioBufferSize; ++i) { @@ -97,9 +97,9 @@ void Synthesizer::initializeImpulseResponse( } const unsigned int sampleCount = std::min(10000U, clippedLength); - m_filters[index].Convolution.initialize(sampleCount); + m_filters[index].convolution.initialize(sampleCount); for (unsigned int i = 0; i < sampleCount; ++i) { - m_filters[index].Convolution.getImpulseResponse()[i] = + m_filters[index].convolution.getImpulseResponse()[i] = volume * impulseResponse[i] / INT16_MAX; } } @@ -125,8 +125,8 @@ void Synthesizer::destroy() { m_audioBuffer.destroy(); for (int i = 0; i < m_inputChannelCount; ++i) { - m_inputChannels[i].Data.destroy(); - m_filters[i].Convolution.destroy(); + m_inputChannels[i].data.destroy(); + m_filters[i].convolution.destroy(); } delete[] m_inputChannels; @@ -172,8 +172,8 @@ void Synthesizer::writeInput(const double *data) { } for (int i = 0; i < m_inputChannelCount; ++i) { - RingBuffer &buffer = m_inputChannels[i].Data; - const double lastInputSample = m_inputChannels[i].LastInputSample; + RingBuffer &buffer = m_inputChannels[i].data; + const double lastInputSample = m_inputChannels[i].lastInputSample; const size_t baseIndex = buffer.writeIndex(); const double distance = inputDistance(m_inputWriteOffset, m_lastInputSampleOffset); @@ -188,7 +188,7 @@ void Synthesizer::writeInput(const double *data) { buffer.write(m_filters[i].antialiasing.fast_f(static_cast(sample))); } - m_inputChannels[i].LastInputSample = data[i]; + m_inputChannels[i].lastInputSample = data[i]; } m_lastInputSampleOffset = m_inputWriteOffset; @@ -198,11 +198,11 @@ void Synthesizer::endInputBlock() { std::unique_lock lk(m_inputLock); for (int i = 0; i < m_inputChannelCount; ++i) { - m_inputChannels[i].Data.removeBeginning(m_inputSamplesRead); + m_inputChannels[i].data.removeBeginning(m_inputSamplesRead); } if (m_inputChannelCount != 0) { - m_latency = m_inputChannels[0].Data.size(); + m_latency = m_inputChannels[0].data.size(); } m_inputSamplesRead = 0; @@ -224,17 +224,17 @@ void Synthesizer::renderAudio() { m_cv0.wait(lk0, [this] { const bool inputAvailable = - m_inputChannels[0].Data.size() > 0 + m_inputChannels[0].data.size() > 0 && m_audioBuffer.size() < 2000; return !m_run || (inputAvailable && !m_processed); }); const int n = std::min( std::max(0, 2000 - (int)m_audioBuffer.size()), - (int)m_inputChannels[0].Data.size()); + (int)m_inputChannels[0].data.size()); for (int i = 0; i < m_inputChannelCount; ++i) { - m_inputChannels[i].Data.read(n, m_inputChannels[i].TransferBuffer); + m_inputChannels[i].data.read(n, m_inputChannels[i].transferBuffer); } m_inputSamplesRead = n; @@ -243,9 +243,9 @@ void Synthesizer::renderAudio() { lk0.unlock(); for (int i = 0; i < m_inputChannelCount; ++i) { - m_filters[i].AirNoiseLowPass.setCutoffFrequency( - static_cast(m_audioParameters.AirNoiseFrequencyCutoff), m_audioSampleRate); - m_filters[i].JitterFilter.setJitterScale(m_audioParameters.InputSampleNoise); + m_filters[i].airNoiseLowPass.setCutoffFrequency( + static_cast(m_audioParameters.airNoiseFrequencyCutoff), m_audioSampleRate); + m_filters[i].jitterFilter.setJitterScale(m_audioParameters.inputSampleNoise); } for (int i = 0; i < n; ++i) { @@ -279,25 +279,25 @@ void Synthesizer::setInputSampleRate(double sampleRate) { } int16_t Synthesizer::renderAudio(int inputSample) { - const float airNoise = m_audioParameters.AirNoise; + const float airNoise = m_audioParameters.airNoise; const float dF_F_mix = m_audioParameters.dF_F_mix; - const float convAmount = m_audioParameters.Convolution; + const float convAmount = m_audioParameters.convolution; float signal = 0; for (int i = 0; i < m_inputChannelCount; ++i) { const float r_0 = 2.0 * ((double)rand() / RAND_MAX) - 1.0; const float jitteredSample = - m_filters[i].JitterFilter.fast_f(m_inputChannels[i].TransferBuffer[inputSample]); + m_filters[i].jitterFilter.fast_f(m_inputChannels[i].transferBuffer[inputSample]); const float f_in = jitteredSample; - const float f_dc = m_filters[i].InputDcFilter.fast_f(f_in); + const float f_dc = m_filters[i].inputDcFilter.fast_f(f_in); const float f = f_in - f_dc; - const float f_p = m_filters[i].Derivative.f(f_in); + const float f_p = m_filters[i].derivative.f(f_in); const float noise = 2.0 * ((double)rand() / RAND_MAX) - 1.0; const float r = - m_filters->AirNoiseLowPass.fast_f(noise); + m_filters->airNoiseLowPass.fast_f(noise); const float r_mixed = airNoise * r + (1 - airNoise); @@ -309,7 +309,7 @@ int16_t Synthesizer::renderAudio(int inputSample) { } const float v = - convAmount * m_filters[i].Convolution.f(v_in) + convAmount * m_filters[i].convolution.f(v_in) + (1 - convAmount) * v_in; signal += v; @@ -317,8 +317,8 @@ int16_t Synthesizer::renderAudio(int inputSample) { signal = m_antialiasing.fast_f(signal); - m_levelingFilter.p_target = m_audioParameters.LevelerTarget; - const float v_leveled = m_levelingFilter.f(signal) * m_audioParameters.Volume; + m_levelingFilter.p_target = m_audioParameters.levelerTarget; + const float v_leveled = m_levelingFilter.f(signal) * m_audioParameters.volume; int r_int = std::lround(v_leveled); if (r_int > INT16_MAX) { r_int = INT16_MAX; diff --git a/src/vtec_valvetrain.cpp b/src/vtec_valvetrain.cpp index 4b4bb270..f1f6818f 100644 --- a/src/vtec_valvetrain.cpp +++ b/src/vtec_valvetrain.cpp @@ -22,16 +22,16 @@ VtecValvetrain::~VtecValvetrain() { } void VtecValvetrain::initialize(const Parameters ¶meters) { - m_intakeCamshaft = parameters.IntakeCamshaft; - m_exhaustCamshaft = parameters.ExhaustCamshaft; - m_vtecIntakeCamshaft = parameters.VtecIntakeCamshaft; - m_vtecExhaustCamshaft = parameters.VtexExhaustCamshaft; + m_intakeCamshaft = parameters.intakeCamshaft; + m_exhaustCamshaft = parameters.exhaustCamshaft; + m_vtecIntakeCamshaft = parameters.vtecIntakeCamshaft; + m_vtecExhaustCamshaft = parameters.vtexExhaustCamshaft; - m_minRpm = parameters.MinRpm; - m_minSpeed = parameters.MinSpeed; - m_minThrottlePosition = parameters.MinThrottlePosition; - m_manifoldVacuum = parameters.ManifoldVacuum; - m_engine = parameters.Engine; + m_minRpm = parameters.minRpm; + m_minSpeed = parameters.minSpeed; + m_minThrottlePosition = parameters.minThrottlePosition; + m_manifoldVacuum = parameters.manifoldVacuum; + m_engine = parameters.engine; } double VtecValvetrain::intakeValveLift(int cylinder) { diff --git a/test/synthesizer_tests.cpp b/test/synthesizer_tests.cpp index 2ebeca58..358780f1 100644 --- a/test/synthesizer_tests.cpp +++ b/test/synthesizer_tests.cpp @@ -8,38 +8,38 @@ using namespace std::chrono_literals; void setupStandardSynthesizer(Synthesizer &synth) { Synthesizer::Parameters params; - params.AudioBufferSize = 512 * 16; - params.AudioSampleRate = 16; - params.InputBufferSize = 256; - params.InputChannelCount = 8; - params.InputSampleRate = 32; + params.audioBufferSize = 512 * 16; + params.audioSampleRate = 16; + params.inputBufferSize = 256; + params.inputChannelCount = 8; + params.inputSampleRate = 32; Synthesizer::AudioParameters audioParams; - audioParams.AirNoise = 0.0; - audioParams.InputSampleNoise = 0.0; - audioParams.LevelerMaxGain = 1.0; - audioParams.LevelerMinGain = 1.0; + audioParams.airNoise = 0.0; + audioParams.inputSampleNoise = 0.0; + audioParams.levelerMaxGain = 1.0; + audioParams.levelerMinGain = 1.0; audioParams.dF_F_mix = 0.0; - params.InitialAudioParameters = audioParams; + params.initialAudioParameters = audioParams; synth.initialize(params); } void setupSynchronizedSynthesizer(Synthesizer &synth) { Synthesizer::Parameters params; - params.AudioBufferSize = 512 * 16; - params.AudioSampleRate = 32; - params.InputBufferSize = 1024; - params.InputChannelCount = 8; - params.InputSampleRate = 32; + params.audioBufferSize = 512 * 16; + params.audioSampleRate = 32; + params.inputBufferSize = 1024; + params.inputChannelCount = 8; + params.inputSampleRate = 32; Synthesizer::AudioParameters audioParams; - audioParams.AirNoise = 0.0; - audioParams.InputSampleNoise = 0.0; - audioParams.LevelerMaxGain = 1.0; - audioParams.LevelerMinGain = 1.0; + audioParams.airNoise = 0.0; + audioParams.inputSampleNoise = 0.0; + audioParams.levelerMaxGain = 1.0; + audioParams.levelerMinGain = 1.0; audioParams.dF_F_mix = 0.0; - params.InitialAudioParameters = audioParams; + params.initialAudioParameters = audioParams; synth.initialize(params); } From 56725cc012581282567900b15871018d55b7ab42 Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Tue, 22 Nov 2022 19:43:38 -0500 Subject: [PATCH 6/8] Reverted broken main.mr file --- assets/main.mr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/main.mr b/assets/main.mr index c792d27c..0dc7be4d 100644 --- a/assets/main.mr +++ b/assets/main.mr @@ -1,6 +1,6 @@ import "engine_sim.mr" import "themes/default.mr" -import "C:\\Users\\ange_\\Downloads\\Nissan L28E.mr" +import "engines/atg-video-2/01_subaru_ej25_eh.mr" use_default_theme() main() From fa4a3c793df8a52ac174471f9d8188c5ff540f01 Mon Sep 17 00:00:00 2001 From: Evert Jans Date: Wed, 18 Jan 2023 14:24:28 +0100 Subject: [PATCH 7/8] added build script --- build.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..85da8a88 --- /dev/null +++ b/build.sh @@ -0,0 +1,7 @@ +#/bin/sh + +mkdir build +cd build/ +#CC=clang CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Release ../engine-sim/ +CC=clang CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Release ../ +cmake --build . --target engine-sim-app -j From 2a02eeb8b10c96881dd6bff9132a633c9666efbe Mon Sep 17 00:00:00 2001 From: Evert Jans Date: Wed, 18 Jan 2023 15:04:55 +0100 Subject: [PATCH 8/8] added engines --- assets/engines/atg-video-2/01_porsche_H6.mr | 484 ++++++++++++++ assets/engines/atg-video-2/01_subaru_EL22.mr | 487 ++++++++++++++ .../engines/atg-video-2/01_subaru_EL22_UB.mr | 486 ++++++++++++++ assets/engines/atg-video-2/01_subaru_EL30.mr | 542 +++++++++++++++ assets/engines/atg-video-2/01_subaru_EL37.mr | 585 ++++++++++++++++ assets/engines/atg-video-2/01_subaru_EL45.mr | 613 +++++++++++++++++ assets/engines/atg-video-2/01_subaru_el15.mr | 382 +++++++++++ .../engines/atg-video-2/01_subaru_el15_bb.mr | 393 +++++++++++ assets/engines/atg-video-2/03_i8.mr | 454 +++++++++++++ .../atg-video-2/04_60_degree_big_bang_v6.mr | 414 ++++++++++++ assets/engines/atg-video-2/07_gm_ls.mr | 3 +- .../engines/atg-video-2/08_ferrari_f136_v8.mr | 3 +- .../engines/atg-video-2/12_ferrari_412_t2.mr | 3 +- assets/engines/atg-video-2/13_rotor.mr | 77 +++ assets/engines/atg-video-2/25cc.mr | 254 +++++++ assets/engines/atg-video-2/50cc.mr | 267 ++++++++ assets/engines/atg-video-2/6 Rotor.mr | 373 +++++++++++ assets/engines/atg-video-2/error_log.log | 1 + assets/engines/atg-video-2/f312t.mr | 475 +++++++++++++ assets/engines/atg-video-2/gx25.mr | 188 ++++++ assets/engines/atg-video-2/i2.mr | 332 ++++++++++ assets/engines/atg-video-2/i2_bb.mr | 335 ++++++++++ assets/engines/atg-video-2/i2_cp.mr | 332 ++++++++++ assets/engines/atg-video-2/i2_cp2.mr | 332 ++++++++++ assets/engines/atg-video-2/i2_cp3.mr | 332 ++++++++++ assets/engines/atg-video-2/porsche_993.mr | 430 ++++++++++++ assets/engines/atg-video-2/porsche_993_b10.mr | 515 ++++++++++++++ assets/engines/atg-video-2/porsche_993_b12.mr | 550 +++++++++++++++ assets/engines/atg-video-2/porsche_993_b8.mr | 487 ++++++++++++++ assets/engines/atg-video-2/the_i3.mr | 357 ++++++++++ assets/engines/atg-video-2/the_i3_mod.mr | 357 ++++++++++ assets/engines/atg-video-2/vw_w16.mr | 626 ++++++++++++++++++ assets/engines/atg-video-2/xplane.mr | 338 ++++++++++ assets/engines/atg-video-2/yz450.mr | 295 +++++++++ assets/main.mr | 42 +- assets/themes/default.mr | 9 +- 36 files changed, 12146 insertions(+), 7 deletions(-) create mode 100644 assets/engines/atg-video-2/01_porsche_H6.mr create mode 100644 assets/engines/atg-video-2/01_subaru_EL22.mr create mode 100644 assets/engines/atg-video-2/01_subaru_EL22_UB.mr create mode 100644 assets/engines/atg-video-2/01_subaru_EL30.mr create mode 100644 assets/engines/atg-video-2/01_subaru_EL37.mr create mode 100644 assets/engines/atg-video-2/01_subaru_EL45.mr create mode 100644 assets/engines/atg-video-2/01_subaru_el15.mr create mode 100644 assets/engines/atg-video-2/01_subaru_el15_bb.mr create mode 100644 assets/engines/atg-video-2/03_i8.mr create mode 100644 assets/engines/atg-video-2/04_60_degree_big_bang_v6.mr create mode 100644 assets/engines/atg-video-2/13_rotor.mr create mode 100644 assets/engines/atg-video-2/25cc.mr create mode 100644 assets/engines/atg-video-2/50cc.mr create mode 100644 assets/engines/atg-video-2/6 Rotor.mr create mode 100644 assets/engines/atg-video-2/error_log.log create mode 100644 assets/engines/atg-video-2/f312t.mr create mode 100644 assets/engines/atg-video-2/gx25.mr create mode 100644 assets/engines/atg-video-2/i2.mr create mode 100644 assets/engines/atg-video-2/i2_bb.mr create mode 100644 assets/engines/atg-video-2/i2_cp.mr create mode 100644 assets/engines/atg-video-2/i2_cp2.mr create mode 100644 assets/engines/atg-video-2/i2_cp3.mr create mode 100644 assets/engines/atg-video-2/porsche_993.mr create mode 100644 assets/engines/atg-video-2/porsche_993_b10.mr create mode 100644 assets/engines/atg-video-2/porsche_993_b12.mr create mode 100644 assets/engines/atg-video-2/porsche_993_b8.mr create mode 100644 assets/engines/atg-video-2/the_i3.mr create mode 100644 assets/engines/atg-video-2/the_i3_mod.mr create mode 100644 assets/engines/atg-video-2/vw_w16.mr create mode 100644 assets/engines/atg-video-2/xplane.mr create mode 100644 assets/engines/atg-video-2/yz450.mr diff --git a/assets/engines/atg-video-2/01_porsche_H6.mr b/assets/engines/atg-video-2/01_porsche_H6.mr new file mode 100644 index 00000000..00e6fd47 --- /dev/null +++ b/assets/engines/atg-video-2/01_porsche_H6.mr @@ -0,0 +1,484 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +/* +Porsche firing order and layout: + +FRONT + +3 + 6 +2 + 5 +1 + 4 + +REAR + +Firing order: 1 6 2 4 3 5 +*/ + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + input chamber_volume: 50 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + /* + FRONT + + 3 + 6 + 2 + 5 + 1 + 4 + + REAR + + Firing order: 1 6 2 4 3 5 + 0 1 2 3 4 5 + */ + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (2.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (4.0 / 6.0) * cycle) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (2.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (4.0 / 6.0) * cycle) + + _exhaust_cam_2 + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (5.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 6.0) * cycle) + _intake_cam_2 + .add_lobe(rot360 + intake_lobe_center + (3.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (5.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 6.0) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + //tdc: 180 * units.deg + tdc: 0 * units.deg + ) + + /* + FRONT + 3 + 6 + 2 + 5 + 1 + 4 + REAR + Firing order: 1 6 2 4 3 5 + 0 1 2 3 4 5 + */ + rod_journal rj4(angle: 0.0 * units.deg) + rod_journal rj1(angle: 180.0 * units.deg) + rod_journal rj5(angle: 240.0 * units.deg) + rod_journal rj2(angle: 60.0 * units.deg) + rod_journal rj6(angle: 120.0 * units.deg) + rod_journal rj3(angle: 300.0 * units.deg) + c1 + .add_rod_journal(rj4) + .add_rod_journal(rj1) + .add_rod_journal(rj5) + .add_rod_journal(rj2) + .add_rod_journal(rj6) + .add_rod_journal(rj3) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust1( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b1(bank_params, angle: 90.0 * units.deg) + cylinder_bank b2(bank_params, angle: -90.0 * units.deg) + /* + FRONT + 3 + 6 + 2 + 5 + 1 + 4 + REAR + Firing order: 1 6 2 4 3 5 + 0 1 2 3 4 5 + */ + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + /* + FRONT + 3 + 6 + 2 + 5 + 1 + 4 + REAR + Firing order: 1 6 2 4 3 5 + 0 1 2 3 4 5 + */ + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire5, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.7 + ) + .set_cylinder_head( + ej25_head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2) + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + + // 1 6 2 4 3 5 + // 0 1 2 3 4 5 + ignition_module + .connect_wire(wires.wire1, (0.0 / 6.0) * cycle) + .connect_wire(wires.wire6, (1.0 / 6.0) * cycle) + .connect_wire(wires.wire2, (2.0 / 6.0) * cycle) + .connect_wire(wires.wire4, (3.0 / 6.0) * cycle) + .connect_wire(wires.wire3, (4.0 / 6.0) * cycle) + .connect_wire(wires.wire5, (5.0 / 6.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/01_subaru_EL22.mr b/assets/engines/atg-video-2/01_subaru_EL22.mr new file mode 100644 index 00000000..b71decaa --- /dev/null +++ b/assets/engines/atg-video-2/01_subaru_EL22.mr @@ -0,0 +1,487 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +/* +Subaru +======= +REAR + 6 +5 + 4 +3 + 2 +1 +FRONT +Firing order: 1 6 3 2 5 4 +*/ + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); +} + +private node head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node cam { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 2 5 4 + 0 1 2 3 4 5 + */ + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (2.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (4.0 / 6.0) * cycle) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (2.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (4.0 / 6.0) * cycle) + + _exhaust_cam_2 + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (5.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 6.0) * cycle) + _intake_cam_2 + .add_lobe(rot360 + intake_lobe_center + (3.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (5.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 6.0) * cycle) +} + +public node subaru { + alias output __out: engine; + + engine engine( + name: "Subaru EL22", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 180 * units.deg + //tdc: 0 * units.deg + ) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 2 5 4 + 0 1 2 3 4 5 + */ + rod_journal rj1(angle: 0.0 * units.deg) + rod_journal rj2(angle: 180.0 * units.deg) + rod_journal rj3(angle: 240.0 * units.deg) + rod_journal rj4(angle: 60.0 * units.deg) + rod_journal rj5(angle: 120.0 * units.deg) + rod_journal rj6(angle: 300.0 * units.deg) + c1 + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust1( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b1(bank_params, angle: 90.0 * units.deg) + cylinder_bank b2(bank_params, angle: -90.0 * units.deg) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 2 5 4 + 0 1 2 3 4 5 + */ + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire5, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .set_cylinder_head( + head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 2 5 4 + 0 1 2 3 4 5 + */ + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.7 + ) + .set_cylinder_head( + head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2) + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + //camshaft cam( + cam camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + + //1 6 3 2 5 4 + //0 1 2 3 4 5 + ignition_module + .connect_wire(wires.wire1, (0.0 / 6.0) * cycle) + .connect_wire(wires.wire6, (1.0 / 6.0) * cycle) + .connect_wire(wires.wire3, (2.0 / 6.0) * cycle) + .connect_wire(wires.wire2, (3.0 / 6.0) * cycle) + .connect_wire(wires.wire5, (4.0 / 6.0) * cycle) + .connect_wire(wires.wire4, (5.0 / 6.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/01_subaru_EL22_UB.mr b/assets/engines/atg-video-2/01_subaru_EL22_UB.mr new file mode 100644 index 00000000..b4247f26 --- /dev/null +++ b/assets/engines/atg-video-2/01_subaru_EL22_UB.mr @@ -0,0 +1,486 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +/* +Subaru +======= +REAR + 6 +5 + 4 +3 + 2 +1 +FRONT +Firing order: 1 3 5 2 4 6 +*/ + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); +} + +private node head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + input chamber_volume: 50 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node cam { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 3 5 2 4 6 + 0 1 2 3 4 5 + */ + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (2.0 / 6.0) * cycle) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (2.0 / 6.0) * cycle) + + _exhaust_cam_2 + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (4.0 / 6.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (5.0 / 6.0) * cycle) + _intake_cam_2 + .add_lobe(rot360 + intake_lobe_center + (3.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (4.0 / 6.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (5.0 / 6.0) * cycle) +} + +public node subaru { + alias output __out: engine; + + engine engine( + name: "Subaru EL22 Unbalanced", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 180 * units.deg + //tdc: 0 * units.deg + ) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 3 5 2 4 6 + 0 1 2 3 4 5 + */ + rod_journal rj1(angle: 0.0 * units.deg) + rod_journal rj2(angle: 180.0 * units.deg) + rod_journal rj3(angle: 120.0 * units.deg) + rod_journal rj4(angle: 300.0 * units.deg) + rod_journal rj5(angle: 240.0 * units.deg) + rod_journal rj6(angle: 60.0 * units.deg) + c1 + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust1( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b1(bank_params, angle: 90.0 * units.deg) + cylinder_bank b2(bank_params, angle: -90.0 * units.deg) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 3 5 2 4 6 + 0 1 2 3 4 5 + */ + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire5, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .set_cylinder_head( + head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + /* + Subaru + ======= + REAR + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 3 5 2 4 6 + 0 1 2 3 4 5 + */ + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.7 + ) + .set_cylinder_head( + head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2) + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + //camshaft cam( + cam camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + + //1 3 5 2 4 6 + //0 1 2 3 4 5 + ignition_module + .connect_wire(wires.wire1, (0.0 / 6.0) * cycle) + .connect_wire(wires.wire3, (1.0 / 6.0) * cycle) + .connect_wire(wires.wire5, (2.0 / 6.0) * cycle) + .connect_wire(wires.wire2, (3.0 / 6.0) * cycle) + .connect_wire(wires.wire4, (4.0 / 6.0) * cycle) + .connect_wire(wires.wire6, (5.0 / 6.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/01_subaru_EL30.mr b/assets/engines/atg-video-2/01_subaru_EL30.mr new file mode 100644 index 00000000..a42bd1a2 --- /dev/null +++ b/assets/engines/atg-video-2/01_subaru_EL30.mr @@ -0,0 +1,542 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +/* +Porsche +======= +FRONT +4 + 8 +3 + 7 +2 + 6 +1 + 5 +REAR +Firing order: 1 7 2 8 5 3 6 4 +Subaru +====== +REAR + 8 +7 + 6 +5 + 4 +3 + 2 +1 +FRONT +Firing order: 1 6 3 8 2 5 4 7 +*/ + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); +} + +private node head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node cam { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + /* + Subaru + ======= + REAR + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 8 2 5 4 7 + 0 1 2 3 4 5 6 7 + */ + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 8.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (2.0 / 8.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (5.0 / 8.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (7.0 / 8.0) * cycle) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 8.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (2.0 / 8.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (5.0 / 8.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (7.0 / 8.0) * cycle) + + _exhaust_cam_2 + .add_lobe(rot360 - exhaust_lobe_center + (4.0 / 8.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (6.0 / 8.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 8.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 8.0) * cycle) + _intake_cam_2 + .add_lobe(rot360 + intake_lobe_center + (4.0 / 8.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (6.0 / 8.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 8.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (3.0 / 8.0) * cycle) +} + +public node subaru { + alias output __out: engine; + + engine engine( + name: "Subaru EL30", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 180 * units.deg + //tdc: 0 * units.deg + ) + /* + Subaru + ======= + REAR + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 8 2 5 4 7 + 0 1 2 3 4 5 6 7 + */ + rod_journal rj1(angle: 0.0 * units.deg) + rod_journal rj6(angle: (90.0 + 180.0) * units.deg) + rod_journal rj3(angle: 180.0 * units.deg) + rod_journal rj8(angle: (270.0 + 180.0) * units.deg) + rod_journal rj2(angle: (0.0 + 180.0) * units.deg) + rod_journal rj5(angle: (90.0) * units.deg) + rod_journal rj4(angle: (180.0 + 180.0) * units.deg) + rod_journal rj7(angle: (270.0) * units.deg) + c1 + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + .add_rod_journal(rj7) + .add_rod_journal(rj8) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust1( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b1(bank_params, angle: 90.0 * units.deg) + cylinder_bank b2(bank_params, angle: -90.0 * units.deg) + /* + Subaru + ======= + REAR + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 8 2 5 4 7 + 0 1 2 3 4 5 6 7 + */ + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire5, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire7, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.3 + ) + .set_cylinder_head( + head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + /* + Subaru + ======= + REAR + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 6 3 8 2 5 4 7 + 0 1 2 3 4 5 6 7 + */ + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.7 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj8, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire8, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.5 + ) + .set_cylinder_head( + head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2) + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + //camshaft cam( + cam camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + + //Firing order: 1 6 3 8 2 5 4 7 + // 0 1 2 3 4 5 6 7 + ignition_module + .connect_wire(wires.wire1, (0.0 / 8.0) * cycle) + .connect_wire(wires.wire6, (1.0 / 8.0) * cycle) + .connect_wire(wires.wire3, (2.0 / 8.0) * cycle) + .connect_wire(wires.wire8, (3.0 / 8.0) * cycle) + .connect_wire(wires.wire2, (4.0 / 8.0) * cycle) + .connect_wire(wires.wire5, (5.0 / 8.0) * cycle) + .connect_wire(wires.wire4, (6.0 / 8.0) * cycle) + .connect_wire(wires.wire7, (7.0 / 8.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/01_subaru_EL37.mr b/assets/engines/atg-video-2/01_subaru_EL37.mr new file mode 100644 index 00000000..b2492ce0 --- /dev/null +++ b/assets/engines/atg-video-2/01_subaru_EL37.mr @@ -0,0 +1,585 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +/* +Porsche +======= +FRONT +5 + 10 +4 + 9 +3 + 8 +2 + 7 +1 + 6 +REAR +Firing order: 1 10 2 8 4 6 5 7 3 9 +Subaru +====== +REAR + 10 +9 + 8 +7 + 6 +5 + 4 +3 + 2 +1 +FRONT +Firing order: 1 10 3 6 7 2 9 4 5 8 +*/ + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); + output wire9: ignition_wire(); + output wire10: ignition_wire(); +} + +private node head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node cam { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + /* + Subaru + ====== + REAR + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 10 3 6 7 2 9 4 5 8 + 0 1 2 3 4 5 6 7 8 9 + */ + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (2.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (8.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (4.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (6.0 / 10.0) * cycle) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (2.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (8.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (4.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (6.0 / 10.0) * cycle) + + _exhaust_cam_2 + .add_lobe(rot360 - exhaust_lobe_center + (5.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (7.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (9.0 / 10.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 10.0) * cycle) + _intake_cam_2 + .add_lobe(rot360 + intake_lobe_center + (5.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (7.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (3.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (9.0 / 10.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 10.0) * cycle) +} + +public node subaru { + alias output __out: engine; + + engine engine( + name: "Subaru EL37", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + //simulation_frequency: 10000 + simulation_frequency: 8000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 180 * units.deg + //tdc: 0 * units.deg + ) + /* + Subaru + ====== + REAR + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 10 3 6 7 2 9 4 5 8 + */ + rod_journal rj1(angle: 0.0 * units.deg) + rod_journal rj10(angle: (72.0 + 180.0) * units.deg) + rod_journal rj3(angle: 144.0 * units.deg) + rod_journal rj6(angle: (216.0 + 180.0) * units.deg) + rod_journal rj7(angle: 288.0 * units.deg) + rod_journal rj2(angle: (360.0 + 180.0) * units.deg) + rod_journal rj9(angle: (72.0 + 0.0) * units.deg) + rod_journal rj4(angle: (144.0 + 180.0) * units.deg) + rod_journal rj5(angle: (216.0 + 0.0) * units.deg) + rod_journal rj8(angle: (288.0 + 180.0) * units.deg) + c1 + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + .add_rod_journal(rj7) + .add_rod_journal(rj8) + .add_rod_journal(rj9) + .add_rod_journal(rj10) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + //intake_flow_rate: k_carb(400.0), + intake_flow_rate: k_carb(700.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust1( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b1(bank_params, angle: 90.0 * units.deg) + cylinder_bank b2(bank_params, angle: -90.0 * units.deg) + /* + Subaru + ====== + REAR + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 10 3 6 7 2 9 4 5 8 + */ + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire5, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire7, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.3 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj9, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire9, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.3 + ) + .set_cylinder_head( + head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + /* + Subaru + ====== + REAR + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 10 3 6 7 2 9 4 5 8 + */ + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.7 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj8, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire8, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.5 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj10, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire10, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.5 + ) + .set_cylinder_head( + head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2) + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + //camshaft cam( + cam camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + + //Firing order: 1 10 3 6 7 2 9 4 5 8 + ignition_module + .connect_wire(wires.wire1, (0.0 / 10.0) * cycle) + .connect_wire(wires.wire10, (1.0 / 10.0) * cycle) + .connect_wire(wires.wire3, (2.0 / 10.0) * cycle) + .connect_wire(wires.wire6, (3.0 / 10.0) * cycle) + .connect_wire(wires.wire7, (4.0 / 10.0) * cycle) + .connect_wire(wires.wire2, (5.0 / 10.0) * cycle) + .connect_wire(wires.wire9, (6.0 / 10.0) * cycle) + .connect_wire(wires.wire4, (7.0 / 10.0) * cycle) + .connect_wire(wires.wire5, (8.0 / 10.0) * cycle) + .connect_wire(wires.wire8, (9.0 / 10.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + //max_clutch_torque: 300 * units.lb_ft + max_clutch_torque: 900 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/01_subaru_EL45.mr b/assets/engines/atg-video-2/01_subaru_EL45.mr new file mode 100644 index 00000000..71e3487c --- /dev/null +++ b/assets/engines/atg-video-2/01_subaru_EL45.mr @@ -0,0 +1,613 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +/* +Subaru +====== +REAR + 12 +11 + 10 +9 + 8 +7 + 6 +5 + 4 +3 + 2 +1 +FRONT +Firing order: 1 11 3 7 5 9 2 12 4 8 6 10 +*/ + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); + output wire9: ignition_wire(); + output wire10: ignition_wire(); + output wire11: ignition_wire(); + output wire12: ignition_wire(); +} + +private node head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node cam { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + /* + Subaru + ====== + REAR + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 11 3 7 5 9 2 12 4 8 6 10 + 0 1 2 3 4 5 6 7 8 9 1011 + */ + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (2.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (4.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (5.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 12.0) * cycle) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (2.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (4.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (3.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (5.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 12.0) * cycle) + + _exhaust_cam_2 + .add_lobe(rot360 - exhaust_lobe_center + (6.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (8.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (10.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (9.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (11.0 / 12.0) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (7.0 / 12.0) * cycle) + _intake_cam_2 + .add_lobe(rot360 + intake_lobe_center + (6.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (8.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (10.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (9.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (11.0 / 12.0) * cycle) + .add_lobe(rot360 + intake_lobe_center + (7.0 / 12.0) * cycle) +} + +public node subaru { + alias output __out: engine; + + engine engine( + name: "Subaru EL37", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + //simulation_frequency: 10000 + simulation_frequency: 8000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 180 * units.deg + //tdc: 0 * units.deg + ) + /* + Subaru + ====== + REAR + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 10 3 6 7 2 9 4 5 8 + */ + /* + Subaru + ====== + REAR + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 11 3 7 5 9 2 12 4 8 6 10 + 0 1 2 3 4 5 6 7 8 9 1011 + */ + rod_journal rj1(angle: 0.0 * units.deg) + rod_journal rj11(angle: 60.0 * units.deg) + rod_journal rj3(angle: 120.0 * units.deg) + rod_journal rj7(angle: 180.0 * units.deg) + rod_journal rj5(angle: 240.0 * units.deg) + rod_journal rj9(angle: 300.0 * units.deg) + + rod_journal rj2(angle: (0.0 + 180.0) * units.deg) + rod_journal rj12(angle: (60.0 + 180.0) * units.deg) + rod_journal rj4(angle: (120.0 + 180.0) * units.deg) + rod_journal rj8(angle: (180.0 + 180.0) * units.deg) + rod_journal rj6(angle: (240.0 + 180.0) * units.deg) + rod_journal rj10(angle: (300.0 + 180.0) * units.deg) + c1 + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + .add_rod_journal(rj7) + .add_rod_journal(rj8) + .add_rod_journal(rj9) + .add_rod_journal(rj10) + .add_rod_journal(rj11) + .add_rod_journal(rj12) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + //intake_flow_rate: k_carb(400.0), + intake_flow_rate: k_carb(700.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust1( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b1(bank_params, angle: 90.0 * units.deg) + cylinder_bank b2(bank_params, angle: -90.0 * units.deg) + /* + Subaru + ====== + REAR + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + FRONT + Firing order: 1 11 3 7 5 9 2 12 4 8 6 10 + 0 1 2 3 4 5 6 7 8 9 1011 + */ + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire5, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire7, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.3 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj9, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire9, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.5 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj11, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire11, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.7 + ) + .set_cylinder_head( + head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.7 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj8, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire8, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.5 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj10, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire10, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.3 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj12, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire12, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.1 + ) + .set_cylinder_head( + head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2) + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + //camshaft cam( + cam camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + + //Firing order: 1 11 3 7 5 9 2 12 4 8 6 10 + ignition_module + .connect_wire(wires.wire1, (0.0 / 12.0) * cycle) + .connect_wire(wires.wire11, (1.0 / 12.0) * cycle) + .connect_wire(wires.wire3, (2.0 / 12.0) * cycle) + .connect_wire(wires.wire7, (3.0 / 12.0) * cycle) + .connect_wire(wires.wire5, (4.0 / 12.0) * cycle) + .connect_wire(wires.wire9, (5.0 / 12.0) * cycle) + .connect_wire(wires.wire2, (6.0 / 12.0) * cycle) + .connect_wire(wires.wire12, (7.0 / 12.0) * cycle) + .connect_wire(wires.wire4, (8.0 / 12.0) * cycle) + .connect_wire(wires.wire8, (9.0 / 12.0) * cycle) + .connect_wire(wires.wire6, (10.0 / 12.0) * cycle) + .connect_wire(wires.wire10, (11.0 / 12.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + //max_clutch_torque: 300 * units.lb_ft + max_clutch_torque: 900 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/01_subaru_el15.mr b/assets/engines/atg-video-2/01_subaru_el15.mr new file mode 100644 index 00000000..ff40e8ac --- /dev/null +++ b/assets/engines/atg-video-2/01_subaru_el15.mr @@ -0,0 +1,382 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_0 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 4) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 4) * cycle) + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 4) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 4) * cycle) + + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center + (2.0 / 4) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 4) * cycle) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + (2.0 / 4) * cycle) + .add_lobe(rot360 + intake_lobe_center + (3.0 / 4) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 180 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + rod_journal rj1(angle: 180.0 * units.deg) + rod_journal rj2(angle: 0.0 * units.deg) + rod_journal rj3(angle: 180.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b0(bank_params, angle: 90.0 * units.deg) + cylinder_bank b1(bank_params, angle: -90.0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0) + ) + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire4, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .set_cylinder_head( + ej25_head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + + engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, (0.0 / 4.0) * cycle) + .connect_wire(wires.wire3, (1.0 / 4.0) * cycle) + .connect_wire(wires.wire2, (2.0 / 4.0) * cycle) + .connect_wire(wires.wire4, (3.0 / 4.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/01_subaru_el15_bb.mr b/assets/engines/atg-video-2/01_subaru_el15_bb.mr new file mode 100644 index 00000000..19494a97 --- /dev/null +++ b/assets/engines/atg-video-2/01_subaru_el15_bb.mr @@ -0,0 +1,393 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_0 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 4) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 4) * cycle) + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 4) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 4) * cycle) + + _exhaust_cam_1 + //.add_lobe(rot360 - exhaust_lobe_center + (2.0 / 4) * cycle) + // Big Bang + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 4) * cycle) + //.add_lobe(rot360 - exhaust_lobe_center + (3.0 / 4) * cycle) + // Big Bang + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 4) * cycle) + _intake_cam_1 + //.add_lobe(rot360 + intake_lobe_center + (2.0 / 4) * cycle) + // Big Bang + .add_lobe(rot360 + intake_lobe_center + (0.0 / 4) * cycle) + //.add_lobe(rot360 + intake_lobe_center + (3.0 / 4) * cycle) + // Big Bang + .add_lobe(rot360 + intake_lobe_center + (1.0 / 4) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 180 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + rod_journal rj1(angle: 180.0 * units.deg) + rod_journal rj2(angle: 0.0 * units.deg) + rod_journal rj3(angle: 180.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b0(bank_params, angle: 90.0 * units.deg) + cylinder_bank b1(bank_params, angle: -90.0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire3, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0) + ) + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire4, + primary_length: 5.0 * units.inch, + sound_attenuation: 0.9 + ) + .set_cylinder_head( + ej25_head( + flip_display: false, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + + engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, (0.0 / 4.0) * cycle) + .connect_wire(wires.wire3, (1.0 / 4.0) * cycle) + //.connect_wire(wires.wire2, (2.0 / 4.0) * cycle) + // Big Bang + .connect_wire(wires.wire2, (0.0 / 4.0) * cycle) + //.connect_wire(wires.wire4, (3.0 / 4.0) * cycle) + .connect_wire(wires.wire4, (1.0 / 4.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/03_i8.mr b/assets/engines/atg-video-2/03_i8.mr new file mode 100644 index 00000000..535b393b --- /dev/null +++ b/assets/engines/atg-video-2/03_i8.mr @@ -0,0 +1,454 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); +} + +label cycle(2 * 360 * units.deg) +// 1 4 7 3 8 5 2 6 +public node wb_ignition { + input wires; + input timing_curve; + input rev_limit: 7500 * units.rpm; + alias output __out: + ignition_module( + timing_curve: timing_curve, + rev_limit: rev_limit, + limiter_duration: 0.1 + ) + .connect_wire(wires.wire1, (0.0 / 8.0) * cycle) + .connect_wire(wires.wire4, (1.0 / 8.0) * cycle) + .connect_wire(wires.wire7, (2.0 / 8.0) * cycle) + .connect_wire(wires.wire3, (3.0 / 8.0) * cycle) + .connect_wire(wires.wire8, (4.0 / 8.0) * cycle) + .connect_wire(wires.wire5, (5.0 / 8.0) * cycle) + .connect_wire(wires.wire2, (6.0 / 8.0) * cycle) + .connect_wire(wires.wire6, (7.0 / 8.0) * cycle); +} + +public node t2jz_camshaft_builder { + input lobe_profile: comp_cams_magnum_11_450_8_lobe_profile(); + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 110.0 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0.0 * units.deg; + input base_radius: 0.75 * units.inch; + + output intake_cam: _intake_cam; + output exhaust_cam: _exhaust_cam; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam(params, lobe_profile: exhaust_lobe_profile) + + label rot(2 * (360 / 8.0) * units.deg) + label rot360(360 * units.deg) + + // 1 4 7 3 8 5 2 6 + _exhaust_cam + .add_lobe((rot360 - exhaust_lobe_center) + 0 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 6 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 3 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 1 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 5 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 7 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 2 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 4 * rot) + /* + .add_lobe((rot360 - exhaust_lobe_center) + 3 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 6 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 2 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 7 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 4 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 1 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 5 * rot) + */ + + _intake_cam + .add_lobe(rot360 + intake_lobe_center + 0 * rot) + .add_lobe(rot360 + intake_lobe_center + 6 * rot) + .add_lobe(rot360 + intake_lobe_center + 3 * rot) + .add_lobe(rot360 + intake_lobe_center + 1 * rot) + .add_lobe(rot360 + intake_lobe_center + 5 * rot) + .add_lobe(rot360 + intake_lobe_center + 7 * rot) + .add_lobe(rot360 + intake_lobe_center + 2 * rot) + .add_lobe(rot360 + intake_lobe_center + 4 * rot) + /* + .add_lobe(rot360 + intake_lobe_center + 3 * rot) + .add_lobe(rot360 + intake_lobe_center + 6 * rot) + .add_lobe(rot360 + intake_lobe_center + 2 * rot) + .add_lobe(rot360 + intake_lobe_center + 7 * rot) + .add_lobe(rot360 + intake_lobe_center + 4 * rot) + .add_lobe(rot360 + intake_lobe_center + 1 * rot) + .add_lobe(rot360 + intake_lobe_center + 5 * rot) + */ +} + +private node t2jz_head { + input intake_camshaft; + input exhaust_camshaft; + input chamber_volume: 50 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.9 * units.inch * 1.9 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +public node t2jz { + alias output __out: engine; + + wires wires() + + engine engine( + name: "[I8]", + starter_torque: 200 * units.lb_ft, + redline: 6000 * units.rpm, + fuel: fuel( + max_burning_efficiency: 1.0 + ), + hf_gain: 0.01, + noise: 1.0, + jitter: 0.23, + simulation_frequency: 10000 + ) + + label stroke(86.0 * units.mm) + label bore(86.0 * units.mm) + label rod_length(142 * units.mm) + label rod_mass(500 * units.g) + label compression_height(32.8 * units.mm) + label crank_mass(15 * units.kg) + label flywheel_mass(10 * units.kg) + label flywheel_radius(7 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 20 * units.kg, radius: 8.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 5.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: constants.pi / 2 + ) + + // 1 5 3 6 2 4 + // 1 4 7 3 8 5 2 6 + rod_journal rj0(angle: 0 * units.deg) + rod_journal rj1(angle: 540 * units.deg) + rod_journal rj2(angle: 270 * units.deg) + rod_journal rj3(angle: 90 * units.deg) + rod_journal rj4(angle: 450 * units.deg) + rod_journal rj5(angle: 630 * units.deg) + rod_journal rj6(angle: 180 * units.deg) + rod_journal rj7(angle: 360 * units.deg) + + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + .add_rod_journal(rj7) + + piston_parameters piston_params( + mass: (200 + 50) * units.g, + blowby: 0, + compression_height: compression_height, + wrist_pin_position: 0 * units.mm, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + intake intake( + plenum_volume: 1.0 * units.L, + plenum_cross_section_area: 10.0 * units.cm2, + intake_flow_rate: k_carb(500.0), + runner_flow_rate: k_carb(200.0), + runner_length: 40.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9965 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 100.0 * units.inch, + audio_volume: 0.2, + impulse_response: ir_lib.mild_exhaust_0_reverb) + exhaust_system exhaust1( + es_params, + length: 100.0 * units.inch, + audio_volume: 0.2, + impulse_response: ir_lib.mild_exhaust_0_reverb) + + label spacing(0.5 * units.inch) + + cylinder_bank b0(bank_params, angle: 0) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: spacing * 5, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: spacing * 4, + sound_attenuation: 0.95 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire3, + primary_length: spacing * 3, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + primary_length: spacing * 3, + sound_attenuation: 0.97 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire5, + primary_length: spacing * 4, + sound_attenuation: 0.98 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + primary_length: spacing * 5, + sound_attenuation: 0.93 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire7, + primary_length: spacing * 5, + sound_attenuation: 0.93 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire8, + primary_length: spacing * 5, + sound_attenuation: 0.93 + ) + + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 220 * units.deg, + gamma: 1.1, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 220 * units.deg, + gamma: 1.1, + lift: 9.60 * units.mm, + steps: 100 + ) + + t2jz_camshaft_builder camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 116 * units.deg, + exhaust_lobe_center: 116 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + b0.set_cylinder_head ( + t2jz_head( + chamber_volume: 50 * units.cc, + intake_camshaft: camshaft.intake_cam, + exhaust_camshaft: camshaft.exhaust_cam, + flow_attenuation: 0.9 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 12 * units.deg) + .add_sample(1000 * units.rpm, 12 * units.deg) + .add_sample(2000 * units.rpm, 20 * units.deg) + .add_sample(3000 * units.rpm, 26 * units.deg) + .add_sample(4000 * units.rpm, 30 * units.deg) + .add_sample(5000 * units.rpm, 34 * units.deg) + .add_sample(6000 * units.rpm, 38 * units.deg) + .add_sample(7000 * units.rpm, 38 * units.deg) + + engine.add_ignition_module( + wb_ignition( + wires: wires, + timing_curve: timing_curve, + rev_limit: 6500 * units.rpm + ) + ) +} + +private node supra_vehicle { + alias output __out: + vehicle( + mass: 3400 * units.lb, + drag_coefficient: 0.4, + cross_sectional_area: (66 * units.inch) * (50 * units.inch), + diff_ratio: 3.15, + tire_radius: 10 * units.inch, + rolling_resistance: 500 * units.N + ); +} + +private node supra_transmission { + alias output __out: + transmission( + max_clutch_torque: 500 * units.lb_ft + ) + .add_gear(5.25) + .add_gear(3.36) + .add_gear(2.17) + .add_gear(1.72) + .add_gear(1.32) + .add_gear(1.0); +} + +public node main { + set_engine(t2jz()) + set_vehicle(supra_vehicle()) + set_transmission(supra_transmission()) +} diff --git a/assets/engines/atg-video-2/04_60_degree_big_bang_v6.mr b/assets/engines/atg-video-2/04_60_degree_big_bang_v6.mr new file mode 100644 index 00000000..b8ed5b88 --- /dev/null +++ b/assets/engines/atg-video-2/04_60_degree_big_bang_v6.mr @@ -0,0 +1,414 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); +} + +private node v6_60_head { + input intake_camshaft; + input exhaust_camshaft; + input chamber_volume: 67 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.35 * units.inch * 1.35 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 2.0 * units.inch * 2.0 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node v6_60_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 0.5 * units.inch; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + // 1 2 3 4 5 6 + // 14 36 25 + // 240 deg from eachother + _exhaust_cam_1 + //1 + .add_lobe(rot360 - exhaust_lobe_center + 0 * units.deg) + //3 + .add_lobe(rot360 - exhaust_lobe_center + 240 * units.deg) + //5 + .add_lobe(rot360 - exhaust_lobe_center + 480 * units.deg) + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center + 0 * units.deg) + .add_lobe(rot360 + intake_lobe_center + 240 * units.deg) + .add_lobe(rot360 + intake_lobe_center + 480 * units.deg) + + _exhaust_cam_2 + //2 + .add_lobe(rot360 - exhaust_lobe_center + 480 * units.deg) + //4 + .add_lobe(rot360 - exhaust_lobe_center + 0 * units.deg) + //6 + .add_lobe(rot360 - exhaust_lobe_center + 240 * units.deg) + _intake_cam_2 + .add_lobe(rot360 + intake_lobe_center + 480 * units.deg) + .add_lobe(rot360 + intake_lobe_center + 0 * units.deg) + .add_lobe(rot360 + intake_lobe_center + 240 * units.deg) +} + +public node v6_60 { + alias output __out: engine; + + engine engine( + name: "60 deg. V6 Big Bang", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 5500 * units.rpm, + throttle_gamma: 2.0 + ) + + wires wires() + + label stroke(3.48 * units.inch) + label bore(3.5 * units.inch) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(50 * units.lb) + label flywheel_mass(30 * units.lb) + label flywheel_radius(7 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 1.0 * units.cm) + ) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 20.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: (90 + 30) * units.deg + ) + + // 1 2 3 4 5 6 + // 14 36 25 + // 240 deg from eachother + //rod_journal rj1(angle: 0.0 * units.deg) + //rod_journal rj2(angle: (0 + 60) * units.deg) + //rod_journal rj3(angle: 240.0 * units.deg) + //rod_journal rj4(angle: (240.0 + 60) * units.deg) + //rod_journal rj5(angle: 120.0 * units.deg) + //rod_journal rj6(angle: (120.0 + 60) * units.deg) + rod_journal rj1(angle: 0.0 * units.deg) + rod_journal rj2(angle: (480 - 60) * units.deg) + rod_journal rj3(angle: 240.0 * units.deg) + rod_journal rj4(angle: (0.0 - 60) * units.deg) + rod_journal rj5(angle: 480.0 * units.deg) + rod_journal rj6(angle: (240.0 - 60) * units.deg) + c1 + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(250.0), + runner_length: 4.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.994, + velocity_decay: 0.5 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 20.0 * units.inch, + primary_flow_rate: k_carb(500.0), + velocity_decay: 1.0, + length: 100.0 * units.inch + ) + + exhaust_system exhaust0( + es_params, + audio_volume: 1.0, + impulse_response: ir_lib.mild_exhaust_0_reverb + ) + exhaust_system exhaust1( + es_params, + audio_volume: 1.0, + impulse_response: ir_lib.mild_exhaust_0_reverb + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + label spacing(5.0 * units.inch) + + cylinder_bank b1(bank_params, angle: 30.0 * units.deg) + cylinder_bank b2(bank_params, angle: -30.0 * units.deg) + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + sound_attenuation: 0.9, + primary_length: spacing * 2 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.2)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire3, + sound_attenuation: 0.95, + primary_length: spacing * 1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.2)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire5, + primary_length: spacing * 0 + ) + .set_cylinder_head( + v6_60_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1) + ) + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + sound_attenuation: 0.95, + primary_length: spacing * 2 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.2)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire4, + sound_attenuation: 0.9, + primary_length: spacing * 1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.2)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire6, + sound_attenuation: 1.0, + primary_length: spacing * 0 + ) + .set_cylinder_head( + v6_60_head( + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2, + flip_display: false) + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 222 * units.deg, + gamma: 1.0, + lift: 400 * units.thou, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 226 * units.deg, + gamma: 1.0, + lift: 300 * units.thou, + steps: 100 + ) + + v6_60_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: 0.75 * units.inch + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 12 * units.deg) + .add_sample(1000 * units.rpm, 20 * units.deg) + .add_sample(2000 * units.rpm, 25 * units.deg) + .add_sample(3000 * units.rpm, 30 * units.deg) + .add_sample(4000 * units.rpm, 30 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 5600 * units.rpm, + limiter_duration: 0.2) + // 1 2 3 4 5 6 + // 14 36 25 + // 240 deg from eachother + ignition_module + .connect_wire(wires.wire1, 0 * units.deg) + .connect_wire(wires.wire2, 480 * units.deg) + .connect_wire(wires.wire3, 240 * units.deg) + .connect_wire(wires.wire4, 0 * units.deg) + .connect_wire(wires.wire5, 480 * units.deg) + .connect_wire(wires.wire6, 240 * units.deg) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) +private node random_car { + alias output __out: + vehicle( + mass: car_mass, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node random_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(v6_60()) + set_vehicle(random_car()) + set_transmission(random_transmission()) +} diff --git a/assets/engines/atg-video-2/07_gm_ls.mr b/assets/engines/atg-video-2/07_gm_ls.mr index 06b0984f..005e46d2 100644 --- a/assets/engines/atg-video-2/07_gm_ls.mr +++ b/assets/engines/atg-video-2/07_gm_ls.mr @@ -160,7 +160,8 @@ public node ls_v8 { hf_gain: 0.01, noise: 1.0, jitter: 0.6, - simulation_frequency: 10000 + //simulation_frequency: 10000 + simulation_frequency: 5000 ) wires wires() diff --git a/assets/engines/atg-video-2/08_ferrari_f136_v8.mr b/assets/engines/atg-video-2/08_ferrari_f136_v8.mr index 781b70ae..99bdcc14 100644 --- a/assets/engines/atg-video-2/08_ferrari_f136_v8.mr +++ b/assets/engines/atg-video-2/08_ferrari_f136_v8.mr @@ -157,7 +157,8 @@ public node f136_v8 { hf_gain: 0.01, noise: 1.0, jitter: 0.15, - simulation_frequency: 10000 + //simulation_frequency: 10000 + simulation_frequency: 5000 ) wires wires() diff --git a/assets/engines/atg-video-2/12_ferrari_412_t2.mr b/assets/engines/atg-video-2/12_ferrari_412_t2.mr index 2af6ebf4..d84fe745 100644 --- a/assets/engines/atg-video-2/12_ferrari_412_t2.mr +++ b/assets/engines/atg-video-2/12_ferrari_412_t2.mr @@ -172,7 +172,8 @@ public node ferrari_412_t2_v12 { hf_gain: 0.01, noise: 1.0, jitter: 0.1, - simulation_frequency: 5000 + //simulation_frequency: 5000 + simulation_frequency: 4000 ) wires wires() diff --git a/assets/engines/atg-video-2/13_rotor.mr b/assets/engines/atg-video-2/13_rotor.mr new file mode 100644 index 00000000..26d4ec27 --- /dev/null +++ b/assets/engines/atg-video-2/13_rotor.mr @@ -0,0 +1,77 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +label cycle(3 * 360 * units.deg) +label sparkadvance(40 * units.deg) + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); +} + +private node rx7_40b { + alias output __out: engine; + + wankel_engine engine( + name: "2JB (6 Rotor 2JZ Crank)", + starter_torque: 180 * units.lb_ft, + starter_speed: 280 * units.rpm, + redline: 10000 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + max_dilution_effect: 1.5, + burning_efficiency_randomness: 1.0 + ), + throttle_gamma: 1.5, + hf_gain: 0.0038, + noise: 1.0, + jitter: 0.8, + simulation_frequency: 7000, + rotor_calculation_quality: 2048, + rotor_housing_resolution: 2048 + ) + + wires wires() + + label store(3 * units.cm) + label radius(10.5 * units.cm) + label depth(8 * units.cm) + + label intake_port_size(24 * units.deg) + label intake_port_angle(136 * units.deg) + + label exhaust_port_size(28 * units.deg) + label exhaust_port_angle(212 * units.deg) + + label spark_angle(30 * units.deg) + + label rotor_mass(4327 * units.g) + label rotor_I(disk_moment_of_inertia(mass: rotor_mass, radius: radius)) + + label intake_port_start(intake_port_angle) + label intake_port_end(intake_port_angle + intake_port_size) + label exhaust_port_start(exhaust_port_angle) + label exhaust_port_end(exhaust_port_angle + exhaust_port_size) + + label carbCFM(140.0) + label idleCFM(0.06) + label idleTP(0.9999) + + crankshaft c0( + throw: 0.5 * stroke, + flywheel_mass: 5 * units.lb, + mass: 5 * units.lb, + friction_torque: 15.0 * units.lb_ft, + moment_of_inertia: 0.22986844776863666 * 0.5, + position_x: 0.0, + position_y: 0.0, + tdc: 0.0 + ) +} diff --git a/assets/engines/atg-video-2/25cc.mr b/assets/engines/atg-video-2/25cc.mr new file mode 100644 index 00000000..cd6c1673 --- /dev/null +++ b/assets/engines/atg-video-2/25cc.mr @@ -0,0 +1,254 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +private node wires { + output wire1: ignition_wire(); +} + +//label sparkadvance(-25.5 * units.deg) +//label sparkadvance(-10 * units.deg) +label sparkadvance(-30 * units.deg) + +private node distributor { + input wires; + input timing_curve; + input rev_limit: 10200 * units.rpm; + input limiter_duration: 0.01 * units.sec; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: limiter_duration) + .connect_wire(wires.wire1, sparkadvance); +} + +private node lobe_profile_int { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 175 * units.deg, + gamma: 1.0, + lift: 5.0 * units.mm, + steps: 100 + ); +} + +private node lobe_profile_exh { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 160 * units.deg, + gamma: 1.0, + lift: 5.0 * units.mm, + steps: 100 + ); +} + +private node camshaft_builder { + input lobe_profile: lobe_profile_int(); + input ex_lobe_profile: lobe_profile_exh(); + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: ex_lobe_profile; + input lobe_separation: 135.0 * units.deg; + input intake_lobe_center: 104.0 * units.deg; + input exhaust_lobe_center: 45.0 * units.deg; + input advance: 0.0 * units.deg; + input base_radius: 10 * units.mm; + + output intake_cam: _intake_cam; + output exhaust_cam: _exhaust_cam; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam(params, lobe_profile: exhaust_lobe_profile) + + label rot360(360 * units.deg) + + _exhaust_cam + .add_lobe(360 * units.deg - exhaust_lobe_center) + + _intake_cam + .add_lobe(360 * units.deg + intake_lobe_center) +} + +public node single { + alias output __out: engine; + + wires wires() + + engine engine( + name: "50cc 4T Single", + starter_torque: 1.5 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 10200 * units.rpm, + fuel: fuel( + max_turbulence_effect: 1.0, + burning_efficiency_randomness: 0.1, + max_burning_efficiency: 1.25 + ) + ) + + crankshaft c0( + throw: 0.5 * 26 * units.mm, + flywheel_mass: 250 * units.g, + mass: 0.1 * units.kg, + friction_torque: 0.0 * units.Nm, + moment_of_inertia: 0.05 * 0.1, + position_x: 0.0, + position_y: 0.0, + tdc: 0 * units.deg + ) + + rod_journal rj0(angle: 90 * units.deg) + + c0 + .add_rod_journal(rj0) + + piston_parameters piston_params( + mass: 100 * units.g, + blowby: 0, + compression_height: 10 * units.mm, + wrist_pin_position: 0 * units.mm, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 100.0 * units.g, + moment_of_inertia: 0.001, + center_of_mass: 0.0, + length: 50 * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: 35 * units.mm, + deck_height: 73 * units.mm + ) + + intake intake( + plenum_volume: 0.5 * units.L, + plenum_cross_section_area: 10.0 * units.cm2, + intake_flow_rate: k_carb(150.0), + idle_flow_rate: k_carb(0.01), + idle_throttle_plate_position: 0.998, + throttle_gamma: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(12000.0), + primary_tube_length: 200.0 * units.mm, + primary_flow_rate: k_carb(1550.0), + velocity_decay: 0.1, + volume: 4.0 * units.L + ) + + exhaust_system exhaust0( + es_params, + audio_volume: 0.5, + impulse_response: ir_lib.default_0 + ) + + cylinder_bank b0(bank_params, angle: -7.5 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1 + ) + + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + camshaft_builder camshaft() + + b0.set_cylinder_head ( + generic_small_engine_head( + intake_camshaft: camshaft.intake_cam, + exhaust_camshaft: camshaft.exhaust_cam, + //chamber_volume: 3.5 * units.cc + chamber_volume: 8 * units.cc + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, -20 * units.deg) + .add_sample(1000 * units.rpm, -20 * units.deg) + .add_sample(2000 * units.rpm, -15 * units.deg) + .add_sample(3000 * units.rpm, -5 * units.deg) + .add_sample(4000 * units.rpm, 5 * units.deg) + .add_sample(5000 * units.rpm, 15 * units.deg) + .add_sample(6000 * units.rpm, 20 * units.deg) + .add_sample(7000 * units.rpm, 25 * units.deg) + .add_sample(8000 * units.rpm, 30 * units.deg) + .add_sample(9000 * units.rpm, 45 * units.deg) + .add_sample(10000 * units.rpm, 50 * units.deg) + .add_sample(11000 * units.rpm, 50 * units.deg) + .add_sample(12000 * units.rpm, 50 * units.deg) + //.add_sample(13000 * units.rpm, 50 * units.deg) + //.add_sample(14000 * units.rpm, 101 * units.deg) + //.add_sample(15000 * units.rpm, 122 * units.deg) + //timing_curve + //.add_sample(0000 * units.rpm, 30 * units.deg) + //.add_sample(1000 * units.rpm, 30 * units.deg) + //.add_sample(2000 * units.rpm, 30 * units.deg) + //.add_sample(3000 * units.rpm, 30 * units.deg) + //.add_sample(5000 * units.rpm, 30 * units.deg) + //.add_sample(6000 * units.rpm, 30 * units.deg) + //.add_sample(7000 * units.rpm, 30 * units.deg) + //.add_sample(8000 * units.rpm, 30 * units.deg) + //.add_sample(9000 * units.rpm, 30 * units.deg) + //.add_sample(10000 * units.rpm, 72 * units.deg) + //.add_sample(11000 * units.rpm, 80 * units.deg) + //.add_sample(12000 * units.rpm, 86.4 * units.deg) + //.add_sample(13000 * units.rpm, 94 * units.deg) + //.add_sample(14000 * units.rpm, 101 * units.deg) + //.add_sample(15000 * units.rpm, 122.5 * units.deg) + + // deg = -0.05128 + 7.206 * (RPM / 1000) + + engine.add_ignition_module( + distributor( + wires: wires, + timing_curve: timing_curve, + rev_limit: 10200 * units.rpm + ) + ) +} + +public node moped { + alias output __out: vehicle; + vehicle vehicle( + mass: 50 * units.kg, + drag_coefficient: 0.75, + cross_sectional_area: (200 * units.mm) * (1600 * units.mm), + diff_ratio: 1.2, + tire_radius: 15 * units.inch, + rolling_resistance: 10 + ) +} + +public node moped_transmission { + alias output __out: trans; + transmission trans( + max_clutch_torque: 10 * units.lb_ft + ) + + trans + .add_gear(32) + .add_gear(20) + .add_gear(10) +} + +public node main { + set_engine(single()) + set_vehicle(moped()) + set_transmission(moped_transmission()) +} + diff --git a/assets/engines/atg-video-2/50cc.mr b/assets/engines/atg-video-2/50cc.mr new file mode 100644 index 00000000..416c2ab0 --- /dev/null +++ b/assets/engines/atg-video-2/50cc.mr @@ -0,0 +1,267 @@ +import "engine_sim.mr" + + +units units() +constants constants() +impulse_response_library ir_lib() + +////// +/// +/// ENGINE NAME: "single" +/// +/// Three speed manual transmission +/// +/// Torque: 5 lb-ft at 2000-4000 RPM +/// Power: 5.5 horsepower at 7500 RPM +/// + +////// + + +private node wires { + output wire1: ignition_wire(); +} + + +label sparkadvance(-25.5 * units.deg) + +private node distributor { + input wires; + input timing_curve; + input rev_limit: 10200 * units.rpm; + input limiter_duration: 0.01 * units.sec; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: limiter_duration) + .connect_wire(wires.wire1, sparkadvance); +} + + +private node lobe_profile_int { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 175 * units.deg, + gamma: 1.0, + lift: 12.0 * units.mm, + steps: 100 + ); +} + + +private node lobe_profile_exh { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 160 * units.deg, + gamma: 1.0, + lift: 8.0 * units.mm, + steps: 100 + ); +} + +private node camshaft_builder { + input lobe_profile: lobe_profile_int(); + input ex_lobe_profile: lobe_profile_exh(); + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: ex_lobe_profile; + input lobe_separation: 135.0 * units.deg; + input intake_lobe_center: 104.0 * units.deg; + input exhaust_lobe_center: 45.0 * units.deg; + input advance: 0.0 * units.deg; + input base_radius: 10 * units.mm; + + output intake_cam: _intake_cam; + output exhaust_cam: _exhaust_cam; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam(params, lobe_profile: exhaust_lobe_profile) + + label rot360(360 * units.deg) + + _exhaust_cam + .add_lobe(360 * units.deg - exhaust_lobe_center) + + _intake_cam + .add_lobe(360 * units.deg + intake_lobe_center) +} + +public node single { + alias output __out: engine; + + wires wires() + + engine engine( + name: "50cc 4T Single", + starter_torque: 1.5 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 10200 * units.rpm, + fuel: fuel( + max_turbulence_effect: 1.0, + burning_efficiency_randomness: 0.1, + max_burning_efficiency: 1.25 + ) + ) + + crankshaft c0( + throw: 0.5 * 40 * units.mm, + flywheel_mass: 350 * units.g, + mass: 0.1 * units.kg, + friction_torque: 0.0 * units.Nm, + moment_of_inertia: 0.05 * 0.2, + position_x: 0.0, + position_y: 0.0, + tdc: 0 * units.deg + ) + + rod_journal rj0(angle: 90 * units.deg) + + c0 + .add_rod_journal(rj0) + + piston_parameters piston_params( + mass: 100 * units.g, + blowby: 0, + compression_height: 25 * units.mm, + wrist_pin_position: -5 * units.mm, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 100.0 * units.g, + moment_of_inertia: 0.001, + center_of_mass: 0.0, + length: 50 * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: 40 * units.mm, + deck_height: 16 * units.mm + ) + + intake intake( + plenum_volume: 0.5 * units.L, + plenum_cross_section_area: 10.0 * units.cm2, + intake_flow_rate: k_carb(150.0), + idle_flow_rate: k_carb(0.01), + idle_throttle_plate_position: 0.998, + throttle_gamma: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(12000.0), + primary_tube_length: 200.0 * units.mm, + primary_flow_rate: k_carb(1550.0), + velocity_decay: 0.1, + volume: 4.0 * units.L + ) + + exhaust_system exhaust0( + es_params, + audio_volume: 0.5, + impulse_response: ir_lib.default_0 + ) + + cylinder_bank b0(bank_params, angle: -7.5 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1 + ) + + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + camshaft_builder camshaft() + + b0.set_cylinder_head ( + generic_small_engine_head( + intake_camshaft: camshaft.intake_cam, + exhaust_camshaft: camshaft.exhaust_cam + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, -20 * units.deg) + .add_sample(1000 * units.rpm, -20 * units.deg) + .add_sample(2000 * units.rpm, -15 * units.deg) + .add_sample(3000 * units.rpm, -5 * units.deg) + .add_sample(4000 * units.rpm, 5 * units.deg) + .add_sample(5000 * units.rpm, 15 * units.deg) + .add_sample(6000 * units.rpm, 20 * units.deg) + .add_sample(7000 * units.rpm, 25 * units.deg) + .add_sample(8000 * units.rpm, 30 * units.deg) + .add_sample(9000 * units.rpm, 45 * units.deg) + .add_sample(10000 * units.rpm, 50 * units.deg) + .add_sample(11000 * units.rpm, 50 * units.deg) + .add_sample(12000 * units.rpm, 50 * units.deg) + //.add_sample(13000 * units.rpm, 50 * units.deg) + //.add_sample(14000 * units.rpm, 101 * units.deg) + //.add_sample(15000 * units.rpm, 122 * units.deg) + //timing_curve + //.add_sample(0000 * units.rpm, 30 * units.deg) + //.add_sample(1000 * units.rpm, 30 * units.deg) + //.add_sample(2000 * units.rpm, 30 * units.deg) + //.add_sample(3000 * units.rpm, 30 * units.deg) + //.add_sample(5000 * units.rpm, 30 * units.deg) + //.add_sample(6000 * units.rpm, 30 * units.deg) + //.add_sample(7000 * units.rpm, 30 * units.deg) + //.add_sample(8000 * units.rpm, 30 * units.deg) + //.add_sample(9000 * units.rpm, 30 * units.deg) + //.add_sample(10000 * units.rpm, 72 * units.deg) + //.add_sample(11000 * units.rpm, 80 * units.deg) + //.add_sample(12000 * units.rpm, 86.4 * units.deg) + //.add_sample(13000 * units.rpm, 94 * units.deg) + //.add_sample(14000 * units.rpm, 101 * units.deg) + //.add_sample(15000 * units.rpm, 122.5 * units.deg) + + // deg = -0.05128 + 7.206 * (RPM / 1000) + + engine.add_ignition_module( + distributor( + wires: wires, + timing_curve: timing_curve, + rev_limit: 10200 * units.rpm + ) + ) +} + +public node moped { + alias output __out: vehicle; + vehicle vehicle( + mass: 50 * units.kg, + drag_coefficient: 0.75, + cross_sectional_area: (200 * units.mm) * (1600 * units.mm), + diff_ratio: 1.2, + tire_radius: 15 * units.inch, + rolling_resistance: 10 + ) +} + +public node moped_transmission { + alias output __out: trans; + transmission trans( + max_clutch_torque: 10 * units.lb_ft + ) + + trans + .add_gear(32) + .add_gear(20) + .add_gear(10) +} + +public node main { + set_engine(single()) + set_vehicle(moped()) + set_transmission(moped_transmission()) +} + diff --git a/assets/engines/atg-video-2/6 Rotor.mr b/assets/engines/atg-video-2/6 Rotor.mr new file mode 100644 index 00000000..ff7231a6 --- /dev/null +++ b/assets/engines/atg-video-2/6 Rotor.mr @@ -0,0 +1,373 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +label cycle(3 * 360 * units.deg) +label sparkadvance(40 * units.deg) + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); +} + +private node rx7_40b { + alias output __out: engine; + + wankel_engine engine( + name: "2JB (6 Rotor 2JZ Crank)", + starter_torque: 180 * units.lb_ft, + starter_speed: 280 * units.rpm, + redline: 10000 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + max_dilution_effect: 1.5, + burning_efficiency_randomness: 1.0 + ), + throttle_gamma: 1.5, + hf_gain: 0.0038, + noise: 1.0, + jitter: 0.8, + simulation_frequency: 15000, + rotor_calculation_quality: 2048, + rotor_housing_resolution: 2048 + ) + + wires wires() + + label stroke(3 * units.cm) + label radius(10.5 * units.cm) + label depth(8 * units.cm) + + label intake_port_size(24 * units.deg) + label intake_port_angle(136 * units.deg) + + label exhaust_port_size(28 * units.deg) + label exhaust_port_angle(212 * units.deg) + + label spark_angle(30 * units.deg) + + label rotor_mass(4327 * units.g) + label rotor_I(disk_moment_of_inertia(mass: rotor_mass, radius: radius)) + + label intake_port_start(intake_port_angle) + label intake_port_end(intake_port_angle + intake_port_size) + label exhaust_port_start(exhaust_port_angle) + label exhaust_port_end(exhaust_port_angle + exhaust_port_size) + + label carbCFM(140.0) + label idleCFM(0.06) + label idleTP(0.9999) + + crankshaft c0( + throw: 0.5 * stroke, + flywheel_mass: 5 * units.lb, + mass: 5 * units.lb, + friction_torque: 15.0 * units.lb_ft, + moment_of_inertia: 0.22986844776863666 * 0.5, + position_x: 0.0, + position_y: 0.0, + tdc: 0.0 + ) + + //1-5-3-6-2-4 (60 deg) + rod_journal rj0(angle: 0.0 * units.deg) //1 + rod_journal rj1(angle: 240.0 * units.deg) //2 + rod_journal rj2(angle: 120.0 * units.deg) //3 + rod_journal rj3(angle: 300.0 * units.deg) //4 + rod_journal rj4(angle: 60.0 * units.deg) //5 + rod_journal rj5(angle: 180.0 * units.deg) //6 + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + + engine.add_crankshaft(c0) + + wankel_rotor rotor0( + mass: rotor_mass, + moment_of_inertia: rotor_I, + radius: radius, + crown_gear_radius: 3 * 0.5 * stroke, + angle: 60 * units.deg, + depth: depth, + depression_volume: 8 * units.cc + ) + + wankel_rotor rotor1( + mass: rotor_mass, + moment_of_inertia: rotor_I, + radius: radius, + crown_gear_radius: 3 * 0.5 * stroke, + angle: 20 * units.deg, + depth: depth, + depression_volume: 8 * units.cc + ) + + wankel_rotor rotor2( + mass: rotor_mass, + moment_of_inertia: rotor_I, + radius: radius, + crown_gear_radius: 3 * 0.5 * stroke, + angle: -20 * units.deg, + depth: depth, + depression_volume: 8 * units.cc + ) + + wankel_rotor rotor3( + mass: rotor_mass, + moment_of_inertia: rotor_I, + radius: radius, + crown_gear_radius: 3 * 0.5 * stroke, + angle: 40 * units.deg, + depth: depth, + depression_volume: 8 * units.cc + ) + + wankel_rotor rotor4( + mass: rotor_mass, + moment_of_inertia: rotor_I, + radius: radius, + crown_gear_radius: 3 * 0.5 * stroke, + angle: -40 * units.deg, + depth: depth, + depression_volume: 8 * units.cc + ) + + wankel_rotor rotor5( + mass: rotor_mass, + moment_of_inertia: rotor_I, + radius: radius, + crown_gear_radius: 3 * 0.5 * stroke, + angle: 0 * units.deg, + depth: depth, + depression_volume: 8 * units.cc + ) + + chevy_bbc_stock_intake intake0( + carburetor_cfm: carbCFM, + idle_flow_rate_cfm: idleCFM, + idle_throttle_plate_position: idleTP + ) + + chevy_bbc_stock_intake intake1( + carburetor_cfm: carbCFM, + idle_flow_rate_cfm: idleCFM, + idle_throttle_plate_position: idleTP + ) + + chevy_bbc_stock_intake intake2( + carburetor_cfm: carbCFM, + idle_flow_rate_cfm: idleCFM, + idle_throttle_plate_position: idleTP + ) + + chevy_bbc_stock_intake intake3( + carburetor_cfm: carbCFM, + idle_flow_rate_cfm: idleCFM, + idle_throttle_plate_position: idleTP + ) + + chevy_bbc_stock_intake intake4( + carburetor_cfm: carbCFM, + idle_flow_rate_cfm: idleCFM, + idle_throttle_plate_position: idleTP + ) + + chevy_bbc_stock_intake intake5( + carburetor_cfm: carbCFM, + idle_flow_rate_cfm: idleCFM, + idle_throttle_plate_position: idleTP + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 10.0 * units.inch, + primary_flow_rate: k_carb(320.0), + velocity_decay: 1.0, + length: 100.0 * units.inch + ) + + exhaust_system exhaust0( + es_params, + length: (180 + 72.0) * units.inch, + audio_volume: 5.5, + impulse_response: ir_lib.minimal_muffling_02) + + engine.add_rotor( + intake0, + exhaust0, + rotor0, + rj0, + wires.wire1, + sound_attenuation: 1.4, + primary_length: 20 * units.inch, + intake_port: default_wankel_peripheral_port(intake_port_start, intake_port_end, k_carb(300.0)), + exhaust_port: default_wankel_peripheral_port(exhaust_port_start, exhaust_port_end, k_carb(300.0)), + intake_runner_cross_section_area: 3.5 * units.cm2, + exhaust_cross_section_area: 6 * units.cm2, + spark_plug_angle: spark_angle + ) + engine.add_rotor( + intake1, + exhaust0, + rotor1, + rj1, + wires.wire2, + sound_attenuation: 1.8, + primary_length: 18 * units.inch, + intake_port: default_wankel_peripheral_port(intake_port_start, intake_port_end, k_carb(300.0)), + exhaust_port: default_wankel_peripheral_port(exhaust_port_start, exhaust_port_end, k_carb(300.0)), + intake_runner_cross_section_area: 3.5 * units.cm2, + exhaust_cross_section_area: 6 * units.cm2, + spark_plug_angle: spark_angle + ) + engine.add_rotor( + intake2, + exhaust0, + rotor2, + rj2, + wires.wire3, + sound_attenuation: 1.0, + primary_length: 16 * units.inch, + intake_port: default_wankel_peripheral_port(intake_port_start, intake_port_end, k_carb(300.0)), + exhaust_port: default_wankel_peripheral_port(exhaust_port_start, exhaust_port_end, k_carb(300.0)), + intake_runner_cross_section_area: 3.5 * units.cm2, + exhaust_cross_section_area: 6 * units.cm2, + spark_plug_angle: spark_angle + ) + engine.add_rotor( + intake3, + exhaust0, + rotor3, + rj3, + wires.wire4, + sound_attenuation: 1.4, + primary_length: 14 * units.inch, + intake_port: default_wankel_peripheral_port(intake_port_start, intake_port_end, k_carb(300.0)), + exhaust_port: default_wankel_peripheral_port(exhaust_port_start, exhaust_port_end, k_carb(300.0)), + intake_runner_cross_section_area: 3.5 * units.cm2, + exhaust_cross_section_area: 6 * units.cm2, + spark_plug_angle: spark_angle + ) + engine.add_rotor( + intake4, + exhaust0, + rotor4, + rj4, + wires.wire5, + sound_attenuation: 1.8, + primary_length: 12 * units.inch, + intake_port: default_wankel_peripheral_port(intake_port_start, intake_port_end, k_carb(300.0)), + exhaust_port: default_wankel_peripheral_port(exhaust_port_start, exhaust_port_end, k_carb(300.0)), + intake_runner_cross_section_area: 3.5 * units.cm2, + exhaust_cross_section_area: 6 * units.cm2, + spark_plug_angle: spark_angle + ) + engine.add_rotor( + intake5, + exhaust0, + rotor5, + rj5, + wires.wire6, + sound_attenuation: 1.0, + primary_length: 10 * units.inch, + intake_port: default_wankel_peripheral_port(intake_port_start, intake_port_end, k_carb(300.0)), + exhaust_port: default_wankel_peripheral_port(exhaust_port_start, exhaust_port_end, k_carb(300.0)), + intake_runner_cross_section_area: 3.5 * units.cm2, + exhaust_cross_section_area: 6 * units.cm2, + spark_plug_angle: spark_angle + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 5 * units.deg) + .add_sample(1000 * units.rpm, 15 * units.deg) + .add_sample(2000 * units.rpm, 25 * units.deg) + .add_sample(3000 * units.rpm, 35 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + .add_sample(5000 * units.rpm, 55 * units.deg) + .add_sample(6000 * units.rpm, 70 * units.deg) + .add_sample(7000 * units.rpm, 75 * units.deg) + .add_sample(8000 * units.rpm, 80 * units.deg) + .add_sample(9000 * units.rpm, 85 * units.deg) + .add_sample(10000 * units.rpm, 90 * units.deg) + + //1-5-3-6-2-4 + engine.add_ignition_module( + ignition_module(timing_curve: timing_curve, rev_limit: 10000 * units.rpm, limiter_duration: 0.05) + .connect_wire(wires.wire1, ((0.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire1, ((6.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire1, ((12.0 / 18.0) * cycle) + sparkadvance) + + .connect_wire(wires.wire2, ((4.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire2, ((10.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire2, ((16.0 / 18.0) * cycle) + sparkadvance) + + .connect_wire(wires.wire3, ((2.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire3, ((8.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire3, ((14.0 / 18.0) * cycle) + sparkadvance) + + .connect_wire(wires.wire4, ((5.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire4, ((11.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire4, ((17.0 / 18.0) * cycle) + sparkadvance) + + .connect_wire(wires.wire5, ((1.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire5, ((7.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire5, ((13.0 / 18.0) * cycle) + sparkadvance) + + .connect_wire(wires.wire6, ((3.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire6, ((9.0 / 18.0) * cycle) + sparkadvance) + .connect_wire(wires.wire6, ((15.0 / 18.0) * cycle) + sparkadvance) + ) +} + +label car_mass(1000 * units.kg) + +private node rx7_car { + alias output __out: + vehicle( + mass: car_mass, + drag_coefficient: 0.14, + cross_sectional_area: (168.5 * units.inch) * (68.9 * units.inch), + diff_ratio: 4.50, + tire_radius: 16 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81, + stiffness: 50 * units.lb_ft / units.deg, + damping: 15.0, + max_flex: 5 * units.deg, + limit_flex: true, + simulate_flex: true + ); +} + +private node rx7_trans { + alias output __out: + transmission( + max_clutch_torque: 1200 * units.lb_ft, + max_clutch_flex: 8 * units.deg, + limit_clutch_flex: true, + clutch_stiffness: 50 * units.lb_ft / units.deg, + clutch_damping: 2.0, + simulate_flex: true + ) + .add_gear(3.483) + .add_gear(2.015) + .add_gear(1.391) + .add_gear(1.00) + .add_gear(0.719); +} + +public node main { + set_engine(rx7_40b()) + set_vehicle(rx7_car()) + set_transmission(rx7_trans()) +} diff --git a/assets/engines/atg-video-2/error_log.log b/assets/engines/atg-video-2/error_log.log new file mode 100644 index 00000000..40302aa0 --- /dev/null +++ b/assets/engines/atg-video-2/error_log.log @@ -0,0 +1 @@ +Can't find file: ../assets/main.mr diff --git a/assets/engines/atg-video-2/f312t.mr b/assets/engines/atg-video-2/f312t.mr new file mode 100644 index 00000000..bbf63dd1 --- /dev/null +++ b/assets/engines/atg-video-2/f312t.mr @@ -0,0 +1,475 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(720 * units.deg) + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); + output wire9: ignition_wire(); + output wire10: ignition_wire(); + output wire11: ignition_wire(); + output wire12: ignition_wire(); +} + +private node f312_t_head { + input intake_camshaft; + input exhaust_camshaft; + input chamber_volume: 21.7 * units.cc; + input intake_runner_volume: 150.0 * units.cc; + input intake_runner_cross_section_area: 10.0 * units.cm2; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 10.0 * units.cm2; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 50 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 80 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 110 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 140 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 190 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 200 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 220 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 240 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 260 * flow_attenuation) + .add_flow_sample(500 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(550 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(600 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(650 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(700 * lift_scale, 280 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 50 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 80 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 110 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 140 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 180 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 200 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 220 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 240 * flow_attenuation) + .add_flow_sample(500 * lift_scale, 260 * flow_attenuation) + .add_flow_sample(550 * lift_scale, 300 * flow_attenuation) + .add_flow_sample(600 * lift_scale, 300 * flow_attenuation) + .add_flow_sample(650 * lift_scale, 300 * flow_attenuation) + .add_flow_sample(700 * lift_scale, 300 * flow_attenuation) + + cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +private node f312_t_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 140 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 10.0 * units.mm; + + output intake_cam_1: _intake_cam_1; + output intake_cam_2: _intake_cam_2; + output exhaust_cam_1: _exhaust_cam_1; + output exhaust_cam_2: _exhaust_cam_2; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_1(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_1(params, lobe_profile: exhaust_lobe_profile) + + camshaft _intake_cam_2(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_2(params, lobe_profile: exhaust_lobe_profile) + + label rot(2 * (360 / 12.0) * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_1 + .add_lobe(rot360 - exhaust_lobe_center) + .add_lobe((rot360 - exhaust_lobe_center) + 8 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 4 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 10 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 2 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 6 * rot) + + _intake_cam_1 + .add_lobe(rot360 + intake_lobe_center) + .add_lobe((rot360 + intake_lobe_center) + 8 * rot) + .add_lobe((rot360 + intake_lobe_center) + 4 * rot) + .add_lobe((rot360 + intake_lobe_center) + 10 * rot) + .add_lobe((rot360 + intake_lobe_center) + 2 * rot) + .add_lobe((rot360 + intake_lobe_center) + 6 * rot) + + _exhaust_cam_2 + .add_lobe((rot360 - exhaust_lobe_center) + 3 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 11 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 7 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 1 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 5 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 9 * rot) + + _intake_cam_2 + .add_lobe((rot360 + intake_lobe_center) + 3 * rot) + .add_lobe((rot360 + intake_lobe_center) + 11 * rot) + .add_lobe((rot360 + intake_lobe_center) + 7 * rot) + .add_lobe((rot360 + intake_lobe_center) + 1 * rot) + .add_lobe((rot360 + intake_lobe_center) + 5 * rot) + .add_lobe((rot360 + intake_lobe_center) + 9 * rot) +} + +public node t_f312 { + alias output __out: engine; + + engine engine( + name: "Ferrari 312T Flat 12", + starter_torque: 80 * units.N, + starter_speed: 150 * units.rpm, + redline: 13200 * units.rpm, + fuel: fuel( + max_turbulence_effect: 0.5, + // added? + max_dilution_effect: 5.0, + burning_efficiency_randomness: 0.05, + max_burning_efficiency: 0.95 + ), + throttle_gamma: 2.0, + hf_gain: 0.002, + noise: 0.8, + jitter: 0.75, + //simulation_frequency: 10000 + simulation_frequency: 5000 + ) + + wires wires() + + label stroke(49.6 * units.mm) + label bore(80 * units.mm) + label rod_length(112 * units.mm) + label compression_height(30 * units.mm) + + crankshaft c1( + throw: stroke / 2, + flywheel_mass: 20 * units.kg, + mass: 20 * units.kg, + friction_torque: 10.0 * units.lb_ft, + moment_of_inertia: 0.2 * 0.5, + position_x: 0.0, + position_y: 0.0, + tdc: 0 * units.deg + ) + + rod_journal rj1(angle: 0.0 * units.deg) + rod_journal rj2(angle: 120.0 * units.deg) + rod_journal rj3(angle: 240.0 * units.deg) + rod_journal rj4(angle: 240.0 * units.deg) + rod_journal rj5(angle: 120.0 * units.deg) + rod_journal rj6(angle: 0.0 * units.deg) + + c1 + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + + piston_parameters piston_params( + mass: 200 * units.g, + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 300.0 * units.g, + moment_of_inertia: 0.0015884918028487504, + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.0 * units.L, + plenum_cross_section_area: 10.0 * units.cm2, + intake_flow_rate: k_carb(1500.0), + runner_flow_rate: k_carb(217.0), + runner_length: 100.0 * units.mm, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9974, + velocity_decay: 0.1 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 150.0 * units.mm, + primary_flow_rate: k_carb(600.0), + velocity_decay: 0.2, + volume: 10.0 * units.L + ) + + exhaust_system exhaust1(es_params, audio_volume: 1.0, impulse_response: ir_lib.default_0) + exhaust_system exhaust2(es_params, audio_volume: 0.1, impulse_response: ir_lib.default_0) + exhaust_system exhaust3(es_params, audio_volume: 0.1, impulse_response: ir_lib.default_0) + exhaust_system exhaust4(es_params, audio_volume: 1.0, impulse_response: ir_lib.default_0) + exhaust_system exhaust5(es_params, audio_volume: 1.0, impulse_response: ir_lib.default_0) + exhaust_system exhaust6(es_params, audio_volume: 0.1, impulse_response: ir_lib.default_0) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b1(bank_params, angle: -90 * units.deg) + b1 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire1, + sound_attenuation: 0.8 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust2, + ignition_wire: wires.wire2, + sound_attenuation: 0.7 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust3, + ignition_wire: wires.wire3, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust4, + ignition_wire: wires.wire4, + sound_attenuation: 0.8 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust5, + ignition_wire: wires.wire5, + sound_attenuation: 0.6 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust6, + ignition_wire: wires.wire6, + sound_attenuation: 0.7 + ) + + cylinder_bank b2(bank_params, angle: 90 * units.deg) + b2 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire7, + sound_attenuation: 0.4 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust2, + ignition_wire: wires.wire8, + sound_attenuation: 0.8 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust3, + ignition_wire: wires.wire9, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust4, + ignition_wire: wires.wire10, + sound_attenuation: 0.7 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust5, + ignition_wire: wires.wire11, + sound_attenuation: 0.6 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.05)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust6, + ignition_wire: wires.wire12, + sound_attenuation: 0.8 + ) + + engine + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + + engine.add_crankshaft(c1) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 174 * units.deg, + gamma: 0.6, + lift: 10.5 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 174 * units.deg, + gamma: 0.6, + lift: 10.5 * units.mm, + steps: 100 + ) + + f312_t_camshaft camshaft( + lobe_profile: "N/A", + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 140 * units.deg, + exhaust_lobe_center: 140 * units.deg, + base_radius: 10 * units.mm + ) + + b1.set_cylinder_head ( + f312_t_head( + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1 + ) + ) + b2.set_cylinder_head ( + f312_t_head( + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2, + flip_display: true + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 10 * units.deg) + .add_sample(1000 * units.rpm, 10 * units.deg) + .add_sample(2000 * units.rpm, 18 * units.deg) + .add_sample(3000 * units.rpm, 20 * units.deg) + .add_sample(4000 * units.rpm, 24 * units.deg) + .add_sample(5000 * units.rpm, 28 * units.deg) + .add_sample(6000 * units.rpm, 32 * units.deg) + .add_sample(7000 * units.rpm, 36 * units.deg) + .add_sample(8000 * units.rpm, 40 * units.deg) + .add_sample(9000 * units.rpm, 44 * units.deg) + .add_sample(10000 * units.rpm, 48 * units.deg) + .add_sample(11000 * units.rpm, 52 * units.deg) + .add_sample(12000 * units.rpm, 56 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 13200 * units.rpm, + limiter_duration: 0.03) + ignition_module + .connect_wire(wires.wire1, (0.0 / 12.0) * cycle) + .connect_wire(wires.wire10, (1.0 / 12.0) * cycle) + .connect_wire(wires.wire5, (2.0 / 12.0) * cycle) + .connect_wire(wires.wire7, (3.0 / 12.0) * cycle) + .connect_wire(wires.wire3, (4.0 / 12.0) * cycle) + .connect_wire(wires.wire11, (5.0 / 12.0) * cycle) + .connect_wire(wires.wire6, (6.0 / 12.0) * cycle) + .connect_wire(wires.wire9, (7.0 / 12.0) * cycle) + .connect_wire(wires.wire2, (8.0 / 12.0) * cycle) + .connect_wire(wires.wire12, (9.0 / 12.0) * cycle) + .connect_wire(wires.wire4, (10.0 / 12.0) * cycle) + .connect_wire(wires.wire8, (11.0 / 12.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +private node f312_t_transmission { + alias output __out: transmission; + + transmission transmission( + max_clutch_torque: 400 * units.N + ) + + transmission.add_gear(3.8) + transmission.add_gear(2.6) + transmission.add_gear(2.0) + transmission.add_gear(1.6) + transmission.add_gear(1.2) +} + +private node f312_t { + alias output __out: + vehicle( + mass: 575 * units.kg, + drag_coefficient: 0.3, + cross_sectional_area: (2030 * units.mm) * (1275 * units.mm), + diff_ratio: 4.2, + tire_radius: 330 * units.mm, + rolling_resistance: 150 * units.N + ); +} + +public node main { + set_engine(t_f312()) + set_transmission(f312_t_transmission()) + set_vehicle(f312_t()) +} diff --git a/assets/engines/atg-video-2/gx25.mr b/assets/engines/atg-video-2/gx25.mr new file mode 100644 index 00000000..a901b0cc --- /dev/null +++ b/assets/engines/atg-video-2/gx25.mr @@ -0,0 +1,188 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +private node wires { + output wire1: ignition_wire(); +} + +public node gx25 { + alias output __out: engine; + + engine engine( + name: "Honda GX25 'Leaf-Blower'", + starter_torque: 200 * units.lb_ft, + starter_speed: 1500 * units.rpm, + //redline: 5800 * units.rpm, + redline: 10000 * units.rpm, + fuel: fuel( + max_turbulence_effect: 0.0, + burning_efficiency_randomness: 0.0, + max_burning_efficiency: 2.0 + //max_burning_efficiency: 1.1 + ) + ) + + wires wires() + + crankshaft c0( + throw: 33 * units.mm / 2, + //flywheel_mass: 5 * units.lb, + flywheel_mass: 500 * units.g, + //mass: 5 * units.lb, + mass: 200 * units.g, + //friction_torque: 0.0 * units.lb_ft, + friction_torque: 0.001 * units.Nm, + moment_of_inertia: 0.03986844776863666 * 0.1, + //moment_of_inertia: 0.03986844776863666 * 0.01, + position_x: 0.0, + position_y: 0.0, + tdc: constants.pi / 2 + ) + + rod_journal rj0(angle: 0.0) + c0 + .add_rod_journal(rj0) + + piston_parameters piston_params( + //mass: 200 * units.g, + mass: 70 * units.g, + //blowby: k_28inH2O(0.1), + //compression_height: 1.0 * units.inch, + compression_height: 15 * units.mm, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + //mass: 300.0 * units.g, + mass: 200.0 * units.g, + moment_of_inertia: 0.0015884918028487504, + center_of_mass: 0.0, + //length: 1.7 * units.inch + length: 50 * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: 31 * units.mm, + deck_height: 90 * units.mm / 1 + ) + + intake intake( + //plenum_volume: 1.0 * units.L, + plenum_volume: 0.05 * units.L, + //plenum_cross_section_area: 20.0 * units.cm2, + plenum_cross_section_area: 10.0 * units.cm2, + intake_flow_rate: k_carb(1500.0), + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.999915, + //throttle_gamma: 7.0 + throttle_gamma: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + //primary_tube_length: 10.0 * units.inch, + primary_tube_length: 10.0 * units.mm, + primary_flow_rate: k_carb(50.0), + velocity_decay: 1.0, + volume: 0.5 * units.L + ) + + exhaust_system exhaust0( + es_params, + audio_volume: 1.0, + impulse_response: ir_lib.default_0 + ) + + cylinder_bank b0(bank_params, angle: 0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1 + ) + + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe lobe( + duration_at_50_thou: 160 * units.deg, + gamma: 1.1, + //lift: 150 * units.thou, + lift: 5.0 * units.mm, + steps: 200 + ) + + vtwin90_camshaft_builder camshaft( + lobe_profile: lobe, + lobe_separation: 114 * units.deg, + base_radius: 400 * units.thou + ) + + b0.set_cylinder_head ( + generic_small_engine_head( + chamber_volume: 0 * units.cc, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 50 * units.deg) + .add_sample(1000 * units.rpm, 50 * units.deg) + .add_sample(2000 * units.rpm, 50 * units.deg) + .add_sample(3000 * units.rpm, 50 * units.deg) + .add_sample(4000 * units.rpm, 50 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 14000 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, 0) + engine.add_ignition_module(ignition_module) +} + +label car_mass(2 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + + +public node main { + set_engine(gx25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} + diff --git a/assets/engines/atg-video-2/i2.mr b/assets/engines/atg-video-2/i2.mr new file mode 100644 index 00000000..b443a343 --- /dev/null +++ b/assets/engines/atg-video-2/i2.mr @@ -0,0 +1,332 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_0 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 2) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 2) * cycle) + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 2) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 2) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 90 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + rod_journal rj1(angle: 0.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b0(bank_params, angle: 0.0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0) + ) + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, (0.0 / 2.0) * cycle) + .connect_wire(wires.wire2, (1.0 / 2.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/i2_bb.mr b/assets/engines/atg-video-2/i2_bb.mr new file mode 100644 index 00000000..a3c235d1 --- /dev/null +++ b/assets/engines/atg-video-2/i2_bb.mr @@ -0,0 +1,335 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_0 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 2) * cycle) + //.add_lobe(rot360 - exhaust_lobe_center + (1.0 / 2) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 2) * cycle) + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 2) * cycle) + //.add_lobe(rot360 + intake_lobe_center + (1.0 / 2) * cycle) + .add_lobe(rot360 + intake_lobe_center + (0.0 / 2) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 90 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + rod_journal rj1(angle: 0.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b0(bank_params, angle: 0.0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0) + ) + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, (0.0 / 2.0) * cycle) + //.connect_wire(wires.wire2, (1.0 / 2.0) * cycle) + .connect_wire(wires.wire2, (0.0 / 2.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/i2_cp.mr b/assets/engines/atg-video-2/i2_cp.mr new file mode 100644 index 00000000..51ad4aec --- /dev/null +++ b/assets/engines/atg-video-2/i2_cp.mr @@ -0,0 +1,332 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_0 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 2) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 4) * cycle) + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 4) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 4) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 90 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + rod_journal rj1(angle: 180.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b0(bank_params, angle: 0.0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0) + ) + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, (0.0 / 4.0) * cycle) + .connect_wire(wires.wire2, (1.0 / 4.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/i2_cp2.mr b/assets/engines/atg-video-2/i2_cp2.mr new file mode 100644 index 00000000..f7dd9768 --- /dev/null +++ b/assets/engines/atg-video-2/i2_cp2.mr @@ -0,0 +1,332 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_0 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 8) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (1.0 / 8) * cycle) + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 8) * cycle) + .add_lobe(rot360 + intake_lobe_center + (1.0 / 8) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 90 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + rod_journal rj1(angle: 90.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b0(bank_params, angle: 0.0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0) + ) + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, (0.0 / 8.0) * cycle) + .connect_wire(wires.wire2, (1.0 / 8.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/i2_cp3.mr b/assets/engines/atg-video-2/i2_cp3.mr new file mode 100644 index 00000000..2e2db142 --- /dev/null +++ b/assets/engines/atg-video-2/i2_cp3.mr @@ -0,0 +1,332 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() +label cycle(2 * 360 * units.deg) + +private node turbulence_to_flame_speed_ratio { + alias output __out: + function(5.0) + .add_sample(0.0, 1.0 * 3.0) + .add_sample(5.0, 1.0 * 1.5 * 5.0) + .add_sample(10.0, 1.0 * 1.5 * 10.0) + .add_sample(15.0, 1.1 * 1.5 * 15.0) + .add_sample(20.0, 1.25 * 1.5 * 20.0) + .add_sample(25.0, 1.25 * 1.5 * 25.0) + .add_sample(30.0, 1.25 * 1.5 * 30.0) + .add_sample(35.0, 1.25 * 1.5 * 35.0) + .add_sample(40.0, 1.25 * 1.5 * 40.0) + .add_sample(45.0, 1.25 * 1.5 * 45.0); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); +} + +private node ej25_head { + input intake_camshaft; + input exhaust_camshaft; + //input chamber_volume: 67 * units.cc; + //input chamber_volume: 50 * units.cc; + input chamber_volume: 41 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.75 * units.inch * 1.75 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +private node ej25_camshaft { + input lobe_profile; + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 114 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0 * units.deg; + input base_radius: 1.0 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + camshaft_parameters params ( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + + label rot180(180 * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam_0 + .add_lobe(rot360 - exhaust_lobe_center + (0.0 / 16) * cycle) + .add_lobe(rot360 - exhaust_lobe_center + (3.0 / 16) * cycle) + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + (0.0 / 16) * cycle) + .add_lobe(rot360 + intake_lobe_center + (3.0 / 16) * cycle) +} + +public node subaru_ej25 { + alias output __out: engine; + + engine engine( + name: "Subaru EL15", + starter_torque: 70 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_burning_efficiency: 0.9, + turbulence_to_flame_speed_ratio: turbulence_to_flame_speed_ratio() + ), + throttle_gamma: 2.0, + hf_gain: 0.01, + noise: 1.0, + jitter: 0.5, + simulation_frequency: 10000 + ) + + wires wires() + + label stroke(79 * units.mm) + //label bore(99.5 * units.mm) + label bore(77.7 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(1.0 * units.inch) + label crank_mass(9.39 * units.kg) + label flywheel_mass(6.8 * units.kg) + label flywheel_radius(6 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) * 2 + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 6.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 1.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: 90 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + rod_journal rj1(angle: 135.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + + piston_parameters piston_params( + mass: (414 + 152) * units.g, // 414 - piston mass, 152 - pin weight + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + intake intake( + plenum_volume: 1.325 * units.L, + plenum_cross_section_area: 20.0 * units.cm2, + intake_flow_rate: k_carb(400.0), + runner_flow_rate: k_carb(100.0), + runner_length: 12.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9978, + velocity_decay: 1.0 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 40.0 * units.inch, + primary_flow_rate: k_carb(400.0), + velocity_decay: 1.0 + ) + + exhaust_system exhaust0( + es_params, + length: 500 * units.mm, + audio_volume: 0.5 * 0.02, + impulse_response: ir_lib.minimal_muffling_02 + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + cylinder_bank b0(bank_params, angle: 0.0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.001)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + primary_length: 2.0 * units.inch, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.002)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2, + primary_length: 3.0 * units.inch, + sound_attenuation: 1.0 + ) + .set_cylinder_head( + ej25_head( + flip_display: true, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0) + ) + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 232 * units.deg, + gamma: 2.0, + lift: 9.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 236 * units.deg, + gamma: 2.0, + lift: 9.60 * units.mm, + steps: 100 + ) + + ej25_camshaft camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 117 * units.deg, + exhaust_lobe_center: 112 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 25 * units.deg) + .add_sample(1000 * units.rpm, 25 * units.deg) + .add_sample(2000 * units.rpm, 30 * units.deg) + .add_sample(3000 * units.rpm, 40 * units.deg) + .add_sample(4000 * units.rpm, 40 * units.deg) + + ignition_module ignition_module( + timing_curve: timing_curve, + rev_limit: 6800 * units.rpm, + limiter_duration: 0.16) + ignition_module + .connect_wire(wires.wire1, (0.0 / 16.0) * cycle) + .connect_wire(wires.wire2, (3.0 / 16.0) * cycle) + + engine.add_ignition_module(ignition_module) +} + +label car_mass(2700 * units.lb) + +private node impreza { + alias output __out: + vehicle( + mass: 2700 * units.lb, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node impreza_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(subaru_ej25()) + set_vehicle(impreza()) + set_transmission(impreza_transmission()) +} diff --git a/assets/engines/atg-video-2/porsche_993.mr b/assets/engines/atg-video-2/porsche_993.mr new file mode 100644 index 00000000..61b21f47 --- /dev/null +++ b/assets/engines/atg-video-2/porsche_993.mr @@ -0,0 +1,430 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +// Engine Sim V0.1.11A +// Porsche 996 C2 285HP @6100 +// porsche_993 +// Created by Ihar Rahatka (oror) 2022 + +label cycle(2 * 360 * units.deg) +label bore(100.0) +label stroke(76.4) +label compression_ratio(11.3) +label con_rod(127.0) +label cyl(6) +label vee(180.0 * units.deg) +label rot90(90.0 * units.deg) +label rot180(180.0 * units.deg) +label rot360(360.0 * units.deg) + +// 964 / 993 Street / Sport Cam valve timings +label IVO(30.0 * units.deg) //BTDC +label IVC(78.0 * units.deg) //ABDC +label EVO(74.0 * units.deg) //BBDC +label EVC(26.0 * units.deg) //ATDC + +label intake_duration(IVO + IVC + rot180) +label exhaust_duration(EVO + EVC + rot180) + +label ILC((-IVO + rot180 + IVC) / 2.0 + rot360) +label ELC((rot180 - EVO + EVC + rot360) / 2.0) + +public node eng_distributor { + input wires; + input timing_curve; + input rev_limit: 6750 * units.rpm; + input limiter_duration: 0.06; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: limiter_duration) + .connect_wire(wires.wire1, (0.0/6.0) * cycle) + .connect_wire(wires.wire6, (1.0/6.0) * cycle) + .connect_wire(wires.wire2, (2.0/6.0) * cycle) + .connect_wire(wires.wire4, (3.0/6.0) * cycle) + .connect_wire(wires.wire3, (4.0/6.0) * cycle) + .connect_wire(wires.wire5, (5.0/6.0) * cycle); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); +} + +public node eng_lobe_profile_int { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: intake_duration, + gamma: 6.0, + lift: 13.2 * units.mm, // valve lift, not lobe lift + steps: 100 + ); +} + +public node eng_lobe_profile_exh { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: exhaust_duration, + gamma: 6.0, + lift: 13.2 * units.mm, // valve lift, not lobe lift + steps: 100 + ); +} + +public node eng_camshaft_builder { + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + camshaft_parameters params( + advance: 0.0 * units.deg, + base_radius: 2.2 * units.cm + ) + + camshaft _intake_cam_0(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_0(params, lobe_profile: eng_lobe_profile_exh()) + + camshaft _intake_cam_1(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_1(params, lobe_profile: eng_lobe_profile_exh()) + + label rot(2 * (360.0 / cyl) * units.deg) + + _intake_cam_0 + .add_lobe(ILC + 0 * rot) + .add_lobe(ILC + 2 * rot) + .add_lobe(ILC + 4 * rot) + + _exhaust_cam_0 + .add_lobe(ELC + 0 * rot) + .add_lobe(ELC + 2 * rot) + .add_lobe(ELC + 4 * rot) + + _intake_cam_1 + .add_lobe(ILC + 3 * rot) + .add_lobe(ILC + 5 * rot) + .add_lobe(ILC + 1 * rot) + + _exhaust_cam_1 + .add_lobe(ELC + 3 * rot) + .add_lobe(ELC + 5 * rot) + .add_lobe(ELC + 1 * rot) +} + +private node add_flow_sample { + input lift; + input flow; + input this; + alias output __out: this; + + this.add_sample(lift * units.mm, k_28inH2O(flow)) +} + +public node eng_head { + input intake_camshaft; + input exhaust_camshaft; + input flip_display: false; + + input flow_attenuation: 1.06; + input lift_scale: 1; + alias output __out: head; + + label bore_radius(bore / 2) + label cyl_area(bore_radius * bore_radius * constants.pi) + + function intake_flow(1 * units.mm) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(1 * lift_scale, 35 * flow_attenuation) + .add_flow_sample(2 * lift_scale, 60 * flow_attenuation) + .add_flow_sample(3 * lift_scale, 90 * flow_attenuation) + .add_flow_sample(4 * lift_scale, 125 * flow_attenuation) + .add_flow_sample(5 * lift_scale, 150 * flow_attenuation) + .add_flow_sample(6 * lift_scale, 175 * flow_attenuation) + .add_flow_sample(7 * lift_scale, 200 * flow_attenuation) + .add_flow_sample(8 * lift_scale, 215 * flow_attenuation) + .add_flow_sample(9 * lift_scale, 230 * flow_attenuation) + .add_flow_sample(10 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(11 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(12 * lift_scale, 238 * flow_attenuation) + + function exhaust_flow(1 * units.mm) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(1 * lift_scale, 35 * flow_attenuation) + .add_flow_sample(2 * lift_scale, 55 * flow_attenuation) + .add_flow_sample(3 * lift_scale, 85 * flow_attenuation) + .add_flow_sample(4 * lift_scale, 105 * flow_attenuation) + .add_flow_sample(5 * lift_scale, 120 * flow_attenuation) + .add_flow_sample(6 * lift_scale, 140 * flow_attenuation) + .add_flow_sample(7 * lift_scale, 150 * flow_attenuation) + .add_flow_sample(8 * lift_scale, 155 * flow_attenuation) + .add_flow_sample(9 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(10 * lift_scale, 165 * flow_attenuation) + .add_flow_sample(11 * lift_scale, 165 * flow_attenuation) + .add_flow_sample(12 * lift_scale, 165 * flow_attenuation) + + cylinder_head head( + chamber_volume: (cyl_area * stroke / compression_ratio) / 1000 * units.cc, + intake_runner_volume: 100.0 * units.cc, + intake_runner_cross_section_area: 29.0 * units.cm2, + exhaust_runner_volume: 25.0 * units.cc, + exhaust_runner_cross_section_area: 9.0 * units.cm2, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +public node eng { + alias output __out: engine; + + engine engine( + name: "Porsche 993 3.6", + starter_torque: 150 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.0, + burning_efficiency_randomness: 0.2, + max_burning_efficiency: 0.94 + ), + throttle_gamma: 1.75, + jitter: 1.0, + noise: 1.0, + simulation_frequency: 10000 + ) + + wires wires() + + crankshaft c0( + throw: (stroke / 2) * units.mm, + flywheel_mass: 2.0 * units.kg, + mass: 13.81 * units.kg, + friction_torque: 1.5 * units.Nm, + moment_of_inertia: 0.15, + position_x: 0.0, + position_y: 0.0, + tdc: 0.000001 * units.deg + ) + + rod_journal rj0(angle: (0.0 / 6.0) * cycle + vee) + rod_journal rj2(angle: (2.0 / 6.0) * cycle + vee) + rod_journal rj4(angle: (4.0 / 6.0) * cycle + vee) + rod_journal rj1(angle: (3.0 / 6.0) * cycle) + rod_journal rj3(angle: (5.0 / 6.0) * cycle) + rod_journal rj5(angle: (1.0 / 6.0) * cycle) + + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + + piston_parameters piston_params( + mass: 440.0 * units.g, + blowby: k_28inH2O(0.05), + compression_height: 31.7 * units.mm, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 535.0 * units.g, + moment_of_inertia: 0.002, + center_of_mass: 0.0, + length: con_rod * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: bore * units.mm, + deck_height: (con_rod + (stroke / 2) + 31.7) * units.mm + ) + + intake intake( + plenum_volume: 1.0 * units.L, + plenum_cross_section_area: 150.0 * units.cm2, + intake_flow_rate: k_carb(550.0), + idle_flow_rate: k_carb(0.01), + idle_throttle_plate_position: 0.9975, + runner_flow_rate: k_carb(550.0), + runner_length: 3.0 * units.cm, + velocity_decay: 0.01 + ) + + exhaust_system_parameters es_params0( + outlet_flow_rate: k_carb(500.0), + primary_tube_length: 106.0 * units.cm, + primary_flow_rate: k_carb(250.0), + velocity_decay: 1.0, + volume: 3.9 * units.L + ) + + exhaust_system_parameters es_params1( + outlet_flow_rate: k_carb(500.0), + primary_tube_length: 100.0 * units.cm, + primary_flow_rate: k_carb(250.0), + velocity_decay: 1.0, + volume: 3.3 * units.L + ) + + // exhaust_system exhaust0(es_params0, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + // exhaust_system exhaust1(es_params1, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + exhaust_system exhaust0(es_params0, impulse_response: ir_lib.default_0) + exhaust_system exhaust1(es_params1, impulse_response: ir_lib.default_0) + + cylinder_bank b0(bank_params, angle: vee / 2) + cylinder_bank b1(bank_params, angle: -vee / 2) + + label div(0.85) + label pl0 ((1.1 * bore / div) * units.mm) + label pl1 ((1.0 * bore / div) * units.mm) + label pl2 ((0.0 * bore / div) * units.mm) + label pl3 ((1.1 * bore / div) * units.mm) + label pl4 ((1.0 * bore / div) * units.mm) + label pl5 ((0.0 * bore / div) * units.mm) + + b0 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl0, + ignition_wire: wires.wire1 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl1, + ignition_wire: wires.wire2 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl2, + ignition_wire: wires.wire3 + ) + + b1 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl3, + ignition_wire: wires.wire4 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl4, + ignition_wire: wires.wire5 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl5, + ignition_wire: wires.wire6 + ) + + engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + + engine.add_crankshaft(c0) + + eng_camshaft_builder camshaft() + + b0.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0, + flip_display: true + ) + ) + b1.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 10.0 * units.deg) + .add_sample(1000 * units.rpm, 15.0 * units.deg) + .add_sample(2000 * units.rpm, 25.0 * units.deg) + .add_sample(3000 * units.rpm, 35.0 * units.deg) + .add_sample(4000 * units.rpm, 35.0 * units.deg) + .add_sample(5000 * units.rpm, 34.5 * units.deg) + .add_sample(6000 * units.rpm, 34.0 * units.deg) + + engine.add_ignition_module( + eng_distributor( + wires: wires, + timing_curve: timing_curve + ) + ) +} + +// 993 +public node veh { + alias output __out: vehicle; + vehicle vehicle( + mass: 1270 * units.kg, + drag_coefficient: 0.32, + cross_sectional_area: (1735 * units.mm) * (1311 * units.mm), + diff_ratio: 3.444, + tire_radius: (632.0 / 2) * units.mm, // 225/50ZR16 + rolling_resistance: 20 + ) +} + +// 993 +public node trn { + alias output __out: trans; + transmission trans( + max_clutch_torque: 400 * units.Nm + ) + + trans + .add_gear(3.82) + .add_gear(2.05) + .add_gear(1.41) + .add_gear(1.12) + .add_gear(0.93) + .add_gear(0.78) +} + +public node main { + set_engine(eng()) + set_vehicle(veh()) + set_transmission(trn()) +} + diff --git a/assets/engines/atg-video-2/porsche_993_b10.mr b/assets/engines/atg-video-2/porsche_993_b10.mr new file mode 100644 index 00000000..494627a7 --- /dev/null +++ b/assets/engines/atg-video-2/porsche_993_b10.mr @@ -0,0 +1,515 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +// Engine Sim V0.1.11A +// Porsche 993 Boxer 10 fictional +// porsche_993_b10 +// Created by Ihar Rahatka (oror) 2022 + +label bore(100.0) +label stroke(76.4) +label compression_ratio(11.3) +label con_rod(127.0) +label intake_valve_lift(13.2) // valve lift, not lobe lift +label exhaust_valve_lift(13.2) // valve lift, not lobe lift +label compression_height(31.7 * units.mm) +label intake_valve_diameter(50.0) +label exhaust_valve_diameter(43.5) +label intake_valves(1.0) +label exhaust_valves(1.0) + +label ci(366.0) +label redline(6500.0) +label intake_cfm((ci * redline * 0.95) / 3456.0) +label exhaust_cfm((redline * 0.001) * ci / 2) + +label cyl(10) +label cyl_per_bank(5) +label cycle(2 * 360 * units.deg) +label vee(180.0 * units.deg) +label rot90(90.0 * units.deg) +label rot180(180.0 * units.deg) +label rot360(360.0 * units.deg) + +// 964 / 993 Street / Sport Cam valve timings +label IVO(30.0 * units.deg) //BTDC +label IVC(78.0 * units.deg) //ABDC +label EVO(74.0 * units.deg) //BBDC +label EVC(26.0 * units.deg) //ATDC + +label intake_duration(IVO + IVC + rot180) +label exhaust_duration(EVO + EVC + rot180) + +label ILC((-IVO + rot180 + IVC) / 2.0 + rot360) +label ELC((rot180 - EVO + EVC + rot360) / 2.0) + +public node eng_distributor { + input wires; + input timing_curve; + input rev_limit: 6750 * units.rpm; + input limiter_duration: 0.06; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: limiter_duration) + .connect_wire(wires.wire1, (0.0/cyl_per_bank) * cycle) + .connect_wire(wires.wire2, (1.0/cyl_per_bank) * cycle) + .connect_wire(wires.wire4, (2.0/cyl_per_bank) * cycle) + .connect_wire(wires.wire5, (3.0/cyl_per_bank) * cycle) + .connect_wire(wires.wire3, (4.0/cyl_per_bank) * cycle) + .connect_wire(wires.wire6, (0.0/cyl_per_bank) * cycle + rot360) + .connect_wire(wires.wire7, (1.0/cyl_per_bank) * cycle + rot360) + .connect_wire(wires.wire9, (2.0/cyl_per_bank) * cycle + rot360) + .connect_wire(wires.wire10, (3.0/cyl_per_bank) * cycle + rot360) + .connect_wire(wires.wire8, (4.0/cyl_per_bank) * cycle + rot360); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); + output wire9: ignition_wire(); + output wire10: ignition_wire(); +} + +public node eng_lobe_profile_int { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: intake_duration, + gamma: 6.0, + lift: intake_valve_lift * units.mm, + steps: 100 + ); +} + +public node eng_lobe_profile_exh { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: exhaust_duration, + gamma: 6.0, + lift: exhaust_valve_lift * units.mm, // valve lift, not lobe lift + steps: 100 + ); +} + +public node eng_camshaft_builder { + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + camshaft_parameters params( + advance: 0.0 * units.deg, + base_radius: 2.2 * units.cm + ) + + camshaft _intake_cam_0(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_0(params, lobe_profile: eng_lobe_profile_exh()) + + camshaft _intake_cam_1(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_1(params, lobe_profile: eng_lobe_profile_exh()) + + label rot(2 * (360.0 / cyl_per_bank) * units.deg) + + _intake_cam_0 + .add_lobe(ILC + 0 * rot) + .add_lobe(ILC + 1 * rot) + .add_lobe(ILC + 4 * rot) + .add_lobe(ILC + 2 * rot) + .add_lobe(ILC + 3 * rot) + + _exhaust_cam_0 + .add_lobe(ELC + 0 * rot) + .add_lobe(ELC + 1 * rot) + .add_lobe(ELC + 4 * rot) + .add_lobe(ELC + 2 * rot) + .add_lobe(ELC + 3 * rot) + + _intake_cam_1 + .add_lobe(ILC + 0 * rot + rot360) + .add_lobe(ILC + 1 * rot + rot360) + .add_lobe(ILC + 4 * rot + rot360) + .add_lobe(ILC + 2 * rot + rot360) + .add_lobe(ILC + 3 * rot + rot360) + + _exhaust_cam_1 + .add_lobe(ELC + 0 * rot + rot360) + .add_lobe(ELC + 1 * rot + rot360) + .add_lobe(ELC + 4 * rot + rot360) + .add_lobe(ELC + 2 * rot + rot360) + .add_lobe(ELC + 3 * rot + rot360) +} + +private node add_flow_sample { + input lift; + input flow; + input this; + alias output __out: this; + + this.add_sample(lift * units.mm, k_28inH2O(flow)) +} + +public node eng_head { + input intake_camshaft; + input exhaust_camshaft; + input flip_display: false; + + alias output __out: head; + + label bore_radius(bore / 2) + label intake_valve_circ(intake_valve_diameter * constants.pi) + label exhaust_valve_circ(exhaust_valve_diameter * constants.pi) + label intake_valve_func(intake_valve_lift * (10.0 / intake_valve_lift)) + label exhaust_valve_func(exhaust_valve_lift * (10.0 / exhaust_valve_lift)) + + function intake_flow(1 * units.mm) + intake_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, intake_valve_circ * 0.01 * intake_valve_func * 3.3761 * intake_valves) + .add_flow_sample(2, intake_valve_circ * 0.02 * intake_valve_func * 3.1574 * intake_valves) + .add_flow_sample(3, intake_valve_circ * 0.03 * intake_valve_func * 3.0143 * intake_valves) + .add_flow_sample(4, intake_valve_circ * 0.04 * intake_valve_func * 2.9503 * intake_valves) + .add_flow_sample(5, intake_valve_circ * 0.05 * intake_valve_func * 2.8938 * intake_valves) + .add_flow_sample(6, intake_valve_circ * 0.06 * intake_valve_func * 2.8134 * intake_valves) + .add_flow_sample(7, intake_valve_circ * 0.07 * intake_valve_func * 2.7560 * intake_valves) + .add_flow_sample(8, intake_valve_circ * 0.08 * intake_valve_func * 2.5924 * intake_valves) + .add_flow_sample(9, intake_valve_circ * 0.09 * intake_valve_func * 2.4651 * intake_valves) + .add_flow_sample(10, intake_valve_circ * 0.1 * intake_valve_func * 2.2668 * intake_valves) + .add_flow_sample(11, intake_valve_circ * 0.11 * intake_valve_func * 2.10 * intake_valves) + .add_flow_sample(12, intake_valve_circ * 0.12 * intake_valve_func * 2.01 * intake_valves) + .add_flow_sample(13, intake_valve_circ * 0.13 * intake_valve_func * 1.90 * intake_valves) + .add_flow_sample(14, intake_valve_circ * 0.14 * intake_valve_func * 1.82 * intake_valves) + .add_flow_sample(15, intake_valve_circ * 0.15 * intake_valve_func * 1.72 * intake_valves) + .add_flow_sample(16, intake_valve_circ * 0.16 * intake_valve_func * 1.63 * intake_valves) + .add_flow_sample(17, intake_valve_circ * 0.17 * intake_valve_func * 1.55 * intake_valves) + .add_flow_sample(18, intake_valve_circ * 0.18 * intake_valve_func * 1.50 * intake_valves) + + function exhaust_flow(1 * units.mm) + exhaust_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, exhaust_valve_circ * 0.01 * exhaust_valve_func * 3.3761 * exhaust_valves) + .add_flow_sample(2, exhaust_valve_circ * 0.02 * exhaust_valve_func * 3.1574 * exhaust_valves) + .add_flow_sample(3, exhaust_valve_circ * 0.03 * exhaust_valve_func * 3.0143 * exhaust_valves) + .add_flow_sample(4, exhaust_valve_circ * 0.04 * exhaust_valve_func * 2.9503 * exhaust_valves) + .add_flow_sample(5, exhaust_valve_circ * 0.05 * exhaust_valve_func * 2.8938 * exhaust_valves) + .add_flow_sample(6, exhaust_valve_circ * 0.06 * exhaust_valve_func * 2.8134 * exhaust_valves) + .add_flow_sample(7, exhaust_valve_circ * 0.07 * exhaust_valve_func * 2.7560 * exhaust_valves) + .add_flow_sample(8, exhaust_valve_circ * 0.08 * exhaust_valve_func * 2.5924 * exhaust_valves) + .add_flow_sample(9, exhaust_valve_circ * 0.09 * exhaust_valve_func * 2.4651 * exhaust_valves) + .add_flow_sample(10, exhaust_valve_circ * 0.1 * exhaust_valve_func * 2.2668 * exhaust_valves) + .add_flow_sample(11, exhaust_valve_circ * 0.11 * exhaust_valve_func * 2.10 * exhaust_valves) + .add_flow_sample(12, exhaust_valve_circ * 0.12 * exhaust_valve_func * 2.01 * exhaust_valves) + .add_flow_sample(13, exhaust_valve_circ * 0.13 * exhaust_valve_func * 1.90 * exhaust_valves) + .add_flow_sample(14, exhaust_valve_circ * 0.14 * exhaust_valve_func * 1.82 * exhaust_valves) + .add_flow_sample(15, exhaust_valve_circ * 0.15 * exhaust_valve_func * 1.72 * exhaust_valves) + .add_flow_sample(16, exhaust_valve_circ * 0.16 * exhaust_valve_func * 1.63 * exhaust_valves) + .add_flow_sample(17, exhaust_valve_circ * 0.17 * exhaust_valve_func * 1.55 * exhaust_valves) + .add_flow_sample(18, exhaust_valve_circ * 0.18 * exhaust_valve_func * 1.50 * exhaust_valves) + + cylinder_head head( + chamber_volume: (circle_area(bore_radius) * stroke / compression_ratio) / 1000 * units.cc, + intake_runner_volume: 75.0 * units.cc, + intake_runner_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * 0.95 * intake_valves, + exhaust_runner_volume: 10.0 * units.cc, + exhaust_runner_cross_section_area: circle_area(exhaust_valve_diameter * units.mm / 2) * 0.95 * exhaust_valves, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +public node eng { + alias output __out: engine; + + engine engine( + name: "Porsche 993 Boxer10 (f)", + starter_torque: 75 * units.Nm, + starter_speed: 400 * units.rpm, + redline: redline * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.0, + burning_efficiency_randomness: 0.2, + max_burning_efficiency: 0.94 + ), + throttle_gamma: 1.75, + jitter: 1.0, + noise: 1.0, + simulation_frequency: 8000 + ) + + wires wires() + + crankshaft c0( + throw: (stroke / 2) * units.mm, + flywheel_mass: 2.0 * units.kg, + mass: 13.81 * units.kg, + friction_torque: 1.5 * units.Nm, + moment_of_inertia: 0.15, + position_x: 0.0, + position_y: 0.0, + tdc: 0.000001 * units.deg + ) + + rod_journal rj0(angle: (0.0 / cyl_per_bank) * cycle + vee) + rod_journal rj2(angle: (1.0 / cyl_per_bank) * cycle + vee) + rod_journal rj4(angle: (4.0 / cyl_per_bank) * cycle + vee) + rod_journal rj6(angle: (2.0 / cyl_per_bank) * cycle + vee) + rod_journal rj8(angle: (3.0 / cyl_per_bank) * cycle + vee) + rod_journal rj1(angle: (0.0 / cyl_per_bank) * cycle) + rod_journal rj3(angle: (1.0 / cyl_per_bank) * cycle) + rod_journal rj5(angle: (4.0 / cyl_per_bank) * cycle) + rod_journal rj7(angle: (2.0 / cyl_per_bank) * cycle) + rod_journal rj9(angle: (3.0 / cyl_per_bank) * cycle) + + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + .add_rod_journal(rj7) + .add_rod_journal(rj8) + .add_rod_journal(rj9) + + piston_parameters piston_params( + mass: 440.0 * units.g, + blowby: k_28inH2O(0.05), + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 535.0 * units.g, + moment_of_inertia: 0.002, + center_of_mass: 0.0, + length: con_rod * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: bore * units.mm, + deck_height: (con_rod + (stroke / 2)) * units.mm + compression_height + ) + + intake intake( + plenum_volume: 1.0 * units.L, + plenum_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * cyl * intake_valves * 1.5, + intake_flow_rate: k_carb(intake_cfm), + idle_flow_rate: k_carb(0.001), + idle_throttle_plate_position: 0.9967, + runner_flow_rate: k_carb(intake_cfm / 3.0), + runner_length: 30.0 * units.cm, + velocity_decay: 0.05 + ) + + exhaust_system_parameters es_params0( + outlet_flow_rate: k_carb(exhaust_cfm), + primary_tube_length: 126.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / cyl * 2), + velocity_decay: 1.0, + volume: 5.0 * units.L + ) + + exhaust_system_parameters es_params1( + outlet_flow_rate: k_carb(exhaust_cfm), + primary_tube_length: 120.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / cyl * 2), + velocity_decay: 1.0, + volume: 4.2 * units.L + ) + + // exhaust_system exhaust0(es_params0, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + // exhaust_system exhaust1(es_params1, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + exhaust_system exhaust0(es_params0, impulse_response: ir_lib.default_0) + exhaust_system exhaust1(es_params1, impulse_response: ir_lib.default_0) + + cylinder_bank b0(bank_params, angle: vee / 2) + cylinder_bank b1(bank_params, angle: -vee / 2) + + label div(0.85) + label pl0 ((0.7 * bore / div) * units.mm) + label pl1 ((0.5 * bore / div) * units.mm) + label pl2 ((0.0 * bore / div) * units.mm) + label pl3 ((0.5 * bore / div) * units.mm) + label pl4 ((0.7 * bore / div) * units.mm) + + b0 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl0, + ignition_wire: wires.wire1 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl1, + ignition_wire: wires.wire2 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl2, + ignition_wire: wires.wire3 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl3, + ignition_wire: wires.wire4 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj8, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl4, + ignition_wire: wires.wire5 + ) + + b1 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl0, + ignition_wire: wires.wire6 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl1, + ignition_wire: wires.wire7 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl2, + ignition_wire: wires.wire8 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl3, + ignition_wire: wires.wire9 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj9, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl4, + ignition_wire: wires.wire10 + ) + + engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + + engine.add_crankshaft(c0) + + eng_camshaft_builder camshaft() + + b0.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0, + flip_display: true + ) + ) + b1.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 10.0 * units.deg) + .add_sample(1000 * units.rpm, 15.0 * units.deg) + .add_sample(2000 * units.rpm, 25.0 * units.deg) + .add_sample(3000 * units.rpm, 35.0 * units.deg) + .add_sample(4000 * units.rpm, 35.0 * units.deg) + .add_sample(5000 * units.rpm, 35.0 * units.deg) + .add_sample(6000 * units.rpm, 35.0 * units.deg) + + engine.add_ignition_module( + eng_distributor( + wires: wires, + timing_curve: timing_curve + ) + ) +} + +// 993 +public node veh { + alias output __out: vehicle; + vehicle vehicle( + mass: 1270 * units.kg, + drag_coefficient: 0.32, + cross_sectional_area: (1735 * units.mm) * (1311 * units.mm), + diff_ratio: 3.2, + tire_radius: (632.0 / 2) * units.mm, // 225/50ZR16 + rolling_resistance: 20 + ) +} + +// 993 +public node trn { + alias output __out: trans; + transmission trans( + max_clutch_torque: 750 * units.Nm + ) + + trans + .add_gear(3.82) + .add_gear(2.05) + .add_gear(1.41) + .add_gear(1.12) + .add_gear(0.93) + .add_gear(0.78) +} +public node main { + set_engine(eng()) + set_vehicle(veh()) + set_transmission(trn()) +} + diff --git a/assets/engines/atg-video-2/porsche_993_b12.mr b/assets/engines/atg-video-2/porsche_993_b12.mr new file mode 100644 index 00000000..e0c66dde --- /dev/null +++ b/assets/engines/atg-video-2/porsche_993_b12.mr @@ -0,0 +1,550 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +// Engine Sim V0.1.11A +// Porsche 993 Boxer 12 fictional +// porsche_993_b12 +// Created by Ihar Rahatka (oror) 2022 + +label bore(100.0) +label stroke(76.4) +label compression_ratio(11.3) +label con_rod(127.0) +label intake_valve_lift(13.2) // valve lift, not lobe lift +label exhaust_valve_lift(13.2) // valve lift, not lobe lift +label compression_height(31.7 * units.mm) +label intake_valve_diameter(50.0) +label exhaust_valve_diameter(43.5) +label intake_valves(1.0) +label exhaust_valves(1.0) + +label ci(440.0) +label redline(7500.0) +label intake_cfm((ci * redline * 0.95) / 3456.0) +label exhaust_cfm((redline * 0.001) * ci / 2) + +label cyl(12) +label cyl_per_bank(6) +label cycle(2 * 360 * units.deg) +label vee(180.0 * units.deg) +label rot90(90.0 * units.deg) +label rot180(180.0 * units.deg) +label rot360(360.0 * units.deg) + +// second block shift +label sb_shift(60.0 * units.deg) + +// 964 / 993 Street / Sport Cam valve timings +label IVO(30.0 * units.deg) //BTDC +label IVC(78.0 * units.deg) //ABDC +label EVO(74.0 * units.deg) //BBDC +label EVC(26.0 * units.deg) //ATDC + +label intake_duration(IVO + IVC + rot180) +label exhaust_duration(EVO + EVC + rot180) + +label ILC((-IVO + rot180 + IVC) / 2.0 + rot360) +label ELC((rot180 - EVO + EVC + rot360) / 2.0) + +public node eng_distributor { + input wires; + input timing_curve; + input rev_limit: 7750 * units.rpm; + input limiter_duration: 0.06; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: limiter_duration) + .connect_wire(wires.wire1, (0.0/6.0) * cycle) + .connect_wire(wires.wire6, (1.0/6.0) * cycle) + .connect_wire(wires.wire2, (2.0/6.0) * cycle) + .connect_wire(wires.wire4, (3.0/6.0) * cycle) + .connect_wire(wires.wire3, (4.0/6.0) * cycle) + .connect_wire(wires.wire5, (5.0/6.0) * cycle) + .connect_wire(wires.wire7, (0.0/6.0) * cycle + sb_shift) + .connect_wire(wires.wire12, (1.0/6.0) * cycle + sb_shift) + .connect_wire(wires.wire8, (2.0/6.0) * cycle + sb_shift + rot360) + .connect_wire(wires.wire10, (3.0/6.0) * cycle + sb_shift) + .connect_wire(wires.wire9, (4.0/6.0) * cycle + sb_shift) + .connect_wire(wires.wire11, (5.0/6.0) * cycle + sb_shift + rot360); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); + output wire9: ignition_wire(); + output wire10: ignition_wire(); + output wire11: ignition_wire(); + output wire12: ignition_wire(); +} + +public node eng_lobe_profile_int { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: intake_duration, + gamma: 6.0, + lift: intake_valve_lift * units.mm, + steps: 100 + ); +} + +public node eng_lobe_profile_exh { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: exhaust_duration, + gamma: 6.0, + lift: exhaust_valve_lift * units.mm, // valve lift, not lobe lift + steps: 100 + ); +} + +public node eng_camshaft_builder { + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + camshaft_parameters params( + advance: 0.0 * units.deg, + base_radius: 2.2 * units.cm + ) + + camshaft _intake_cam_0(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_0(params, lobe_profile: eng_lobe_profile_exh()) + + camshaft _intake_cam_1(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_1(params, lobe_profile: eng_lobe_profile_exh()) + + label rot(2 * (360.0 / cyl_per_bank) * units.deg) + + _intake_cam_0 + .add_lobe(ILC + 0 * rot) + .add_lobe(ILC + 0 * rot + sb_shift) + .add_lobe(ILC + 2 * rot) + .add_lobe(ILC + 2 * rot + sb_shift + rot360) + .add_lobe(ILC + 4 * rot) + .add_lobe(ILC + 4 * rot + sb_shift) + + _exhaust_cam_0 + .add_lobe(ELC + 0 * rot) + .add_lobe(ELC + 0 * rot + sb_shift) + .add_lobe(ELC + 2 * rot) + .add_lobe(ELC + 2 * rot + sb_shift + rot360) + .add_lobe(ELC + 4 * rot) + .add_lobe(ELC + 4 * rot + sb_shift) + + _intake_cam_1 + .add_lobe(ILC + 3 * rot) + .add_lobe(ILC + 3 * rot + sb_shift) + .add_lobe(ILC + 5 * rot) + .add_lobe(ILC + 5 * rot + sb_shift + rot360) + .add_lobe(ILC + 1 * rot) + .add_lobe(ILC + 1 * rot + sb_shift) + + _exhaust_cam_1 + .add_lobe(ELC + 3 * rot) + .add_lobe(ELC + 3 * rot + sb_shift) + .add_lobe(ELC + 5 * rot) + .add_lobe(ELC + 5 * rot + sb_shift + rot360) + .add_lobe(ELC + 1 * rot) + .add_lobe(ELC + 1 * rot + sb_shift) +} + +private node add_flow_sample { + input lift; + input flow; + input this; + alias output __out: this; + + this.add_sample(lift * units.mm, k_28inH2O(flow)) +} + +public node eng_head { + input intake_camshaft; + input exhaust_camshaft; + input flip_display: false; + + alias output __out: head; + + label bore_radius(bore / 2) + label intake_valve_circ(intake_valve_diameter * constants.pi) + label exhaust_valve_circ(exhaust_valve_diameter * constants.pi) + label intake_valve_func(intake_valve_lift * (10.0 / intake_valve_lift)) + label exhaust_valve_func(exhaust_valve_lift * (10.0 / exhaust_valve_lift)) + + function intake_flow(1 * units.mm) + intake_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, intake_valve_circ * 0.01 * intake_valve_func * 3.3761 * intake_valves) + .add_flow_sample(2, intake_valve_circ * 0.02 * intake_valve_func * 3.1574 * intake_valves) + .add_flow_sample(3, intake_valve_circ * 0.03 * intake_valve_func * 3.0143 * intake_valves) + .add_flow_sample(4, intake_valve_circ * 0.04 * intake_valve_func * 2.9503 * intake_valves) + .add_flow_sample(5, intake_valve_circ * 0.05 * intake_valve_func * 2.8938 * intake_valves) + .add_flow_sample(6, intake_valve_circ * 0.06 * intake_valve_func * 2.8134 * intake_valves) + .add_flow_sample(7, intake_valve_circ * 0.07 * intake_valve_func * 2.7560 * intake_valves) + .add_flow_sample(8, intake_valve_circ * 0.08 * intake_valve_func * 2.5924 * intake_valves) + .add_flow_sample(9, intake_valve_circ * 0.09 * intake_valve_func * 2.4651 * intake_valves) + .add_flow_sample(10, intake_valve_circ * 0.1 * intake_valve_func * 2.2668 * intake_valves) + .add_flow_sample(11, intake_valve_circ * 0.11 * intake_valve_func * 2.10 * intake_valves) + .add_flow_sample(12, intake_valve_circ * 0.12 * intake_valve_func * 2.01 * intake_valves) + .add_flow_sample(13, intake_valve_circ * 0.13 * intake_valve_func * 1.90 * intake_valves) + .add_flow_sample(14, intake_valve_circ * 0.14 * intake_valve_func * 1.82 * intake_valves) + .add_flow_sample(15, intake_valve_circ * 0.15 * intake_valve_func * 1.72 * intake_valves) + .add_flow_sample(16, intake_valve_circ * 0.16 * intake_valve_func * 1.63 * intake_valves) + .add_flow_sample(17, intake_valve_circ * 0.17 * intake_valve_func * 1.55 * intake_valves) + .add_flow_sample(18, intake_valve_circ * 0.18 * intake_valve_func * 1.50 * intake_valves) + + function exhaust_flow(1 * units.mm) + exhaust_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, exhaust_valve_circ * 0.01 * exhaust_valve_func * 3.3761 * exhaust_valves) + .add_flow_sample(2, exhaust_valve_circ * 0.02 * exhaust_valve_func * 3.1574 * exhaust_valves) + .add_flow_sample(3, exhaust_valve_circ * 0.03 * exhaust_valve_func * 3.0143 * exhaust_valves) + .add_flow_sample(4, exhaust_valve_circ * 0.04 * exhaust_valve_func * 2.9503 * exhaust_valves) + .add_flow_sample(5, exhaust_valve_circ * 0.05 * exhaust_valve_func * 2.8938 * exhaust_valves) + .add_flow_sample(6, exhaust_valve_circ * 0.06 * exhaust_valve_func * 2.8134 * exhaust_valves) + .add_flow_sample(7, exhaust_valve_circ * 0.07 * exhaust_valve_func * 2.7560 * exhaust_valves) + .add_flow_sample(8, exhaust_valve_circ * 0.08 * exhaust_valve_func * 2.5924 * exhaust_valves) + .add_flow_sample(9, exhaust_valve_circ * 0.09 * exhaust_valve_func * 2.4651 * exhaust_valves) + .add_flow_sample(10, exhaust_valve_circ * 0.1 * exhaust_valve_func * 2.2668 * exhaust_valves) + .add_flow_sample(11, exhaust_valve_circ * 0.11 * exhaust_valve_func * 2.10 * exhaust_valves) + .add_flow_sample(12, exhaust_valve_circ * 0.12 * exhaust_valve_func * 2.01 * exhaust_valves) + .add_flow_sample(13, exhaust_valve_circ * 0.13 * exhaust_valve_func * 1.90 * exhaust_valves) + .add_flow_sample(14, exhaust_valve_circ * 0.14 * exhaust_valve_func * 1.82 * exhaust_valves) + .add_flow_sample(15, exhaust_valve_circ * 0.15 * exhaust_valve_func * 1.72 * exhaust_valves) + .add_flow_sample(16, exhaust_valve_circ * 0.16 * exhaust_valve_func * 1.63 * exhaust_valves) + .add_flow_sample(17, exhaust_valve_circ * 0.17 * exhaust_valve_func * 1.55 * exhaust_valves) + .add_flow_sample(18, exhaust_valve_circ * 0.18 * exhaust_valve_func * 1.50 * exhaust_valves) + + cylinder_head head( + chamber_volume: (circle_area(bore_radius) * stroke / compression_ratio) / 1000 * units.cc, + intake_runner_volume: 75.0 * units.cc, + intake_runner_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * 0.95 * intake_valves, + exhaust_runner_volume: 10.0 * units.cc, + exhaust_runner_cross_section_area: circle_area(exhaust_valve_diameter * units.mm / 2) * 0.95 * exhaust_valves, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +public node eng { + alias output __out: engine; + + engine engine( + name: "Porsche 993 Boxer12 (f)", + starter_torque: 115 * units.Nm, + starter_speed: 400 * units.rpm, + redline: redline * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.0, + burning_efficiency_randomness: 0.2, + max_burning_efficiency: 0.94 + ), + throttle_gamma: 1.75, + jitter: 1.0, + noise: 1.0, + simulation_frequency: 6500 + ) + + wires wires() + + crankshaft c0( + throw: (stroke / 2) * units.mm, + flywheel_mass: 2.0 * units.kg, + mass: 13.81 * units.kg, + friction_torque: 1.5 * units.Nm, + moment_of_inertia: 0.15, + position_x: 0.0, + position_y: 0.0, + tdc: 0.000001 * units.deg + ) + + rod_journal rj0(angle: (0.0 / 6.0) * cycle + vee) + rod_journal rj0_1(angle: (0.0 / 6.0) * cycle + vee + sb_shift) + rod_journal rj2(angle: (2.0 / 6.0) * cycle + vee) + rod_journal rj2_1(angle: (2.0 / 6.0) * cycle + vee + sb_shift + rot360) + rod_journal rj4(angle: (4.0 / 6.0) * cycle + vee) + rod_journal rj4_1(angle: (4.0 / 6.0) * cycle + vee + sb_shift) + rod_journal rj1(angle: (3.0 / 6.0) * cycle) + rod_journal rj1_1(angle: (3.0 / 6.0) * cycle + sb_shift) + rod_journal rj3(angle: (5.0 / 6.0) * cycle) + rod_journal rj3_1(angle: (5.0 / 6.0) * cycle + sb_shift + rot360) + rod_journal rj5(angle: (1.0 / 6.0) * cycle) + rod_journal rj5_1(angle: (1.0 / 6.0) * cycle + sb_shift) + + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj0_1) + .add_rod_journal(rj1_1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj2_1) + .add_rod_journal(rj3_1) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj4_1) + .add_rod_journal(rj5_1) + + piston_parameters piston_params( + mass: 440.0 * units.g, + blowby: k_28inH2O(0.05), + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 535.0 * units.g, + moment_of_inertia: 0.002, + center_of_mass: 0.0, + length: con_rod * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: bore * units.mm, + deck_height: (con_rod + (stroke / 2)) * units.mm + compression_height + ) + + intake intake( + plenum_volume: 1.0 * units.L, + plenum_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * cyl * intake_valves * 1.5, + intake_flow_rate: k_carb(intake_cfm), + idle_flow_rate: k_carb(0.001), + idle_throttle_plate_position: 0.9969, + runner_flow_rate: k_carb(intake_cfm / 3.0), + runner_length: 30.0 * units.cm, + velocity_decay: 0.05 + ) + + exhaust_system_parameters es_params0( + outlet_flow_rate: k_carb(exhaust_cfm), + primary_tube_length: 125.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / cyl * 2), + velocity_decay: 1.0, + volume: 5.3 * units.L + ) + + exhaust_system_parameters es_params1( + outlet_flow_rate: k_carb(exhaust_cfm), + primary_tube_length: 120.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / cyl * 2), + velocity_decay: 1.0, + volume: 5.0 * units.L + ) + + // exhaust_system exhaust0(es_params0, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + // exhaust_system exhaust1(es_params1, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + exhaust_system exhaust0(es_params0, impulse_response: ir_lib.default_0) + exhaust_system exhaust1(es_params1, impulse_response: ir_lib.default_0) + + cylinder_bank b0(bank_params, angle: vee / 2) + cylinder_bank b1(bank_params, angle: -vee / 2) + + label div(0.85) + label pl0 ((0.3 * bore / div) * units.mm) + label pl1 ((0.3 * bore / div) * units.mm) + label pl2 ((0.3 * bore / div) * units.mm) + label pl3 ((0.0 * bore / div) * units.mm) + label pl4 ((0.0 * bore / div) * units.mm) + label pl5 ((0.0 * bore / div) * units.mm) + + b0 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl0, + ignition_wire: wires.wire1 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0_1, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl1, + ignition_wire: wires.wire7 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl2, + ignition_wire: wires.wire2 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2_1, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl3, + ignition_wire: wires.wire8 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl4, + ignition_wire: wires.wire3 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4_1, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl5, + ignition_wire: wires.wire9 + ) + + b1 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl0, + ignition_wire: wires.wire4 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1_1, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl1, + ignition_wire: wires.wire10 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl2, + ignition_wire: wires.wire5 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3_1, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl3, + ignition_wire: wires.wire11 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl4, + ignition_wire: wires.wire6 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5_1, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl5, + ignition_wire: wires.wire12 + ) + + engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + + engine.add_crankshaft(c0) + + eng_camshaft_builder camshaft() + + b0.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0, + flip_display: true + ) + ) + b1.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 10.0 * units.deg) + .add_sample(1000 * units.rpm, 15.0 * units.deg) + .add_sample(2000 * units.rpm, 25.0 * units.deg) + .add_sample(3000 * units.rpm, 27.0 * units.deg) + .add_sample(4000 * units.rpm, 29.0 * units.deg) + .add_sample(5000 * units.rpm, 33.0 * units.deg) + .add_sample(6000 * units.rpm, 35.0 * units.deg) + .add_sample(7000 * units.rpm, 37.0 * units.deg) + + engine.add_ignition_module( + eng_distributor( + wires: wires, + timing_curve: timing_curve + ) + ) +} + +// 993 +public node veh { + alias output __out: vehicle; + vehicle vehicle( + mass: 1270 * units.kg, + drag_coefficient: 0.32, + cross_sectional_area: (1735 * units.mm) * (1311 * units.mm), + diff_ratio: 3.2, + tire_radius: (632.0 / 2) * units.mm, // 225/50ZR16 + rolling_resistance: 20 + ) +} + +// 993 +public node trn { + alias output __out: trans; + transmission trans( + max_clutch_torque: 850 * units.Nm + ) + + trans + .add_gear(3.82) + .add_gear(2.05) + .add_gear(1.41) + .add_gear(1.12) + .add_gear(0.93) + .add_gear(0.78) +} +public node main { + set_engine(eng()) + set_vehicle(veh()) + set_transmission(trn()) +} + diff --git a/assets/engines/atg-video-2/porsche_993_b8.mr b/assets/engines/atg-video-2/porsche_993_b8.mr new file mode 100644 index 00000000..4876ae86 --- /dev/null +++ b/assets/engines/atg-video-2/porsche_993_b8.mr @@ -0,0 +1,487 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +// Engine Sim V0.1.11A +// Porsche 993 Boxer 8 fictional +// porsche_993_b8 +// Created by Ihar Rahatka (oror) 2022 + +label bore(100.0) +label stroke(76.4) +label compression_ratio(11.3) +label con_rod(127.0) +label intake_valve_lift(13.2) // valve lift, not lobe lift +label exhaust_valve_lift(13.2) // valve lift, not lobe lift +label compression_height(31.7 * units.mm) +label intake_valve_diameter(50.0) +label exhaust_valve_diameter(43.5) +label intake_valves(1.0) +label exhaust_valves(1.0) + +label ci(293.0) +label redline(6500.0) +label intake_cfm((ci * redline * 0.95) / 3456.0) +label exhaust_cfm((redline * 0.001) * ci / 2) + +label cyl(8) +label cycle(2 * 360 * units.deg) +label vee(180.0 * units.deg) +label rot90(90.0 * units.deg) +label rot180(180.0 * units.deg) +label rot360(360.0 * units.deg) + +// 964 / 993 Street / Sport Cam valve timings +label IVO(30.0 * units.deg) //BTDC +label IVC(78.0 * units.deg) //ABDC +label EVO(74.0 * units.deg) //BBDC +label EVC(26.0 * units.deg) //ATDC + +label intake_duration(IVO + IVC + rot180) +label exhaust_duration(EVO + EVC + rot180) + +label ILC((-IVO + rot180 + IVC) / 2.0 + rot360) +label ELC((rot180 - EVO + EVC + rot360) / 2.0) + +public node eng_distributor { + input wires; + input timing_curve; + input rev_limit: 6750 * units.rpm; + input limiter_duration: 0.06; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: limiter_duration) + .connect_wire(wires.wire1, (0.0/cyl) * cycle) + .connect_wire(wires.wire7, (1.0/cyl) * cycle) + .connect_wire(wires.wire4, (2.0/cyl) * cycle) + .connect_wire(wires.wire6, (3.0/cyl) * cycle) + .connect_wire(wires.wire5, (4.0/cyl) * cycle) + .connect_wire(wires.wire3, (5.0/cyl) * cycle) + .connect_wire(wires.wire8, (6.0/cyl) * cycle) + .connect_wire(wires.wire2, (7.0/cyl) * cycle); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); +} + +public node eng_lobe_profile_int { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: intake_duration, + gamma: 6.0, + lift: intake_valve_lift * units.mm, + steps: 100 + ); +} + +public node eng_lobe_profile_exh { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: exhaust_duration, + gamma: 6.0, + lift: exhaust_valve_lift * units.mm, // valve lift, not lobe lift + steps: 100 + ); +} + +public node eng_camshaft_builder { + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + + camshaft_parameters params( + advance: 0.0 * units.deg, + base_radius: 2.2 * units.cm + ) + + camshaft _intake_cam_0(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_0(params, lobe_profile: eng_lobe_profile_exh()) + + camshaft _intake_cam_1(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_1(params, lobe_profile: eng_lobe_profile_exh()) + + label rot(2 * (360.0 / cyl) * units.deg) + + _intake_cam_0 + .add_lobe(ILC + 0 * rot) + .add_lobe(ILC + 7 * rot) + .add_lobe(ILC + 5 * rot) + .add_lobe(ILC + 2 * rot) + + _exhaust_cam_0 + .add_lobe(ELC + 0 * rot) + .add_lobe(ELC + 7 * rot) + .add_lobe(ELC + 5 * rot) + .add_lobe(ELC + 2 * rot) + + _intake_cam_1 + .add_lobe(ILC + 4 * rot) + .add_lobe(ILC + 3 * rot) + .add_lobe(ILC + 1 * rot) + .add_lobe(ILC + 6 * rot) + + _exhaust_cam_1 + .add_lobe(ELC + 4 * rot) + .add_lobe(ELC + 3 * rot) + .add_lobe(ELC + 1 * rot) + .add_lobe(ELC + 6 * rot) +} + +private node add_flow_sample { + input lift; + input flow; + input this; + alias output __out: this; + + this.add_sample(lift * units.mm, k_28inH2O(flow)) +} + +public node eng_head { + input intake_camshaft; + input exhaust_camshaft; + input flip_display: false; + + alias output __out: head; + + label bore_radius(bore / 2) + label intake_valve_circ(intake_valve_diameter * constants.pi) + label exhaust_valve_circ(exhaust_valve_diameter * constants.pi) + label intake_valve_func(intake_valve_lift * (10.0 / intake_valve_lift)) + label exhaust_valve_func(exhaust_valve_lift * (10.0 / exhaust_valve_lift)) + + function intake_flow(1 * units.mm) + intake_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, intake_valve_circ * 0.01 * intake_valve_func * 3.3761 * intake_valves) + .add_flow_sample(2, intake_valve_circ * 0.02 * intake_valve_func * 3.1574 * intake_valves) + .add_flow_sample(3, intake_valve_circ * 0.03 * intake_valve_func * 3.0143 * intake_valves) + .add_flow_sample(4, intake_valve_circ * 0.04 * intake_valve_func * 2.9503 * intake_valves) + .add_flow_sample(5, intake_valve_circ * 0.05 * intake_valve_func * 2.8938 * intake_valves) + .add_flow_sample(6, intake_valve_circ * 0.06 * intake_valve_func * 2.8134 * intake_valves) + .add_flow_sample(7, intake_valve_circ * 0.07 * intake_valve_func * 2.7560 * intake_valves) + .add_flow_sample(8, intake_valve_circ * 0.08 * intake_valve_func * 2.5924 * intake_valves) + .add_flow_sample(9, intake_valve_circ * 0.09 * intake_valve_func * 2.4651 * intake_valves) + .add_flow_sample(10, intake_valve_circ * 0.1 * intake_valve_func * 2.2668 * intake_valves) + .add_flow_sample(11, intake_valve_circ * 0.11 * intake_valve_func * 2.10 * intake_valves) + .add_flow_sample(12, intake_valve_circ * 0.12 * intake_valve_func * 2.01 * intake_valves) + .add_flow_sample(13, intake_valve_circ * 0.13 * intake_valve_func * 1.90 * intake_valves) + .add_flow_sample(14, intake_valve_circ * 0.14 * intake_valve_func * 1.82 * intake_valves) + .add_flow_sample(15, intake_valve_circ * 0.15 * intake_valve_func * 1.72 * intake_valves) + .add_flow_sample(16, intake_valve_circ * 0.16 * intake_valve_func * 1.63 * intake_valves) + .add_flow_sample(17, intake_valve_circ * 0.17 * intake_valve_func * 1.55 * intake_valves) + .add_flow_sample(18, intake_valve_circ * 0.18 * intake_valve_func * 1.50 * intake_valves) + + function exhaust_flow(1 * units.mm) + exhaust_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, exhaust_valve_circ * 0.01 * exhaust_valve_func * 3.3761 * exhaust_valves) + .add_flow_sample(2, exhaust_valve_circ * 0.02 * exhaust_valve_func * 3.1574 * exhaust_valves) + .add_flow_sample(3, exhaust_valve_circ * 0.03 * exhaust_valve_func * 3.0143 * exhaust_valves) + .add_flow_sample(4, exhaust_valve_circ * 0.04 * exhaust_valve_func * 2.9503 * exhaust_valves) + .add_flow_sample(5, exhaust_valve_circ * 0.05 * exhaust_valve_func * 2.8938 * exhaust_valves) + .add_flow_sample(6, exhaust_valve_circ * 0.06 * exhaust_valve_func * 2.8134 * exhaust_valves) + .add_flow_sample(7, exhaust_valve_circ * 0.07 * exhaust_valve_func * 2.7560 * exhaust_valves) + .add_flow_sample(8, exhaust_valve_circ * 0.08 * exhaust_valve_func * 2.5924 * exhaust_valves) + .add_flow_sample(9, exhaust_valve_circ * 0.09 * exhaust_valve_func * 2.4651 * exhaust_valves) + .add_flow_sample(10, exhaust_valve_circ * 0.1 * exhaust_valve_func * 2.2668 * exhaust_valves) + .add_flow_sample(11, exhaust_valve_circ * 0.11 * exhaust_valve_func * 2.10 * exhaust_valves) + .add_flow_sample(12, exhaust_valve_circ * 0.12 * exhaust_valve_func * 2.01 * exhaust_valves) + .add_flow_sample(13, exhaust_valve_circ * 0.13 * exhaust_valve_func * 1.90 * exhaust_valves) + .add_flow_sample(14, exhaust_valve_circ * 0.14 * exhaust_valve_func * 1.82 * exhaust_valves) + .add_flow_sample(15, exhaust_valve_circ * 0.15 * exhaust_valve_func * 1.72 * exhaust_valves) + .add_flow_sample(16, exhaust_valve_circ * 0.16 * exhaust_valve_func * 1.63 * exhaust_valves) + .add_flow_sample(17, exhaust_valve_circ * 0.17 * exhaust_valve_func * 1.55 * exhaust_valves) + .add_flow_sample(18, exhaust_valve_circ * 0.18 * exhaust_valve_func * 1.50 * exhaust_valves) + + cylinder_head head( + chamber_volume: (circle_area(bore_radius) * stroke / compression_ratio) / 1000 * units.cc, + intake_runner_volume: 200.0 * units.cc, + intake_runner_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * 0.95 * intake_valves, + exhaust_runner_volume: 20.0 * units.cc, + exhaust_runner_cross_section_area: circle_area(exhaust_valve_diameter * units.mm / 2) * 0.95 * exhaust_valves, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +public node eng { + alias output __out: engine; + + engine engine( + name: "Porsche 993 Boxer8 (f)", + starter_torque: 75 * units.Nm, + starter_speed: 400 * units.rpm, + redline: redline * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.0, + burning_efficiency_randomness: 0.2, + max_burning_efficiency: 0.94 + ), + throttle_gamma: 1.75, + jitter: 1.0, + noise: 1.0, + simulation_frequency: 8000 + ) + + wires wires() + + crankshaft c0( + throw: (stroke / 2) * units.mm, + flywheel_mass: 2.0 * units.kg, + mass: 13.81 * units.kg, + friction_torque: 1.5 * units.Nm, + moment_of_inertia: 0.15, + position_x: 0.0, + position_y: 0.0, + tdc: 0.000001 * units.deg + ) + + rod_journal rj0(angle: (0.0 / cyl) * cycle + vee) + rod_journal rj2(angle: (7.0 / cyl) * cycle + vee) + rod_journal rj4(angle: (5.0 / cyl) * cycle + vee) + rod_journal rj6(angle: (2.0 / cyl) * cycle + vee) + rod_journal rj1(angle: (4.0 / cyl) * cycle) + rod_journal rj3(angle: (3.0 / cyl) * cycle) + rod_journal rj5(angle: (1.0 / cyl) * cycle) + rod_journal rj7(angle: (6.0 / cyl) * cycle) + + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + .add_rod_journal(rj4) + .add_rod_journal(rj5) + .add_rod_journal(rj6) + .add_rod_journal(rj7) + + piston_parameters piston_params( + mass: 440.0 * units.g, + blowby: k_28inH2O(0.05), + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 535.0 * units.g, + moment_of_inertia: 0.002, + center_of_mass: 0.0, + length: con_rod * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: bore * units.mm, + deck_height: (con_rod + (stroke / 2)) * units.mm + compression_height + ) + + intake intake( + plenum_volume: 1.5 * units.L, + plenum_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * cyl * intake_valves * 1.5, + intake_flow_rate: k_carb(intake_cfm), + idle_flow_rate: k_carb(0.001), + idle_throttle_plate_position: 0.9967, + runner_flow_rate: k_carb(intake_cfm / 2), + runner_length: 30.0 * units.cm, + velocity_decay: 0.05 + ) + + exhaust_system_parameters es_params0( + outlet_flow_rate: k_carb(exhaust_cfm), + primary_tube_length: 106.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / cyl * 2), + velocity_decay: 1.0, + volume: 3.9 * units.L + ) + + exhaust_system_parameters es_params1( + outlet_flow_rate: k_carb(exhaust_cfm), + primary_tube_length: 100.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / cyl * 2), + velocity_decay: 1.0, + volume: 3.3 * units.L + ) + + // exhaust_system exhaust0(es_params0, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + // exhaust_system exhaust1(es_params1, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + exhaust_system exhaust0(es_params0, impulse_response: ir_lib.default_0) + exhaust_system exhaust1(es_params1, impulse_response: ir_lib.default_0) + + cylinder_bank b0(bank_params, angle: vee / 2) + cylinder_bank b1(bank_params, angle: -vee / 2) + + label div(0.85) + label pl0 ((2.1 * bore / div) * units.mm) + label pl1 ((2.0 * bore / div) * units.mm) + label pl2 ((1.0 * bore / div) * units.mm) + label pl3 ((0.0 * bore / div) * units.mm) + label pl4 ((2.1 * bore / div) * units.mm) + label pl5 ((2.0 * bore / div) * units.mm) + label pl6 ((1.0 * bore / div) * units.mm) + label pl7 ((0.0 * bore / div) * units.mm) + + b0 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl0, + ignition_wire: wires.wire1 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl1, + ignition_wire: wires.wire2 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl2, + ignition_wire: wires.wire3 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl3, + ignition_wire: wires.wire4 + ) + + b1 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl4, + ignition_wire: wires.wire5 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl5, + ignition_wire: wires.wire6 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl6, + ignition_wire: wires.wire7 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl7, + ignition_wire: wires.wire8 + ) + + engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + + engine.add_crankshaft(c0) + + eng_camshaft_builder camshaft() + + b0.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0, + flip_display: true + ) + ) + b1.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 10.0 * units.deg) + .add_sample(1000 * units.rpm, 15.0 * units.deg) + .add_sample(2000 * units.rpm, 25.0 * units.deg) + .add_sample(3000 * units.rpm, 35.0 * units.deg) + .add_sample(4000 * units.rpm, 35.0 * units.deg) + .add_sample(5000 * units.rpm, 35.0 * units.deg) + .add_sample(6000 * units.rpm, 35.0 * units.deg) + + engine.add_ignition_module( + eng_distributor( + wires: wires, + timing_curve: timing_curve + ) + ) +} + +// 993 +public node veh { + alias output __out: vehicle; + vehicle vehicle( + mass: 1270 * units.kg, + drag_coefficient: 0.32, + cross_sectional_area: (1735 * units.mm) * (1311 * units.mm), + diff_ratio: 3.444, + tire_radius: (632.0 / 2) * units.mm, // 225/50ZR16 + rolling_resistance: 20 + ) +} + +// 993 +public node trn { + alias output __out: trans; + transmission trans( + max_clutch_torque: 600 * units.Nm + ) + + trans + .add_gear(3.82) + .add_gear(2.05) + .add_gear(1.41) + .add_gear(1.12) + .add_gear(0.93) + .add_gear(0.78) +} +public node main { + set_engine(eng()) + set_vehicle(veh()) + set_transmission(trn()) +} + diff --git a/assets/engines/atg-video-2/the_i3.mr b/assets/engines/atg-video-2/the_i3.mr new file mode 100644 index 00000000..f7f2397a --- /dev/null +++ b/assets/engines/atg-video-2/the_i3.mr @@ -0,0 +1,357 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +float airfuel_ratio(14.7) + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + +} + +label cycle(2 * 360 * units.deg) +public node wb_ignition { + input wires; + input timing_curve; + input rev_limit: 11500 * units.rpm; + alias output __out: + ignition_module( + timing_curve: timing_curve, + rev_limit: rev_limit, + limiter_duration: 0.01 + ) + .connect_wire(wires.wire1, (0.0 / 3.0) * cycle) + .connect_wire(wires.wire2, (1.0 / 3.0) * cycle) + .connect_wire(wires.wire3, (2.0 / 3.0) * cycle); + +} + +public node i5_camshaft_builder { + input lobe_profile: comp_cams_magnum_11_450_8_lobe_profile(); + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 110.0 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0.0 * units.deg; + input base_radius: 0.75 * units.inch; + + output intake_cam: _intake_cam; + output exhaust_cam: _exhaust_cam; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam(params, lobe_profile: exhaust_lobe_profile) + + label rot(2 * (360 / 3.0) * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam + .add_lobe(rot360 - exhaust_lobe_center) + .add_lobe((rot360 - exhaust_lobe_center) + 1 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 2 * rot) + + _intake_cam + .add_lobe(rot360 + intake_lobe_center) + .add_lobe(rot360 + intake_lobe_center + 1 * rot) + .add_lobe(rot360 + intake_lobe_center + 2 * rot) + +} + +private node audi_i5_head { + input intake_camshaft; + input exhaust_camshaft; + input chamber_volume: 50 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.9 * units.inch * 1.9 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +public node kohler_ch750 { + alias output __out: engine; + + wires wires() + + engine engine( + name: "i3", + starter_torque: 400 * units.lb_ft, + starter_speed: 650 * units.rpm, + redline: 11500 * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.5, + max_burning_efficiency: 1.05), + hf_gain: 0.01, + noise: 1.0, + jitter: 0.299, + simulation_frequency: 10000 + ) + + label stroke(79.5 * units.mm) + label bore(86.4 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(26.8 * units.mm) + label crank_mass(5.39 * units.kg) + label flywheel_mass(1.8 * units.kg) + label flywheel_radius(2.5 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 8.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 5.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: constants.pi / 2 + ) + + rod_journal rj0(angle: (0.0 / 3.0) * 360 * units.deg) + rod_journal rj1(angle: (2.0 / 3.0) * 360 * units.deg) + rod_journal rj2(angle: (1.0 / 3.0) * 360 * units.deg) + + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + + piston_parameters piston_params( + mass: (204 + 92) * units.g, // 414 - piston mass, 152 - pin weight + blowby: 0, + compression_height: compression_height, + wrist_pin_position: 0 * units.mm, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + intake intake( + plenum_volume: 1.0 * units.L, + plenum_cross_section_area: 15.0 * units.cm2, + intake_flow_rate: k_carb(2250.0), + runner_flow_rate: k_carb(1945.0), + runner_length: 5.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9991, + velocity_decay: 0.095, + molecular_afr: airfuel_ratio + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 10.0 * units.inch, + primary_flow_rate: k_carb(800.0), + velocity_decay: 1.0, + volume: 10.0 * units.L + ) + + exhaust_system exhaust0( + es_params, audio_volume: 1.0 * 0.01, impulse_response: ir_lib.mild_exhaust_0) + exhaust_system exhaust1( + es_params, audio_volume: 0.8 * 0.01, impulse_response: ir_lib.mild_exhaust_0) + + cylinder_bank b0(bank_params, angle: 0) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.2)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.6)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + sound_attenuation: 0.8 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.6)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire3, + sound_attenuation: 0.9 + ) + + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 233 * units.deg, + gamma: 2.0, + lift: 31.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 235 * units.deg, + gamma: 2.0, + lift: 30.60 * units.mm, + steps: 100 + ) + + i5_camshaft_builder camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 116 * units.deg, + exhaust_lobe_center: 116 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + b0.set_cylinder_head ( + audi_i5_head( + chamber_volume: 50 * units.cc, + intake_camshaft: camshaft.intake_cam, + exhaust_camshaft: camshaft.exhaust_cam, + flow_attenuation: 0.9 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 12 * units.deg) + .add_sample(1000 * units.rpm, 12 * units.deg) + .add_sample(2000 * units.rpm, 20 * units.deg) + .add_sample(3000 * units.rpm, 26 * units.deg) + .add_sample(4000 * units.rpm, 30 * units.deg) + .add_sample(5000 * units.rpm, 34 * units.deg) + .add_sample(6000 * units.rpm, 36 * units.deg) + .add_sample(7000 * units.rpm, 38 * units.deg) + .add_sample(8000 * units.rpm, 39 * units.deg) + .add_sample(9000 * units.rpm, 39 * units.deg) + .add_sample(10000 * units.rpm, 39 * units.deg) + .add_sample(11000 * units.rpm, 39 * units.deg) + .add_sample(12000 * units.rpm, 40 * units.deg) + + engine.add_ignition_module( + wb_ignition( + wires: wires, + timing_curve: timing_curve, + rev_limit: 11500 * units.rpm + ) + ) +} + +public node motorcycle { + alias output __out: vehicle; + vehicle vehicle( + mass: 190 * units.kg, + drag_coefficient: 0.4, + cross_sectional_area: (400 * units.mm) * (1400 * units.mm), + diff_ratio: 2.9, + tire_radius: 15 * units.inch, + rolling_resistance: 20 + ) +} + +public node motorcycle_transmission { + alias output __out: trans; + transmission trans( + max_clutch_torque: 350 * units.lb_ft + ) + + trans + .add_gear(4.5) + .add_gear(2.7) + .add_gear(1.9) + .add_gear(1.45) + .add_gear(1.20) + .add_gear(1.0) +} + +public node main { + set_engine(kohler_ch750()) + set_transmission(motorcycle_transmission()) + set_vehicle(motorcycle()) +} diff --git a/assets/engines/atg-video-2/the_i3_mod.mr b/assets/engines/atg-video-2/the_i3_mod.mr new file mode 100644 index 00000000..f7f2397a --- /dev/null +++ b/assets/engines/atg-video-2/the_i3_mod.mr @@ -0,0 +1,357 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +float airfuel_ratio(14.7) + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + +} + +label cycle(2 * 360 * units.deg) +public node wb_ignition { + input wires; + input timing_curve; + input rev_limit: 11500 * units.rpm; + alias output __out: + ignition_module( + timing_curve: timing_curve, + rev_limit: rev_limit, + limiter_duration: 0.01 + ) + .connect_wire(wires.wire1, (0.0 / 3.0) * cycle) + .connect_wire(wires.wire2, (1.0 / 3.0) * cycle) + .connect_wire(wires.wire3, (2.0 / 3.0) * cycle); + +} + +public node i5_camshaft_builder { + input lobe_profile: comp_cams_magnum_11_450_8_lobe_profile(); + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: lobe_profile; + input lobe_separation: 110.0 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: 0.0 * units.deg; + input base_radius: 0.75 * units.inch; + + output intake_cam: _intake_cam; + output exhaust_cam: _exhaust_cam; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam(params, lobe_profile: exhaust_lobe_profile) + + label rot(2 * (360 / 3.0) * units.deg) + label rot360(360 * units.deg) + + _exhaust_cam + .add_lobe(rot360 - exhaust_lobe_center) + .add_lobe((rot360 - exhaust_lobe_center) + 1 * rot) + .add_lobe((rot360 - exhaust_lobe_center) + 2 * rot) + + _intake_cam + .add_lobe(rot360 + intake_lobe_center) + .add_lobe(rot360 + intake_lobe_center + 1 * rot) + .add_lobe(rot360 + intake_lobe_center + 2 * rot) + +} + +private node audi_i5_head { + input intake_camshaft; + input exhaust_camshaft; + input chamber_volume: 50 * units.cc; + input intake_runner_volume: 149.6 * units.cc; + input intake_runner_cross_section_area: 1.9 * units.inch * 1.9 * units.inch; + input exhaust_runner_volume: 50.0 * units.cc; + input exhaust_runner_cross_section_area: 1.25 * units.inch * 1.25 * units.inch; + + input flow_attenuation: 1.0; + input lift_scale: 1.0; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 58 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 103 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 156 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 214 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 249 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 268 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 280 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 281 * flow_attenuation) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0 * lift_scale, 0 * flow_attenuation) + .add_flow_sample(50 * lift_scale, 37 * flow_attenuation) + .add_flow_sample(100 * lift_scale, 72 * flow_attenuation) + .add_flow_sample(150 * lift_scale, 113 * flow_attenuation) + .add_flow_sample(200 * lift_scale, 160 * flow_attenuation) + .add_flow_sample(250 * lift_scale, 196 * flow_attenuation) + .add_flow_sample(300 * lift_scale, 222 * flow_attenuation) + .add_flow_sample(350 * lift_scale, 235 * flow_attenuation) + .add_flow_sample(400 * lift_scale, 245 * flow_attenuation) + .add_flow_sample(450 * lift_scale, 246 * flow_attenuation) + + generic_cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: intake_runner_volume, + intake_runner_cross_section_area: intake_runner_cross_section_area, + exhaust_runner_volume: exhaust_runner_volume, + exhaust_runner_cross_section_area: exhaust_runner_cross_section_area, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + valvetrain: standard_valvetrain( + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ), + flip_display: flip_display + ) +} + +public node kohler_ch750 { + alias output __out: engine; + + wires wires() + + engine engine( + name: "i3", + starter_torque: 400 * units.lb_ft, + starter_speed: 650 * units.rpm, + redline: 11500 * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.5, + max_burning_efficiency: 1.05), + hf_gain: 0.01, + noise: 1.0, + jitter: 0.299, + simulation_frequency: 10000 + ) + + label stroke(79.5 * units.mm) + label bore(86.4 * units.mm) + label rod_length(5.142 * units.inch) + label rod_mass(535 * units.g) + label compression_height(26.8 * units.mm) + label crank_mass(5.39 * units.kg) + label flywheel_mass(1.8 * units.kg) + label flywheel_radius(2.5 * units.inch) + + label crank_moment( + disk_moment_of_inertia(mass: crank_mass, radius: stroke / 2) + ) + label flywheel_moment( + disk_moment_of_inertia(mass: flywheel_mass, radius: flywheel_radius) + ) + label other_moment( // Moment from cams, pulleys, etc [estimated] + disk_moment_of_inertia(mass: 10 * units.kg, radius: 8.0 * units.cm) + ) + + crankshaft c0( + throw: stroke / 2, + flywheel_mass: flywheel_mass, + mass: crank_mass, + friction_torque: 5.0 * units.lb_ft, + moment_of_inertia: + crank_moment + flywheel_moment + other_moment, + position_x: 0.0, + position_y: 0.0, + tdc: constants.pi / 2 + ) + + rod_journal rj0(angle: (0.0 / 3.0) * 360 * units.deg) + rod_journal rj1(angle: (2.0 / 3.0) * 360 * units.deg) + rod_journal rj2(angle: (1.0 / 3.0) * 360 * units.deg) + + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + + piston_parameters piston_params( + mass: (204 + 92) * units.g, // 414 - piston mass, 152 - pin weight + blowby: 0, + compression_height: compression_height, + wrist_pin_position: 0 * units.mm, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: rod_mass, + moment_of_inertia: rod_moment_of_inertia( + mass: rod_mass, + length: rod_length + ), + center_of_mass: 0.0, + length: rod_length + ) + + cylinder_bank_parameters bank_params( + bore: bore, + deck_height: stroke / 2 + rod_length + compression_height + ) + + intake intake( + plenum_volume: 1.0 * units.L, + plenum_cross_section_area: 15.0 * units.cm2, + intake_flow_rate: k_carb(2250.0), + runner_flow_rate: k_carb(1945.0), + runner_length: 5.0 * units.inch, + idle_flow_rate: k_carb(0.0), + idle_throttle_plate_position: 0.9991, + velocity_decay: 0.095, + molecular_afr: airfuel_ratio + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1000.0), + primary_tube_length: 10.0 * units.inch, + primary_flow_rate: k_carb(800.0), + velocity_decay: 1.0, + volume: 10.0 * units.L + ) + + exhaust_system exhaust0( + es_params, audio_volume: 1.0 * 0.01, impulse_response: ir_lib.mild_exhaust_0) + exhaust_system exhaust1( + es_params, audio_volume: 0.8 * 0.01, impulse_response: ir_lib.mild_exhaust_0) + + cylinder_bank b0(bank_params, angle: 0) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.2)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1, + sound_attenuation: 0.9 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.6)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust1, + ignition_wire: wires.wire2, + sound_attenuation: 0.8 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.6)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire3, + sound_attenuation: 0.9 + ) + + engine + .add_cylinder_bank(b0) + + engine.add_crankshaft(c0) + + harmonic_cam_lobe intake_lobe( + duration_at_50_thou: 233 * units.deg, + gamma: 2.0, + lift: 31.78 * units.mm, + steps: 100 + ) + + harmonic_cam_lobe exhaust_lobe( + duration_at_50_thou: 235 * units.deg, + gamma: 2.0, + lift: 30.60 * units.mm, + steps: 100 + ) + + i5_camshaft_builder camshaft( + lobe_profile: "N/A", + + intake_lobe_profile: intake_lobe, + exhaust_lobe_profile: exhaust_lobe, + intake_lobe_center: 116 * units.deg, + exhaust_lobe_center: 116 * units.deg, + base_radius: (34.0 / 2) * units.mm + ) + + b0.set_cylinder_head ( + audi_i5_head( + chamber_volume: 50 * units.cc, + intake_camshaft: camshaft.intake_cam, + exhaust_camshaft: camshaft.exhaust_cam, + flow_attenuation: 0.9 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 12 * units.deg) + .add_sample(1000 * units.rpm, 12 * units.deg) + .add_sample(2000 * units.rpm, 20 * units.deg) + .add_sample(3000 * units.rpm, 26 * units.deg) + .add_sample(4000 * units.rpm, 30 * units.deg) + .add_sample(5000 * units.rpm, 34 * units.deg) + .add_sample(6000 * units.rpm, 36 * units.deg) + .add_sample(7000 * units.rpm, 38 * units.deg) + .add_sample(8000 * units.rpm, 39 * units.deg) + .add_sample(9000 * units.rpm, 39 * units.deg) + .add_sample(10000 * units.rpm, 39 * units.deg) + .add_sample(11000 * units.rpm, 39 * units.deg) + .add_sample(12000 * units.rpm, 40 * units.deg) + + engine.add_ignition_module( + wb_ignition( + wires: wires, + timing_curve: timing_curve, + rev_limit: 11500 * units.rpm + ) + ) +} + +public node motorcycle { + alias output __out: vehicle; + vehicle vehicle( + mass: 190 * units.kg, + drag_coefficient: 0.4, + cross_sectional_area: (400 * units.mm) * (1400 * units.mm), + diff_ratio: 2.9, + tire_radius: 15 * units.inch, + rolling_resistance: 20 + ) +} + +public node motorcycle_transmission { + alias output __out: trans; + transmission trans( + max_clutch_torque: 350 * units.lb_ft + ) + + trans + .add_gear(4.5) + .add_gear(2.7) + .add_gear(1.9) + .add_gear(1.45) + .add_gear(1.20) + .add_gear(1.0) +} + +public node main { + set_engine(kohler_ch750()) + set_transmission(motorcycle_transmission()) + set_vehicle(motorcycle()) +} diff --git a/assets/engines/atg-video-2/vw_w16.mr b/assets/engines/atg-video-2/vw_w16.mr new file mode 100644 index 00000000..8ba7f8a4 --- /dev/null +++ b/assets/engines/atg-video-2/vw_w16.mr @@ -0,0 +1,626 @@ +import "engine_sim.mr" + +units units() +constants constants() +impulse_response_library ir_lib() + +// Engine Sim V0.1.11A +// VW W12 +// vw_w16 +// Created by Ihar Rahatka (oror) 2022 +// 1-14-9-4-7-12-15-6-13-8-3-16-11-2-5-10 + +label bore(86.0) +label stroke(86.0) +label compression_ratio(8.3) +label con_rod(170.0) +label compression_height(31.0134 * units.mm) +label intake_valve_diameter(29.5) +label exhaust_valve_diameter(26.0) +label intake_valves(2.0) +label exhaust_valves(2.0) + +label ci(488.0) +label redline(6600.0) +label intake_cfm((ci * redline * 0.90) / 3456.0) +label exhaust_cfm((redline * 0.001) * ci / 2) + +label cyl(16) +label cycle(2 * 360 * units.deg) +label vee(90.0 * units.deg) // angle between two VR banks +label vree(15.0 * units.deg) // angle between two rows within one VR bank +label rot(2 * (360.0 / cyl) * units.deg) +label rot90(90.0 * units.deg) +label rot180(180.0 * units.deg) +label rot360(360.0 * units.deg) + +// A8L valve timings +label intake_valve_lift(10.0) +label exhaust_valve_lift(10.0) +label IVO(26.0 * units.deg) //BTDC +label IVC(29.0 * units.deg) //ABDC +label EVO(44.0 * units.deg) //BBDC +label EVC(9.0 * units.deg) //ATDC + +label intake_duration(IVO + IVC + rot180) +label exhaust_duration(EVO + EVC + rot180) + +label ILC((-IVO + rot180 + IVC) / 2.0 + rot360) +label ELC((rot180 - EVO + EVC + rot360) / 2.0) + +public node engine_distributor_even { + input wires; + input timing_curve; + input rev_limit: 7000 * units.rpm; + input limiter_duration: 0.02; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: limiter_duration) + .connect_wire(wires.wire1, (0.0/cyl) * cycle) + .connect_wire(wires.wire14, (1.0/cyl) * cycle) + .connect_wire(wires.wire9, (2.0/cyl) * cycle) + .connect_wire(wires.wire4, (3.0/cyl) * cycle) + .connect_wire(wires.wire7, (4.0/cyl) * cycle) + .connect_wire(wires.wire12, (5.0/cyl) * cycle) + .connect_wire(wires.wire15, (6.0/cyl) * cycle) + .connect_wire(wires.wire6, (7.0/cyl) * cycle) + .connect_wire(wires.wire13, (8.0/cyl) * cycle) + .connect_wire(wires.wire8, (9.0/cyl) * cycle) + .connect_wire(wires.wire3, (10.0/cyl) * cycle) + .connect_wire(wires.wire16, (11.0/cyl) * cycle) + .connect_wire(wires.wire11, (12.0/cyl) * cycle) + .connect_wire(wires.wire2, (13.0/cyl) * cycle) + .connect_wire(wires.wire5, (14.0/cyl) * cycle) + .connect_wire(wires.wire10, (15.0/cyl) * cycle); +} + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + output wire5: ignition_wire(); + output wire6: ignition_wire(); + output wire7: ignition_wire(); + output wire8: ignition_wire(); + output wire9: ignition_wire(); + output wire10: ignition_wire(); + output wire11: ignition_wire(); + output wire12: ignition_wire(); + output wire13: ignition_wire(); + output wire14: ignition_wire(); + output wire15: ignition_wire(); + output wire16: ignition_wire(); +} + +private node add_sym_sample { + input angle; + input lift; + input this; + alias output __out: this; + + this.add_sample(angle * units.deg, lift * units.thou) + this.add_sample(-angle * units.deg, lift * units.thou) +} + +public node eng_lobe_profile_int { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: intake_duration, + gamma: 4.0, + lift: intake_valve_lift * units.mm, + steps: 100 + ); +} + +public node eng_lobe_profile_exh { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: exhaust_duration, + gamma: 4.0, + lift: exhaust_valve_lift * units.mm, + steps: 100 + ); +} + +// even firing camshaft +public node engine_camshaft_builder_even { + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + output intake_cam_1: _intake_cam_1; + output exhaust_cam_1: _exhaust_cam_1; + output intake_cam_2: _intake_cam_2; + output exhaust_cam_2: _exhaust_cam_2; + output intake_cam_3: _intake_cam_3; + output exhaust_cam_3: _exhaust_cam_3; + + camshaft_parameters params( + advance: 0, + base_radius: 1.7 * units.cm + ) + + camshaft _intake_cam_0(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_0(params, lobe_profile: eng_lobe_profile_exh()) + camshaft _intake_cam_1(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_1(params, lobe_profile: eng_lobe_profile_exh()) + camshaft _intake_cam_2(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_2(params, lobe_profile: eng_lobe_profile_exh()) + camshaft _intake_cam_3(params, lobe_profile: eng_lobe_profile_int()) + camshaft _exhaust_cam_3(params, lobe_profile: eng_lobe_profile_exh()) + + _intake_cam_0 + .add_lobe(ILC + 0 * rot) + .add_lobe(ILC + 10 * rot) + .add_lobe(ILC + 14 * rot) + .add_lobe(ILC + 4 * rot) + _exhaust_cam_0 + .add_lobe(ELC + 0 * rot) + .add_lobe(ELC + 10 * rot) + .add_lobe(ELC + 14 * rot) + .add_lobe(ELC + 4 * rot) + + _intake_cam_1 + .add_lobe(ILC + 13 * rot) + .add_lobe(ILC + 3 * rot) + .add_lobe(ILC + 7 * rot) + .add_lobe(ILC + 9 * rot) + _exhaust_cam_1 + .add_lobe(ELC + 13 * rot) + .add_lobe(ELC + 3 * rot) + .add_lobe(ELC + 7 * rot) + .add_lobe(ELC + 9 * rot) + + _intake_cam_2 + .add_lobe(ILC + 2 * rot) + .add_lobe(ILC + 12 * rot) + .add_lobe(ILC + 8 * rot) + .add_lobe(ILC + 6 * rot) + _exhaust_cam_2 + .add_lobe(ELC + 2 * rot) + .add_lobe(ELC + 12 * rot) + .add_lobe(ELC + 8 * rot) + .add_lobe(ELC + 6 * rot) + + _intake_cam_3 + .add_lobe(ILC + 15 * rot) + .add_lobe(ILC + 5 * rot) + .add_lobe(ILC + 1 * rot) + .add_lobe(ILC + 11 * rot) + _exhaust_cam_3 + .add_lobe(ELC + 15 * rot) + .add_lobe(ELC + 5 * rot) + .add_lobe(ELC + 1 * rot) + .add_lobe(ELC + 11 * rot) +} + +private node add_flow_sample { + input lift; + input flow; + input this; + alias output __out: this; + + this.add_sample(lift * units.mm, k_28inH2O(flow)) +} + +public node eng_head { + input intake_camshaft; + input exhaust_camshaft; + input flip_display: false; + + alias output __out: head; + + label bore_radius(bore / 2) + label intake_valve_circ(intake_valve_diameter * constants.pi) + label exhaust_valve_circ(exhaust_valve_diameter * constants.pi) + label intake_valve_func(intake_valve_lift * (10.0 / intake_valve_lift)) + label exhaust_valve_func(exhaust_valve_lift * (10.0 / exhaust_valve_lift)) + + function intake_flow(1 * units.mm) + intake_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, intake_valve_circ * 0.01 * intake_valve_func * 3.3761 * intake_valves) + .add_flow_sample(2, intake_valve_circ * 0.02 * intake_valve_func * 3.1574 * intake_valves) + .add_flow_sample(3, intake_valve_circ * 0.03 * intake_valve_func * 3.0143 * intake_valves) + .add_flow_sample(4, intake_valve_circ * 0.04 * intake_valve_func * 2.9503 * intake_valves) + .add_flow_sample(5, intake_valve_circ * 0.05 * intake_valve_func * 2.8938 * intake_valves) + .add_flow_sample(6, intake_valve_circ * 0.06 * intake_valve_func * 2.8134 * intake_valves) + .add_flow_sample(7, intake_valve_circ * 0.07 * intake_valve_func * 2.7560 * intake_valves) + .add_flow_sample(8, intake_valve_circ * 0.08 * intake_valve_func * 2.5924 * intake_valves) + .add_flow_sample(9, intake_valve_circ * 0.09 * intake_valve_func * 2.4651 * intake_valves) + .add_flow_sample(10, intake_valve_circ * 0.1 * intake_valve_func * 2.2668 * intake_valves) + .add_flow_sample(11, intake_valve_circ * 0.11 * intake_valve_func * 2.10 * intake_valves) + .add_flow_sample(12, intake_valve_circ * 0.12 * intake_valve_func * 2.01 * intake_valves) + .add_flow_sample(13, intake_valve_circ * 0.13 * intake_valve_func * 1.90 * intake_valves) + .add_flow_sample(14, intake_valve_circ * 0.14 * intake_valve_func * 1.82 * intake_valves) + + function exhaust_flow(1 * units.mm) + exhaust_flow + .add_flow_sample(0, 0.0) + .add_flow_sample(1, exhaust_valve_circ * 0.01 * exhaust_valve_func * 3.3761 * exhaust_valves) + .add_flow_sample(2, exhaust_valve_circ * 0.02 * exhaust_valve_func * 3.1574 * exhaust_valves) + .add_flow_sample(3, exhaust_valve_circ * 0.03 * exhaust_valve_func * 3.0143 * exhaust_valves) + .add_flow_sample(4, exhaust_valve_circ * 0.04 * exhaust_valve_func * 2.9503 * exhaust_valves) + .add_flow_sample(5, exhaust_valve_circ * 0.05 * exhaust_valve_func * 2.8938 * exhaust_valves) + .add_flow_sample(6, exhaust_valve_circ * 0.06 * exhaust_valve_func * 2.8134 * exhaust_valves) + .add_flow_sample(7, exhaust_valve_circ * 0.07 * exhaust_valve_func * 2.7560 * exhaust_valves) + .add_flow_sample(8, exhaust_valve_circ * 0.08 * exhaust_valve_func * 2.5924 * exhaust_valves) + .add_flow_sample(9, exhaust_valve_circ * 0.09 * exhaust_valve_func * 2.4651 * exhaust_valves) + .add_flow_sample(10, exhaust_valve_circ * 0.1 * exhaust_valve_func * 2.2668 * exhaust_valves) + .add_flow_sample(11, exhaust_valve_circ * 0.11 * exhaust_valve_func * 2.10 * exhaust_valves) + .add_flow_sample(12, exhaust_valve_circ * 0.12 * exhaust_valve_func * 2.01 * exhaust_valves) + .add_flow_sample(13, exhaust_valve_circ * 0.13 * exhaust_valve_func * 1.90 * exhaust_valves) + .add_flow_sample(14, exhaust_valve_circ * 0.14 * exhaust_valve_func * 1.82 * exhaust_valves) + + cylinder_head head( + chamber_volume: (circle_area(bore_radius) * stroke / compression_ratio) / 1000 * units.cc, + intake_runner_volume: 100.0 * units.cc, + intake_runner_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * 0.85 * intake_valves, + exhaust_runner_volume: 10.0 * units.cc, + exhaust_runner_cross_section_area: circle_area(exhaust_valve_diameter * units.mm / 2) * 0.85 * exhaust_valves, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +public node eng { + alias output __out: engine; + + engine engine( + name: "VAG 8.0 W16", + //starter_torque: 100 * units.lb_ft, + starter_torque: 110 * units.Nm, + starter_speed: 200 * units.rpm, + redline: 6500 * units.rpm, + fuel: fuel( + max_turbulence_effect: 3.0, + burning_efficiency_randomness: 0.1, + max_burning_efficiency: 0.95 + ), + throttle_gamma: 1.5, + jitter: 0.75, + noise: 0.75, + simulation_frequency: 5000 + ) + + wires wires() + + crankshaft c0( + throw: (stroke / 2) * units.mm, + flywheel_mass: 3 * units.kg, + mass: 34 * units.kg, + friction_torque: 15.0 * units.Nm, + moment_of_inertia: 0.3, + position_x: 0.0, + position_y: 0.0, + tdc: 0.0000001 * units.deg + ) + + rod_journal rj0_0(angle: (0.0 / cyl) * cycle + rot90 + vee / 2 + vree / 2) + rod_journal rj1_0(angle: (13.0 / cyl) * cycle + rot90 + vee / 2 - vree / 2) + rod_journal rj2_0(angle: (10.0 / cyl) * cycle + rot90 + vee / 2 + vree / 2) + rod_journal rj3_0(angle: (3.0 / cyl) * cycle + rot90 + vee / 2 - vree / 2) + rod_journal rj4_0(angle: (14.0 / cyl) * cycle + rot90 + vee / 2 + vree / 2) + rod_journal rj5_0(angle: (7.0 / cyl) * cycle + rot90 + vee / 2 - vree / 2) + rod_journal rj6_0(angle: (4.0 / cyl) * cycle + rot90 + vee / 2 + vree / 2) + rod_journal rj7_0(angle: (9.0 / cyl) * cycle + rot90 + vee / 2 - vree / 2) + + c0 + .add_rod_journal(rj0_0) + .add_rod_journal(rj1_0) + .add_rod_journal(rj2_0) + .add_rod_journal(rj3_0) + .add_rod_journal(rj4_0) + .add_rod_journal(rj5_0) + .add_rod_journal(rj6_0) + .add_rod_journal(rj7_0) + + piston_parameters piston_params( + mass: 247.252 * units.g, + blowby: k_28inH2O(0.05), + compression_height: compression_height, + wrist_pin_position: 0.0, + displacement: 0.0 + ) + + connecting_rod_parameters cr_params( + mass: 457.0 * units.g, + moment_of_inertia: 0.002, + center_of_mass: 0.0, + length: con_rod * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: bore * units.mm, + deck_height: (con_rod + stroke / 2) * units.mm + compression_height + ) + + intake intake( + plenum_volume: 2.0 * units.L, + plenum_cross_section_area: circle_area(intake_valve_diameter * units.mm / 2) * cyl * 2 * intake_valves, + intake_flow_rate: k_carb(intake_cfm), + idle_flow_rate: k_carb(0.01), + idle_throttle_plate_position: 0.996, + runner_flow_rate: k_carb(intake_cfm / 8), + runner_length: 10.0 * units.cm, + velocity_decay: 0.05 + ) + + exhaust_system_parameters es_params0( + outlet_flow_rate: k_carb(exhaust_cfm / 2), + primary_tube_length: 225.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / 8), + velocity_decay: 1.5, + volume: 6.1 * units.L + ) + + exhaust_system_parameters es_params1( + outlet_flow_rate: k_carb(exhaust_cfm / 2), + primary_tube_length: 220.0 * units.cm, + primary_flow_rate: k_carb(exhaust_cfm / 8), + velocity_decay: 1.5, + volume: 6.0 * units.L + ) + + // exhaust_system exhaust0(es_params0, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + // exhaust_system exhaust1(es_params1, impulse_response: impulse_response(filename: "E:/smooth_m.wav", volume: 0.01)) + exhaust_system exhaust0(es_params0, impulse_response: ir_lib.default_0) + exhaust_system exhaust1(es_params1, impulse_response: ir_lib.default_0) + + cylinder_bank b0(bank_params, angle: vee / 2 + vree / 2) + cylinder_bank b1(bank_params, angle: vee / 2 - vree / 2) + cylinder_bank b2(bank_params, angle: -vee / 2 + vree / 2) + cylinder_bank b3(bank_params, angle: -vee / 2 - vree / 2) + + // Veyron setup + label div(1.2) + label shift(60.0) + label shift2(400.0) + label pl0 ((0.0 * bore / div) * units.mm) + label pl1 ((1.0 * bore / div + shift) * units.mm) + label pl2 ((1.0 * bore / div) * units.mm) + label pl3 ((0.0 * bore / div + shift) * units.mm) + label pl4 ((1.9 * bore / div + shift2) * units.mm) + label pl5 ((1.7 * bore / div + shift + shift2) * units.mm) + label pl6 ((1.0 * bore / div + shift2) * units.mm) + label pl7 ((0.0 * bore / div + shift + shift2) * units.mm) + + b0.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl0, + ignition_wire: wires.wire1 + ) + b1.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl1, + ignition_wire: wires.wire2 + ) + b0.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl2, + ignition_wire: wires.wire3 + ) + b1.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl3, + ignition_wire: wires.wire4 + ) + b0.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl4, + ignition_wire: wires.wire5 + ) + b1.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl5, + ignition_wire: wires.wire6 + ) + b0.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl6, + ignition_wire: wires.wire7 + ) + b1.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7_0, + intake: intake, + exhaust_system: exhaust0, + primary_length: pl7, + ignition_wire: wires.wire8 + ) + + b2.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl0, + ignition_wire: wires.wire9 + ) + b3.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl1, + ignition_wire: wires.wire10 + ) + b2.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl2, + ignition_wire: wires.wire11 + ) + b3.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl3, + ignition_wire: wires.wire12 + ) + b2.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj4_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl4, + ignition_wire: wires.wire13 + ) + b3.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj5_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl5, + ignition_wire: wires.wire14 + ) + b2.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj6_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl6, + ignition_wire: wires.wire15 + ) + b3.add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj7_0, + intake: intake, + exhaust_system: exhaust1, + primary_length: pl7, + ignition_wire: wires.wire16 + ) + + engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + .add_cylinder_bank(b2) + .add_cylinder_bank(b3) + + engine.add_crankshaft(c0) + + engine_camshaft_builder_even camshaft() + + b0.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0, + flip_display: true + ) + ) + b1.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_1, + exhaust_camshaft: camshaft.exhaust_cam_1, + flip_display: true + ) + ) + + b2.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_2, + exhaust_camshaft: camshaft.exhaust_cam_2 + ) + ) + b3.set_cylinder_head ( + eng_head( + intake_camshaft: camshaft.intake_cam_3, + exhaust_camshaft: camshaft.exhaust_cam_3 + ) + ) + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0000 * units.rpm, 10 * units.deg) + .add_sample(1000 * units.rpm, 15 * units.deg) + .add_sample(2000 * units.rpm, 20 * units.deg) + .add_sample(3000 * units.rpm, 25 * units.deg) + .add_sample(4000 * units.rpm, 30 * units.deg) + .add_sample(5000 * units.rpm, 33 * units.deg) + .add_sample(6000 * units.rpm, 35 * units.deg) + + engine.add_ignition_module( + engine_distributor_even( + wires: wires, + timing_curve: timing_curve + ) + ) +} + +// Veyron 16.4 +public node veh { + alias output __out: vehicle; + vehicle vehicle( + mass: 1888 * units.kg, + drag_coefficient: 0.355, + cross_sectional_area: (1998 * units.mm) * (1204 * units.mm), + diff_ratio: 2.8, + tire_radius: (711.0 / 2) * units.mm, + rolling_resistance: 25 + ) +} + +// Veyron 16.4 +public node trn { + alias output __out: trans; + transmission trans( + max_clutch_torque: 1100 * units.Nm + ) + + trans + .add_gear(3.18) + .add_gear(2.26) + .add_gear(1.68) + .add_gear(1.29) + .add_gear(1.06) + .add_gear(0.88) + .add_gear(0.80) +} + +public node main { + set_engine(eng()) + set_transmission(trn()) + set_vehicle(veh()) +} diff --git a/assets/engines/atg-video-2/xplane.mr b/assets/engines/atg-video-2/xplane.mr new file mode 100644 index 00000000..874596ad --- /dev/null +++ b/assets/engines/atg-video-2/xplane.mr @@ -0,0 +1,338 @@ +import "engine_sim.mr" +import "../../part-library/part_library.mr" + +units units() +constants constants() + +label cycle(2 * 360 * units.deg) +label sparkadvance(-35 * units.deg) + +private node wires { + output wire1: ignition_wire(); + output wire2: ignition_wire(); + output wire3: ignition_wire(); + output wire4: ignition_wire(); + +} + +// Firing order : 3, 1, 2, 0 : 4, 2, 3, 1 +public node R1_distributor { + input wires; + input timing_curve; + input rev_limit; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: 0.02 * units.sec) + .connect_wire(wires.wire1, ((6.0/8.0) * cycle) + sparkadvance) + .connect_wire(wires.wire2, ((3.0/8.0) * cycle) + sparkadvance) + .connect_wire(wires.wire3, ((5.0/8.0) * cycle) + sparkadvance) + .connect_wire(wires.wire4, ((0.0/8.0) * cycle) + sparkadvance); +} + +public node R1_intake_lobe_profile { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 210 * units.deg, + gamma: 1.1, + lift: 12 * units.mm, + steps: 100 + ); +} + +public node R1_exhaust_lobe_profile { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 225 * units.deg, + gamma: 1.1, + lift: 14 * units.mm, + steps: 100 + ); +} + +public node R1_camshaft_builder { + input lobe_profile: R1_intake_lobe_profile(); + input ex_lobe_profile: R1_exhaust_lobe_profile(); + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: ex_lobe_profile; + input lobe_separation: 103.0 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: -30.0 * units.deg; + input base_radius: 0.6 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + + label rot90(90 * units.deg) + label rot360(360 * units.deg) + + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + 6 * rot90) + .add_lobe(rot360 + intake_lobe_center + 3 * rot90) + .add_lobe(rot360 + intake_lobe_center + 5 * rot90) + .add_lobe(rot360 + intake_lobe_center + 0 * rot90) + + _exhaust_cam_0 + .add_lobe(rot360 - intake_lobe_center + 6 * rot90) + .add_lobe(rot360 - intake_lobe_center + 3 * rot90) + .add_lobe(rot360 - intake_lobe_center + 5 * rot90) + .add_lobe(rot360 - intake_lobe_center + 0 * rot90) +} + +private node add_flow_sample { + input lift; + input flow; + input this; + alias output __out: this; + + this.add_sample(lift * units.thou, k_28inH2O(flow)) +} + +public node R1_head { + input intake_camshaft; + input exhaust_camshaft; + input chamber_volume: 45.0 * units.cc; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0, 0) + .add_flow_sample(160, 135) + .add_flow_sample(210, 186) + .add_flow_sample(260, 210) + .add_flow_sample(310, 256) + .add_flow_sample(360, 285) + .add_flow_sample(410, 322) + .add_flow_sample(460, 330) + .add_flow_sample(510, 365) + .add_flow_sample(560, 385) + .add_flow_sample(610, 404) + .add_flow_sample(660, 410) + .add_flow_sample(710, 424) + .add_flow_sample(760, 424) + .add_flow_sample(810, 424) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0, 0) + .add_flow_sample(160, 135) + .add_flow_sample(210, 180) + .add_flow_sample(260, 210) + .add_flow_sample(310, 242) + .add_flow_sample(360, 250) + .add_flow_sample(410, 266) + .add_flow_sample(460, 280) + .add_flow_sample(510, 291) + .add_flow_sample(560, 301) + .add_flow_sample(610, 317) + .add_flow_sample(660, 324) + .add_flow_sample(710, 338) + .add_flow_sample(760, 338) + .add_flow_sample(810, 338) + + cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: 400.00 * units.cc, + intake_runner_cross_section_area: 12.00 * units.cm2, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +public node xplane { + alias output __out: engine; + + engine engine( + name: "r1", + starter_torque: 30 * units.lb_ft, + starter_speed: 500 * units.rpm, + redline: 14000 * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.0, + burning_efficiency_randomness: 0.2, + max_burning_efficiency: 1.75 + ) + ) + + wires wires() + + crankshaft c0( + throw: 50.9 * units.mm/2, + flywheel_mass: 0.4 * units.lb, + mass: 4 * units.lb, + friction_torque: 7.0 * units.lb_ft, + moment_of_inertia: 0.22986844776863666, + position_x: 0.0, + position_y: 0.0, + tdc: (constants.pi / 4) + 0 * units.deg + ) + + rod_journal rj0(angle: 180.0 * units.deg) + rod_journal rj1(angle: 270.0 * units.deg) + rod_journal rj2(angle: 90.0 * units.deg) + rod_journal rj3(angle: 0.0 * units.deg) + c0 + .add_rod_journal(rj0) + .add_rod_journal(rj1) + .add_rod_journal(rj2) + .add_rod_journal(rj3) + + piston_parameters piston_params( + mass: 172 * units.g, + compression_height: 30.00 * units.mm, + wrist_pin_position: 0.0, + displacement: -5 * units.cc + ) + + connecting_rod_parameters cr_params( + mass: 75.0 * units.g, + moment_of_inertia: 0.0015884918028487504, + center_of_mass: 0.0, + length: 102 * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: 79 * units.mm, + deck_height: 160 * units.mm + ) + + performer_rpm_intake intake( + carburetor_cfm: 1400.0, + idle_flow_rate_cfm: 0.005, + idle_throttle_plate_position: 0.9994 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1550.0), + primary_tube_length: 50.0 * units.inch, + primary_flow_rate: k_carb(1550.0), + velocity_decay: 0.0, + volume: 140.0 * units.L + ) + + //impulse_response ir0(filename: "../../sound-library/smooth/smooth_35.wav", volume: 0.001) + impulse_response ir0(filename: "../../sound-library/smooth/smooth_35.wav", volume: 0.1) + exhaust_system exhaust0(es_params, audio_volume: 1.0, impulse_response: ir0) + + cylinder_bank b0(bank_params, angle: 0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire2 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire3 + ) + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire4 + ) + + engine.add_cylinder_bank(b0) + engine.add_crankshaft(c0) + + R1_camshaft_builder camshaft( + lobe_profile: R1_intake_lobe_profile(), + ex_lobe_profile: R1_exhaust_lobe_profile() + ) + + b0.set_cylinder_head ( + R1_head( + chamber_volume: 22.5 * units.cc, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0 + ) + ) + + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0 * units.rpm, 0 * units.deg) + .add_sample(1000 * units.rpm, 14 * units.deg) + .add_sample(2000 * units.rpm, 22 * units.deg) + .add_sample(3000 * units.rpm, 26 * units.deg) + .add_sample(4000 * units.rpm, 33 * units.deg) + .add_sample(5000 * units.rpm, 34 * units.deg) + .add_sample(6000 * units.rpm, 35 * units.deg) + .add_sample(7000 * units.rpm, 36 * units.deg) + .add_sample(8000 * units.rpm, 40 * units.deg) + .add_sample(9000 * units.rpm, 45 * units.deg) + .add_sample(10000 * units.rpm, 50 * units.deg) + .add_sample(11000 * units.rpm, 55 * units.deg) + .add_sample(12000 * units.rpm, 60 * units.deg) + .add_sample(13000 * units.rpm, 65 * units.deg) + .add_sample(14000 * units.rpm, 70 * units.deg) + + + engine.add_ignition_module( + R1_distributor( + wires: wires, + timing_curve: timing_curve, + rev_limit: 14000 * units.rpm + )) +} + +label car_mass(2700 * units.lb) +private node random_car { + alias output __out: + vehicle( + mass: car_mass, + drag_coefficient: 0.3, + cross_sectional_area: (72 * units.inch) * (56 * units.inch), + diff_ratio: 3.9, + tire_radius: 10 * units.inch, + rolling_resistance: 0.015 * car_mass * 9.81 + ); +} + +private node random_transmission { + alias output __out: + transmission( + max_clutch_torque: 300 * units.lb_ft + ) + .add_gear(3.636) + .add_gear(2.375) + .add_gear(1.761) + .add_gear(1.346) + .add_gear(0.971) + .add_gear(0.756); +} + +public node main { + set_engine(xplane()) + set_transmission(random_transmission()) + set_vehicle(random_car()) +} diff --git a/assets/engines/atg-video-2/yz450.mr b/assets/engines/atg-video-2/yz450.mr new file mode 100644 index 00000000..8add64d4 --- /dev/null +++ b/assets/engines/atg-video-2/yz450.mr @@ -0,0 +1,295 @@ +import "engine_sim.mr" +import "../../part-library/part_library.mr" + +units units() +constants constants() + +label cycle(2 * 360 * units.deg) +label sparkadvance(-35 * units.deg) + +private node wires { + output wire1: ignition_wire(); +} + +public node YZ_distributor { + input wires; + input timing_curve; + input rev_limit; + alias output __out: + ignition_module(timing_curve: timing_curve, rev_limit: rev_limit, limiter_duration: 0.02 * units.sec) + .connect_wire(wires.wire1, ((0.0/8.0) * cycle) + sparkadvance); +} + +public node YZ_intake_lobe_profile { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 210 * units.deg, + gamma: 1.1, + lift: 12 * units.mm, + steps: 100 + ); +} + +public node YZ_exhaust_lobe_profile { + alias output __out: + harmonic_cam_lobe( + duration_at_50_thou: 225 * units.deg, + gamma: 1.1, + lift: 14 * units.mm, + steps: 100 + ); +} + +public node YZ_camshaft_builder { + input lobe_profile: YZ_intake_lobe_profile(); + input ex_lobe_profile: YZ_exhaust_lobe_profile(); + input intake_lobe_profile: lobe_profile; + input exhaust_lobe_profile: ex_lobe_profile; + input lobe_separation: 103.0 * units.deg; + input intake_lobe_center: lobe_separation; + input exhaust_lobe_center: lobe_separation; + input advance: -30.0 * units.deg; + input base_radius: 0.6 * units.inch; + + output intake_cam_0: _intake_cam_0; + output exhaust_cam_0: _exhaust_cam_0; + + camshaft_parameters params( + advance: advance, + base_radius: base_radius + ) + + camshaft _intake_cam_0(params, lobe_profile: intake_lobe_profile) + camshaft _exhaust_cam_0(params, lobe_profile: exhaust_lobe_profile) + + label rot90(90 * units.deg) + label rot360(360 * units.deg) + + _intake_cam_0 + .add_lobe(rot360 + intake_lobe_center + 0 * rot90) + _exhaust_cam_0 + .add_lobe(rot360 - intake_lobe_center + 0 * rot90) +} + +private node add_flow_sample { + input lift; + input flow; + input this; + alias output __out: this; + + this.add_sample(lift * units.thou, k_28inH2O(flow)) +} + +public node YZ_head { + input intake_camshaft; + input exhaust_camshaft; + input chamber_volume: 45.0 * units.cc; + input flip_display: false; + alias output __out: head; + + function intake_flow(50 * units.thou) + intake_flow + .add_flow_sample(0, 0) + .add_flow_sample(160, 135) + .add_flow_sample(210, 186) + .add_flow_sample(260, 210) + .add_flow_sample(310, 256) + .add_flow_sample(360, 285) + .add_flow_sample(410, 322) + .add_flow_sample(460, 330) + .add_flow_sample(510, 365) + .add_flow_sample(560, 385) + .add_flow_sample(610, 404) + .add_flow_sample(660, 410) + .add_flow_sample(710, 424) + .add_flow_sample(760, 424) + .add_flow_sample(810, 424) + + function exhaust_flow(50 * units.thou) + exhaust_flow + .add_flow_sample(0, 0) + .add_flow_sample(160, 135) + .add_flow_sample(210, 180) + .add_flow_sample(260, 210) + .add_flow_sample(310, 242) + .add_flow_sample(360, 250) + .add_flow_sample(410, 266) + .add_flow_sample(460, 280) + .add_flow_sample(510, 291) + .add_flow_sample(560, 301) + .add_flow_sample(610, 317) + .add_flow_sample(660, 324) + .add_flow_sample(710, 338) + .add_flow_sample(760, 338) + .add_flow_sample(810, 338) + + cylinder_head head( + chamber_volume: chamber_volume, + intake_runner_volume: 400.00 * units.cc, + intake_runner_cross_section_area: 12.00 * units.cm2, + + intake_port_flow: intake_flow, + exhaust_port_flow: exhaust_flow, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft, + flip_display: flip_display + ) +} + +public node YZ { + alias output __out: engine; + + engine engine( + name: "yz450f", + starter_torque: 40 * units.lb_ft, + starter_speed: 1200 * units.rpm, + redline: 11600 * units.rpm, + fuel: fuel( + max_turbulence_effect: 2.0, + burning_efficiency_randomness: 0.2, + max_burning_efficiency: 1.3 + ), + simulation_frequency: 20000, + hf_gain: 2.0, + noise: 1.0, + jitter: 0.2 + ) + + wires wires() + + crankshaft c0( + throw: 60.8 * units.mm/2, + flywheel_mass: 0.4 * units.lb, + mass: 4 * units.lb, + friction_torque: 7.0 * units.lb_ft, + moment_of_inertia: 0.01, + position_x: 0.0, + position_y: 0.0, + tdc: (constants.pi / 4) + 0 * units.deg + ) + + rod_journal rj0(angle: 0.0 * units.deg) + c0 + .add_rod_journal(rj0) + + piston_parameters piston_params( + mass: 172 * units.g, + compression_height: 30.00 * units.mm, + wrist_pin_position: 0.0, + displacement: -5 * units.cc + ) + + connecting_rod_parameters cr_params( + mass: 75.0 * units.g, + moment_of_inertia: 0.001, + center_of_mass: 0.0, + length: 84 * units.mm + ) + + cylinder_bank_parameters bank_params( + bore: 97 * units.mm, + deck_height: 155 * units.mm + //deck_height: 145 * units.mm + ) + + performer_rpm_intake intake( + carburetor_cfm: 1400.0, + idle_flow_rate_cfm: 0.002, + idle_throttle_plate_position: 0.9985 + ) + + exhaust_system_parameters es_params( + outlet_flow_rate: k_carb(1550.0), + primary_tube_length: 50.0 * units.inch, + primary_flow_rate: k_carb(1550.0), + velocity_decay: 0.0, + volume: 140.0 * units.L + ) + + impulse_response ir0(filename: "../../sound-library/smooth/smooth_35.wav", volume: 0.001) + exhaust_system exhaust0(es_params, audio_volume: 1.0, impulse_response: ir0) + + cylinder_bank b0(bank_params, angle: 0 * units.deg) + b0 + .add_cylinder( + piston: piston(piston_params, blowby: k_28inH2O(0.1)), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0, + intake: intake, + exhaust_system: exhaust0, + ignition_wire: wires.wire1 + ) + + engine.add_cylinder_bank(b0) + engine.add_crankshaft(c0) + + YZ_camshaft_builder camshaft( + lobe_profile: YZ_intake_lobe_profile(), + ex_lobe_profile: YZ_exhaust_lobe_profile() + ) + + b0.set_cylinder_head ( + YZ_head( + //chamber_volume: 22.5 * units.cc, + chamber_volume: 0 * units.cc, + intake_camshaft: camshaft.intake_cam_0, + exhaust_camshaft: camshaft.exhaust_cam_0 + ) + ) + + + function timing_curve(1000 * units.rpm) + timing_curve + .add_sample(0 * units.rpm, 0 * units.deg) + .add_sample(1000 * units.rpm, 14 * units.deg) + .add_sample(2000 * units.rpm, 22 * units.deg) + .add_sample(3000 * units.rpm, 26 * units.deg) + .add_sample(4000 * units.rpm, 33 * units.deg) + .add_sample(5000 * units.rpm, 34 * units.deg) + .add_sample(6000 * units.rpm, 35 * units.deg) + .add_sample(7000 * units.rpm, 36 * units.deg) + .add_sample(8000 * units.rpm, 40 * units.deg) + .add_sample(9000 * units.rpm, 45 * units.deg) + .add_sample(10000 * units.rpm, 50 * units.deg) + .add_sample(11000 * units.rpm, 55 * units.deg) + .add_sample(12000 * units.rpm, 60 * units.deg) + + engine.add_ignition_module( + YZ_distributor( + wires: wires, + timing_curve: timing_curve, + rev_limit: 11600 * units.rpm + )) +} + +public node YZ_vehicle { + alias output __out: vehicle; + vehicle vehicle( + mass: 107 * units.kg, + drag_coefficient: 0.0012, + cross_sectional_area: (85.8 * units.inch) * (3 * units.inch), + diff_ratio: 16.00, + tire_radius: 19 * units.inch, + rolling_resistance: 900 + ) +} + +public node YZ_transmission { + alias output __out: trans; + transmission trans( + max_clutch_torque: 300 * units.lb_ft + ) + + trans + .add_gear(1.929) + .add_gear(1.533) + .add_gear(1.278) + .add_gear(1.091) + .add_gear(0.952) +} + +public node main { + set_engine(YZ()) + set_transmission(YZ_transmission()) + set_vehicle(YZ_vehicle()) +} diff --git a/assets/main.mr b/assets/main.mr index b68972e9..874e7db1 100644 --- a/assets/main.mr +++ b/assets/main.mr @@ -1,6 +1,46 @@ import "engine_sim.mr" import "themes/default.mr" -import "../workspace/video-engines/motor-trend/01_X8.mr" +//import "../workspace/video-engines/motor-trend/01_X8.mr" +//import "engines/atg-video-2/01_subaru_ej25_eh.mr" +//import "engines/atg-video-2/6 Rotor.mr" +//import "engines/atg-video-2/13_rotor.mr" +//import "engines/atg-video-2/f312t.mr" +//import "engines/atg-video-1/02_kohler_ch750.mr" +//import "engines/atg-video-2/04_60_degree_v6.mr" +//import "engines/atg-video-2/04_60_degree_big_bang_v6.mr" +//import "engines/atg-video-2/05_odd_fire_v6.mr" +//import "engines/atg-video-2/06_even_fire_v6.mr" +//import "engines/atg-video-2/07_gm_ls.mr" +//import "engines/atg-video-2/08_ferrari_f136_v8.mr" +//import "engines/atg-video-2/12_ferrari_412_t2.mr" +//import "engines/atg-video-2/03_2jz.mr" +//import "engines/atg-video-2/03_i8.mr" +import "engines/atg-video-2/01_subaru_el15.mr" +//import "engines/atg-video-2/01_subaru_el15_bb.mr" +//import "engines/atg-video-2/yz450.mr" +//import "engines/atg-video-2/01_subaru_H12.mr" +//import "engines/atg-video-2/porsche_993_b8.mr" +//import "engines/atg-video-2/porsche_993_b10.mr" +//import "engines/atg-video-2/porsche_993_b12.mr" +//import "engines/atg-video-2/gx25.mr" +//import "engines/atg-video-2/50cc.mr" +//import "engines/atg-video-2/25cc.mr" +//import "engines/atg-video-2/01_subaru_EL22.mr" +//import "engines/atg-video-2/01_subaru_EL22_UB.mr" +//import "engines/atg-video-2/01_subaru_EL30.mr" +//import "engines/atg-video-2/01_subaru_EL37.mr" +//import "engines/atg-video-2/01_subaru_EL45.mr" +//import "engines/atg-video-2/vw_w16.mr" +//import "engines/atg-video-2/the_i3.mr" +//import "engines/atg-video-2/xplane.mr" +//import "engines/atg-video-1/01_honda_trx520.mr" +//import "engines/atg-video-1/02_kohler_ch750.mr" +//import "engines/atg-video-2/11_merlin_v12.mr" +//import "engines/atg-video-2/i2.mr" +//import "engines/atg-video-2/i2_bb.mr" +//import "engines/atg-video-2/i2_cp.mr" +//import "engines/atg-video-2/i2_cp2.mr" +//import "engines/atg-video-2/i2_cp3.mr" use_default_theme() main() diff --git a/assets/themes/default.mr b/assets/themes/default.mr index cbf4ecfc..e05b2f60 100644 --- a/assets/themes/default.mr +++ b/assets/themes/default.mr @@ -3,9 +3,12 @@ import "engine_sim.mr" unit_names units() public node use_default_theme { input start_fullscreen: false; - input speed_units: units.mph; - input pressure_units: units.inHg; - input torque_units: units.lb_ft; + //input speed_units: units.mph; + input speed_units: units.kph; + //input pressure_units: units.inHg; + input pressure_units: units.bar; + //input torque_units: units.lb_ft; + input torque_units: units.Nm; input power_units: units.hp; set_application_settings(