common_signal_target.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2020,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  *
22  * Authors: Christoph Rösmann
23  *********************************************************************/
24 
26 
27 #include <iostream>
28 #include <sstream>
29 #include <string>
30 #include <vector>
31 
32 namespace corbo {
33 
35 {
36  if (measurement->header.name.empty())
37  {
38  PRINT_ERROR_NAMED("signal name missing in signal header. Skipping signal.");
39  return;
40  }
41  if (measurement->getValues().empty())
42  {
43  PRINT_WARNING_NAMED("measurement does not contain any values.");
44  }
45 
46  std::string signal_name;
47  SignalInterface::Ptr signal;
48  SignalGroup* group = expandGroups(measurement->header.name, &signal_name, &signal);
49  if (!signal)
50  {
51  // new signal, store all measurements with same name into a TimeSeries signal
52  signal = std::make_shared<TimeSeriesSignal>();
53  signal->header = measurement->header; // copy header to parent object
54  group->group_signals.push_back(signal);
55  }
56  TimeSeriesSignal::Ptr ts = std::dynamic_pointer_cast<TimeSeriesSignal>(signal);
57  if (!ts)
58  {
59  PRINT_ERROR_NAMED("previous signal with same name but different type detected. Skipping signal.");
60  return;
61  }
62  ts->add(*measurement);
63 }
64 
66 {
67  if (time_series->header.name.empty())
68  {
69  PRINT_ERROR_NAMED("signal name missing in signal header. Skipping signal.");
70  return;
71  }
72 
73  std::string signal_name;
74  SignalInterface::Ptr signal;
75  SignalGroup* group = expandGroups(time_series->header.name, &signal_name, &signal);
76  if (!signal)
77  {
78  // new signal, store all measurements with same name into a TimeSeries signal
79  signal = std::make_shared<TimeSeriesSequenceSignal>();
80  signal->header = time_series->header; // copy header to parent object
81  group->group_signals.push_back(signal);
82  }
83  TimeSeriesSequenceSignal::Ptr sequence = std::dynamic_pointer_cast<TimeSeriesSequenceSignal>(signal);
84  if (!sequence)
85  {
86  PRINT_ERROR_NAMED("previous signal with same name but different type detected. Skipping signal.");
87  return;
88  }
89  sequence->add(time_series->getTimeSeriesPtr());
90 }
91 
93 {
94  if (indexed_values->header.name.empty())
95  {
96  PRINT_ERROR_NAMED("signal name missing in signal header. Skipping signal.");
97  return;
98  }
99  if (indexed_values->getValueDimension() == 0)
100  {
101  PRINT_WARNING_NAMED("value vector is empty.");
102  }
103 
104  std::string signal_name;
105  SignalInterface::Ptr signal;
106  SignalGroup* group = expandGroups(indexed_values->header.name, &signal_name, &signal);
107  if (!signal)
108  {
109  // new signal, store all measurements with same name into a IndexedValuesSet signal
110  signal = std::make_shared<IndexedValuesSetSignal>();
111  signal->header = indexed_values->header; // copy header to parent object
112  group->group_signals.push_back(signal);
113  }
114  IndexedValuesSetSignal::Ptr set = std::dynamic_pointer_cast<IndexedValuesSetSignal>(signal);
115  if (!set)
116  {
117  PRINT_ERROR_NAMED("previous signal with same name but different type detected. Skipping signal.");
118  return;
119  }
120  set->add(*indexed_values);
121 }
122 
124 {
125  if (indexed_values_set->header.name.empty())
126  {
127  PRINT_ERROR_NAMED("signal name missing in signal header. Skipping signal.");
128  return;
129  }
130 
131  std::string signal_name;
132  SignalInterface::Ptr signal;
133  SignalGroup* group = expandGroups(indexed_values_set->header.name, &signal_name, &signal);
134  if (!signal)
135  {
136  // new signal
137  group->group_signals.push_back(indexed_values_set);
138  }
139  else
140  {
141  PRINT_ERROR_NAMED("Already received a previous signal with the same name. IndexedValuesSetSignal does not support signal stacking.");
142  }
143 }
144 
146 {
147  if (matrix->header.name.empty())
148  {
149  PRINT_ERROR_NAMED("signal name missing in signal header. Skipping signal.");
150  return;
151  }
152  if (matrix->isEmpty())
153  {
154  PRINT_WARNING_NAMED("signal data is empty.");
155  }
156 
157  std::string signal_name;
158  SignalInterface::Ptr signal;
159  SignalGroup* group = expandGroups(matrix->header.name, &signal_name, &signal);
160  if (!signal)
161  {
162  // new signal, store all measurements with same name into a IndexedValuesSet signal
163  signal = std::make_shared<MatrixSetSignal>();
164  signal->header = matrix->header; // copy header to parent object
165  group->group_signals.push_back(signal);
166  }
167  MatrixSetSignal::Ptr set = std::dynamic_pointer_cast<MatrixSetSignal>(signal);
168  if (!set)
169  {
170  PRINT_ERROR_NAMED("previous signal with same name but different type detected. Skipping signal.");
171  return;
172  }
173  set->add(matrix);
174 }
175 
176 void CommonSignalTarget::removeSignal(const std::string& name)
177 {
178  SignalGroup* signal_group = getGroup(name);
179 
180  if (!signal_group) return;
181  if (signal_group == &_signals) return;
182 
183  SignalGroup* signal_group_parent = signal_group->parent;
184 
185  for (int i = 0; i < (int)signal_group_parent->children.size(); ++i)
186  {
187  if (&signal_group_parent->children[i] == signal_group)
188  {
189  signal_group_parent->children.erase(signal_group_parent->children.begin() + i);
190  return;
191  }
192  }
193 
194  // TODO(Kraemer): Remove single parents
195 
196  PRINT_DEBUG_NAMED("Signal " << name << " not found");
197 }
198 
200 {
201  // parse groups / namespaces:
202  std::vector<std::string> groups;
203  std::istringstream stream(full_group_name);
204  std::string current;
205  while (std::getline(stream, current, SIGNAL_NAMESPACE_DELIMITER))
206  {
207  groups.push_back(current);
208  }
209 
210  SignalGroup* group = &_signals;
211 
212  for (int i = 0; i < (int)groups.size(); ++i)
213  {
214  // if (i == (int)groups.size() - 1)
215  // {
216  // return group;
217  // }
218  auto it = std::find_if(group->children.begin(), group->children.end(), [&](const SignalGroup& item) { return item.group_name == groups[i]; });
219  if (it != group->children.end())
220  {
221  group = &(*it);
222  }
223  else
224  {
225  // PRINT_DEBUG_NAMED("Signal " << full_group_name << " not found");
226  return nullptr;
227  }
228  }
229  return group;
230 }
231 
232 SignalInterface::Ptr CommonSignalTarget::getSignal(const std::string& full_signal_name)
233 {
234  // remove signal name from group name;
235  std::string full_group_name;
236  // std::string signal_name;
237  std::size_t found = full_signal_name.find_last_of(SIGNAL_NAMESPACE_DELIMITER);
238  if (found < full_signal_name.size())
239  {
240  full_group_name = full_signal_name.substr(0, found);
241  // signal_name = full_signal_name.substr(found+1);
242  }
243  // else
244  // {
245  // signal_name = full_signal_name;
246  // }
247 
248  // get leaf group
249  SignalGroup* group = getGroup(full_group_name);
250  if (group)
251  {
252  // search signals in group
253  for (SignalInterface::Ptr& signal : group->group_signals)
254  {
255  if (signal->header.name.compare(full_signal_name) == 0)
256  {
257  // found
258  return signal;
259  }
260  }
261  }
262  return {};
263 }
264 
265 CommonSignalTarget::SignalGroup* CommonSignalTarget::expandGroups(const std::string full_signal_name, std::string* signal_name_out,
266  SignalInterface::Ptr* signal)
267 {
268  // parse groups / namespaces:
269  std::vector<std::string> groups;
270  std::istringstream stream(full_signal_name);
271  std::string current;
272  while (std::getline(stream, current, SIGNAL_NAMESPACE_DELIMITER))
273  {
274  groups.push_back(current);
275  }
276 
277  // the last string in groups contains the actual signal name
278  // now traverse tree and construct children if necessary
279  int n = (int)groups.size();
280  SignalGroup* group = &_signals;
281  for (int i = 0; i < n; ++i)
282  {
283  if (i == n - 1) // final group reached, this item is the signal name
284  {
285  if (signal_name_out) *signal_name_out = groups.back();
286  if (signal)
287  {
288  // also export signal if found
289  auto it =
290  std::find_if(group->group_signals.begin(), group->group_signals.end(),
291  [&full_signal_name](const SignalInterface::Ptr& sig) { return sig->header.name.compare(full_signal_name) == 0; });
292  if (it != group->group_signals.end())
293  *signal = *it;
294  else
295  signal->reset();
296  }
297  return group;
298  }
299  std::string group_name = groups[i];
300  auto it = std::find_if(group->children.begin(), group->children.end(),
301  [&group_name](const SignalGroup& child) { return child.group_name.compare(group_name) == 0; });
302  if (it == group->children.end())
303  {
304  // group not created yet
305  SignalGroup new_group;
306  new_group.group_name = group_name;
307  new_group.parent = group;
308  group->children.push_back(new_group);
309  group = &group->children.back();
310  }
311  else
312  {
313  // group found
314  group = &(*it);
315  }
316  }
317  return group;
318 }
319 
321 {
322  _signals.group_signals.clear();
323  _signals.children.clear();
324 }
325 
326 } // namespace corbo
void clear()
Erase stored signals.
void removeSignal(const std::string &name)
#define PRINT_ERROR_NAMED(msg)
Definition: console.h:260
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:102
Signal for a sequence of time series objects.
Definition: signals.h:333
#define PRINT_WARNING_NAMED(msg)
Definition: console.h:255
SignalGroup * expandGroups(const std::string full_signal_name, std::string *signal_name_out=nullptr, SignalInterface::Ptr *signal=nullptr)
Parse full signal name, create tree-sub-groups if not found and return related signal group...
return int(ret)+1
void sendMatrix(MatrixSignal::Ptr matrix) override
Send a matrix to the target.
std::shared_ptr< TimeSeriesSignal > Ptr
Definition: signals.h:247
void sendIndexedValues(IndexedValuesSignal::Ptr indexed_values) override
Send signal containing values indexed by a single integer.
std::shared_ptr< MatrixSetSignal > Ptr
Definition: signals.h:610
void sendTimeSeries(TimeSeriesSignal::Ptr time_series) override
Send a time series to the target.
std::vector< SignalGroup > children
Container for children (sub-namespace)
std::vector< SignalInterface::Ptr > group_signals
set of signals in the current group
void sendIndexedValuesSet(IndexedValuesSetSignal::Ptr indexed_values_set) override
Send signal containing a set of values indexed by integers (int to double[] map)
std::shared_ptr< TimeSeriesSequenceSignal > Ptr
Definition: signals.h:336
SignalInterface::Ptr getSignal(const std::string &full_signal_name)
SignalGroup _signals
Root element of the signal tree.
#define PRINT_DEBUG_NAMED(msg)
Definition: console.h:245
Signal containing a set of matrices.
Definition: signals.h:607
std::string group_name
Identifier for the current group / signal namespace.
std::shared_ptr< SignalInterface > Ptr
Definition: signals.h:136
void sendMeasurement(Measurement::ConstPtr measurement) override
Send a measurement to the target.
std::shared_ptr< const Measurement > ConstPtr
Definition: signals.h:175
std::shared_ptr< MatrixSignal > Ptr
Definition: signals.h:542
Time Series signal (trajectory resp. sequence of values w.r.t. time)
Definition: signals.h:244
SignalGroup * getGroup(const std::string &full_group_name)
constexpr const char SIGNAL_NAMESPACE_DELIMITER
Definition: signals.h:46
PlainMatrixType mat * n
Definition: eigenvalues.cpp:41
Tree node containing a group of signals and a set of child tree nodes.
std::shared_ptr< IndexedValuesSignal > Ptr
Definition: signals.h:393
std::shared_ptr< IndexedValuesSetSignal > Ptr
Definition: signals.h:477
Signal containing values indexed by an integer (int to double[] map)
Definition: signals.h:474


control_box_rst
Author(s): Christoph Rösmann
autogenerated on Mon Feb 28 2022 22:06:46