rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
init_tps.cpp
Go to the documentation of this file.
1#include "pch.h"
2
3#include "adc_subscription.h"
4#include "functional_sensor.h"
5#include "redundant_sensor.h"
7#include "proxy_sensor.h"
8#include "linear_func.h"
9#include "tps.h"
11#include "defaults.h"
12
13struct TpsConfig {
15 float closed;
16 float open;
17 float min;
18 float max;
19};
20
21PUBLIC_API_WEAK float getFuncPairAllowedSplit() {
22 return 0.5f;
23}
24
25class FuncSensPair {
26public:
27AdcSubscriptionEntry *adc = nullptr;
28 FuncSensPair(float divideInput, SensorType type)
29 : m_func(divideInput)
30 , m_sens(type, MS2NT(10))
31 {
32 m_sens.setFunction(m_func);
33 }
34
35 bool init(const TpsConfig& cfg) {
36 // If the configuration was invalid, don't continue to configure the sensor
37 if (!configure(cfg)) {
38 return false;
39 }
40
41 adc = AdcSubscription::SubscribeSensor(m_sens, cfg.channel, /*lowpassCutoffHz*/ 200);
42
43 return m_sens.Register();
44 }
45
46 void deinit() {
48 }
49
50 SensorType type() const {
51 return m_sens.type();
52 }
53
54 const char* name() const {
55 return m_sens.getSensorName();
56 }
57
58private:
59 bool configure(const TpsConfig& cfg) {
60 // Only configure if we have a channel
61 if (!isAdcChannelValid(cfg.channel)) {
62#if EFI_UNIT_TEST
63 printf("Configured NO hardware %s\n", name());
64#endif
65 return false;
66 }
67
68 float scaledClosed = cfg.closed / m_func.getDivideInput();
69 float scaledOpen = cfg.open / m_func.getDivideInput();
70
71 float split = std::abs(scaledOpen - scaledClosed);
72
73 // If the voltage for closed vs. open is very near, something is wrong with your calibration
74 if (split < getFuncPairAllowedSplit()) {
75 firmwareError(ObdCode::OBD_TPS_Configuration, "\"%s\" problem: open %.2f/closed %.2f cal values are too close together. Check your calibration and wiring!", name(),
76 cfg.open,
77 cfg.closed);
78 return false;
79 }
80
81 m_func.configure(
82 cfg.closed, 0,
83 cfg.open, POSITION_FULLY_OPEN,
84 cfg.min, cfg.max
85 );
86
87#if EFI_UNIT_TEST
88 printf("Configured YES %s\n", name());
89#endif
90 return true;
91 }
92
93 LinearFunc m_func;
94 FunctionalSensor m_sens;
95};
96
97struct RedundantPair {
98public:
99 RedundantPair(FuncSensPair& pri, FuncSensPair& sec, SensorType outputType)
100 : m_pri(pri)
101 , m_sec(sec)
102 , m_redund(outputType, m_pri.type(), m_sec.type())
103 {
104 }
105
106 void init(bool isFordTps, RedundantFordTps* fordTps, float secondaryMaximum, const TpsConfig& primary, const TpsConfig& secondary, bool allowIdenticalSensors = false) {
107 bool hasFirst = m_pri.init(primary);
108 if (!hasFirst) {
109 // no input if we have no first channel
110 return;
111 }
112
113 if (!allowIdenticalSensors) {
114 // Check that the primary and secondary aren't too close together - if so, the user may have done
115 // an unsafe thing where they wired a single sensor to both inputs. Don't do that!
116 bool hasBothSensors = isAdcChannelValid(primary.channel) && isAdcChannelValid(secondary.channel);
117 bool tooCloseClosed = std::abs(primary.closed - secondary.closed) < 0.2f;
118 bool tooCloseOpen = std::abs(primary.open - secondary.open) < 0.2f;
119
120 if (hasBothSensors && tooCloseClosed && tooCloseOpen) {
121 firmwareError(ObdCode::OBD_TPS_Configuration, "Configuration for redundant pair %s/%s are too similar - did you wire one sensor to both inputs...?", m_pri.name(), m_sec.name());
122 return;
123 }
124 }
125
126 bool hasSecond = m_sec.init(secondary);
127
128 if (engineConfiguration->etbSplit <= 0 || engineConfiguration->etbSplit > MAX_TPS_PPS_DISCREPANCY) {
129 engineConfiguration->etbSplit = MAX_TPS_PPS_DISCREPANCY;
130 }
131
132 if (isFordTps && fordTps) {
133 // we have a secondary
134 fordTps->configure(engineConfiguration->etbSplit, secondaryMaximum);
135 fordTps->Register();
136 } else {
137 // not ford TPS
138 m_redund.configure(engineConfiguration->etbSplit, !hasSecond);
139#if EFI_UNIT_TEST
140printf("init m_redund.Register() %s\n", getSensorType(m_redund.type()));
141#endif
142 m_redund.Register();
143 }
144 }
145
146 void deinit(bool isFordTps, RedundantFordTps* fordTps) {
147 m_pri.deinit();
148 m_sec.deinit();
149
150 if (isFordTps && fordTps) {
151 fordTps->unregister();
152 } else {
153 m_redund.unregister();
154 }
155
156 }
157
158 // technical debt: oop violation: this method is specific to PPS usage
159 void updateUnfilteredRawValues() {
160 engine->outputChannels.rawRawPpsPrimary = m_pri.adc == nullptr ? 0 : m_pri.adc->sensorVolts;
161 engine->outputChannels.rawRawPpsSecondary = m_sec.adc == nullptr ? 0 : m_sec.adc->sensorVolts;
162 }
163
164private:
165 FuncSensPair& m_pri;
166 FuncSensPair& m_sec;
167
168 RedundantSensor m_redund;
169};
170
171static FuncSensPair tps1p(TPS_TS_CONVERSION, SensorType::Tps1Primary);
172static FuncSensPair tps1s(TPS_TS_CONVERSION, SensorType::Tps1Secondary);
173static FuncSensPair tps2p(TPS_TS_CONVERSION, SensorType::Tps2Primary);
174static FuncSensPair tps2s(TPS_TS_CONVERSION, SensorType::Tps2Secondary);
175
176// Used in case of "normal", non-Ford ETB TPS
177static RedundantPair analogTps1(tps1p, tps1s, SensorType::Tps1);
178static RedundantPair tps2(tps2p, tps2s, SensorType::Tps2);
179
180#if EFI_SENT_SUPPORT
182#endif
183
184// Used only in case of weird Ford-style ETB TPS
188
189// Pedal sensors and redundancy
193
195 pedal.updateUnfilteredRawValues();
196}
197
198// This sensor indicates the driver's throttle intent - Pedal if we have one, TPS if not.
201
202// These sensors are TPS-like, so handle them in here too
204static FuncSensPair idlePos(PACK_MULT_VOLTAGE, SensorType::IdlePosition);
205
206void initTps() {
207 criticalAssertVoid(engineConfiguration != nullptr, "null engineConfiguration");
210
214
215 float tpsSecondaryMaximum = engineConfiguration->tpsSecondaryMaximum;
216 if (tpsSecondaryMaximum < 20) {
217 // don't allow <20% split point
218 tpsSecondaryMaximum = 20;
219 }
220
221
222#if EFI_SENT_SUPPORT
223 if (isDigitalTps1()) {
225 } else
226#endif
227 {
228 analogTps1.init(isFordTps, &fordTps1, tpsSecondaryMaximum,
231 );
232 }
233
234 tps2.init(isFordTps, &fordTps2, tpsSecondaryMaximum,
237 );
238
239 float ppsSecondaryMaximum = engineConfiguration->ppsSecondaryMaximum;
240 if (ppsSecondaryMaximum < 20) {
241 // don't allow <20% split point
242 ppsSecondaryMaximum = 20;
243 }
244
245 // Pedal sensors
246 pedal.init(isFordPps, &fordPps, ppsSecondaryMaximum,
250 );
253 if (!arg) {
254 return arg;
255 }
256 static ExpAverage ppsExpAverage;
258 SensorResult result = ppsExpAverage.initOrAverage(arg.Value);
259 return result;
260 });
262
263 // TPS-like stuff that isn't actually a TPS
266 }
267
268 // Route the pedal or TPS to driverIntent as appropriate
271 } else {
273 }
274
276}
277
278void deinitTps() {
281
282 analogTps1.deinit(isFordTps, &fordTps1);
283 tps2.deinit(isFordTps, &fordTps2);
284 pedal.deinit(isFordPps, &fordPps);
285
286#if EFI_SENT_SUPPORT
288#endif
289
290 wastegate.deinit();
291 idlePos.deinit();
292}
bool isAdcChannelValid(adc_channel_e hwChannel)
Definition adc_inputs.h:23
uint16_t channel
Definition adc_inputs.h:104
uint16_t adc
Definition adc_inputs.h:103
const char * getSensorType(SensorType value)
static AdcSubscriptionEntry * SubscribeSensor(FunctionalSensorBase &sensor, adc_channel_e channel, float lowpassCutoffHZ, float voltsPerAdcVolt=0.0f)
static void UnsubscribeSensor(FunctionalSensorBase &sensor)
TunerStudioOutputChannels outputChannels
Definition engine.h:109
void setSmoothingFactor(float p_smoothingFactor)
Definition exp_average.h:26
float initOrAverage(float value)
Definition exp_average.h:9
Class for sensors that convert from some raw floating point value (ex: voltage, frequency,...
void setConverter(functionFunctionPtr p_converter)
void setProxiedSensor(SensorType proxiedSensor)
void configure(float maxDifference, float secondaryMaximum)
bool Register()
Definition sensor.cpp:131
void unregister()
Definition sensor.cpp:135
static EngineAccessor engine
Definition engine.h:413
engine_configuration_s & activeConfiguration
static constexpr engine_configuration_s * engineConfiguration
void firmwareError(ObdCode code, const char *fmt,...)
void updateUnfilteredRawPedal()
Definition init_tps.cpp:194
void initTps()
Definition init_tps.cpp:206
static FuncSensPair wastegate(1, SensorType::WastegatePosition)
static ProxySensor ppsFilterSensor(SensorType::AcceleratorPedal)
static RedundantFordTps fordTps1(SensorType::Tps1, SensorType::Tps1Primary, SensorType::Tps1Secondary)
static FuncSensPair tps1s(TPS_TS_CONVERSION, SensorType::Tps1Secondary)
static RedundantPair pedal(pedalPrimary, pedalSecondary, SensorType::AcceleratorPedalUnfiltered)
static RedundantPair tps2(tps2p, tps2s, SensorType::Tps2)
PUBLIC_API_WEAK float getFuncPairAllowedSplit()
Definition init_tps.cpp:21
static FuncSensPair tps2s(TPS_TS_CONVERSION, SensorType::Tps2Secondary)
static FuncSensPair tps1p(TPS_TS_CONVERSION, SensorType::Tps1Primary)
static FuncSensPair idlePos(PACK_MULT_VOLTAGE, SensorType::IdlePosition)
static RedundantPair analogTps1(tps1p, tps1s, SensorType::Tps1)
static FuncSensPair tps2p(TPS_TS_CONVERSION, SensorType::Tps2Primary)
void deinitTps()
Definition init_tps.cpp:278
static ProxySensor driverIntent(SensorType::DriverThrottleIntent)
static FuncSensPair pedalSecondary(1, SensorType::AcceleratorPedalSecondary)
static RedundantFordTps fordPps(SensorType::AcceleratorPedalUnfiltered, SensorType::AcceleratorPedalPrimary, SensorType::AcceleratorPedalSecondary)
SentTps sentTps
Definition init_tps.cpp:181
static FuncSensPair pedalPrimary(1, SensorType::AcceleratorPedalPrimary)
static RedundantFordTps fordTps2(SensorType::Tps2, SensorType::Tps2Primary, SensorType::Tps2Secondary)
@ OBD_TPS_Configuration
A sensor to duplicate a sensor to an additional SensorType.
float percent_t
expected< float > SensorResult
Definition sensor.h:46
SensorType
Definition sensor_type.h:18
@ AcceleratorPedalPrimary
@ AcceleratorPedalSecondary
@ DriverThrottleIntent
@ AcceleratorPedalUnfiltered
Definition tps.h:34
bool isDigitalTps1()
Definition tps.cpp:83
printf("\n")