GCC Code Coverage Report


Directory: src/
File: src/Linearisation.cpp
Date: 2026-09-03 17:04:53
Exec Total Coverage
Lines: 0 45 0.0%
Branches: 0 43 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/Linearisation.h"
24
25 #include "Base.h"
26 #include "reta/Interpolation.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 struct RETA_LOCAL Linearisation::Impl : public Base
41 {
42 Impl(shared_ptr<Task>,
43 const string &,
44 const double tableInit[][2],
45 unsigned int tableRows,
46 unsigned int width);
47
48 void update(const vector<double> &);
49
50 shared_ptr<Task> task;
51
52 enum Mode { LookupTable, Exponential } mode;
53
54 Interpolation table;
55
56 double expFactor;
57 vector<double> expOutput;
58
59 vector<double> output; /**< Output value selected by mode. */
60 };
61
62 /****************************************************************************/
63
64 Linearisation::Impl::Impl(
65 shared_ptr<Task> task,
66 const string &prefix,
67 const double tableInit[][2],
68 unsigned int tableRows,
69 unsigned int width) :
70 Base {prefix},
71 task {task},
72 mode {LookupTable},
73 table {task, prefix + "/Table", tableInit, tableRows, width},
74 expFactor {1.0},
75 expOutput(width, 0.0),
76 output(width, 0.0)
77 {
78 checkZeroWidth(width);
79
80 pdserv *pdserv {task->getPdServ()};
81 pdtask *pdtask {task->getPdTask()};
82
83 pdserv_parameter(
84 pdserv, (prefix + "/Mode").c_str(), 0666, pd_sint32_T, &mode, 1,
85 NULL, NULL, NULL);
86
87 pdserv_parameter(
88 pdserv, (prefix + "/ExpFactor").c_str(), 0666, pd_double_T,
89 &expFactor, 1, NULL, NULL, NULL);
90 pdserv_signal(
91 pdtask, 1, (prefix + "/ExpOutput").c_str(), pd_double_T,
92 expOutput.data(), expOutput.size(), NULL);
93 }
94
95 /****************************************************************************/
96
97 /** Linearisation.
98 * Depending on the selected mode, the output is either taken from a lookup
99 * table (with interpolation) or calculated as an exponential function of the
100 * input.
101 */
102 void Linearisation::Impl::update(const vector<double> &input)
103 {
104 checkSize(input, output);
105
106 table.update(input);
107
108 for (unsigned int i = 0; i < output.size(); i++) {
109 expOutput[i] = exp(input[i] * expFactor);
110 }
111
112 switch (mode) {
113 case LookupTable:
114 output = table.getOutputVector();
115 break;
116
117 case Exponential:
118 output = expOutput;
119 break;
120 }
121 }
122
123 /****************************************************************************/
124
125 Linearisation::Linearisation(
126 shared_ptr<Task> task,
127 const string &prefix,
128 const double tableInit[][2],
129 unsigned int tableRows,
130 unsigned int width) :
131 impl {make_unique<Impl>(task, prefix, tableInit, tableRows, width)}
132 {}
133
134 /****************************************************************************/
135
136 Linearisation::~Linearisation()
137 {}
138
139 /****************************************************************************/
140
141 void Linearisation::update(double input)
142 {
143 impl->update(vector<double> {input});
144 }
145
146 /****************************************************************************/
147
148 void Linearisation::update(const vector<double> &input)
149 {
150 impl->update(input);
151 }
152
153 /****************************************************************************/
154
155 void Linearisation::update(function<double(unsigned int)> input)
156 {
157 vector<double> inputVector(impl->output.size());
158
159 for (unsigned int i = 0; i < impl->output.size(); i++) {
160 inputVector[i] = input(i);
161 }
162
163 impl->update(inputVector);
164 }
165
166 /****************************************************************************/
167
168 double Linearisation::getOutput(unsigned int i) const
169 {
170 return impl->output.at(i);
171 }
172
173 /****************************************************************************/
174
175 vector<double> Linearisation::getOutputVector() const
176 {
177 return impl->output;
178 }
179
180 /****************************************************************************/
181