rusEFI
The most advanced open source ECU
Functions | Variables
interpolation.cpp File Reference

Detailed Description

Linear interpolation algorithms.

See test_interpolation_3d.cpp

Date
Oct 17, 2013
Author
Andrey Belomutskiy, (c) 2012-2020
Dmitry Sidin, (c) 2015

Definition in file interpolation.cpp.

Functions

static void testBinary ()
 
float interpolateMsg (const char *msg, float x1, float y1, float x2, float y2, float x)
 Linear interpolation by two points. More...
 
float interpolateClampedWithValidation (float x1, float y1, float x2, float y2, float x)
 
float interpolateClamped (float x1, float y1, float x2, float y2, float x)
 
int findIndex2 (const float array[], unsigned size, float value)
 
int findIndex (const float array[], int size, float value)
 
void initInterpolation ()
 

Variables

float array16 [] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
 

Function Documentation

◆ findIndex()

int findIndex ( const float  array[],
int  size,
float  value 
)

Definition at line 155 of file interpolation.cpp.

155  {
156  return findIndexMsg("", array, size, value);
157 }
int findIndexMsg(const char *msg, const kType array[], int size, kType value)
Binary search.
composite packet size

Referenced by testBinary().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ findIndex2()

int findIndex2 ( const float  array[],
unsigned  size,
float  value 
)

Another implementation, which one is faster?

it should be "if (j < size && array[j] <= value)" but in our case size is always power of 2 thus size is always more then j

Definition at line 131 of file interpolation.cpp.

131  {
132  efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !cisnan(value), "NaN in findIndex2", 0);
133  efiAssert(ObdCode::CUSTOM_ERR_ASSERT, size > 1, "size in findIndex", 0);
134 // if (size <= 1)
135 // return size && *array <= value ? 0 : -1;
136 
137  signed i = 0;
138  //unsigned b = 1 << int(log(float(size) - 1) / 0.69314718055994530942);
139  unsigned b = size >> 1; // in our case size is always a power of 2
140  efiAssert(ObdCode::CUSTOM_ERR_ASSERT, b + b == size, "Size not power of 2", -1);
141  for (; b; b >>= 1) {
142  unsigned j = i | b;
143  /**
144  * it should be
145  * "if (j < size && array[j] <= value)"
146  * but in our case size is always power of 2 thus size is always more then j
147  */
148  // efiAssert(ObdCode::CUSTOM_ERR_ASSERT, j < size, "size", 0);
149  if (array[j] <= value)
150  i = j;
151  }
152  return i || *array <= value ? i : -1;
153 }
@ CUSTOM_ERR_ASSERT

Referenced by testBinary().

Here is the caller graph for this function:

◆ initInterpolation()

void initInterpolation ( )

Definition at line 159 of file interpolation.cpp.

159  {
160 #if BINARY_PERF && ! EFI_UNIT_TEST
161  addConsoleAction("binarytest", testBinary);
162 #endif
163 }
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
static void testBinary()

Referenced by commonInitEngineController().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpolateClamped()

float interpolateClamped ( float  x1,
float  y1,
float  x2,
float  y2,
float  x 
)

todo: use 'interpolateClampedWithValidation' wider?

See also
interpolateMsg

Definition at line 115 of file interpolation.cpp.

115  {
116  // note how we assume order of x1 and x2 here! see also interpolateClampedWithValidation
117  if (x <= x1)
118  return y1;
119  if (x >= x2)
120  return y2;
121 
122  // todo: do we care with code duplication with interpolateMsg above?
123  float a = INTERPOLATION_A(x1, y1, x2, y2);
124  float b = y1 - a * x1;
125  return a * x + b;
126 }

Referenced by ThrottleModelBase::estimateThrottleFlow(), flexCallback(), IdleController::getClosedLoop(), getCrankingAdvance(), getCrankingFuel3(), IdleController::getIdleTimingAdjustment(), IdleController::getOpenLoop(), getRunningAdvance(), IdleController::getRunningOpenLoop(), EtbController::getSetpointEtb(), FuelComputer::getStoichiometricRatio(), IFuelComputer::getTCharge(), IFuelComputer::getTChargeCoefficient(), AirmassVeModelBase::getVe(), interpolateClampedWithValidation(), HellaOilLevelSensor::onEdge(), setHysteresis(), LimpManager::updateRevLimit(), and updateVrThresholdPwm().

Here is the caller graph for this function:

◆ interpolateClampedWithValidation()

