Skip to content

Commit 455c36b

Browse files
committed
Refined the form of test suites generated for the PID controller.
1 parent 6266a20 commit 455c36b

File tree

2 files changed

+61
-32
lines changed

2 files changed

+61
-32
lines changed

doc/html-manual/cover.shtml

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ is plotted in the Figure below.
7777
22: // Vertical speed of the UAV detected by GPS sensor
7878
23: float estimator_z_dot;
7979
24:
80-
25: /** PID funciton OUTPUTS */
80+
25: /** PID function OUTPUTS */
8181
26: float desired_gaz;
8282
27: float desired_pitch;
8383
28:
84-
29: /** Accumulated error in the control */
85-
30: float climb_sum_err;
84+
29: /** The state variable: accumulated error in the control */
85+
30: float climb_sum_err=0;
8686
31:
8787
32: /** Computes desired_gaz and desired_pitch */
8888
33: void climb_pid_run()
@@ -118,26 +118,35 @@ is plotted in the Figure below.
118118
63: __CPROVER_assume(desired_climb>=-MAX_CLIMB && desired_climb<=MAX_CLIMB);
119119
64: __CPROVER_assume(estimator_z_dot>=-MAX_CLIMB && estimator_z_dot<=MAX_CLIMB);
120120
65:
121-
66: climb_pid_run();
122-
67:
123-
68: }
124-
69:
125-
70: return 0;
126-
72: }
121+
66: __CPROVER_input("desired_climb", desired_climb);
122+
67: __CPROVER_input("estimator_z_dot", estimator_z_dot);
123+
68:
124+
69: climb_pid_run();
125+
70:
126+
71: __CPROVER_output("desired_gaz", desired_gaz);
127+
72: __CPROVER_output("desired_pitch", desired_pitch);
128+
73:
129+
74: }
130+
75:
131+
76: return 0;
132+
77: }
127133
</code></pre>
128134

129135
<p class="justified">
130136
In order to test the PID controller, we construct a main control loop,
131-
which repeatedly invokes the function <code>climb_pid_run</code> (line 66).
132-
In the beginning of each loop iteration, the values of the desired speed <code>desired_climb</code>
133-
and the estimated speed <code>estimated_z_dot</code> are assigned non-deterministically.
137+
which repeatedly invokes the function <code>climb_pid_run</code> (line 69).
138+
This PID function has two input variables: the desired speed <code>desired_climb</code>
139+
and the estimated speed <code>estimated_z_dot</code>.
140+
In the beginning of each loop iteration, values of the inputs are assigned non-deterministically.
134141
Subsequently, the <code>__CPROVER_assume</code> statement in lines 63 and 64 guarantees that
135-
their values are bounded within a valid range.
142+
both values are bounded within a valid range.
143+
The <code>__CPROVER_input</code> and <code>__CPROVER_output</code> will help clarify the inputs
144+
and outputs of interest for generating test suites.
136145
</p>
137146

138147
<p class="justified">
139148
To demonstrate the automatic test suite generation in CBMC,
140-
we call the following command
149+
we call the following command and we are going to explain the command line options one by one.
141150
</p>
142151

143152
<pre><code>cbmc pid.c --cover mcdc --unwind 6 --trace --xml-ui
@@ -172,16 +181,37 @@ goals at the same time. Each trace corresponds to a test case.
172181
</p>
173182

