GCC Code Coverage Report


Directory: src/
File: src/BusMonitor.cpp
Date: 2026-09-03 17:04:53
Exec Total Coverage
Lines: 0 58 0.0%
Branches: 0 56 0.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/BusMonitor.h"
24
25 #include "Base.h"
26 #include "reta/Message.h"
27
28 using namespace Reta;
29 using namespace std;
30
31 /****************************************************************************/
32
33 struct RETA_LOCAL Reta::BusMonitor::Impl : public Base
34 {
35 Impl(shared_ptr<Task>, const string &, unsigned int);
36
37 shared_ptr<Task> task;
38 const string prefix;
39
40 vector<double> integrator;
41 vector<double> limit;
42 vector<uint8_t> valid;
43 Message error;
44 };
45
46 /****************************************************************************/
47
48 BusMonitor::Impl::Impl(
49 shared_ptr<Task> task,
50 const string &prefix,
51 unsigned int width) :
52 Base {prefix},
53 task {task},
54 prefix {prefix},
55 integrator(width, 0.0),
56 limit(width, 0.05),
57 valid(width, false),
58 error {task, prefix + "/Error", width}
59 {
60 checkZeroWidth(width);
61
62 pdserv *pdserv {task->getPdServ()};
63 pdtask *pdtask {task->getPdTask()};
64
65 pdserv_signal(
66 pdtask, 1, (prefix + "/Integrator").c_str(), pd_double_T,
67 integrator.data(), integrator.size(), NULL);
68 pdserv_parameter(
69 pdserv, (prefix + "/Limit").c_str(), 0666, pd_double_T,
70 limit.data(), limit.size(), NULL, NULL, NULL);
71 pdserv_signal(
72 pdtask, 1, (prefix + "/Valid").c_str(), pd_boolean_T,
73 valid.data(), valid.size(), NULL);
74 }
75
76 /****************************************************************************/
77
78 BusMonitor::BusMonitor(
79 shared_ptr<Task> task,
80 const string &prefix,
81 unsigned int width) :
82 impl {make_unique<Impl>(task, prefix, width)}
83 {}
84
85 /****************************************************************************/
86
87 BusMonitor::~BusMonitor()
88 {}
89
90 /****************************************************************************/
91
92 void BusMonitor::update(bool domainValid, bool acknowledgeMessages)
93 {
94 update(vector<uint8_t> {domainValid}, acknowledgeMessages);
95 }
96
97 /****************************************************************************/
98
99 void BusMonitor::update(
100 function<bool(unsigned int)> domainValid,
101 bool acknowledgeMessages)
102 {
103 vector<uint8_t> validVector(impl->valid.size());
104 for (unsigned int i = 0; i < impl->valid.size(); i++) {
105 validVector[i] = domainValid(i);
106 }
107
108 update(validVector, acknowledgeMessages);
109 }
110
111 /****************************************************************************/
112
113 void BusMonitor::update(
114 const vector<uint8_t> &domainValid,
115 bool acknowledgeMessages)
116 {
117 impl->checkSize(domainValid, impl->valid);
118
119 for (unsigned int i = 0; i < impl->valid.size(); i++) {
120 impl->integrator[i] +=
121 (domainValid[i] ? -0.1 : 1.0) * impl->task->getPeriod();
122
123 if (impl->integrator[i] < 0.0) {
124 impl->integrator[i] = 0.0;
125 }
126 else if (impl->integrator[i] > impl->limit[i]) {
127 impl->integrator[i] = impl->limit[i];
128 }
129
130 impl->valid[i] = impl->integrator[i] < impl->limit[i];
131 }
132
133 impl->error.update(
134 [this](unsigned int i) { return !impl->valid.at(i); },
135 acknowledgeMessages);
136 }
137
138 /****************************************************************************/
139
140 bool BusMonitor::isValid(unsigned int i) const
141 {
142 return impl->valid.at(i);
143 }
144
145 /****************************************************************************/
146
147 vector<uint8_t> BusMonitor::getValidVector() const
148 {
149 return impl->valid;
150 }
151
152 /****************************************************************************/
153
154 bool BusMonitor::anyValid() const
155 {
156 for (auto valid : impl->valid) {
157 if (valid) {
158 return valid;
159 }
160 }
161
162 return false;
163 }
164
165 /****************************************************************************/
166
167 bool BusMonitor::getError(unsigned int i) const
168 {
169 return impl->error.getState(i);
170 }
171
172 /****************************************************************************/
173
174 vector<uint8_t> BusMonitor::getErrorVector() const
175 {
176 return impl->error.getStateVector();
177 }
178
179 /****************************************************************************/
180
181 bool BusMonitor::anyError() const
182 {
183 return impl->error.anyState();
184 }
185
186 /****************************************************************************/
187
188 bool BusMonitor::eventRising(unsigned int i) const
189 {
190 return impl->error.getRising(i);
191 }
192
193 /****************************************************************************/
194
195 bool BusMonitor::anyEventRising() const
196 {
197 return impl->error.anyRising();
198 }
199
200 /****************************************************************************/
201