CurveDataSequencer.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2015 by Ralf Kaestner *
3  * ralf.kaestner@gmail.com *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the Lesser GNU General Public License as published by*
7  * the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * Lesser GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the Lesser GNU General Public License *
16  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17  ******************************************************************************/
18 
20 
22 
23 namespace rqt_multiplot {
24 
25 /*****************************************************************************/
26 /* Constructors and Destructor */
27 /*****************************************************************************/
28 
30  QObject(parent),
31  config_(0),
32  broker_(0) {
33 }
34 
36 }
37 
38 /*****************************************************************************/
39 /* Accessors */
40 /*****************************************************************************/
41 
43  if (config != config_) {
44  bool wasSubscribed = isSubscribed();
45 
46  if (config_) {
48  SIGNAL(changed()), this, SLOT(configAxisConfigChanged()));
50  SIGNAL(changed()), this, SLOT(configAxisConfigChanged()));
51  disconnect(config_, SIGNAL(subscriberQueueSizeChanged(size_t)),
52  this, SLOT(configSubscriberQueueSizeChanged(size_t)));
53 
54  unsubscribe();
55  }
56 
57  config_ = config;
58 
59  if (config) {
60  connect(config->getAxisConfig(CurveConfig::X),
61  SIGNAL(changed()), this, SLOT(configAxisConfigChanged()));
62  connect(config->getAxisConfig(CurveConfig::Y),
63  SIGNAL(changed()), this, SLOT(configAxisConfigChanged()));
64  connect(config, SIGNAL(subscriberQueueSizeChanged(size_t)),
65  this, SLOT(configSubscriberQueueSizeChanged(size_t)));
66 
67  if (wasSubscribed)
68  subscribe();
69  }
70  }
71 }
72 
74  return config_;
75 }
76 
78  if (broker != broker_) {
79  bool wasSubscribed = isSubscribed();
80 
81  if (broker_)
82  unsubscribe();
83 
84  broker_ = broker;
85 
86  if (broker && wasSubscribed)
87  subscribe();
88  }
89 }
90 
92  return broker_;
93 }
94 
96  return !subscribedTopics_.isEmpty();
97 }
98 
99 /*****************************************************************************/
100 /* Methods */
101 /*****************************************************************************/
102 
104  if (isSubscribed())
105  unsubscribe();
106 
107  if (config_ && broker_) {
110 
111  if (xAxisConfig->getTopic() == yAxisConfig->getTopic()) {
112  QString topic = xAxisConfig->getTopic();
113 
114  MessageBroker::PropertyMap properties;
115  properties[MessageSubscriber::QueueSize] = QVariant::
116  fromValue<qulonglong>(config_->getSubscriberQueueSize());
117 
118  if (broker_->subscribe(topic, this,
119  SLOT(subscriberMessageReceived(const QString&,
120  const Message&)), properties)) {
123  }
124  }
125  else {
126  QString xTopic = xAxisConfig->getTopic();
127  QString yTopic = yAxisConfig->getTopic();
128 
129  MessageBroker::PropertyMap properties;
130  properties[MessageSubscriber::QueueSize] = QVariant::
131  fromValue<qulonglong>(config_->getSubscriberQueueSize());
132 
133  if (broker_->subscribe(xTopic, this,
134  SLOT(subscriberXAxisMessageReceived(const QString&,
135  const Message&)), properties))
137 
138  if (broker_->subscribe(yTopic, this,
139  SLOT(subscriberYAxisMessageReceived(const QString&,
140  const Message&)), properties))
142  }
143  }
144 
145  if (!subscribedTopics_.isEmpty())
146  emit subscribed();
147 }
148 
150  if (isSubscribed()) {
151  for (QMap<CurveConfig::Axis, QString>::iterator it = subscribedTopics_.
152  begin(); it != subscribedTopics_.end(); ++it)
153  broker_->unsubscribe(it.value(), this);
154 
155  subscribedTopics_.clear();
156  timeFields_.clear();
157  timeValues_.clear();
158 
159  emit unsubscribed();
160  }
161 }
162 
164  if (!config_)
165  return;
166 
169 
170  QPointF point;
171 
172  if (xAxisConfig->getFieldType() == CurveAxisConfig::MessageData) {
174  getMember(xAxisConfig->getField().toStdString());
175 
176  point.setX(variant.getNumericValue());
177  }
178  else
179  point.setX(message.getReceiptTime().toSec());
180 
181  if (yAxisConfig->getFieldType() == CurveAxisConfig::MessageData) {
182  try {
184  getMember(yAxisConfig->getField().toStdString());
185 
186  point.setY(variant.getNumericValue());
187  } catch (const variant_topic_tools::NoSuchMemberException& e) {
188  ROS_WARN_STREAM_ONCE("Exception in processMessage while retrieving"
189  " member '" << yAxisConfig->getField().toStdString() << "': " <<
190  e.what());
191  }
192  }
193  else
194  point.setY(message.getReceiptTime().toSec());
195 
196  emit pointReceived(point);
197 }
198 
200  Message& message) {
201  if (!config_)
202  return;
203 
204  CurveAxisConfig* axisConfig = config_->getAxisConfig(axis);
205 
206  if (axisConfig) {
207  if (!timeFields_.contains(axis)) {
208  timeFields_[axis] = QString();
209 
210  if (axisConfig->getFieldType() == CurveAxisConfig::MessageData) {
211  QStringList fieldParts = axisConfig->getField().split("/");
212 
213  while (!fieldParts.isEmpty()) {
214  fieldParts.removeLast();
215 
216  QString parentField = fieldParts.join("/");
218 
219  if (!parentField.isEmpty())
220  variant = message.getVariant().getMember(fieldParts.join("/").
221  toStdString());
222  else
223  variant = message.getVariant();
224 
226 
227  if (type.hasHeader()) {
228  timeFields_[axis] = parentField+"/header/stamp";
229  break;
230  }
231  }
232  }
233  }
234 
235  TimeValue timeValue;
236 
237  if (!timeFields_[axis].isEmpty()) {
239  getMember(timeFields_[axis].toStdString());
240 
241  timeValue.time_ = variant.getValue<ros::Time>();
242  }
243  else
244  timeValue.time_ = message.getReceiptTime();
245 
246  if (axisConfig->getFieldType() == CurveAxisConfig::MessageData) {
248  getMember(axisConfig->getField().toStdString());
249 
250  timeValue.value_ = variant.getNumericValue();
251  }
252  else
253  timeValue.value_ = message.getReceiptTime().toSec();
254 
255  if (timeValues_[axis].isEmpty() ||
256  (timeValue.time_ > timeValues_[axis].last().time_))
257  timeValues_[axis].append(timeValue);
258  }
259 
260  interpolate();
261 }
262 
264  TimeValueList& timeValuesX = timeValues_[CurveConfig::X];
265  TimeValueList& timeValuesY = timeValues_[CurveConfig::Y];
266 
267  while ((timeValuesX.count() > 1) && (timeValuesY.count() > 1)) {
268  while ((timeValuesX.count() > 1) &&
269  ((++timeValuesX.begin())->time_ < timeValuesY.front().time_))
270  timeValuesX.removeFirst();
271 
272  while ((timeValuesY.count() > 1) &&
273  ((++timeValuesY.begin())->time_ < timeValuesX.front().time_))
274  timeValuesY.removeFirst();
275 
276  if ((timeValuesY.front().time_ >= timeValuesX.front().time_) &&
277  (timeValuesX.count() > 1)) {
278  QPointF point;
279 
280  const TimeValue& firstX = timeValuesX.first();
281  const TimeValue& secondX = *(++timeValuesX.begin());
282 
283  point.setX(firstX.value_+(secondX.value_-firstX.value_)*
284  (timeValuesY.front().time_-firstX.time_).toSec()/
285  (secondX.time_-firstX.time_).toSec());
286  point.setY(timeValuesY.front().value_);
287 
288  timeValuesY.removeFirst();
289 
290  emit pointReceived(point);
291  }
292  else if ((timeValuesX.front().time_ >= timeValuesY.front().time_) &&
293  (timeValuesY.count() > 1)) {
294  QPointF point;
295 
296  const TimeValue& firstY = timeValuesY.first();
297  const TimeValue& secondY = *(++timeValuesY.begin());
298 
299  point.setX(timeValuesX.front().value_);
300  point.setY(firstY.value_+(secondY.value_-firstY.value_)*
301  (timeValuesX.front().time_-firstY.time_).toSec()/
302  (secondY.time_-firstY.time_).toSec());
303 
304  timeValuesX.removeFirst();
305 
306  emit pointReceived(point);
307  }
308  }
309 }
310 
311 /*****************************************************************************/
312 /* Slots */
313 /*****************************************************************************/
314 
316  if (isSubscribed()) {
317  unsubscribe();
318  subscribe();
319  }
320 }
321 
323  if (isSubscribed()) {
324  unsubscribe();
325  subscribe();
326  }
327 }
328 
330  const Message& message) {
331  processMessage(message);
332 }
333 
335  const Message& message) {
336  processMessage(CurveConfig::X, message);
337 }
338 
340  const Message& message) {
341  processMessage(CurveConfig::Y, message);
342 }
343 
344 }
const DataType & getType() const
const QString & getTopic() const
const variant_topic_tools::MessageVariant & getVariant() const
Definition: Message.cpp:54
void pointReceived(const QPointF &point)
MessageBroker * getBroker() const
Variant getMember(int index) const
size_t getSubscriberQueueSize() const
void configSubscriberQueueSizeChanged(size_t queueSize)
void subscriberMessageReceived(const QString &topic, const Message &message)
CurveAxisConfig * getAxisConfig(Axis axis) const
Definition: CurveConfig.cpp:73
QMap< CurveConfig::Axis, QString > timeFields_
type_traits::DataType< T >::ValueType & getValue()
QMap< int, QVariant > PropertyMap
Definition: MessageBroker.h:33
void subscriberXAxisMessageReceived(const QString &topic, const Message &message)
void subscriberYAxisMessageReceived(const QString &topic, const Message &message)
virtual bool subscribe(const QString &topic, QObject *receiver, const char *method, const PropertyMap &properties=PropertyMap(), Qt::ConnectionType type=Qt::AutoConnection)=0
void setConfig(CurveConfig *config)
const QString & getField() const
void processMessage(const Message &message)
QMap< CurveConfig::Axis, QString > subscribedTopics_
QMap< CurveConfig::Axis, TimeValueList > timeValues_
#define ROS_WARN_STREAM_ONCE(args)
virtual bool unsubscribe(const QString &topic, QObject *receiver, const char *method=0)=0
void setBroker(MessageBroker *broker)
QLinkedList< TimeValue > TimeValueList
const ros::Time & getReceiptTime() const
Definition: Message.cpp:46


rqt_multiplot_plugin
Author(s): Ralf Kaestner
autogenerated on Fri Jan 15 2021 03:47:53