174183
<p class="justified">
175-
For the example above, the following test suites are generated.
184+
In the end, the following test suites are automatically generated for testing the PID controller.
176185
A test suite consists of a sequence of input parameters that are
177186
passed to the PID function <code>climb_pid_run</code> at each loop iteration.
187+
For example, Test 1 covers the MC/DC goal with id="climb_pid_run.coverage.1".
178188
<pre><code>Test suite:
179-
T1: (desired_climb=-1.000000f, estimator_z_dot=-1.000000f)
180-
<em>goal id: climb_pid_run.coverage.1</em>
181-
T2: (desired_climb=-1.000000f, estimator_z_dot=-1.000000f); (desired_climb=1.000000f, estimator_z_dot=1.000000f)
182-
<em>goal id: climb_pid_run.coverage.2</em>
183-
T3: (desired_climb=0.000000f, estimator_z_dot=1.000000f)
184-
<em>goal id: climb_pid_run.coverage.3</em>
189+
Test 1.
190+
(iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f
191+
192+
Test 2.
193+
(iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f
194+
(iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f
195+
196+
Test 3.
197+
(iteration 1) desired_climb=0.000000f, estimator_z_dot=-1.000000f
198+
(iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f
199+
200+
Test 4.
201+
(iteration 1) desired_climb=1.000000f, estimator_z_dot=-1.000000f
202+
(iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f
203+
(iteration 3) desired_climb=1.000000f, estimator_z_dot=-1.000000f
204+
(iteration 4) desired_climb=1.000000f, estimator_z_dot=-1.000000f
205+
(iteration 5) desired_climb=0.000000f, estimator_z_dot=-1.000000f
206+
(iteration 6) desired_climb=1.000000f, estimator_z_dot=-1.000000f
207+
208+
Test 5.
209+
(iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f
210+
(iteration 2) desired_climb=-1.000000f, estimator_z_dot=1.000000f
211+
(iteration 3) desired_climb=-1.000000f, estimator_z_dot=1.000000f
212+
(iteration 4) desired_climb=-1.000000f, estimator_z_dot=1.000000f
213+
(iteration 5) desired_climb=-1.000000f, estimator_z_dot=1.000000f
214+
(iteration 6) desired_climb=-1.000000f, estimator_z_dot=1.000000f
185215
</code></pre>
186216
</p>
187217

@@ -191,14 +221,7 @@ function body six times. In order to achieve the complete coverage on all the in
191221
in the PID function <code>climb_pid_run</code>, the loop must be unwound sufficient enough times.
192222
For example, <code>climb_pid_run</code> needs to be called at least six times for evaluating the
193223
condition <code>climb_sum_err>MAX_CLIMB_SUM_ERR</code> in line 48 to <em>true</em>.
194-
This corresponds to the test suite below.
195-
<pre><code>(desired_climb=-1.000000f, estimator_z_dot=1.000000f);
196-
(desired_climb=-1.000000f, estimator_z_dot=0.000000f);
197-
(desired_climb=-1.000000f, estimator_z_dot=1.000000f);
198-
(desired_climb=-1.000000f, estimator_z_dot=1.000000f);
199-
(desired_climb=-1.000000f, estimator_z_dot=1.000000f);
200-
(desired_climb=-1.000000f, estimator_z_dot=1.000000f).
201-
</code></pre>
224+
This corresponds to the Test 5.
202225
An introduction to the use of loop unwinding can be found
203226
in <a href="cbmc-loops.shtml">Understanding Loop Unwinding</a>.
204227
</p>

doc/html-manual/pid.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ float desired_climb;
2222
// Vertical speed of the UAV detected by GPS sensor
2323
float estimator_z_dot;
2424

25-
/** PID funciton OUTPUTS */
25+
/** PID function OUTPUTS */
2626
float desired_gaz;
2727
float desired_pitch;
2828

29-
/** Accumulated error in the control */
30-
float climb_sum_err;
29+
/** The state variable: accumulated error in the control */
30+
float climb_sum_err=0;
3131

3232
/** Computes desired_gaz and desired_pitch */
3333
void climb_pid_run()
@@ -63,8 +63,14 @@ int main()
6363
__CPROVER_assume(desired_climb>=-MAX_CLIMB && desired_climb<=MAX_CLIMB);
6464
__CPROVER_assume(estimator_z_dot>=-MAX_CLIMB && estimator_z_dot<=MAX_CLIMB);
6565

66+
__CPROVER_input("desired_climb", desired_climb);
67+
__CPROVER_input("estimator_z_dot", estimator_z_dot);
68+
6669
climb_pid_run();
6770

71+
__CPROVER_output("desired_gaz", desired_gaz);
72+
__CPROVER_output("desired_pitch", desired_pitch);
73+
6874
}
6975

7076
return 0;

0 commit comments

Comments
 (0)