diff --git a/firmware/CHANGELOG.md b/firmware/CHANGELOG.md index bfa694b354..269a02c0e7 100644 --- a/firmware/CHANGELOG.md +++ b/firmware/CHANGELOG.md @@ -27,6 +27,9 @@ All notable user-facing or behavior-altering changes will be documented in this ## Month 202x Release - "Release Name" +## Added + - Improved vehicle speed sensor configuration: now uses real physical constants about tires, gear ratio, sensor, etc. + ### Fixed - Faster engine sync + startup on engines with crank-speed primary trigger diff --git a/firmware/config/engines/mazda_miata_vvt.cpp b/firmware/config/engines/mazda_miata_vvt.cpp index c61c447b15..daa6b22087 100644 --- a/firmware/config/engines/mazda_miata_vvt.cpp +++ b/firmware/config/engines/mazda_miata_vvt.cpp @@ -687,12 +687,12 @@ void setMiataNB2_Proteus_TCU() { // "VR 1" engineConfiguration->triggerInputPins[0] = GPIOE_7; - engineConfiguration->vehicleSpeedCoef = 1; // "VR 2" engineConfiguration->vehicleSpeedSensorInputPin = GPIOE_8; - - + engineConfiguration->driveWheelRevPerKm = 544; // 205/50R15 + engineConfiguration->vssGearRatio = 4.3; + engineConfiguration->vssToothCount = 22; // "Highside 2" engineConfiguration->tcu_solenoid[0] = GPIOA_8; diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index 272a865667..ee7f77d6c8 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -697,8 +697,9 @@ static void setDefaultEngineConfiguration() { engineConfiguration->isAlternatorControlEnabled = false; - engineConfiguration->vehicleSpeedCoef = 1.0f; - + engineConfiguration->driveWheelRevPerKm = 500; + engineConfiguration->vssGearRatio = 3.73; + engineConfiguration->vssToothCount = 21; engineConfiguration->mapErrorDetectionTooLow = 5; engineConfiguration->mapErrorDetectionTooHigh = 250; diff --git a/firmware/controllers/sensors/converters/vehicle_speed_converter.h b/firmware/controllers/sensors/converters/vehicle_speed_converter.h index 1dc9e2c3c2..f152faa626 100644 --- a/firmware/controllers/sensors/converters/vehicle_speed_converter.h +++ b/firmware/controllers/sensors/converters/vehicle_speed_converter.h @@ -4,7 +4,20 @@ class VehicleSpeedConverter : public SensorConverter { public: SensorResult convert(float frequency) const override { - auto speed = frequency * engineConfiguration->vehicleSpeedCoef; - return speed; + auto vssRevPerKm = engineConfiguration->driveWheelRevPerKm * engineConfiguration->vssGearRatio; + + auto pulsePerKm = (vssRevPerKm * engineConfiguration->vssToothCount); + + if (pulsePerKm == 0) { + // avoid div by 0 + return 0; + } + + auto kmPerPulse = 1 / pulsePerKm; + + // 1 pulse 3600 sec 1 km km + // --------- * ---------- * --------- = ---- + // sec 1 hr 1 pulse hr + return frequency * 3600 * kmPerPulse; } }; diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index f7c46c926f..bdc12178db 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -1143,11 +1143,8 @@ static void setValue(const char *paramStr, const char *valueStr) { currentI++; } - - if (strEqualCaseInsensitive(paramStr, "vsscoeff")) { - engineConfiguration->vehicleSpeedCoef = valueF; #if EFI_ALTERNATOR_CONTROL - } else if (strEqualCaseInsensitive(paramStr, "alt_t")) { + if (strEqualCaseInsensitive(paramStr, "alt_t")) { if (valueI > 10) { engineConfiguration->alternatorControl.periodMs = valueI; } @@ -1156,14 +1153,9 @@ static void setValue(const char *paramStr, const char *valueStr) { engineConfiguration->alternatorControl.offset = valueI; } else if (strEqualCaseInsensitive(paramStr, "alt_p")) { setAltPFactor(valueF); + } else #endif /* EFI_ALTERNATOR_CONTROL */ -// } else if (strEqualCaseInsensitive(paramStr, "cranking_rpm")) { -// } else if (strEqualCaseInsensitive(paramStr, "cranking_rpm")) { -// } else if (strEqualCaseInsensitive(paramStr, "cranking_rpm")) { -// } else if (strEqualCaseInsensitive(paramStr, "cranking_rpm")) { -// } else if (strEqualCaseInsensitive(paramStr, "cranking_rpm")) { -// } else if (strEqualCaseInsensitive(paramStr, "cranking_rpm")) { - } else if (strEqualCaseInsensitive(paramStr, "warning_period")) { + if (strEqualCaseInsensitive(paramStr, "warning_period")) { engineConfiguration->warningPeriod = valueI; } else if (strEqualCaseInsensitive(paramStr, "dwell")) { setConstantDwell(valueF); diff --git a/firmware/hw_layer/digital_input/digital_input_exti.cpp b/firmware/hw_layer/digital_input/digital_input_exti.cpp index 6b169372ed..fcd5fd9162 100644 --- a/firmware/hw_layer/digital_input/digital_input_exti.cpp +++ b/firmware/hw_layer/digital_input/digital_input_exti.cpp @@ -68,12 +68,13 @@ void efiExtiEnablePin(const char *msg, brain_pin_e brainPin, uint32_t mode, Exti return; } - ioline_t line = PAL_LINE(port, index); - palEnableLineEvent(line, mode); - channel.Name = msg; channel.Callback = cb; channel.CallbackData = cb_data; + channel.Timestamp = 0; + + ioline_t line = PAL_LINE(port, index); + palEnableLineEvent(line, mode); } void efiExtiDisablePin(brain_pin_e brainPin) @@ -101,6 +102,7 @@ void efiExtiDisablePin(brain_pin_e brainPin) palDisableLineEvent(line); /* mark unused */ + channel.Timestamp = 0; channel.Name = nullptr; channel.Callback = nullptr; channel.CallbackData = nullptr; diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 0ba63d9567..8c7b57958c 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -534,8 +534,7 @@ float vbattDividerCoeff;+This is the ratio of the resistors for the battery volt float fanOnTemperature;+Cooling fan turn-on temperature threshold, in Celsius;"deg C", 1, 0, 0, 150, 0 float fanOffTemperature;+Cooling fan turn-off temperature threshold, in Celsius;"deg C", 1, 0, 0, 150, 0 - -float vehicleSpeedCoef;+This coefficient translates vehicle speed input frequency (in Hz) into vehicle speed, km/h;"coef", 1, 0, 0.01, 2000, 2 +float driveWheelRevPerKm;Number of revolutions per kilometer for the wheels your vehicle speed sensor is connected to. Use an online calculator to determine this based on your tire size.;"revs/km", 1, 0, 100, 1000, 1 custom can_nbc_e 4 bits, U32, @OFFSET@, [0:4], "None", "FIAT", "VAG", "MAZDA RX8", "BMW", "W202", "BMW E90", "Haltech", "VAG MQB", "Nissan VQ35", "Genesis Coupe", "Honda K", "type 12", "type 13", "type 14", "INVALID" can_nbc_e canNbcType;set can_mode X @@ -638,8 +637,11 @@ uint8_t knockRetardAggression;+Ignition timing to remove when a knock event occu uint8_t knockRetardReapplyRate;+After a knock event, reapply timing at this rate.;"deg/s", 0.1, 0, 0, 10, 1 uint8_t knockRetardMaximum;+Maximum amount of knock retard.;"deg", 1, 0, 0, 30, 0 -uint8_t mapCamDetectionThreshold;;"", 1, 0, 0, 240, 0 -float unused616;;"", 1, 0, 0, 1, 0 + uint8_t mapCamDetectionThreshold;;"", 1, 0, 0, 240, 0 + uint16_t autoscale vssGearRatio;Number of turns of your vehicle speed sensor per turn of the wheels. For example if your sensor is on the transmission output, enter your axle/differential ratio. If you are using a hub-mounted sensor, enter a value of 1.0.; "ratio", 0.001, 0, 0, 60, 3 + uint8_t vssToothCount;Number of pulses output per revolution of the shaft where your VSS is mounted. For example, GM applications of the T56 output 17 pulses per revolution of the transmission output shaft.;"count", 1, 0, 1, 100, 0 + uint8_t unusedNearVss;;"", 1, 0, 0, 1, 0 + ! todo: rename to triggerSimulatorRpm int triggerSimulatorFrequency;+Same RPM is used for two ways of producing simulated RPM. See also triggerSimulatorPins (with wires)\nSee also directSelfStimulation (no wires, bypassing input hardware)\nrpm X\nTODO: rename to triggerSimulatorRpm;"Rpm", 1, 0, 0, 30000, 0 diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 6d41bb0e53..1d97d35a95 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -3166,7 +3166,9 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" dialog = speedSensorAnalog field = "Input pin", vehicleSpeedSensorInputPin - field = "revolution to speed mult", vehicleSpeedCoef + field = "Wheel revolutions per kilometer", driveWheelRevPerKm + field = "Speed sensor gear ratio", vssGearRatio + field = "Speed sensor tooth count", vssToothCount dialog = speedSensorCan field = "Vss Car Type", canVssNbcType, { enableCanVss } diff --git a/java_console/autotest/src/main/java/com/rusefi/f4discovery/VssHardwareLoopTest.java b/java_console/autotest/src/main/java/com/rusefi/f4discovery/VssHardwareLoopTest.java index 0e8b657009..75caeeadce 100644 --- a/java_console/autotest/src/main/java/com/rusefi/f4discovery/VssHardwareLoopTest.java +++ b/java_console/autotest/src/main/java/com/rusefi/f4discovery/VssHardwareLoopTest.java @@ -29,24 +29,27 @@ public class VssHardwareLoopTest extends RusefiTestBase { @Test public void test() { ecu.setEngineType(engine_type_e.FRANKENSO_MIATA_NA6_MAP); - ecu.sendCommand(getEnableCommand(Fields.CMD_EXTERNAL_STIMULATION)); - ecu.changeRpm(1400); + ecu.changeRpm(1000); - // moving second trigger to another pin - ecu.sendCommand(CMD_TRIGGER_PIN + " 1 PA8"); + ecu.sendCommand(CMD_TRIGGER_SIMULATOR_PIN + " 0 none"); + ecu.sendCommand(CMD_TRIGGER_SIMULATOR_PIN + " 1 none"); + ecu.sendCommand(CMD_TRIGGER_PIN + " 1 none"); + + // Hook up 1khz idle on formerly-trigger-stim pin + ecu.sendCommand(CMD_IDLE_PIN + " PD2"); + ecu.sendCommand("set idle_solenoid_freq 1000"); EcuTestHelper.assertSomewhatClose("VSS no input", 0, SensorCentral.getInstance().getValue(Sensor.VSS)); - // attaching VSS to trigger simulator since there is a jumper on test discovery + // attaching VSS to idle output since there is a jumper on test discovery ecu.sendCommand("set " + CMD_VSS_PIN + " pa5"); sleep(2 * Timeouts.SECOND); - EcuTestHelper.assertSomewhatClose("VSS with input", 3, SensorCentral.getInstance().getValue(Sensor.VSS)); + EcuTestHelper.assertSomewhatClose("VSS with input", 92, SensorCentral.getInstance().getValue(Sensor.VSS)); // not related to VSS test, just need to validate this somewhere, so this random test is as good as any if (ControllerConnectorState.firmwareVersion == null) throw new IllegalStateException("firmwareVersion has not arrived"); } - } diff --git a/java_console/models/src/main/java/com/rusefi/core/Sensor.java b/java_console/models/src/main/java/com/rusefi/core/Sensor.java index 0c276a31a8..1afca6dafc 100644 --- a/java_console/models/src/main/java/com/rusefi/core/Sensor.java +++ b/java_console/models/src/main/java/com/rusefi/core/Sensor.java @@ -27,7 +27,7 @@ public enum Sensor { // RPM, vss RPM(GAUGE_NAME_RPM, SensorCategory.SENSOR_INPUTS, FieldType.UINT16, 4, 1, 0, 8000, "RPM"), SPEED2RPM("SpeedToRpm", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 6, 1.0 / PACK_MULT_PERCENT, 0, 5, "RPM/kph"), - VSS(GAUGE_NAME_VVS, SensorCategory.OPERATIONS, FieldType.UINT8, 8, 1, 0, 150, "kph"), + VSS(GAUGE_NAME_VVS, SensorCategory.OPERATIONS, FieldType.UINT8, 10, 1, 0, 150, "kph"), // Temperatures INT_TEMP(GAUGE_NAME_CPU_TEMP, SensorCategory.OPERATIONS, FieldType.INT8, 11, 1, 0, 5, "C"), diff --git a/unit_tests/tests/sensor/test_vehicle_speed_converter.cpp b/unit_tests/tests/sensor/test_vehicle_speed_converter.cpp index 39a874d17e..a4251af732 100644 --- a/unit_tests/tests/sensor/test_vehicle_speed_converter.cpp +++ b/unit_tests/tests/sensor/test_vehicle_speed_converter.cpp @@ -1,73 +1,53 @@ #include "pch.h" #include "vehicle_speed_converter.h" -static constexpr engine_type_e ENGINE_TEST_HELPER = TEST_ENGINE; +#define EXPECT_NEAR_M3(x, y) EXPECT_NEAR((x), (y), 1e-3) -class VehicleSpeedConverterTest : public ::testing::Test { +float GetVssFor(float revPerKm, float axle, float teeth, float hz) { + EngineTestHelper eth(TEST_ENGINE); -public: - EngineTestHelper eth; VehicleSpeedConverter dut; - VehicleSpeedConverterTest() : eth(ENGINE_TEST_HELPER) { - } + engineConfiguration->driveWheelRevPerKm = revPerKm; + engineConfiguration->vssGearRatio = axle; + engineConfiguration->vssToothCount = teeth; - void SetUp() override { - } - - void SetCoef(float new_coef) { - engineConfiguration->vehicleSpeedCoef = new_coef; - } - - float GetFrequencyBySpeedAndCoef(float speed, float coef) { - return (speed / coef); - } - - void TestForSpeedWithCoef(float expectedSpeed, float coef) - { - SetCoef(coef); - auto inputFreq = GetFrequencyBySpeedAndCoef(expectedSpeed, coef); - auto result = dut.convert(inputFreq); - ASSERT_TRUE(result.Valid); - ASSERT_NEAR(expectedSpeed, result.Value, 0.01f); - } -}; - -/* - * Converter must return valid and expected result for setted coef - */ -TEST_F(VehicleSpeedConverterTest, returnExpectedResultForSettedCoef) { - - TestForSpeedWithCoef(0.0f, 0.5f); - TestForSpeedWithCoef(0.5f, 0.5f); - TestForSpeedWithCoef(10.0f, 0.5f); - TestForSpeedWithCoef(0.0f, 10.0f); - TestForSpeedWithCoef(0.5f, 10.0f); - TestForSpeedWithCoef(10.0f, 10.0f); + return dut.convert(hz).value_or(-1); } -/* - * Converter must always return strong float zero if coef == 0.0f - */ -TEST_F(VehicleSpeedConverterTest, zeroCoefReturnsZeroSpeedOnAnyInput) { - - SetCoef(0.0f); +TEST(VehicleSpeed, FakeCases) { + // 0hz -> 0kph + EXPECT_NEAR_M3(0, GetVssFor(500, 5, 10, 0)); - { - auto result = dut.convert(0.0f); - ASSERT_TRUE(result.Valid); - ASSERT_FLOAT_EQ(0.0f, result.Value); - } + // 1000hz -> 144 kph + EXPECT_NEAR_M3(144, GetVssFor(500, 5, 10, 1000)); - { - auto result = dut.convert(0.5f); - ASSERT_TRUE(result.Valid); - ASSERT_FLOAT_EQ(0.0f, result.Value); - } + // Half size tires -> half speed + EXPECT_NEAR_M3(72, GetVssFor(1000, 5, 10, 1000)); - { - auto result = dut.convert(10.0f); - ASSERT_TRUE(result.Valid); - ASSERT_FLOAT_EQ(0.0f, result.Value); - } + // Double the axle ratio -> half the speed + EXPECT_NEAR_M3(72, GetVssFor(500, 10, 10, 1000)); + + // Twice as many teeth -> half speed + EXPECT_NEAR_M3(72, GetVssFor(500, 5, 20, 1000)); +} + +TEST(VehicleSpeed, RealCases) { + // V8 Volvo + // 205/50R16 tire -> 521 rev/km + // 3.73 axle ratio + // 17 tooth speedo gear + EXPECT_NEAR_M3(108.970f, GetVssFor(521, 3.73, 17, 1000)); + + // NB miata + // 205/50R15 tire -> 544 rev/km + // 4.3 axle ratio + // 21 tooth speedo gear + EXPECT_NEAR_M3(73.285f, GetVssFor(544, 4.3, 21, 1000)); + + // Some truck with ABS sensors + // 265/65R18 tire -> 391 rev/km + // 1.0 ratio because ABS sensors are hub mounted + // 48 tooth abs sensor + EXPECT_NEAR_M3(191.816f, GetVssFor(391, 1, 48, 1000)); }