From d44c435ceb5cbaf5b4ec5de6ac89a481269bcb7d Mon Sep 17 00:00:00 2001 From: Ange Yaghi Date: Tue, 19 Jul 2022 02:35:40 -0400 Subject: [PATCH] Added camshaft, cylinder head and function nodes --- assets/test.mr | 69 ++++++++++++++++ dependencies/submodules/piranha | 2 +- es/actions/actions.mr | 60 +++++++++++++- es/objects/objects.mr | 105 +++++++++++++++++++++++- scripting/include/actions.h | 54 +++++++++++- scripting/include/camshaft_node.h | 67 +++++++++++++++ scripting/include/channel_types.h | 15 ++++ scripting/include/connecting_rod_node.h | 6 +- scripting/include/crankshaft_node.h | 10 ++- scripting/include/cylinder_bank_node.h | 35 +++++++- scripting/include/cylinder_head_node.h | 67 +++++++++++++++ scripting/include/engine_context.h | 57 +++++++++++++ scripting/include/engine_node.h | 33 +++++--- scripting/include/function_node.h | 64 +++++++++++++++ scripting/include/rod_journal_node.h | 15 ---- scripting/src/channel_types.cpp | 10 +++ scripting/src/engine_context.cpp | 98 ++++++++++++++++++++++ scripting/src/language_rules.cpp | 13 +++ 18 files changed, 737 insertions(+), 43 deletions(-) create mode 100644 scripting/include/camshaft_node.h create mode 100644 scripting/include/cylinder_head_node.h create mode 100644 scripting/include/engine_context.h create mode 100644 scripting/include/function_node.h create mode 100644 scripting/src/engine_context.cpp diff --git a/assets/test.mr b/assets/test.mr index 9e2af6b5..6eb03433 100644 --- a/assets/test.mr +++ b/assets/test.mr @@ -14,6 +14,75 @@ c0 .add_rod_journal(rj2) .add_rod_journal(rj3) +piston_parameters piston_params( + mass: 0.0, + blowby: 0.0, + compression_height: 0.0, + wrist_pin_position: 0.0, + displacement: 0.0 +) +connecting_rod_parameters cr_params( + mass: 0.0, + moment_of_inertia: 0.0, + center_of_mass: 0.0, + length: 0.0 +) +cylinder_bank_parameters bank_params( + angle: 0.0, + bore: 0.0, + deck_height: 0.0 +) +cylinder_bank b0(bank_params, angle: 0.0) +cylinder_bank b1(bank_params, angle: 0.0) + +b0 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3 + ) + +b1 + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj0 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj1 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj2 + ) + .add_cylinder( + piston: piston(piston_params), + connecting_rod: connecting_rod(cr_params), + rod_journal: rj3 + ) + +engine + .add_cylinder_bank(b0) + .add_cylinder_bank(b1) + engine.add_crankshaft(c0) set_engine( diff --git a/dependencies/submodules/piranha b/dependencies/submodules/piranha index 3b6761c6..7dee68f4 160000 --- a/dependencies/submodules/piranha +++ b/dependencies/submodules/piranha @@ -1 +1 @@ -Subproject commit 3b6761c66d020b1156da74d00d1c288d5541633d +Subproject commit 7dee68f46444620b28c38ccf2d80a9b7d6c66ba0 diff --git a/es/actions/actions.mr b/es/actions/actions.mr index 09116df0..0393f405 100644 --- a/es/actions/actions.mr +++ b/es/actions/actions.mr @@ -36,5 +36,63 @@ public node add_crankshaft { input this; alias output out: this; - _add_crankshaft(crankshaft, this) + _add_crankshaft(crankshaft, engine: this) +} + +private node _add_cylinder_bank => __engine_sim__add_cylinder_bank { + input engine [engine]; + input cylinder_bank [cylinder_bank]; +} + +public node add_cylinder_bank { + input cylinder_bank; + input this; + alias output __out: this; + + _add_cylinder_bank(engine: this, cylinder_bank) +} + +private node _add_cylinder => __engine_sim__add_cylinder { + input piston [piston]; + input connecting_rod [connecting_rod]; + input rod_journal [rod_journal]; + input cylinder_bank [cylinder_bank]; +} + +public node add_cylinder { + input piston; + input connecting_rod; + input rod_journal; + input this; + alias output __out: this; + + _add_cylinder(piston, connecting_rod, rod_journal, cylinder_bank: this) +} + +private node _add_sample => __engine_sim__add_sample { + input x [float]; + input y [float]; + input function [function]; +} + +public node add_sample { + input x; + input y; + input this; + alias output __out: this; + + _add_sample(x: x, y: y, function: this) +} + +private node _add_lobe => __engine_sim__add_lobe { + input centerline [float]; + input camshaft [camshaft]; +} + +public node add_lobe { + input centerline; + input this; + alias output __out: this; + + _add_lobe(centerline: centerline, camshaft: this) } diff --git a/es/objects/objects.mr b/es/objects/objects.mr index 2fff7b46..dc4d09b7 100644 --- a/es/objects/objects.mr +++ b/es/objects/objects.mr @@ -14,6 +14,9 @@ public node rod_journal_channel => __engine_sim__rod_journal { /* void */ } public node connecting_rod_channel => __engine_sim__connecting_rod_channel { /* void */ } public node piston_channel => __engine_sim__piston_channel { /* void */ } public node cylinder_bank_channel => __engine_sim__cylinder_bank_channel { /* void */ } +public node function_channel => __engine_sim__function_channel { /* void */ } +public node cylinder_head_channel => __engine_sim__cylinder_head_channel { /* void */ } +public node camshaft_channel => __engine_sim__camshaft_channel { /* void */ } // Engine public node _build_engine => __engine_sim__engine { @@ -82,7 +85,7 @@ private node _connecting_rod => __engine_sim__connecting_rod { public node connecting_rod { input params: connecting_rod_parameters(); - alias output __out: + alias output __out [_connecting_rod]: _connecting_rod( mass: params.mass, moment_of_inertia: params.moment_of_inertia, @@ -122,7 +125,7 @@ private node _piston => __engine_sim__piston { public node piston { input params: piston_parameters(); - alias output __out: + alias output __out [_piston]: _piston( mass: params.mass, blowby: params.blowby, @@ -133,7 +136,7 @@ public node piston { } // Cylinder Bank -private node cylinder_bank_parameter_defaults { +public node cylinder_bank_parameter_defaults { input angle: 0.0; input bore: 0.0; input deck_height: 0.0; @@ -158,10 +161,104 @@ public node cylinder_bank { input angle: parameters.angle; input bore: parameters.bore; input deck_height: parameters.deck_height; - alias output __out: + alias output __out [_cylinder_bank]: _cylinder_bank( angle: angle, bore: bore, deck_height: deck_height ); } + +// Function +public node function => __engine_sim__function { + input filter_radius [float]: 1.0; + alias output __out [function_channel]; +} + +// Cylinder +public node cylinder_friction_parameter_defaults { + output friction_k: 0.06; + output breakaway_friction: 0.0; + output breakaway_friction_velocity: 0.0; + output viscous_friction_coefficient: 0.0; +} + +public node cylinder_friction_parameters { + input copy: cylinder_friction_parameter_defaults(); + input friction_k: copy.friction_k; + input breakaway_friction: copy.breakaway_friction; + input breakaway_friction_velocity: copy.breakaway_friction_velocity; + input viscous_friction_coefficient: copy.viscous_friction_coefficient; +} + +// Cylinder Head +public node cylinder_head_parameter_defaults { + output intake_port_flow: function(); + output exhaust_port_flow: function(); + output chamber_volume: 0.0; + output flip_display: false; +} + +public node cylinder_head_parameters { + input copy: cylinder_head_parameter_defaults(); + input intake_port_flow: copy.intake_port_flow; + input exhaust_port_flow: copy.exhaust_port_flow; + input chamber_volume: copy.chamber_volume; + input flip_display: copy.flip_display; +} + +private node _cylinder_head => __engine_sim__cylinder_head_node { + input intake_port_flow [function]; + input exhaust_port_flow [function]; + input intake_camshaft [camshaft]; + input exhaust_camshaft [camshaft]; + input chamber_volume [float]; + input flip_display [bool]; + alias output __out [cylinder_head_channel]; +} + +public node cylinder_head { + input params: cylinder_head_parameters(); + input intake_camshaft; + input exhaust_camshaft; + alias output __out [_cylinder_head]: + _cylinder_head( + intake_port_flow: params.intake_port_flow, + exhaust_port_flow: params.exhaust_port_flow, + chamber_volume: params.chamber_volume, + flip_display: params.flip_display, + intake_camshaft: intake_camshaft, + exhaust_camshaft: exhaust_camshaft + ); +} + +// Camshaft +public node camshaft_parameter_defaults { + output advance: 0.0; + output base_radius: 0.0; + output lobe_profile: function(); +} + +public node camshaft_parameters { + input copy: camshaft_parameter_defaults(); + input advance: copy.advance; + input base_radius: copy.base_radius; + input lobe_profile: copy.lobe_profile; +} + +private node _camshaft => __engine_sim__camshaft { + input advance [float]; + input base_radius [float]; + input lobe_profile [function]; + alias output __out [camshaft_channel]; +} + +public node camshaft { + input parameters: camshaft_parameters(); + alias output __out [_camshaft]: + _camshaft( + advance: parameters.advance, + base_radius: parameters.base_radius, + lobe_profile: parameters.lobe_profile + ); +} diff --git a/scripting/include/actions.h b/scripting/include/actions.h index 52a28a13..effd73fd 100644 --- a/scripting/include/actions.h +++ b/scripting/include/actions.h @@ -9,6 +9,8 @@ #include "crankshaft_node.h" #include "rod_journal_node.h" #include "cylinder_bank_node.h" +#include "function_node.h" +#include "camshaft_node.h" namespace es_script { @@ -49,8 +51,6 @@ namespace es_script { virtual void _evaluate() { readAllInputs(); - - m_crankshaft->addRodJournal(m_rodJournal); } protected: @@ -138,6 +138,56 @@ namespace es_script { CylinderBankNode *m_cylinderBank = nullptr; }; + class AddSampleNode : public Node { + public: + AddSampleNode() { /* void */ } + virtual ~AddSampleNode() { /* void */ } + + protected: + virtual void registerInputs() { + addInput("x", &m_x); + addInput("y", &m_y); + addInput("function", &m_function, InputTarget::Type::Object); + + Node::registerInputs(); + } + + virtual void _evaluate() { + readAllInputs(); + + m_function->addSample(m_x, m_y); + } + + protected: + double m_x = 0; + double m_y = 0; + FunctionNode *m_function = nullptr; + }; + + class AddLobeNode : public Node { + public: + AddLobeNode() { /* void */ } + virtual ~AddLobeNode() { /* void */ } + + protected: + virtual void registerInputs() { + addInput("centerline", &m_centerline); + addInput("camshaft", &m_camshaft, InputTarget::Type::Object); + + Node::registerInputs(); + } + + virtual void _evaluate() { + readAllInputs(); + + m_camshaft->addLobe(m_centerline); + } + + protected: + double m_centerline = 0; + CamshaftNode *m_camshaft = nullptr; + }; + } /* namespace es_script */ #endif /* ATG_ENGINE_SIM_ACTIONS_H */ diff --git a/scripting/include/camshaft_node.h b/scripting/include/camshaft_node.h new file mode 100644 index 00000000..f4e20371 --- /dev/null +++ b/scripting/include/camshaft_node.h @@ -0,0 +1,67 @@ +#ifndef ATG_ENGINE_SIM_CAMSHAFT_NODE_H +#define ATG_ENGINE_SIM_CAMSHAFT_NODE_H + +#include "object_reference_node.h" + +#include "engine_context.h" +#include "function_node.h" + +#include "engine_sim.h" + +#include +#include + +namespace es_script { + + class CamshaftNode : public ObjectReferenceNode { + public: + CamshaftNode() { /* void */ } + virtual ~CamshaftNode() { /* void */ } + + void generate( + Camshaft *camshaft, + Crankshaft *crankshaft, + EngineContext *context) const + { + Camshaft::Parameters parameters = m_parameters; + 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) { + camshaft->setLobeCenterline(i, m_lobes[i]); + } + } + + void addLobe(double lobeCenterline) { + m_lobes.push_back(lobeCenterline); + } + + protected: + virtual void registerInputs() { + addInput("advance", &m_parameters.Advance); + addInput("base_radius", &m_parameters.BaseRadius); + addInput("lobe_profile", &m_lobeProfile); + + ObjectReferenceNode::registerInputs(); + } + + virtual void _evaluate() { + setOutput(this); + + // Read inputs + readAllInputs(); + + m_parameters.Crankshaft = nullptr; + } + + Camshaft::Parameters m_parameters; + FunctionNode *m_lobeProfile = nullptr; + std::vector m_lobes; + }; + +} /* namespace es_script */ + +#endif /* ATG_ENGINE_SIM_CAMSHAFT_NODE_H */ diff --git a/scripting/include/channel_types.h b/scripting/include/channel_types.h index d64d24ae..2be12051 100644 --- a/scripting/include/channel_types.h +++ b/scripting/include/channel_types.h @@ -12,6 +12,11 @@ namespace es_script { static const piranha::ChannelType ConnectingRodChannel; static const piranha::ChannelType CylinderBankChannel; static const piranha::ChannelType PistonChannel; + static const piranha::ChannelType FunctionChannel; + static const piranha::ChannelType IntakeChannel; + static const piranha::ChannelType ExhaustChannel; + static const piranha::ChannelType CylinderHeadChannel; + static const piranha::ChannelType CamshaftChannel; }; template @@ -26,6 +31,11 @@ namespace es_script { class ConnectingRodNode; class CylinderBankNode; class PistonNode; + class FunctionNode; + class IntakeNode; + class ExhaustNode; + class CylinderHeadNode; + class CamshaftNode; #define ASSIGN_CHANNEL_TYPE(type, channel) \ template <> extern inline const piranha::ChannelType *LookupChannelType() { \ @@ -39,6 +49,11 @@ namespace es_script { ASSIGN_CHANNEL_TYPE(ConnectingRodNode, ConnectingRodChannel); ASSIGN_CHANNEL_TYPE(CylinderBankNode, CylinderBankChannel); ASSIGN_CHANNEL_TYPE(PistonNode, PistonChannel); + ASSIGN_CHANNEL_TYPE(FunctionNode, FunctionChannel); + ASSIGN_CHANNEL_TYPE(IntakeNode, IntakeChannel); + ASSIGN_CHANNEL_TYPE(ExhaustNode, ExhaustChannel); + ASSIGN_CHANNEL_TYPE(CylinderHeadNode, CylinderHeadChannel); + ASSIGN_CHANNEL_TYPE(CamshaftNode, CamshaftChannel); } /* namespace es_script */ diff --git a/scripting/include/connecting_rod_node.h b/scripting/include/connecting_rod_node.h index 9dec3f82..54514b6b 100644 --- a/scripting/include/connecting_rod_node.h +++ b/scripting/include/connecting_rod_node.h @@ -19,11 +19,12 @@ namespace es_script { void generate( ConnectingRod *connectingRod, - Crankshaft *crankshaft) const + Crankshaft *crankshaft, + int rodJournal) const { ConnectingRod::Parameters params = m_parameters; params.Crankshaft = crankshaft; - params.Journal = m_rodJournal->getJournalIndex(); + params.Journal = rodJournal; params.Piston = nullptr; connectingRod->initialize(params); @@ -50,7 +51,6 @@ namespace es_script { } ConnectingRod::Parameters m_parameters; - RodJournalNode *m_rodJournal = nullptr; }; } /* namespace es_script */ diff --git a/scripting/include/crankshaft_node.h b/scripting/include/crankshaft_node.h index a903889d..d014ff12 100644 --- a/scripting/include/crankshaft_node.h +++ b/scripting/include/crankshaft_node.h @@ -4,6 +4,7 @@ #include "object_reference_node.h" #include "rod_journal_node.h" +#include "engine_context.h" #include "engine_sim.h" @@ -18,12 +19,10 @@ namespace es_script { virtual ~CrankshaftNode() { /* void */ } void addRodJournal(RodJournalNode *rodJournal) { - rodJournal->setJournalIndex((int)m_rodJournals.size()); - rodJournal->setCrankshaft(this); m_rodJournals.push_back(rodJournal); } - void generate(Crankshaft *crankshaft) const { + void generate(Crankshaft *crankshaft, EngineContext *context) { Crankshaft::Parameters params = m_parameters; params.RodJournals = (int)m_rodJournals.size(); @@ -31,10 +30,13 @@ namespace es_script { for (int i = 0; i < params.RodJournals; ++i) { RodJournalNode *rodJournal = m_rodJournals[i]; crankshaft->setRodJournalAngle( - rodJournal->getJournalIndex(), + i, rodJournal->getAngle() ); + context->addRodJournal(rodJournal, i); } + + context->addCrankshaft(this, crankshaft); } protected: diff --git a/scripting/include/cylinder_bank_node.h b/scripting/include/cylinder_bank_node.h index 184d9f22..de0eb3f9 100644 --- a/scripting/include/cylinder_bank_node.h +++ b/scripting/include/cylinder_bank_node.h @@ -26,18 +26,49 @@ namespace es_script { CylinderBankNode() { /* void */ } virtual ~CylinderBankNode() { /* void */ } - void generate(int index, CylinderBank *cylinderBank) const { + void generate( + int index, + int cylinderBaseIndex, + CylinderBank *cylinderBank, + Crankshaft *crankshaft, + Engine *engine, + EngineContext *context) const + { CylinderBank::Parameters params = m_parameters; params.CylinderCount = (int)m_cylinders.size(); params.Index = index; cylinderBank->initialize(params); + + const int n = getCylinderCount(); + for (int i = 0; i < n; ++i) { + Piston *piston = engine->getPiston(cylinderBaseIndex + i); + ConnectingRod *rod = engine->getConnectingRod(cylinderBaseIndex + i); + + m_cylinders[i].piston->generate( + piston, + rod, + cylinderBank, + cylinderBaseIndex + 1); + m_cylinders[i].rod->generate( + rod, + crankshaft, + context->getRodJournalIndex(m_cylinders[i].rodJournal)); + } } - void addCylinder(PistonNode *piston, ConnectingRodNode *rod, RodJournalNode *rodJournal) { + void addCylinder( + PistonNode *piston, + ConnectingRodNode *rod, + RodJournalNode *rodJournal) + { m_cylinders.push_back({ piston, rod, rodJournal }); } + int getCylinderCount() const { + return (int)m_cylinders.size(); + } + protected: virtual void registerInputs() { addInput("angle", &m_parameters.Angle); diff --git a/scripting/include/cylinder_head_node.h b/scripting/include/cylinder_head_node.h new file mode 100644 index 00000000..eb13b14f --- /dev/null +++ b/scripting/include/cylinder_head_node.h @@ -0,0 +1,67 @@ +#ifndef ATG_ENGINE_SIM_CYLINDER_HEAD_NODE_H +#define ATG_ENGINE_SIM_CYLINDER_HEAD_NODE_H + +#include "object_reference_node.h" + +#include "engine_sim.h" + +#include +#include + +namespace es_script { + + class CylinderHeadNode : public ObjectReferenceNode { + public: + CylinderHeadNode() { /* void */ } + virtual ~CylinderHeadNode() { /* void */ } + + void generate(CylinderHead *head, CylinderBank *bank) const { + CylinderHead::Parameters params = m_parameters; + params.Bank = bank; + + head->initialize(params); + } + + protected: + virtual void registerInputs() { + addInput( + "intake_port_flow", + &m_parameters.IntakePortFlow, + InputTarget::Type::Object); + addInput( + "exhaust_port_flow", + &m_parameters.ExhaustPortFlow, + InputTarget::Type::Object); + addInput( + "intake_camshaft", + &m_parameters.IntakeCam, + InputTarget::Type::Object); + addInput( + "exhaust_camshaft", + &m_parameters.ExhaustCam, + InputTarget::Type::Object); + addInput("chamber_volume", &m_parameters.CombustionChamberVolume); + addInput("flip_display", &m_parameters.FlipDisplay); + + ObjectReferenceNode::registerInputs(); + } + + virtual void _evaluate() { + setOutput(this); + + // Read inputs + readAllInputs(); + + m_parameters.Bank = nullptr; + m_parameters.ExhaustCam = nullptr; + m_parameters.IntakeCam = nullptr; + m_parameters.IntakePortFlow = nullptr; + m_parameters.ExhaustPortFlow = nullptr; + } + + CylinderHead::Parameters m_parameters; + }; + +} /* namespace es_script */ + +#endif /* ATG_ENGINE_SIM_CYLINDER_HEAD_NODE_H */ diff --git a/scripting/include/engine_context.h b/scripting/include/engine_context.h new file mode 100644 index 00000000..5c78024c --- /dev/null +++ b/scripting/include/engine_context.h @@ -0,0 +1,57 @@ +#ifndef ATG_ENGINE_SIM_ENGINE_CONTEXT_H +#define ATG_ENGINE_SIM_ENGINE_CONTEXT_H + +#include "engine_sim.h" + +#include + +namespace es_script { + + class CylinderHeadNode; + class CylinderBankNode; + class CrankshaftNode; + class FunctionNode; + class ExhaustNode; + class IntakeNode; + class RodJournalNode; + + class EngineContext { + public: + EngineContext(); + ~EngineContext(); + + void addHead(CylinderHeadNode *node, CylinderHead *head); + CylinderHead *getHead(CylinderHeadNode *head); + + void addBank(CylinderBankNode *node, CylinderBank *bank); + CylinderBank *getBank(CylinderBankNode *bank) const; + + void addRodJournal(RodJournalNode *node, int index); + int getRodJournalIndex(RodJournalNode *node) const; + + void addIntake(IntakeNode *node, Intake *intake); + Intake *getIntake(IntakeNode *intake) const; + + void addExhaust(ExhaustNode *node, ExhaustSystem *exhaust); + ExhaustSystem *getExhaust(ExhaustNode *exhaust) const; + + void addFunction(FunctionNode *node, Function *function); + Function *getFunction(FunctionNode *exhaust) const; + + void addCrankshaft(CrankshaftNode *node, Crankshaft *crankshaft); + Crankshaft *getCrankshaft(CrankshaftNode *node) const; + + protected: + std::map m_heads; + std::map m_banks; + std::map m_exhaustSystems; + std::map m_intakes; + std::map m_functions; + std::map m_rodJournals; + std::map m_crankshafts; + }; + +} /* namespace es_script */ + +#endif /* ATG_ENGINE_SIM_ENGINE_CONTEXT_H */ + diff --git a/scripting/include/engine_node.h b/scripting/include/engine_node.h index c93499d8..7b75882c 100644 --- a/scripting/include/engine_node.h +++ b/scripting/include/engine_node.h @@ -5,6 +5,7 @@ #include "crankshaft_node.h" #include "cylinder_bank_node.h" +#include "engine_context.h" #include "engine_sim.h" @@ -18,17 +19,34 @@ namespace es_script { virtual ~EngineNode() { /* void */ } void buildEngine(Engine *engine) { + int cylinderCount = 0; + for (const CylinderBankNode *bank : m_cylinderBanks) { + cylinderCount += bank->getCylinderCount(); + } + + EngineContext context; Engine::Parameters parameters = m_parameters; parameters.CrankshaftCount = (int)m_crankshafts.size(); - parameters.CylinderBanks = 0; - parameters.CylinderCount = 0; + parameters.CylinderBanks = (int)m_cylinderBanks.size(); + parameters.CylinderCount = cylinderCount; parameters.ExhaustSystemCount = 0; parameters.IntakeCount = 0; engine->initialize(parameters); for (int i = 0; i < parameters.CrankshaftCount; ++i) { - m_crankshafts[i]->generate(engine->getCrankshaft(i)); + m_crankshafts[i]->generate(engine->getCrankshaft(i), &context); + } + + int cylinderIndex = 0; + for (int i = 0; i < parameters.CylinderBanks; ++i) { + m_cylinderBanks[i]->generate( + i, + cylinderIndex + i, + engine->getCylinderBank(i), + engine->getCrankshaft(0), + engine, + &context); } } @@ -58,14 +76,7 @@ namespace es_script { setOutput(this); // Read inputs - Engine::Parameters params; - params.Fuel.Density = readAtomicInput("fuel_density"); - params.Fuel.EnergyDensity = readAtomicInput("fuel_energy_density"); - params.Fuel.MolecularMass = readAtomicInput("fuel_molecular_mass"); - params.Name = readAtomicInput("name"); - params.Redline = readAtomicInput("redline"); - params.StarterSpeed = readAtomicInput("starter_speed"); - params.StarterTorque = readAtomicInput("starter_torque"); + readAllInputs(); } Engine::Parameters m_parameters; diff --git a/scripting/include/function_node.h b/scripting/include/function_node.h new file mode 100644 index 00000000..03fc0e78 --- /dev/null +++ b/scripting/include/function_node.h @@ -0,0 +1,64 @@ +#ifndef ATG_ENGINE_SIM_FUNCTION_NODE_H +#define ATG_ENGINE_SIM_FUNCTION_NODE_H + +#include "object_reference_node.h" + +#include "engine_context.h" + +#include "engine_sim.h" + +namespace es_script { + + class FunctionNode : public ObjectReferenceNode { + public: + struct Sample { + double x, y; + }; + + public: + FunctionNode() { /* void */ } + virtual ~FunctionNode() { /* void */ } + + void addSample(double x, double y) { + m_samples.push_back({ x, y }); + } + + Function *generate(EngineContext *context) { + Function *existingFunction = context->getFunction(this); + if (existingFunction != nullptr) { + return existingFunction; + } + else { + Function *function = new Function; + function->initialize((int)m_samples.size(), m_filterRadius); + + for (const Sample &sample : m_samples) { + function->addSample(sample.x, sample.y); + } + + context->addFunction(this, function); + return function; + } + } + + protected: + virtual void registerInputs() { + addInput("filter_radius", &m_filterRadius); + + ObjectReferenceNode::registerInputs(); + } + + virtual void _evaluate() { + setOutput(this); + + // Read inputs + readAllInputs(); + } + + std::vector m_samples; + double m_filterRadius = 0.0; + }; + +} /* namespace es_script */ + +#endif /* ATG_ENGINE_SIM_FUNCTION_NODE_H */ diff --git a/scripting/include/rod_journal_node.h b/scripting/include/rod_journal_node.h index b7aab75e..490a444f 100644 --- a/scripting/include/rod_journal_node.h +++ b/scripting/include/rod_journal_node.h @@ -19,18 +19,6 @@ namespace es_script { return m_angle; } - int getJournalIndex() const { - return m_journalIndex; - } - - void setJournalIndex(int index) { - m_journalIndex = index; - } - - void setCrankshaft(CrankshaftNode *crankshaft) { - m_crankshaft = crankshaft; - } - protected: virtual void registerInputs() { addInput("angle", &m_angle); @@ -45,10 +33,7 @@ namespace es_script { readAllInputs(); } - int m_journalIndex = 0; double m_angle = 0.0; - - CrankshaftNode *m_crankshaft = nullptr; }; } /* namespace es_script */ diff --git a/scripting/src/channel_types.cpp b/scripting/src/channel_types.cpp index cc821fd0..5004c28f 100644 --- a/scripting/src/channel_types.cpp +++ b/scripting/src/channel_types.cpp @@ -12,3 +12,13 @@ const piranha::ChannelType es_script::ObjectChannel::CylinderBankChannel("CylinderBankChannel"); const piranha::ChannelType es_script::ObjectChannel::PistonChannel("PistonChannel"); +const piranha::ChannelType + es_script::ObjectChannel::FunctionChannel("FunctionChannel"); +const piranha::ChannelType + es_script::ObjectChannel::IntakeChannel("IntakeChannel"); +const piranha::ChannelType + es_script::ObjectChannel::ExhaustChannel("ExhaustChannel"); +const piranha::ChannelType + es_script::ObjectChannel::CylinderHeadChannel("CylinderHeadChannel"); +const piranha::ChannelType + es_script::ObjectChannel::CamshaftChannel("CamshaftChannel"); diff --git a/scripting/src/engine_context.cpp b/scripting/src/engine_context.cpp new file mode 100644 index 00000000..2b4d63f9 --- /dev/null +++ b/scripting/src/engine_context.cpp @@ -0,0 +1,98 @@ +#include "../include/engine_context.h" + +#include "../include/cylinder_bank_node.h" + +es_script::EngineContext::EngineContext() { + /* void */ +} + +es_script::EngineContext::~EngineContext() { + /* void */ +} + +void es_script::EngineContext::addHead(CylinderHeadNode *node, CylinderHead *head) { + m_heads[node] = head; +} + +CylinderHead *es_script::EngineContext::getHead(CylinderHeadNode *head) { + auto it = m_heads.find(head); + if (it != m_heads.end()) { + return it->second; + } + else return nullptr; +} + +void es_script::EngineContext::addBank(CylinderBankNode *node, CylinderBank *bank) { + m_banks[node] = bank; +} + +CylinderBank *es_script::EngineContext::getBank(CylinderBankNode *bank) const { + auto it = m_banks.find(bank); + if (it != m_banks.end()) { + return it->second; + } + else return nullptr; +} + +void es_script::EngineContext::addRodJournal(RodJournalNode *node, int index) { + m_rodJournals[node] = index; +} + +int es_script::EngineContext::getRodJournalIndex(RodJournalNode *node) const { + auto it = m_rodJournals.find(node); + if (it != m_rodJournals.end()) { + return it->second; + } + else return -1; +} + +void es_script::EngineContext::addIntake(IntakeNode *node, Intake *intake) { + m_intakes[node] = intake; +} + +Intake *es_script::EngineContext::getIntake(IntakeNode *intake) const { + auto it = m_intakes.find(intake); + if (it != m_intakes.end()) { + return it->second; + } + else return nullptr; +} + +void es_script::EngineContext::addExhaust(ExhaustNode *node, ExhaustSystem *exhaust) { + m_exhaustSystems[node] = exhaust; +} + +ExhaustSystem *es_script::EngineContext::getExhaust(ExhaustNode *exhaust) const { + auto it = m_exhaustSystems.find(exhaust); + if (it != m_exhaustSystems.end()) { + return it->second; + } + else return nullptr; +} + +void es_script::EngineContext::addFunction(FunctionNode *node, Function *function) { + m_functions[node] = function; +} + +Function *es_script::EngineContext::getFunction(FunctionNode *exhaust) const { + auto it = m_functions.find(exhaust); + if (it != m_functions.end()) { + return it->second; + } + else return nullptr; +} + +void es_script::EngineContext::addCrankshaft( + CrankshaftNode *node, + Crankshaft *crankshaft) +{ + m_crankshafts[node] = crankshaft; +} + +Crankshaft *es_script::EngineContext::getCrankshaft(CrankshaftNode *node) const { + auto it = m_crankshafts.find(node); + if (it != m_crankshafts.end()) { + return it->second; + } + else return nullptr; +} diff --git a/scripting/src/language_rules.cpp b/scripting/src/language_rules.cpp index b4c2f5ce..1fd85e73 100644 --- a/scripting/src/language_rules.cpp +++ b/scripting/src/language_rules.cpp @@ -4,6 +4,8 @@ #include "../include/engine_node.h" #include "../include/actions.h" #include "../include/rod_journal_node.h" +#include "../include/camshaft_node.h" +#include "../include/cylinder_head_node.h" es_script::LanguageRules::LanguageRules() { /* void */ @@ -39,6 +41,12 @@ void es_script::LanguageRules::registerBuiltinNodeTypes() { "__engine_sim__piston_channel", &es_script::ObjectChannel::PistonChannel); registerBuiltinType( "__engine_sim__cylinder_bank_channel", &es_script::ObjectChannel::CylinderBankChannel); + registerBuiltinType( + "__engine_sim__function_channel", &es_script::ObjectChannel::FunctionChannel); + registerBuiltinType( + "__engine_sim__cylinder_head_channel", &es_script::ObjectChannel::CylinderHeadChannel); + registerBuiltinType( + "__engine_sim__camshaft_channel", &es_script::ObjectChannel::CamshaftChannel); // Literals registerBuiltinType( @@ -84,6 +92,8 @@ void es_script::LanguageRules::registerBuiltinNodeTypes() { registerBuiltinType("__engine_sim__add_crankshaft"); registerBuiltinType("__engine_sim__add_cylinder_bank"); registerBuiltinType("__engine_sim__add_cylinder"); + registerBuiltinType("__engine_sim__add_sample"); + registerBuiltinType("__engine_sim__add_lobe"); // Objects registerBuiltinType("__engine_sim__engine"); @@ -92,6 +102,9 @@ void es_script::LanguageRules::registerBuiltinNodeTypes() { registerBuiltinType("__engine_sim__connecting_rod"); registerBuiltinType("__engine_sim__cylinder_bank"); registerBuiltinType("__engine_sim__piston"); + registerBuiltinType("__engine_sim__function"); + registerBuiltinType("__engine_sim__cylinder_head_node"); + registerBuiltinType("__engine_sim__camshaft"); // String operations registerBuiltinType