From c7ca1b2ef4eb234ce3a4c27df96f1c61fcd7e52f Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Mon, 18 Jan 2021 15:31:06 -0800 Subject: [PATCH] Save more space in the angle cache (#2228) * store event angles in a scaled field * tests * comment --- .../trigger/decoders/trigger_structure.h | 9 ++++++++- unit_tests/tests/test_fuel_map.cpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/firmware/controllers/trigger/decoders/trigger_structure.h b/firmware/controllers/trigger/decoders/trigger_structure.h index 5e59ae30bf..922ce407d4 100644 --- a/firmware/controllers/trigger/decoders/trigger_structure.h +++ b/firmware/controllers/trigger/decoders/trigger_structure.h @@ -13,6 +13,7 @@ #include "engine_ptr.h" #include "state_sequence.h" #include "engine_configuration_generated_structures.h" +#include "scaled_channel.h" #define FOUR_STROKE_ENGINE_CYCLE 720 @@ -304,11 +305,17 @@ private: class TriggerFormDetails { public: TriggerFormDetails(); + /** * These angles are in event coordinates - with synchronization point located at angle zero. * These values are pre-calculated for performance reasons. + * + * This is stored in 1/64th degree units to save space (only 2 bytes vs. 4 byte float) + * 720 (deg) * 64 = ~46000, so no risk of overflowing when storing a full engine cycle. + * Most triggers actually have integer angles for all teeth, so exactly zero information is lost in that case. */ - angle_t eventAngles[PWM_PHASE_MAX_COUNT]; + scaled_channel eventAngles[PWM_PHASE_MAX_COUNT]; + /** * this cache allows us to find a close-enough (with one degree precision) trigger wheel index by * given angle with fast constant speed. That's a performance optimization for event scheduling. diff --git a/unit_tests/tests/test_fuel_map.cpp b/unit_tests/tests/test_fuel_map.cpp index ffcee5af32..d7bfcc3b0f 100644 --- a/unit_tests/tests/test_fuel_map.cpp +++ b/unit_tests/tests/test_fuel_map.cpp @@ -144,9 +144,9 @@ TEST(misc, testAngleResolver) { TriggerFormDetails *triggerFormDetails = &engine->triggerCentral.triggerFormDetails; engine->initializeTriggerWaveform(NULL PASS_ENGINE_PARAMETER_SUFFIX); - assertEqualsM("index 2", 52.76, triggerFormDetails->eventAngles[3]); // this angle is relation to synch point + assertEqualsM("index 2", 52.75, triggerFormDetails->eventAngles[3]); // this angle is relation to synch point assertEqualsM("time 2", 0.3233, ts->wave.getSwitchTime(2)); - assertEqualsM("index 5", 412.76, triggerFormDetails->eventAngles[6]); + assertEqualsM("index 5", 412.75, triggerFormDetails->eventAngles[6]); assertEqualsM("time 5", 0.5733, ts->wave.getSwitchTime(5)); ASSERT_EQ(4, ts->getTriggerWaveformSynchPointIndex()); @@ -158,32 +158,32 @@ TEST(misc, testAngleResolver) { printf("*************************************************** testAngleResolver 0\r\n"); findTriggerPosition(&ENGINE(triggerCentral.triggerShape), &ENGINE(triggerCentral.triggerFormDetails),&injectionStart, -122, engineConfiguration->globalTriggerAngleOffset); ASSERT_EQ( 2, injectionStart.triggerEventIndex) << "eventIndex@0"; - ASSERT_NEAR(0.24, injectionStart.angleOffsetFromTriggerEvent, EPS5D); + ASSERT_NEAR(0.25, injectionStart.angleOffsetFromTriggerEvent, EPS5D); printf("*************************************************** testAngleResolver 0.1\r\n"); findTriggerPosition(&ENGINE(triggerCentral.triggerShape), &ENGINE(triggerCentral.triggerFormDetails),&injectionStart, -80, engineConfiguration->globalTriggerAngleOffset); ASSERT_EQ( 2, injectionStart.triggerEventIndex) << "eventIndex@0"; - ASSERT_FLOAT_EQ(42.24, injectionStart.angleOffsetFromTriggerEvent); + ASSERT_FLOAT_EQ(42.25, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 0.2\r\n"); findTriggerPosition(&ENGINE(triggerCentral.triggerShape), &ENGINE(triggerCentral.triggerFormDetails),&injectionStart, -54, engineConfiguration->globalTriggerAngleOffset); ASSERT_EQ( 2, injectionStart.triggerEventIndex) << "eventIndex@0"; - ASSERT_FLOAT_EQ(68.2400, injectionStart.angleOffsetFromTriggerEvent); + ASSERT_FLOAT_EQ(68.25, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 0.3\r\n"); findTriggerPosition(&ENGINE(triggerCentral.triggerShape), &ENGINE(triggerCentral.triggerFormDetails),&injectionStart, -53, engineConfiguration->globalTriggerAngleOffset); ASSERT_EQ(2, injectionStart.triggerEventIndex); - ASSERT_FLOAT_EQ(69.24, injectionStart.angleOffsetFromTriggerEvent); + ASSERT_FLOAT_EQ(69.25, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 1\r\n"); findTriggerPosition(&ENGINE(triggerCentral.triggerShape), &ENGINE(triggerCentral.triggerFormDetails),&injectionStart, 0, engineConfiguration->globalTriggerAngleOffset); ASSERT_EQ(2, injectionStart.triggerEventIndex); - ASSERT_FLOAT_EQ(122.24, injectionStart.angleOffsetFromTriggerEvent); + ASSERT_FLOAT_EQ(122.25, injectionStart.angleOffsetFromTriggerEvent); printf("*************************************************** testAngleResolver 2\r\n"); findTriggerPosition(&ENGINE(triggerCentral.triggerShape), &ENGINE(triggerCentral.triggerFormDetails),&injectionStart, 56, engineConfiguration->globalTriggerAngleOffset); ASSERT_EQ(2, injectionStart.triggerEventIndex); - ASSERT_FLOAT_EQ(178.24, injectionStart.angleOffsetFromTriggerEvent); + ASSERT_FLOAT_EQ(178.25, injectionStart.angleOffsetFromTriggerEvent); TriggerWaveform t; confgiureFordAspireTriggerWaveform(&t);