rusEFI
The most advanced open source ECU
sensor.h
Go to the documentation of this file.
1 /**
2  * @file sensor.h
3  * @brief Base class for sensors. Inherit this class to implement a new type of sensor.
4  *
5  * This file defines the basis for all sensor inputs to the ECU, and provides a registry
6  * so that consumers may be agnostic to how each sensor may work.
7  *
8  * HOW TO ADD A NEW SENSOR TYPE:
9  *
10  * 1. Add an entry to the enum in sensor_type.h. Be sure to add it ABOVE the placeholder
11  * at the end of the list.
12  *
13  * 2. In the init/sensor folder, create/modify logic to create an instance of the new sensor,
14  * configure it if necessary, and call its Register() function if it should be enabled.
15  * See init_oil_pressure.cpp for a minimal example.
16  *
17  * 3. Consume the new sensor with instance(s) of SensorConsumer<SensorType::MyNewSensor>
18  *
19  * Consumers:
20  *
21  * tl;dr: Use a SensorConsumer. See sensor_consumer.h
22  *
23  * All a consumer does is look up whether a particular sensor is present in the table,
24  * and if so, asks it for the current reading. This could synchronously perform sensor
25  * acquisition and conversion (not recommended), or use a previously stored value (recommended!).
26  * This functionality is implemented in sensor_consumer.h, and sensor.cpp.
27  *
28  * Providers:
29  * Instantiate a subclass of Sensor, and implement the Get() function.
30  * Call Register() to install the new sensor in the registry, preparing it for use.
31  *
32  * Mocking:
33  * The sensor table supports mocking each sensors value. Call Sensor::SetMockValue to
34  * set a mock value for a particular sensor, and Sensor::ResetMockValue or
35  * Sensor::ResetAllMocks to reset one or all stored mock values.
36  *
37  * Composite Sensors:
38  * Some sensors may be implemented as composite sensors, ie sensors that depend on other
39  * sensors to determine their reading. For example, the throttle pedal may have a pair of
40  * potentiometers that provide redundancy for the pedal's position. Each one may be its
41  * own sensor, then with one "master" sensors that combines the results of the others, and
42  * provides validation of whether the readings agree.
43  *
44  * @date September 12, 2019
45  * @author Matthew Kennedy, (c) 2019
46  */
47 
48 #pragma once
49 
50 #include "sensor_type.h"
51 #include <rusefi/expected.h>
52 
53 #include <cstddef>
54 
55 using SensorResult = expected<float>;
56 
57 // Fwd declare - nobody outside of Sensor.cpp needs to see inside this type
58 class SensorRegistryEntry;
59 
60 class Sensor {
61 public:
62  // Register this sensor in the sensor registry.
63  // Returns true if registration succeeded, or false if
64  // another sensor of the same type is already registered.
65  bool Register();
66 
67  // Print information about this sensor
68  virtual void showInfo(const char* sensorName) const = 0;
69 
70  // Print information about all sensors
71  static void showAllSensorInfo();
72 
73  // Print information about a particular sensor
74  static void showInfo(SensorType type);
75 
76  // Remove all sensors from the sensor registry - tread carefully if you use this outside of a unit test
77  static void resetRegistry();
78 
79  /*
80  * Static helper for sensor lookup
81  */
82  static const Sensor *getSensorOfType(SensorType type);
83 
84  /*
85  * Get a reading from the specified sensor.
86  */
88 
89  /*
90  * Get a reading from the specified sensor, or zero if unavailable.
91  */
92  static float getOrZero(SensorType type) {
93  return Sensor::get(type).value_or(0);
94  }
95 
96  /*
97  * Get a raw (unconverted) value from the sensor, if available.
98  */
99  static float getRaw(SensorType type);
100 
101  /*
102  * Get whether a sensor is redundant (a composite of multiple other sensors that can check consistency between them)
103  */
104  static bool isRedundant(SensorType type);
105 
106  /*
107  * Query whether there is a sensor of a particular type currently registered.
108  */
109  static bool hasSensor(SensorType type);
110 
111  /*
112  * Mock a value for a particular sensor.
113  */
114  static void setMockValue(SensorType type, float value, bool mockRedundant = false);
115 
116 
117  static void setInvalidMockValue(SensorType type);
118 
119  /*
120  * Mock a value for a particular sensor.
121  */
122  static void setMockValue(int type, float value);
123 
124  /*
125  * Reset mock for a particular sensor.
126  */
127  static void resetMockValue(SensorType type);
128 
129  /*
130  * Reset mocking for all sensors.
131  */
132  static void resetAllMocks();
133 
134  /*
135  * Inhibit sensor timeouts. Used if you're doing something that will block sensor updates, such as
136  * erasing flash memory (which stalls the CPU on some MCUs)
137  */
138  static void inhibitTimeouts(bool inhibit);
139 
140  /*
141  * Get a friendly name for the sensor.
142  * For example, CLT, IAT, Throttle Position 2, etc.
143  */
144  const char* getSensorName() const { return getSensorName(m_type); }
145  static const char* getSensorName(SensorType type);
146 
147  // Retrieve the current reading from the sensor.
148  //
149  // Override this in a particular sensor's implementation. As reading sensors is in many hot paths,
150  // it is unwise to synchronously read the sensor or do anything otherwise costly here. At the most,
151  // this should be field lookup and simple math.
152  virtual SensorResult get() const = 0;
153 
154  // Retrieve whether the sensor is present. Some sensors may be registered but not present, i.e. if initialization failed.
155  virtual bool hasSensor() const {
156  return true;
157  }
158 
159  /*
160  * Get an unconverted value from the sensor, if available.
161  */
162  virtual float getRaw() const {
163  return 0;
164  }
165 
166  /*
167  * Get whether this sensor is redundant (backed by multiple other sensors)
168  */
169  virtual bool isRedundant() const {
170  // By default sensors are not redundant
171  return false;
172  }
173 
174  void unregister();
175 
176  SensorType type() const {
177  return m_type;
178  }
179 
180 protected:
181  // Protected constructor - only subclasses call this
183  : m_type(type) {}
184 
186 
187 private:
189 
190  // Get this sensor's index in the list
191  constexpr size_t getIndex() {
192  return getIndex(m_type);
193  }
194 
195  // Get the index in the list for a sensor of particular type
196  static constexpr size_t getIndex(SensorType type) {
197  return static_cast<size_t>(type);
198  }
199 
200  /*
201  * Static helper for sensor lookup
202  */
203  static SensorRegistryEntry *getEntryForType(SensorType type);
204 };
205 
206 SensorType findSensorTypeByName(const char *name);
Definition: sensor.h:60
const SensorType m_type
Definition: sensor.h:188
static void setMockValue(SensorType type, float value, bool mockRedundant=false)
Definition: sensor.cpp:203
static void resetMockValue(SensorType type)
Definition: sensor.cpp:220
Sensor(SensorType type)
Definition: sensor.h:182
static SensorRegistryEntry * getEntryForType(SensorType type)
Definition: sensor.cpp:148
bool Register()
Definition: sensor.cpp:131
static void setInvalidMockValue(SensorType type)
Definition: sensor.cpp:195
static constexpr size_t getIndex(SensorType type)
Definition: sensor.h:196
virtual bool hasSensor() const
Definition: sensor.h:155
static const Sensor * getSensorOfType(SensorType type)
Definition: sensor.cpp:158
virtual SensorResult get() const =0
virtual bool isRedundant() const
Definition: sensor.h:169
virtual float getRaw() const
Definition: sensor.h:162
static void showAllSensorInfo()
Definition: sensor.cpp:246
virtual void showInfo(const char *sensorName) const =0
static void inhibitTimeouts(bool inhibit)
Definition: sensor.cpp:241
static float getOrZero(SensorType type)
Definition: sensor.h:92
static void resetAllMocks()
Definition: sensor.cpp:228
static void resetRegistry()
Definition: sensor.cpp:139
static bool s_inhibitSensorTimeouts
Definition: sensor.h:185
SensorType type() const
Definition: sensor.h:176
void unregister()
Definition: sensor.cpp:135
constexpr size_t getIndex()
Definition: sensor.h:191
const char * getSensorName() const
Definition: sensor.h:144
SensorType findSensorTypeByName(const char *name)
Definition: sensor.cpp:268
expected< float > SensorResult
Definition: sensor.h:55
Enumeration of sensors supported by the ECU.
SensorType
Definition: sensor_type.h:18