Line data Source code
1 : /*
2 : * @file test_interpolation_3d.cpp
3 : *
4 : * Created on: Oct 17, 2013
5 : * @author Andrey Belomutskiy, (c) 2012-2020
6 : */
7 :
8 : #include "pch.h"
9 :
10 : #include <stdlib.h>
11 :
12 : #include "efi_interpolation.h"
13 :
14 : #define RPM_COUNT 5
15 : #define VALUE_COUNT 4
16 :
17 : float rpmBins[RPM_COUNT] = { 100, 200, 300, 400, 500 };
18 : scaled_channel<uint8_t, 1, 50> rpmBinsScaledByte[5] = { 100, 200, 300, 400, 500};
19 :
20 : float mafBins[VALUE_COUNT] = { 1, 2, 3, 4 };
21 : scaled_channel<int, 10> mafBinsScaledInt[VALUE_COUNT] = { 1, 2, 3, 4 };
22 : scaled_channel<uint8_t, 10> mafBinsScaledByte[VALUE_COUNT] = { 1, 2, 3, 4 };
23 :
24 : scaled_channel<uint32_t, 10000, 3> mapScaledChannel[VALUE_COUNT][RPM_COUNT] = {
25 : { 1, 2, 3, 4, 4},
26 : { 2, 3, 4, 200, 200 },
27 : { 3, 4, 200, 500, 500 },
28 : { 4, 5, 300, 600, 600 },
29 : };
30 :
31 : float map[VALUE_COUNT][RPM_COUNT] = {
32 : { 1, 2, 3, 4, 4},
33 : { 2, 3, 4, 200, 200 },
34 : { 3, 4, 200, 500, 500 },
35 : { 4, 5, 300, 600, 600 },
36 : };
37 :
38 30 : static float getValue(float rpm, float maf) {
39 30 : Map3D<RPM_COUNT, VALUE_COUNT, float, float, float> x1{"x"};
40 : // note "5, 4" above
41 : // note "map[4][5], Bins[4], rpm[5] below
42 30 : x1.initTable(map, rpmBins, mafBins);
43 30 : float result1 = x1.getValue(rpm, maf);
44 :
45 :
46 30 : Map3D<RPM_COUNT, VALUE_COUNT, float, float, int> x2{"x"};
47 30 : x2.initTable(map, rpmBins, mafBinsScaledInt);
48 30 : float result2 = x2.getValue(rpm, maf);
49 30 : EXPECT_NEAR_M4(result1, result2);
50 :
51 :
52 30 : Map3D<RPM_COUNT, VALUE_COUNT, float, float, uint8_t> x3{"x"};
53 30 : x3.initTable(map, rpmBins, mafBinsScaledByte);
54 30 : float result3 = x3.getValue(rpm, maf);
55 30 : EXPECT_NEAR_M4(result1, result3);
56 :
57 30 : Map3D<RPM_COUNT, VALUE_COUNT, float, uint8_t, float> x4{"x"};
58 30 : x4.initTable(map, rpmBinsScaledByte, mafBins);
59 30 : float result4 = x4.getValue(rpm, maf);
60 30 : EXPECT_NEAR_M4(result1, result4);
61 :
62 30 : float result5 = interpolate3d(
63 : map,
64 : mafBinsScaledInt, maf,
65 : rpmBinsScaledByte, rpm
66 : );
67 30 : EXPECT_NEAR_M4(result1, result5);
68 :
69 : // Test with values stored in scaled bytes
70 30 : Map3D<RPM_COUNT, VALUE_COUNT, uint32_t, float, float> x6{"x"};
71 30 : x6.initTable(mapScaledChannel, rpmBins, mafBins);
72 30 : float result6 = x6.getValue(rpm, maf);
73 30 : EXPECT_NEAR(result1, result6, 1e-3);
74 :
75 60 : return result1;
76 : }
77 :
78 1 : static void newTestToComfirmInterpolation() {
79 : // here's how the table loos like:
80 : //
81 : //__RPM_
82 : //__300_|_10|200|
83 : //__200_|__3|__4|
84 : //______|__2|__3|_LOAD
85 :
86 1 : map[1][2] = 10;
87 1 : mapScaledChannel[1][2] = 10;
88 :
89 :
90 : // let's start by testing corners
91 1 : EXPECT_NEAR_M4(3, getValue(/*rpm*/200, 2));
92 1 : EXPECT_NEAR_M4(4, getValue(/*rpm*/200, 3)) << "low rpm high load";
93 :
94 1 : EXPECT_NEAR_M4(10, getValue(/*rpm*/300, 2));
95 1 : EXPECT_NEAR_M4(200, getValue(/*rpm*/300, 3));
96 :
97 : // now testing middles of cell sides
98 1 : EXPECT_NEAR_M4(3.5, getValue(/*rpm*/200, 2.5)) << "low rpm middle";
99 1 : EXPECT_NEAR_M4(105, getValue(/*rpm*/300, 2.5)) << "high rpm";
100 :
101 1 : EXPECT_NEAR_M4(6.5, getValue(/*rpm*/250, 2)) << "low load middle";
102 1 : EXPECT_NEAR_M4(102, getValue(/*rpm*/250, 3));
103 :
104 : // slowly go from middle side towards center
105 1 : EXPECT_NEAR_M4(16.05, getValue(/*rpm*/250, 2.1)) << "middle @ 2.1";
106 1 : EXPECT_NEAR_M4(25.6, getValue(/*rpm*/250, 2.2)) << "middle @ 2.2";
107 1 : EXPECT_NEAR_M4(35.15, getValue(/*rpm*/250, 2.3)) << "middle @ 2.3";
108 :
109 1 : EXPECT_NEAR_M4(54.25, getValue(/*rpm*/250, 2.5)) << "middle cell";
110 :
111 : // issue #604: interpolation outside of the table
112 : // X above the range
113 1 : EXPECT_NEAR_M4(230, getValue(/*rpm*/800, 2.1)) << "800 @ 2.1";
114 1 : EXPECT_NEAR_M4(290, getValue(/*rpm*/800, 2.3)) << "800 @ 2.3";
115 1 : EXPECT_NEAR_M4(530, getValue(/*rpm*/800, 3.3)) << "800 @ 3.3";
116 :
117 : // X below the range
118 1 : EXPECT_NEAR_M4(2.1, getValue(/*rpm*/-810, 2.1)) << "-810 @ 2.1";
119 1 : EXPECT_NEAR_M4(2.3, getValue(/*rpm*/-820, 2.3)) << "-820 @ 2.3";
120 :
121 : // Y above the range
122 1 : EXPECT_NEAR_M4(330, getValue(/*rpm*/310, 12.1)) << "310 @ 12.1";
123 1 : EXPECT_NEAR_M4(360, getValue(/*rpm*/320, 12.3)) << "320 @ 12.3";
124 :
125 : // Y below the range
126 1 : EXPECT_NEAR_M4(3.1, getValue(/*rpm*/310, -12.1)) << "310 @ -12.1";
127 1 : EXPECT_NEAR_M4(3.2, getValue(/*rpm*/320, -12.3)) << "320 @ -12.3";
128 1 : }
129 :
130 4 : TEST(misc, testInterpolate3d) {
131 1 : printf("*** no interpolation here 1\r\n");
132 1 : EXPECT_NEAR_M4(2, getValue(100, 2));
133 :
134 1 : printf("*** no interpolation here 2\r\n");
135 1 : EXPECT_NEAR_M4(5, getValue(200, 4));
136 :
137 1 : printf("*** rpm interpolated value expected1\r\n");
138 1 : EXPECT_NEAR_M4(2.5, getValue(150, 2));
139 :
140 1 : printf("*** rpm interpolated value expected2\r\n");
141 1 : EXPECT_NEAR_M4(102, getValue(250, 3));
142 :
143 1 : printf("*** both rpm and maf interpolated value expected\r\n");
144 1 : EXPECT_NEAR_M4(361, getValue(335.3, 3.551));
145 :
146 1 : printf("*** both rpm and maf interpolated value expected 2\r\n");
147 1 : EXPECT_NEAR_M4(203.6, getValue(410.01, 2.012));
148 :
149 1 : printf("*** both rpm and maf interpolated value expected 3\r\n");
150 1 : EXPECT_NEAR_M4(600, getValue(1000000, 1000));
151 :
152 1 : printf("*** both rpm and maf interpolated value expected 4\r\n");
153 :
154 1 : EXPECT_NEAR_M4(4, getValue(410.01, -1));
155 :
156 :
157 1 : EXPECT_NEAR_M4(1, getValue(-1, -1));
158 :
159 1 : newTestToComfirmInterpolation();
160 1 : }
|