ros_source.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2015, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28 //
29 // *****************************************************************************
33 
34 namespace swri_profiler_tools
35 {
36 static const QString LIVE_PROFILE_NAME = "ROS Capture [current]";
37 static const QString DEAD_PROFILE_NAME = "ROS Capture";
38 
40  :
41  db_(db),
42  backend_(NULL),
43  profile_key_(-1),
44  connected_(false)
45 {
46 }
47 
49 {
50  ros_thread_.quit();
51  if (!ros_thread_.wait(500)) {
52  qWarning("ROS thread is not closing in timely fashion. This can happen "
53  "when the network connection is lost or ROS master has shutdown. "
54  "We will attempt to forcibly terminate the thread.");
55  ros_thread_.terminate();
56  }
57 }
58 
60 {
61  if (backend_) {
62  return;
63  }
64 
65  // We run the backend in another thread. Aside from starting up the
66  // backend, this object's main function is to keep track of state
67  // and provide access to that information without having to deal
68  // with thread-safe data access.
69  backend_ = new RosSourceBackend();
70  backend_->moveToThread(&ros_thread_);
71 
72  QObject::connect(&ros_thread_, SIGNAL(finished()),
73  backend_, SLOT(deleteLater()));
74 
75  QObject::connect(backend_, SIGNAL(connected(bool, QString)),
76  this, SLOT(handleConnected(bool, QString)));
77  QObject::connect(backend_, SIGNAL(indexReceived(swri_profiler_msgs::ProfileIndexArray)),
78  this, SLOT(handleIndex(swri_profiler_msgs::ProfileIndexArray)));
79  QObject::connect(backend_, SIGNAL(dataReceived(swri_profiler_msgs::ProfileDataArray)),
80  this, SLOT(handleData(swri_profiler_msgs::ProfileDataArray)));
81 
82  ros_thread_.start();
83 }
84 
85 void RosSource::handleConnected(bool is_connected, QString uri)
86 {
87  connected_ = is_connected;
88  master_uri_ = uri;
90 
91  if (!connected_) {
93 
94  if (profile_key_ >= 0) {
95  Profile &profile = db_->profile(profile_key_);
96  if (profile.isValid() && profile.name() == LIVE_PROFILE_NAME) {
97  profile.setName(DEAD_PROFILE_NAME);
98  }
99  }
100  profile_key_ = -1;
101  }
102 }
103 
104 void RosSource::handleIndex(swri_profiler_msgs::ProfileIndexArray msg)
105 {
107 }
108 
109 void RosSource::handleData(swri_profiler_msgs::ProfileDataArray msg)
110 {
111  NewProfileDataVector new_data;
112  if (!msg_adapter_.processData(new_data, msg)) {
113  return;
114  }
115 
116  // todo(elliotjo): If we detect a large gap, we should create a new
117  // profile for the data to handle the use case of leaving the
118  // profiler open throughout a development session. We should also
119  // consider the case where data is coming from a computer with a bad
120  // clock. We'll either allocate a huge timespan or constantly
121  // generate new profiles. Either are really bad.
122 
123  if (profile_key_ < 0) {
124  profile_key_ = db_->createProfile(LIVE_PROFILE_NAME);
125  if (profile_key_ < 0) {
126  qWarning("Failed to create a new profile. Dropping data.");
127  return;
128  }
129  }
130 
131  db_->profile(profile_key_).addData(new_data);
132 }
133 } // namespace swri_profiler_tools
static const QString LIVE_PROFILE_NAME
Definition: ros_source.cpp:36
void setName(const QString &name)
Definition: profile.cpp:451
void addData(const NewProfileDataVector &data)
Definition: profile.cpp:75
void handleIndex(swri_profiler_msgs::ProfileIndexArray msg)
Definition: ros_source.cpp:104
void processIndex(const swri_profiler_msgs::ProfileIndexArray &msg)
std::vector< NewProfileData > NewProfileDataVector
const QString & name() const
Definition: profile.h:211
void handleConnected(bool connected, QString uri)
Definition: ros_source.cpp:85
ProfilerMsgAdapter msg_adapter_
Definition: ros_source.h:78
int createProfile(const QString &name)
RosSourceBackend * backend_
Definition: ros_source.h:76
void connected(bool connected, QString uri)
bool processData(NewProfileDataVector &out_data, const swri_profiler_msgs::ProfileDataArray &msg)
void handleData(swri_profiler_msgs::ProfileDataArray msg)
Definition: ros_source.cpp:109
static const QString DEAD_PROFILE_NAME
Definition: ros_source.cpp:37
RosSource(ProfileDatabase *db)
Definition: ros_source.cpp:39


swri_profiler_tools
Author(s):
autogenerated on Fri Nov 27 2020 03:44:18