GCC Code Coverage Report


Directory: src/
File: src/FunctionGenerator.cpp
Date: 2026-09-03 17:04:53
Exec Total Coverage
Lines: 249 249 100.0%
Branches: 185 289 64.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * Copyright (C) 2021 Jonathan Grahl <jonathan.grahl@igh.de>
4 * 2021 Florian Pose <florian.pose@igh.de>
5 *
6 * This file is part of the reta library (realtime-automation).
7 *
8 * The reta library is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation, either version 3 of the License, or (at
11 * your option) any later version.
12 *
13 * The reta library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with the reta library. If not, see <http://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23 #include "reta/FunctionGenerator.h"
24
25 #include "Base.h"
26 #include "reta/UserParameter.h"
27
28 #include <cmath>
29
30 using std::function;
31 using std::make_unique;
32 using std::shared_ptr;
33 using std::string;
34 using std::vector;
35
36 using namespace Reta;
37
38 /****************************************************************************/
39
40 22 struct RETA_LOCAL FunctionGenerator::Impl : public Base
41 {
42 Impl(shared_ptr<Task>, const string &, unsigned int);
43
44 void update(const vector<uint8_t> &, const vector<uint8_t> &);
45 void triggerRampOnce(unsigned int);
46 void triggerSineOnce(unsigned int);
47
48 shared_ptr<Task> task;
49
50 enum RampPhase { Rise, High, Fall, Low };
51
52 vector<double> offset;
53
54 UserParameter sineStartCyclic;
55 UserParameter sineStartOnce;
56 UserParameter sineStop;
57 vector<uint8_t> sineAllowStart;
58 vector<uint8_t> sineState;
59 vector<uint8_t> sineOneShot;
60 vector<double> sineFrequency;
61 vector<double> sineAmplitude;
62 vector<double> sineInput;
63 vector<double> sineOutput;
64 vector<double> sineSpeed;
65
66 UserParameter rampStartCyclic;
67 UserParameter rampStartOnce;
68 UserParameter rampStop;
69 vector<uint8_t> rampAllowStart;
70 vector<uint8_t> rampState;
71 vector<uint8_t> rampOneShot;
72 vector<double> rampAmplitude;
73 vector<double> riseTime;
74 vector<double> highTime;
75 vector<double> fallTime;
76 vector<double> lowTime;
77 vector<RampPhase> rampPhase;
78 vector<double> rampTime;
79 vector<double> rampOutput;
80 vector<double> rampSpeed;
81 vector<uint8_t> rampFinishedEvent;
82 vector<uint8_t> sineFinishedEvent;
83
84 vector<double> output;
85 vector<double> speed;
86 };
87
88 /****************************************************************************/
89
90 23 FunctionGenerator::Impl::Impl(
91 shared_ptr<Task> task,
92 const string &prefix,
93 23 unsigned int width) :
94 Base {prefix},
95 task {task},
96 offset(width, 0.0),
97
1/2
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
46 sineStartCyclic(task, prefix + "/Sine/StartCyclic", width),
98
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 sineStartOnce(task, prefix + "/Sine/StartOnce", width),
99
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 sineStop(task, prefix + "/Sine/Stop", width),
100 sineAllowStart(width, false),
101 sineState(width, false),
102 sineOneShot(width, false),
103 sineFrequency(width, 1.0),
104 sineAmplitude(width, 1.0),
105 sineInput(width, 0.0),
106 sineOutput(width, 0.0),
107 sineSpeed(width, 0.0),
108
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 rampStartCyclic(task, prefix + "/Ramp/StartCyclic", width),
109
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 rampStartOnce(task, prefix + "/Ramp/StartOnce", width),
110
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 rampStop(task, prefix + "/Ramp/Stop", width),
111 rampAllowStart(width, false),
112 rampState(width, false),
113 rampOneShot(width, false),
114 rampAmplitude(width, 1.0),
115 riseTime(width, 0.2),
116 highTime(width, 0.8),
117 fallTime(width, 0.2),
118 lowTime(width, 0.8),
119 rampPhase(width, Rise),
120 rampTime(width, 0.0),
121 rampOutput(width, 0.0),
122 rampSpeed(width, 0.0),
123 rampFinishedEvent(width, false),
124 sineFinishedEvent(width, false),
125 output(width, 0.0),
126
32/62
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 22 times.
✓ Branch 10 taken 1 times.
✓ Branch 14 taken 22 times.
✗ Branch 15 not taken.
✓ Branch 19 taken 22 times.
✗ Branch 20 not taken.
✓ Branch 24 taken 22 times.
✗ Branch 25 not taken.
✓ Branch 29 taken 22 times.
✗ Branch 30 not taken.
✓ Branch 34 taken 22 times.
✗ Branch 35 not taken.
✓ Branch 39 taken 22 times.
✗ Branch 40 not taken.
✓ Branch 44 taken 22 times.
✗ Branch 45 not taken.
✓ Branch 49 taken 22 times.
✗ Branch 50 not taken.
✓ Branch 54 taken 22 times.
✗ Branch 55 not taken.
✓ Branch 59 taken 22 times.
✗ Branch 60 not taken.
✓ Branch 64 taken 22 times.
✗ Branch 65 not taken.
✓ Branch 69 taken 22 times.
✗ Branch 70 not taken.
✓ Branch 74 taken 22 times.
✗ Branch 75 not taken.
✓ Branch 79 taken 22 times.
✗ Branch 80 not taken.
✓ Branch 84 taken 22 times.
✗ Branch 85 not taken.
✓ Branch 89 taken 22 times.
✗ Branch 90 not taken.
✓ Branch 94 taken 22 times.
✗ Branch 95 not taken.
✓ Branch 99 taken 22 times.
✗ Branch 100 not taken.
✓ Branch 104 taken 22 times.
✗ Branch 105 not taken.
✓ Branch 109 taken 22 times.
✗ Branch 110 not taken.
✓ Branch 114 taken 22 times.
✗ Branch 115 not taken.
✓ Branch 119 taken 22 times.
✗ Branch 120 not taken.
✓ Branch 124 taken 22 times.
✗ Branch 125 not taken.
✓ Branch 129 taken 22 times.
✗ Branch 130 not taken.
✓ Branch 134 taken 22 times.
✗ Branch 135 not taken.
✓ Branch 139 taken 22 times.
✗ Branch 140 not taken.
✓ Branch 144 taken 22 times.
✗ Branch 145 not taken.
✓ Branch 149 taken 22 times.
✗ Branch 150 not taken.
✓ Branch 154 taken 22 times.
✗ Branch 155 not taken.
288 speed(width, 0.0)
127 {
128
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 checkZeroWidth(width);
129
130
1/2
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
22 pdserv *pdserv {task->getPdServ()};
131
1/2
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
22 pdtask *pdtask {task->getPdTask()};
132
133
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
134
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Offset").c_str(), 0666, pd_double_T,
135 22 offset.data(), offset.size(), NULL, NULL, NULL);
136
137
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
138
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Sine/AllowStart").c_str(), pd_boolean_T,
139 22 sineAllowStart.data(), sineAllowStart.size(), NULL);
140
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
141
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Sine/State").c_str(), pd_boolean_T,
142 22 sineState.data(), sineState.size(), NULL);
143
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
144
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Sine/OneShot").c_str(), pd_boolean_T,
145 22 sineOneShot.data(), sineOneShot.size(), NULL);
146
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
147
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Sine/Frequency").c_str(), 0666, pd_double_T,
148 22 sineFrequency.data(), sineFrequency.size(), NULL, NULL, NULL);
149
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
150
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Sine/Amplitude").c_str(), 0666, pd_double_T,
151 22 sineAmplitude.data(), sineAmplitude.size(), NULL, NULL, NULL);
152
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
153
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Sine/Input").c_str(), pd_double_T,
154 22 sineInput.data(), sineInput.size(), NULL);
155
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
156
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Sine/Output").c_str(), pd_double_T,
157 22 sineOutput.data(), sineOutput.size(), NULL);
158
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
159
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Sine/Speed").c_str(), pd_double_T,
160 22 sineSpeed.data(), sineSpeed.size(), NULL);
161
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
162
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Sine/FinishedEvent").c_str(), pd_boolean_T,
163 22 sineFinishedEvent.data(), sineFinishedEvent.size(), NULL);
164
165
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
166
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/AllowStart").c_str(), pd_boolean_T,
167 22 rampAllowStart.data(), rampAllowStart.size(), NULL);
168
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
169
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/State").c_str(), pd_boolean_T,
170 22 rampState.data(), rampState.size(), NULL);
171
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
172
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/OneShot").c_str(), pd_boolean_T,
173 22 rampOneShot.data(), rampOneShot.size(), NULL);
174
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
175
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Ramp/Amplitude").c_str(), 0666, pd_double_T,
176 22 rampAmplitude.data(), rampAmplitude.size(), NULL, NULL, NULL);
177
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
178
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Ramp/RiseTime").c_str(), 0666, pd_double_T,
179 22 riseTime.data(), riseTime.size(), NULL, NULL, NULL);
180
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
181
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Ramp/HighTime").c_str(), 0666, pd_double_T,
182 22 highTime.data(), highTime.size(), NULL, NULL, NULL);
183
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
184
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Ramp/FallTime").c_str(), 0666, pd_double_T,
185 22 fallTime.data(), fallTime.size(), NULL, NULL, NULL);
186
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_parameter(
187
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdserv, (prefix + "/Ramp/LowTime").c_str(), 0666, pd_double_T,
188 22 lowTime.data(), lowTime.size(), NULL, NULL, NULL);
189
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
190
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/Time").c_str(), pd_double_T,
191 22 rampTime.data(), rampTime.size(), NULL);
192
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
193
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/Phase").c_str(), pd_sint32_T,
194 22 rampPhase.data(), rampPhase.size(), NULL);
195
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
196
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/Output").c_str(), pd_double_T,
197 22 rampOutput.data(), rampOutput.size(), NULL);
198
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
199
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/Speed").c_str(), pd_double_T,
200 22 rampSpeed.data(), rampSpeed.size(), NULL);
201
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
202
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Ramp/FinishedEvent").c_str(), pd_boolean_T,
203 22 rampFinishedEvent.data(), rampFinishedEvent.size(), NULL);
204
205
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
206
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
44 pdtask, 1, (prefix + "/Output").c_str(), pd_double_T,
207 22 output.data(), output.size(), NULL);
208
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
44 pdserv_signal(
209
1/2
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
44 pdtask, 1, (prefix + "/Speed").c_str(), pd_double_T, speed.data(),
210 speed.size(), NULL);
211 22 }
212
213 /****************************************************************************/
214
215 90 void FunctionGenerator::Impl::update(
216 const vector<uint8_t> &extStop,
217 const vector<uint8_t> &extError)
218 {
219 90 checkSize(extStop, output);
220 89 checkSize(extError, output);
221
222 89 sineStartCyclic.update();
223 89 sineStartOnce.update();
224 89 sineStop.update();
225
226 89 rampStartCyclic.update();
227 89 rampStartOnce.update();
228 89 rampStop.update();
229
230
2/2
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 89 times.
182 for (unsigned int i = 0; i < output.size(); i++) {
231
4/4
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 55 times.
✓ Branch 4 taken 37 times.
✓ Branch 5 taken 1 times.
93 sineAllowStart[i] = !sineState[i] && !extError[i];
232
233
8/8
✓ Branch 1 taken 92 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 90 times.
✓ Branch 5 taken 2 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 89 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 89 times.
93 if (sineStop.getChanged(i) || extError[i] || extStop[i]) {
234 4 sineState[i] = false;
235 }
236
6/6
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 52 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 36 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 88 times.
89 else if (!sineState[i] && sineStartOnce.getChanged(i)) {
237 1 sineState[i] = true;
238 1 sineOneShot[i] = true;
239 1 sineInput[i] = 0.0;
240 }
241
6/6
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 52 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 35 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 87 times.
88 else if (!sineState[i] && sineStartCyclic.getChanged(i)) {
242 1 sineState[i] = true;
243 1 sineOneShot[i] = false;
244 1 sineInput[i] = 0.0;
245 }
246
247 93 bool triggerSineFinishedEvent = false;
248
2/2
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 39 times.
93 if (sineState[i]) {
249 54 sineInput[i] += sineFrequency[i] * task->getPeriod();
250 54 sineOutput[i] = sin(sineInput[i] * 2.0 * M_PI) * sineAmplitude[i];
251 108 sineSpeed[i] = 2.0 * M_PI * cos(sineInput[i] * 2.0 * M_PI)
252 54 * sineAmplitude[i] * sineFrequency[i];
253
254
6/6
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 31 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 53 times.
54 if (sineOneShot[i] && sineInput[i] >= 1.0) {
255 1 sineState[i] = false;
256 1 triggerSineFinishedEvent = true;
257 }
258 }
259 else {
260 39 sineOutput[i] = 0.0;
261 39 sineSpeed[i] = 0.0;
262 }
263
264
4/4
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 27 times.
✓ Branch 4 taken 65 times.
✓ Branch 5 taken 1 times.
93 rampAllowStart[i] = !rampState[i] && !extError[i];
265
266
8/8
✓ Branch 1 taken 92 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 90 times.
✓ Branch 5 taken 2 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 89 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 89 times.
93 if (rampStop.getChanged(i) || extError[i] || extStop[i]) {
267 4 rampState[i] = false;
268 }
269
6/6
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 24 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 64 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 88 times.
89 else if (!rampState[i] && rampStartOnce.getChanged(i)) {
270 1 triggerRampOnce(i);
271 }
272
6/6
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 24 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 63 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 87 times.
88 else if (!rampState[i] && rampStartCyclic.getChanged(i)) {
273 1 rampState[i] = true;
274 1 rampOneShot[i] = false;
275 1 rampTime[i] = 0.0;
276 1 rampPhase[i] = Rise;
277 }
278
279 93 bool triggerRampFinishedEvent = false;
280
281
2/2
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 67 times.
93 if (rampState[i]) {
282
4/5
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
26 switch (rampPhase[i]) {
283 12 case Rise:
284
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 10 times.
12 if (rampTime[i] >= riseTime[i]) {
285 2 rampTime[i] = 0.0;
286 2 rampPhase[i] = High;
287 }
288 else {
289 10 rampSpeed[i] = rampAmplitude[i] / riseTime[i];
290 10 rampOutput[i] = rampSpeed[i] * rampTime[i];
291 10 break;
292 }
293 [[fallthrough]];
294
295 case High:
296
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
6 if (rampTime[i] >= highTime[i]) {
297 2 rampTime[i] = 0.0;
298 2 rampPhase[i] = Fall;
299 }
300 else {
301 4 rampOutput[i] = rampAmplitude[i];
302 4 rampSpeed[i] = 0.0;
303 4 break;
304 }
305 [[fallthrough]];
306
307 case Fall:
308
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
8 if (rampTime[i] >= fallTime[i]) {
309 2 rampTime[i] = 0.0;
310 2 rampPhase[i] = Low;
311 }
312 else {
313 6 rampSpeed[i] = -rampAmplitude[i] / fallTime[i];
314 6 rampOutput[i] =
315 6 rampAmplitude[i] + rampSpeed[i] * rampTime[i];
316 6 break;
317 }
318 [[fallthrough]];
319
320 case Low:
321
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
6 if (rampTime[i] >= lowTime[i]) {
322 2 rampTime[i] = 0.0;
323 2 rampPhase[i] = Rise;
324 2 triggerRampFinishedEvent = true;
325
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (rampOneShot[i]) {
326 1 rampState[i] = false;
327 }
328 }
329 6 rampOutput[i] = 0.0;
330 6 rampSpeed[i] = 0.0;
331 }
332 26 rampTime[i] += task->getPeriod();
333 }
334 else {
335 67 rampOutput[i] = 0.0;
336 67 rampSpeed[i] = 0.0;
337 }
338
339 93 output[i] = offset[i] + sineOutput[i] + rampOutput[i];
340 93 speed[i] = sineSpeed[i] + rampSpeed[i];
341
342 /** Funktion im Sequencer ignorieren.
343 * Damit es moeglich ist nur eine der beiden Funktionen im
344 * Sequencer zu nutzen, kann die jeweils andere auf eine
345 * Amplitude von 0.0 gesetzt werden. Um nicht durchgehend diese
346 * Funktion aktiv zu haben, wird sie hier direkt auf "fertig"
347 * gesetzt. So kann der Sequencer einen Schritt weiter gehen,
348 * ohne auf die andere Funktion warten zu muessen. */
349
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 92 times.
93 if (rampAmplitude[i] == 0.0) {
350 1 triggerRampFinishedEvent = true;
351 }
352
353
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 92 times.
93 if (sineAmplitude[i] == 0.0) {
354 1 triggerSineFinishedEvent = true;
355 }
356
357 93 rampFinishedEvent[i] = triggerRampFinishedEvent;
358 93 sineFinishedEvent[i] = triggerSineFinishedEvent;
359 }
360 89 }
361
362 /****************************************************************************/
363
364 4 void FunctionGenerator::Impl::triggerRampOnce(unsigned int i)
365 {
366
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
4 if (!rampState.at(i) && rampAmplitude.at(i) != 0.0) {
367 4 rampState[i] = true;
368 4 rampOneShot[i] = true;
369 4 rampTime[i] = 0.0;
370 4 rampPhase[i] = Rise;
371 }
372 4 }
373
374 /****************************************************************************/
375
376 3 void FunctionGenerator::Impl::triggerSineOnce(unsigned int i)
377 {
378
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
3 if (!sineState.at(i) && sineAmplitude.at(i) != 0.0) {
379 3 sineState[i] = true;
380 3 sineOneShot[i] = true;
381 3 sineInput[i] = 0.0;
382 }
383 3 }
384
385 /****************************************************************************/
386
387 23 FunctionGenerator::FunctionGenerator(
388 shared_ptr<Task> task,
389 const string &prefix,
390 23 unsigned int width) :
391 23 impl {make_unique<Impl>(task, prefix, width)}
392 22 {}
393
394 /****************************************************************************/
395
396 22 FunctionGenerator::~FunctionGenerator()
397 22 {}
398
399 /****************************************************************************/
400
401 87 void FunctionGenerator::update(bool extStop, bool extError)
402 {
403
3/6
✓ Branch 2 taken 87 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 87 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 87 times.
✗ Branch 10 not taken.
87 update(vector<uint8_t> {extStop}, vector<uint8_t> {extError});
404 87 }
405
406 /****************************************************************************/
407
408 90 void FunctionGenerator::update(
409 const vector<uint8_t> &extStop,
410 const vector<uint8_t> &extError)
411 {
412 90 impl->update(extStop, extError);
413 89 }
414
415 /****************************************************************************/
416
417 1 void FunctionGenerator::update(
418 function<bool(unsigned int)> extStop,
419 function<bool(unsigned int)> extError)
420 {
421
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 vector<uint8_t> extStopVector(impl->output.size());
422
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 vector<uint8_t> extErrorVector(impl->output.size());
423
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
4 for (unsigned int i = 0; i < impl->output.size(); i++) {
424
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 extStopVector[i] = extStop(i);
425
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 extErrorVector[i] = extError(i);
426 }
427
428
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 update(extStopVector, extErrorVector);
429 1 }
430
431 /****************************************************************************/
432
433 5 void FunctionGenerator::setRampAmplitude(double value, unsigned int i)
434 {
435 5 impl->rampAmplitude.at(i) = value;
436 5 }
437
438 /****************************************************************************/
439
440 2 void FunctionGenerator::setRiseTime(double value, unsigned int i)
441 {
442 2 impl->riseTime.at(i) = value;
443 2 }
444
445 /****************************************************************************/
446
447 2 void FunctionGenerator::setHighTime(double value, unsigned int i)
448 {
449 2 impl->highTime.at(i) = value;
450 2 }
451
452 /****************************************************************************/
453
454 2 void FunctionGenerator::setFallTime(double value, unsigned int i)
455 {
456 2 impl->fallTime.at(i) = value;
457 2 }
458
459 /****************************************************************************/
460
461 2 void FunctionGenerator::setLowTime(double value, unsigned int i)
462 {
463 2 impl->lowTime.at(i) = value;
464 2 }
465
466 /****************************************************************************/
467
468 5 void FunctionGenerator::setSineAmplitude(double value, unsigned int i)
469 {
470 5 impl->sineAmplitude.at(i) = value;
471 5 }
472
473 /****************************************************************************/
474
475 2 void FunctionGenerator::setSineFrequency(double value, unsigned int i)
476 {
477 2 impl->sineFrequency.at(i) = value;
478 2 }
479
480 /****************************************************************************/
481
482 35 double FunctionGenerator::getOutput(unsigned int i) const
483 {
484 35 return impl->output.at(i);
485 }
486
487 /****************************************************************************/
488
489 2 vector<double> FunctionGenerator::getOutputVector() const
490 {
491 2 return impl->output;
492 }
493
494 /****************************************************************************/
495
496 34 double FunctionGenerator::getSpeed(unsigned int i) const
497 {
498 34 return impl->speed.at(i);
499 }
500
501 /****************************************************************************/
502
503 1 vector<double> FunctionGenerator::getSpeedVector() const
504 {
505 1 return impl->speed;
506 }
507
508 /****************************************************************************/
509
510 3 void FunctionGenerator::triggerRampOnce(unsigned int i)
511 {
512 3 impl->triggerRampOnce(i);
513 3 }
514
515 /****************************************************************************/
516
517 3 void FunctionGenerator::triggerSineOnce(unsigned int i)
518 {
519 3 impl->triggerSineOnce(i);
520 3 }
521
522 /****************************************************************************/
523
524 14 bool FunctionGenerator::getRampFinishedEvent(unsigned int i) const
525 {
526 14 return impl->rampFinishedEvent.at(i);
527 }
528
529 /****************************************************************************/
530
531 33 bool FunctionGenerator::getSineFinishedEvent(unsigned int i) const
532 {
533 33 return impl->sineFinishedEvent.at(i);
534 }
535
536 /****************************************************************************/
537
538 62 bool FunctionGenerator::getSineState(unsigned int i) const
539 {
540 62 return impl->sineState.at(i);
541 }
542
543 /****************************************************************************/
544
545 22 bool FunctionGenerator::getRampState(unsigned int i) const
546 {
547 22 return impl->rampState.at(i);
548 }
549
550 /****************************************************************************/
551