285
|
1 //////////////////////////////////////////////////////////////////////////////
|
|
2 /// deco_volume_test.cpp
|
|
3 /// Unit test for gas consumption c code.
|
|
4 /// Copyright (c) 2015, JD Gascuel, HeinrichsWeikamp, all right reserved.
|
|
5 //////////////////////////////////////////////////////////////////////////////
|
|
6 // HISTORY
|
288
|
7 // 2015-05-27 jDG: Creation for gas volum re-introduction in hwOS 1.82
|
285
|
8
|
|
9 extern "C" {
|
|
10 # include "p2_deco.c"
|
|
11 }
|
|
12
|
|
13 #include <gtest/gtest.h>
|
293
|
14 #include <iostream>
|
285
|
15
|
|
16 //////////////////////////////////////////////////////////////////////////////
|
|
17 /// \brief Defines a default OC gas list
|
|
18 static void setup_gas()
|
|
19 {
|
|
20 char_I_first_gas = 1;
|
|
21
|
|
22 #define DEFINE_GAS(gas, o2, he, depth, role) \
|
|
23 char_I_deco_N2_ratio [gas-1] = 100 - o2 - he; \
|
|
24 char_I_deco_He_ratio [gas-1] = he; \
|
|
25 char_I_deco_gas_change[gas-1] = depth;
|
|
26
|
|
27 DEFINE_GAS(1, 21, 0, 0, 1); // Gas#1 : Air FIRST
|
|
28 DEFINE_GAS(2, 18, 30, 0, 2); // Gas#2 : Tx18/30 TRAVEL
|
|
29 DEFINE_GAS(3, 80, 0, 9, 3); // Gas#3 : Nx80 @ 9m DECO
|
286
|
30 DEFINE_GAS(4, 21, 0, 0, 0); // Gas#2 : air @ 10m DISABLED
|
|
31 DEFINE_GAS(5, 21, 0, 0, 0); // Gas#2 : air @ 40m DISABLED
|
285
|
32 }
|
|
33
|
|
34 //////////////////////////////////////////////////////////////////////////////
|
|
35 /// \brief Define a default deco plan.
|
293
|
36 static void setup_plan(const char* stops,
|
|
37 const char* gas)
|
285
|
38 {
|
293
|
39 int depth = 3 * (stops ? strlen(stops) : 0);
|
|
40
|
295
|
41 if( ! depth )
|
|
42 std::cout << " no deco" << std::endl;
|
|
43
|
293
|
44 int s = 0;
|
|
45 while( depth > 0 && s < NUM_STOPS ) {
|
295
|
46 std::cout << " " << std::setw(2) << int(stops[s]) << "' @ " << depth << "m" << std::endl;
|
|
47
|
293
|
48 char_O_deco_time [s] = stops[s];
|
|
49 char_O_deco_depth[s] = depth;
|
|
50 char_O_deco_gas [s] = gas ? gas[s] : 1; // Gas#1 by default
|
|
51 ++s;
|
|
52 depth -= 3;
|
|
53 }
|
285
|
54 // Done
|
293
|
55 for(; s<NUM_STOPS; ++s) {
|
285
|
56 char_O_deco_time [s] = 0;
|
|
57 char_O_deco_depth[s] = 0;
|
|
58 char_O_deco_gas [s] = 0;
|
|
59 }
|
|
60 }
|
|
61
|
293
|
62 static void setup_dive(int bottom, int depth,
|
|
63 const char* stops = 0, const char* gas = 0)
|
285
|
64 {
|
|
65 setup_gas();
|
293
|
66 setup_plan(stops, gas);
|
285
|
67
|
286
|
68 char_I_bottom_depth = depth;
|
|
69 char_I_bottom_time = bottom;
|
|
70 }
|
|
71
|
|
72 //////////////////////////////////////////////////////////////////////////////
|
|
73 /// \brief Gas consumption at a fixed depth
|
|
74 static float fixed(int rmv, int time, int depth) {
|
|
75 return rmv * time * (1 + 0.1f*depth);
|
|
76 }
|
|
77
|
|
78 TEST(gas_volume, fixed)
|
|
79 {
|
|
80 EXPECT_EQ(20*30*1, fixed(20,30, 0)); // 30' @ 0m
|
|
81 EXPECT_EQ(20*30*5, fixed(20,30,40)); // 30' @ 40m
|
|
82 }
|
|
83
|
|
84 //////////////////////////////////////////////////////////////////////////////
|
|
85 /// \brief Gas consumption during an ascent at 10m/min.
|
|
86 static float ascent(int rmv, int oldDepth, int newDepth)
|
|
87 {
|
|
88 return rmv
|
|
89 * abs(oldDepth-newDepth)*0.1f // Ascent time
|
|
90 * (1 + 0.05f*(oldDepth + newDepth)); // Avg pressure.
|
|
91 }
|
|
92
|
|
93 TEST(gas_volume, ascent)
|
|
94 {
|
|
95 EXPECT_EQ(0, ascent(20, 30, 30)); // 30m -> 30m : no time, no conso
|
|
96 EXPECT_EQ(20*4*(1+2), ascent(20, 40, 0)); // 40m -> 0m : 4min, avg 20m
|
|
97 EXPECT_EQ(20*4*(1+2), ascent(20, 0, 40)); // 0m -> 40m : 4min, avg 20m
|
285
|
98 }
|
|
99
|
293
|
100 static void check_volumes(float G1, const char* L1,
|
|
101 float G2, const char* L2,
|
|
102 float G3, const char* L3,
|
|
103 float G4, const char* L4,
|
|
104 float G5, const char* L5)
|
286
|
105 {
|
293
|
106 std::cout << " " << std::setw(6) << G1 << " = " << L1 << std::endl;
|
|
107 std::cout << " " << std::setw(6) << G2 << " = " << L2 << std::endl;
|
|
108 std::cout << " " << std::setw(6) << G3 << " = " << L3 << std::endl;
|
|
109 std::cout << " " << std::setw(6) << G4 << " = " << L4 << std::endl;
|
|
110 std::cout << " " << std::setw(6) << G5 << " = " << L5 << std::endl;
|
|
111
|
|
112 EXPECT_NEAR(G1, int_O_gas_volumes[0], 1) << L1;
|
|
113 EXPECT_NEAR(G2, int_O_gas_volumes[1], 1) << L2;
|
|
114 EXPECT_NEAR(G3, int_O_gas_volumes[2], 1) << L3;
|
|
115 EXPECT_NEAR(G4, int_O_gas_volumes[3], 1) << L4;
|
|
116 EXPECT_NEAR(G5, int_O_gas_volumes[4], 1) << L5;
|
|
117 }
|
|
118
|
|
119 //////////////////////////////////////////////////////////////////////////////
|
|
120 // v1.82 ZH-L16+GF, OC, 30%/85%
|
|
121 TEST(gas_volume, OC_13min30m)
|
|
122 {
|
|
123 char_I_const_ppO2 = 0; // OC
|
|
124 setup_dive(13, 30); // 13' @ 30m --> no deco
|
286
|
125
|
|
126 ASSERT_NO_THROW( deco_gas_volumes() );
|
293
|
127 check_volumes(fixed(20,13,30) + ascent(20,30,0), "Gas1: 1190 L",
|
|
128 0, "",
|
|
129 0, "",
|
|
130 0, "",
|
|
131 0, "");
|
|
132 }
|
|
133
|
|
134 //////////////////////////////////////////////////////////////////////////////
|
|
135 // v1.82 ZH-L16+GF, OC, 30%/85%
|
|
136 TEST(gas_volume, OC_15min30m)
|
|
137 {
|
|
138 char_I_const_ppO2 = 0; // OC
|
|
139 char stops[] = {1, 0};
|
|
140 char gas[] = {3, 0};
|
|
141 setup_dive(15, 30, stops, gas); // 15' @ 30m --> 1min at 3m
|
|
142
|
|
143 ASSERT_NO_THROW( deco_gas_volumes() );
|
|
144 check_volumes(fixed(20,15,30) + ascent(20,30,3), "Gas1: 1343 L",
|
|
145 0, "",
|
|
146 fixed(20, 1, 3) + ascent(20, 3,0), "Gas3: 33",
|
|
147 0, "",
|
|
148 0, "");
|
|
149 }
|
|
150
|
|
151 //////////////////////////////////////////////////////////////////////////////
|
|
152 // v1.82 ZH-L16+GF, OC, 30%/85%
|
|
153 TEST(gas_volume, OC_29min30m)
|
|
154 {
|
|
155 char_I_const_ppO2 = 0; // OC
|
|
156 char stops[] = {1, 1, 2, 4, 0};
|
|
157 char gas[] = {1, 3, 3, 3, 0};
|
|
158 setup_dive(29, 30, stops, gas); // 29' @ 30m --> 1' 1' 2' 4'
|
|
159
|
|
160 ASSERT_NO_THROW( deco_gas_volumes() );
|
|
161 check_volumes(fixed(20,29,30) + ascent(20,30,12) +
|
|
162 fixed(20, 1,12) + ascent(20,12, 9), "Gas1: 2488 L",
|
|
163 0, "",
|
|
164 fixed(20, 1, 9) + ascent(20, 9, 6) +
|
|
165 fixed(20, 2, 6) + ascent(20, 6, 3) +
|
|
166 fixed(20, 4, 3) + ascent(20, 3, 0), "Gas3: 232 L",
|
|
167 0, "",
|
|
168 0, "");
|
286
|
169 }
|
|
170
|
|
171 //////////////////////////////////////////////////////////////////////////////
|
293
|
172 // v1.82 ZH-L16+GF, OC, 30%/85%
|
|
173 TEST(gas_volume, OC_15min60m)
|
285
|
174 {
|
293
|
175 char_I_const_ppO2 = 0; // OC
|
|
176 char stops[] = {2, 1, 2, 4, 3, 4, 9, 0};
|
|
177 char gas[] = {1, 1, 1, 1, 3, 3, 3, 0};
|
|
178 setup_dive(15, 60, stops, gas); // 15' @ 60m --> DTR 32'
|
285
|
179
|
286
|
180 ASSERT_NO_THROW( deco_gas_volumes() );
|
293
|
181 check_volumes(fixed(20,15,60) + ascent(20,60,21) +
|
|
182 fixed(20, 2,21) + ascent(20,21,18) +
|
|
183 fixed(20, 1,18) + ascent(20,18,15) +
|
|
184 fixed(20, 2,15) + ascent(20,15,12) +
|
|
185 fixed(20, 4,12) + ascent(20,12, 9), "Gas1: 3010 L",
|
|
186 0, "",
|
|
187 fixed(20, 3, 9) + ascent(20, 9, 6) +
|
|
188 fixed(20, 4, 6) + ascent(20, 6, 3) +
|
|
189 fixed(20, 9, 3) + ascent(20, 3, 0), "Gas3: 502 L",
|
|
190 0, "",
|
|
191 0, "");
|
|
192 }
|
|
193
|
|
194 //////////////////////////////////////////////////////////////////////////////
|
|
195 // v1.82 ZH-L16+GF, CCR, 30%/85%
|
295
|
196 TEST(gas_volume, CCR_23min30m)
|
293
|
197 {
|
|
198 char_I_const_ppO2 = 140;// SP 1.4 bar
|
295
|
199 setup_dive(23, 30); // 23' @ 30m --> no deco / no BAIL deco
|
293
|
200
|
|
201 ASSERT_NO_THROW( deco_gas_volumes() );
|
295
|
202 check_volumes(/*NO BTM CONSO*/ ascent(20,30,0), "Gas1: 150 L",
|
293
|
203 0, "",
|
|
204 0, "",
|
|
205 0, "",
|
|
206 0, "");
|
285
|
207 }
|
290
|
208
|
|
209 //////////////////////////////////////////////////////////////////////////////
|
293
|
210 // v1.82 ZH-L16+GF, CCR, 30%/85%
|
295
|
211 TEST(gas_volume, CCR_25min30m)
|
290
|
212 {
|
295
|
213 char_I_const_ppO2 = 140;// SP 1.4 bar
|
293
|
214 char stops[] = {1, 0};
|
|
215 char gas[] = {3, 0};
|
295
|
216 setup_dive(25, 30, stops, gas); // 25' @ 30m --> no deco / BAIL 1' @ 3m
|
293
|
217
|
|
218 ASSERT_NO_THROW( deco_gas_volumes() );
|
295
|
219 check_volumes(/*NO BTM CONSO*/ ascent(20,30,3), "Gas1: 143 L",
|
293
|
220 0, "",
|
295
|
221 fixed(20, 1, 3) + ascent(20, 3,0), "Gas3: 33 L",
|
293
|
222 0, "",
|
|
223 0, "");
|
|
224 }
|
|
225
|
|
226 //////////////////////////////////////////////////////////////////////////////
|
|
227 // v1.82 ZH-L16+GF, CCR, 30%/85%
|
295
|
228 TEST(gas_volume, CCR_45min30m)
|
293
|
229 {
|
|
230 char_I_const_ppO2 = 140; // SP 1.4 bar
|
295
|
231 char stops[] = {1, 2, 5, 0};
|
|
232 char gas[] = {3, 3, 3, 0};
|
|
233 setup_dive(45, 30, stops, gas); // 45' @ 30m
|
290
|
234
|
|
235 ASSERT_NO_THROW( deco_gas_volumes() );
|
295
|
236 check_volumes(/*NO BTM CONSO*/ ascent(20,30, 9), "Gas1: 124 L",
|
293
|
237 0, "",
|
|
238 fixed(20, 1, 9) + ascent(20, 9, 6) +
|
|
239 fixed(20, 2, 6) + ascent(20, 6, 3) +
|
295
|
240 fixed(20, 5, 3) + ascent(20, 3, 0), "Gas3: 258 L",
|
|
241 0, "",
|
|
242 0, "");
|
|
243 }
|
|
244
|
|
245 //////////////////////////////////////////////////////////////////////////////
|
|
246 // v1.82 ZH-L16+GF, CCR, 30%/85%
|
|
247 TEST(gas_volume, CCR_19min51m)
|
|
248 {
|
|
249 char_I_const_ppO2 = 140; // SP 1.4 bar
|
|
250 char stops[] = {1, 2, 2, 4, 3, 4, 9, 0};
|
|
251 char gas[] = {1, 1, 1, 1, 3, 3, 3, 0};
|
|
252 setup_dive(19, 51, stops, gas); // 19' @ 51m --> 20' CCR / 31' BAIL
|
|
253
|
|
254 ASSERT_NO_THROW( deco_gas_volumes() );
|
|
255 check_volumes(/*NO BTM CONSO*/ ascent(20,51,21) +
|
|
256 fixed(20, 1,21) + ascent(20,21,18) +
|
|
257 fixed(20, 2,18) + ascent(20,18,15) +
|
|
258 fixed(20, 2,15) + ascent(20,15,12) +
|
|
259 fixed(20, 4,12) + ascent(20,12, 9), "Gas1: 786 L",
|
|
260 0, "",
|
|
261 fixed(20, 3, 9) + ascent(20, 9, 6) +
|
|
262 fixed(20, 4, 6) + ascent(20, 6, 3) +
|
|
263 fixed(20, 9, 3) + ascent(20, 3, 0), "Gas3: 502 L",
|
293
|
264 0, "",
|
|
265 0, "");
|
|
266 }
|
290
|
267
|
293
|
268 //////////////////////////////////////////////////////////////////////////////
|
|
269 // v1.82 ZH-L16+GF, CCR, 30%/85%
|
|
270 TEST(gas_volume, CCR_15min60m)
|
|
271 {
|
|
272 char_I_const_ppO2 = 140; // SP 1.4 bar
|
296
|
273 char stops[] = {2, 1, 1, 3, 5, 4, 8, 0}; // BAILOUT mode
|
|
274 char gas[] = {3, 3, 3, 3, 3, 5, 5, 0};
|
293
|
275 setup_dive(15, 60, stops, gas); // 15' @ 60m --> DTR 32'
|
|
276
|
296
|
277 DEFINE_GAS(3, 32, 0, 40, 3); // Gas#3 : Nx32 @ 40m DECO
|
|
278 DEFINE_GAS(5, 90, 0, 6, 3); // Gas#5 : Nx90 @ 6m DECO
|
|
279
|
293
|
280 ASSERT_NO_THROW( deco_gas_volumes() );
|
296
|
281 check_volumes(/*NO BTM CONSO*/ ascent(20,60,21), "Gas1: 394 L",
|
293
|
282 0, "",
|
296
|
283 fixed(20, 2,21) + ascent(20,21,18) +
|
|
284 fixed(20, 1,18) + ascent(20,18,15) +
|
|
285 fixed(20, 1,15) + ascent(20,15,12) +
|
|
286 fixed(20, 3,12) + ascent(20,12, 9) +
|
|
287 fixed(20, 5, 9) + ascent(20, 9, 6), "Gas3: 623 L",
|
293
|
288 0, "",
|
296
|
289 fixed(20, 4, 6) + ascent(20, 6, 3) +
|
|
290 fixed(20, 8, 3) + ascent(20, 3, 0), "Gas5: 352 L");
|
290
|
291 }
|