float interpolateClampedWithValidation ( float  x1,
float  y1,
float  x2,
float  y2,
float  x 
)

Definition at line 104 of file interpolation.cpp.

104  {
105  if (x1 >= x2) {
106  criticalError("interpolateClamped %f has to be smaller than %f", x1, x2);
107  }
108  return interpolateClamped(x1, y1, x2, y2, x);
109 }
float interpolateClamped(float x1, float y1, float x2, float y2, float x)
Here is the call graph for this function:

◆ interpolateMsg()

float interpolateMsg ( const char *  msg,
float  x1,
float  y1,
float  x2,
float  y2,
float  x 
)

Linear interpolation by two points.

Parameters
x1key of the first point
y1value of the first point
x2key of the second point
y2value of the second point
Xkey to be interpolated
Note
For example, "interpolateMsg("", engineConfiguration.tpsMin, 0, engineConfiguration.tpsMax, 100, adc);"
See also
interpolateClamped

we could end up here for example while resetting bins while changing engine type

Definition at line 74 of file interpolation.cpp.

74  {
75  if (cisnan(x1) || cisnan(x2) || cisnan(y1) || cisnan(y2)) {
76  warning(ObdCode::CUSTOM_ERR_INTERPOLATE_1, "interpolate%s: why param", msg);
77  return NAN;
78  }
79  if (cisnan(x)) {
80  warning(ObdCode::CUSTOM_ERR_INTERPOLATE_2, "interpolate%s: why X", msg);
81  return NAN;
82  }
83  // todo: double comparison using EPS
84  if (x1 == x2) {
85  /**
86  * we could end up here for example while resetting bins while changing engine type
87  */
88  warning(ObdCode::CUSTOM_ERR_INTERPOLATE_3, "interpolate%s: Same x1 and x2 in interpolate: %.2f/%.2f", msg, x1, x2);
89  return NAN;
90  }
91 
92  // a*x1 + b = y1
93  // a*x2 + b = y2
94 // efiAssertVoid(ObdCode::CUSTOM_ERR_ASSERT_VOID, x1 != x2, "no way we can interpolate");
95  float a = INTERPOLATION_A(x1, y1, x2, y2);
96  if (cisnan(a)) {
97  warning(ObdCode::CUSTOM_ERR_INTERPOLATE_4, "interpolate%s: why a", msg);
98  return NAN;
99  }
100  float b = y1 - a * x1;
101  return a * x + b;
102 }
bool warning(ObdCode code, const char *fmt,...)
@ CUSTOM_ERR_INTERPOLATE_3
@ CUSTOM_ERR_INTERPOLATE_4
@ CUSTOM_ERR_INTERPOLATE_2
@ CUSTOM_ERR_INTERPOLATE_1

Referenced by decodeTpsSentValue(), getAdvanceForRpm(), getAfr(), IFuelComputer::getTChargeCoefficient(), lua_interpolate(), and setLinearCurve().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ testBinary()

static void testBinary ( )
static

Definition at line 25 of file interpolation.cpp.

25  {
26  const int size16 = 16;
27 
28  uint32_t totalOld = 0;
29  uint32_t totalNew = 0;
30 
31  for (int v = 0; v <= 16; v++) {
32  uint32_t timeOld;
33  {
34  uint32_t start = getTimeNowLowerNt();
35  int temp = 0;
36  for (int i = 0; i < COUNT; i++) {
37  temp += findIndex(array16, size16, v);
38  }
39  timeOld = getTimeNowLowerNt() - start;
40  }
41  uint32_t timeNew;
42  {
43  uint32_t start = getTimeNowLowerNt();
44  int temp = 0;
45  for (int i = 0; i < COUNT; i++) {
46  temp += findIndex2(array16, size16, v);
47  }
48  timeNew = getTimeNowLowerNt() - start;
49  }
50  efiPrintf("for v=%d old=%d ticks", v, timeOld);
51  efiPrintf("for v=%d new=%d ticks", v, timeNew);
52 
53  totalOld += timeOld;
54  totalNew += timeNew;
55  }
56  efiPrintf("totalOld=%d ticks", totalOld);
57  efiPrintf("totalNew=%d ticks", totalNew);
58 
59 }
int findIndex(const float array[], int size, float value)
int findIndex2(const float array[], unsigned size, float value)
float array16[]
uint32_t getTimeNowLowerNt()

Referenced by initInterpolation().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ array16

float array16[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }

Definition at line 23 of file interpolation.cpp.

Referenced by testBinary().

Go to the source code of this file.