GCC Code Coverage Report


Directory: src/
File: src/Relay.cpp
Date: 2026-09-03 17:04:53
Exec Total Coverage
Lines: 0 43 0.0%
Branches: 0 48 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/Relay.h"
24
25 #include "Base.h"
26
27 using namespace Reta;
28 using namespace std;
29
30 /****************************************************************************/
31
32 struct RETA_LOCAL Relay::Impl : public Base
33 {
34 Impl(shared_ptr<Task>,
35 const std::string &,
36 double,
37 double,
38 double,
39 unsigned int);
40
41 shared_ptr<Task> task;
42
43 vector<double> upperHisteresis;
44 vector<double> lowerHisteresis;
45 vector<double> switchPoint;
46 vector<uint8_t> output;
47 };
48
49 /****************************************************************************/
50
51 Relay::Impl::Impl(
52 shared_ptr<Task> task,
53 const std::string &prefix,
54 double initSwitchPoint,
55 double initUpperHisteresis,
56 double initLowerHisteresis,
57 unsigned int width) :
58 Base {prefix},
59 task {task},
60 upperHisteresis(width, initUpperHisteresis),
61 lowerHisteresis(width, initLowerHisteresis),
62 switchPoint(width, initSwitchPoint),
63 output(width, false)
64 {
65 checkZeroWidth(width);
66
67 pdserv *pdserv {task->getPdServ()};
68 pdtask *pdtask {task->getPdTask()};
69
70 pdserv_parameter(
71 pdserv, (prefix + "/UpperHisteresis").c_str(), 0666, pd_double_T,
72 upperHisteresis.data(), upperHisteresis.size(), NULL, NULL, NULL);
73 pdserv_parameter(
74 pdserv, (prefix + "/LowerHisteresis").c_str(), 0666, pd_double_T,
75 lowerHisteresis.data(), lowerHisteresis.size(), NULL, NULL, NULL);
76 pdserv_parameter(
77 pdserv, (prefix + "/SwitchPoint").c_str(), 0666, pd_double_T,
78 switchPoint.data(), switchPoint.size(), NULL, NULL, NULL);
79 pdserv_signal(
80 pdtask, 1, (prefix + "/Output").c_str(), pd_uint8_T,
81 output.data(), output.size(), NULL);
82 }
83
84 /****************************************************************************/
85
86 Relay::Relay(
87 shared_ptr<Task> task,
88 const std::string &prefix,
89 double initSwitchPoint,
90 double initUpperHisteresis,
91 double initLowerHisteresis,
92 unsigned int width) :
93 impl {make_unique<Impl>(
94 task,
95 prefix,
96 initSwitchPoint,
97 initUpperHisteresis,
98 initLowerHisteresis,
99 width)}
100 {}
101
102 /****************************************************************************/
103
104 Relay::~Relay()
105 {}
106
107 /****************************************************************************/
108
109 void Relay::update(double input)
110 {
111 update(vector<double> {input});
112 }
113
114 /****************************************************************************/
115
116 void Relay::update(std::function<double(unsigned int)> input)
117 {
118 vector<double> inputVector(impl->output.size());
119 for (unsigned int i = 0; i < impl->output.size(); i++) {
120 inputVector[i] = input(i);
121 }
122
123 update(inputVector);
124 }
125
126 /****************************************************************************/
127
128 void Relay::update(const vector<double> &input)
129 {
130 impl->checkSize(input, impl->output);
131
132 for (unsigned int i = 0; i < impl->output.size(); i++) {
133 auto upperSwitchPoint(
134 impl->switchPoint[i] + impl->upperHisteresis[i]);
135 auto lowerSwitchPoint(
136 impl->switchPoint[i] + impl->lowerHisteresis[i]);
137
138 if (input[i] >= upperSwitchPoint) {
139 impl->output[i] = true;
140 }
141 else if (input[i] <= lowerSwitchPoint) {
142 impl->output[i] = false;
143 }
144 }
145 }
146
147 /****************************************************************************/
148
149 bool Relay::getOutput(unsigned int i) const
150 {
151 return impl->output[i];
152 }
153
154 /****************************************************************************/
155
156 const std::vector<uint8_t> Relay::getOutputVector() const
157 {
158 return impl->output;
159 }
160
161 /****************************************************************************/
162