Hmm, that didn't quite work right (#955)

* maybe that wasn't a good idea

* we don't need a copy because you can't clear the func after setting it

* no longer a template - move logic to cpp

* fix tests

* rename to avoid object collision
This commit is contained in:
Matthew Kennedy 2019-09-25 04:26:56 -07:00 committed by rusefi
parent 0a70bdf6f8
commit ee5643f1bf
8 changed files with 44 additions and 47 deletions

View File

@ -0,0 +1,26 @@
#include "functional_sensor.h"
void FunctionalSensor::postRawValue(float inputValue) {
// Report the raw value
float *rawReportLocation = m_rawReportingLocation;
if (rawReportLocation) {
*rawReportLocation = inputValue;
}
// If no function is set, this sensor isn't valid.
if (!m_function) {
invalidate();
return;
}
auto r = m_function->convert(inputValue);
// This has to happen so that we set the valid bit after
// the value is stored, to prevent the data race of reading
// an old invalid value
if (r.Valid) {
setValidValue(r.Value);
} else {
invalidate();
}
}

View File

@ -12,13 +12,6 @@
#include <type_traits>
struct FunctionalSensorBase : public StoredValueSensor {
FunctionalSensorBase(SensorType type)
: StoredValueSensor(type) {}
virtual void postRawValue(float value) = 0;
};
/**
* @brief Class for sensors that convert from some raw floating point
* value (ex: voltage, frequency, pulse width) to a sensor reading.
@ -30,46 +23,24 @@ struct FunctionalSensorBase : public StoredValueSensor {
* Register an instance of the new class with an interface
* that provides and posts raw values so the sensor can update.
*/
template <typename TFunc>
class FunctionalSensor final : public FunctionalSensorBase {
static_assert(std::is_base_of_v<SensorConverter, TFunc>, "TFunc must inherit from SensorConverter");
static_assert(std::is_default_constructible_v<TFunc>, "TFunc must be default constructible");
class FunctionalSensor final : public StoredValueSensor {
public:
explicit FunctionalSensor(SensorType type)
: FunctionalSensorBase(type) {}
: StoredValueSensor(type) { }
void postRawValue(float inputValue) {
// Report the raw value
float *rawReportLocation = m_rawReportingLocation;
if (rawReportLocation) {
*rawReportLocation = inputValue;
}
auto r = m_function.convert(inputValue);
// This has to happen so that we set the valid bit after
// the value is stored, to prevent the data race of reading
// an old invalid value
if (r.Valid) {
setValidValue(r.Value);
} else {
invalidate();
}
}
void postRawValue(float inputValue);
void setRawReportingLocation(float *rawReportingLocation) {
m_rawReportingLocation = rawReportingLocation;
}
// Allow access to the underlying function
TFunc &f() {
return m_function;
void setFunction(SensorConverter& func) {
m_function = &func;
}
private:
float *m_rawReportingLocation = nullptr;
// Conversion function for this sensor
TFunc m_function;
SensorConverter* m_function = nullptr;
};

View File

@ -11,4 +11,5 @@ CONTROLLERS_SENSORS_SRC_CPP = $(PROJECT_DIR)/controllers/sensors/thermistors.cp
$(PROJECT_DIR)/controllers/sensors/maf2map.cpp \
$(PROJECT_DIR)/controllers/sensors/hip9011_lookup.cpp \
$(PROJECT_DIR)/controllers/sensors/sensor.cpp \
$(PROJECT_DIR)/controllers/sensors/functional_sensor.cpp \
$(PROJECT_DIR)/controllers/sensors/converters/linear_func.cpp

View File

@ -10,7 +10,7 @@ EXTERN_ENGINE;
#if !EFI_UNIT_TEST
struct AdcSubscriptionEntry {
FunctionalSensorBase *Sensor;
FunctionalSensor *Sensor;
float VoltsPerAdcVolt;
adc_channel_e Channel;
};
@ -18,7 +18,7 @@ struct AdcSubscriptionEntry {
static size_t s_nextEntry = 0;
static AdcSubscriptionEntry s_entries[8];
void AdcSubscription::SubscribeSensor(FunctionalSensorBase &sensor,
void AdcSubscription::SubscribeSensor(FunctionalSensor &sensor,
adc_channel_e channel,
float voltsPerAdcVolt /*= 0.0f*/) {
// Don't subscribe null channels

View File

@ -9,6 +9,6 @@
class AdcSubscription {
public:
static void SubscribeSensor(FunctionalSensorBase &sensor, adc_channel_e channel, float voltsPerAdcVolt = 0.0f);
static void SubscribeSensor(FunctionalSensor &sensor, adc_channel_e channel, float voltsPerAdcVolt = 0.0f);
static void UpdateSubscribers();
};

View File

@ -10,7 +10,8 @@ EXTERN_ENGINE;
extern TunerStudioOutputChannels tsOutputChannels;
FunctionalSensor<LinearFunc> oilpSensor(SensorType::OilPressure);
LinearFunc oilpSensorFunc;
FunctionalSensor oilpSensor(SensorType::OilPressure);
void initOilPressure() {
// Only register if we have a sensor
@ -29,7 +30,8 @@ void initOilPressure() {
float greaterOutput = val1 > val2 ? val1 : val2;
// Allow slightly negative output (-5kpa) so as to not fail the sensor when engine is off
oilpSensor.f().configure(sensorCfg->v1, val1, sensorCfg->v2, val2, /*minOutput*/ -5, greaterOutput);
oilpSensorFunc.configure(sensorCfg->v1, val1, sensorCfg->v2, val2, /*minOutput*/ -5, greaterOutput);
oilpSensor.setFunction(oilpSensorFunc);
// Tell it to report to its output channel
oilpSensor.setReportingLocation(&tsOutputChannels.oilPressure);

View File

@ -17,6 +17,7 @@ protected:
: dut(SensorType::Clt) {}
void SetUp() override {
dut.setFunction(func);
Sensor::resetRegistry();
}
@ -24,7 +25,8 @@ protected:
Sensor::resetRegistry();
}
FunctionalSensor<DoublerFunc> dut;
FunctionalSensor dut;
DoublerFunc func;
};
TEST_F(SensorConverted, TestValid) {
@ -64,8 +66,3 @@ TEST_F(SensorConverted, TestInvalid) {
EXPECT_FLOAT_EQ(s.Value, 0);
}
}
TEST_F(SensorConverted, TestGet) {
// we're only checking that this compiles
DoublerFunc &f = dut.f();
}

View File

@ -29,7 +29,7 @@ TESTS_SRC_CPP = \
tests/test_gpiochip.cpp \
\
tests/sensor/basic_sensor.cpp \
tests/sensor/functional_sensor.cpp \
tests/sensor/func_sensor.cpp \
tests/sensor/function_pointer_sensor.cpp \
tests/sensor/mock_sensor.cpp \
tests/sensor/sensor_reader.cpp \