roscpp_plugin_provider.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, Dirk Thomas, TU Darmstadt
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following
13  * disclaimer in the documentation and/or other materials provided
14  * with the distribution.
15  * * Neither the name of the TU Darmstadt nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "roscpp_plugin_provider.h"
34 
36 #include <rqt_gui_cpp/plugin.h>
37 
39 
40 #include <nodelet/nodelet.h>
42 #include <ros/ros.h>
43 
44 #include <stdexcept>
45 #include <sys/types.h>
46 #ifdef WIN32
47 #include <process.h> // for getpid()
48 #else
49 #include <unistd.h>
50 #endif
51 #include <iostream>
52 
53 namespace rqt_gui_cpp {
54 
56  : qt_gui_cpp::CompositePluginProvider()
57  , node_initialized_(false)
58  , wait_for_master_dialog_(0)
59  , wait_for_master_thread_(0)
60 {
61  QList<PluginProvider*> plugin_providers;
62  plugin_providers.append(new NodeletPluginProvider("rqt_gui", "rqt_gui_cpp::Plugin"));
63  set_plugin_providers(plugin_providers);
64 }
65 
67 {
68  if (ros::isStarted())
69  {
70  ros::shutdown();
71  }
72 }
73 
74 void* RosCppPluginProvider::load(const QString& plugin_id, qt_gui_cpp::PluginContext* plugin_context)
75 {
76  init_node();
77  return qt_gui_cpp::CompositePluginProvider::load(plugin_id, plugin_context);
78 }
79 
81 {
82  init_node();
83  return qt_gui_cpp::CompositePluginProvider::load_plugin(plugin_id, plugin_context);
84 }
85 
87 {
88  // check if master is available
89  if (ros::master::check())
90  {
91  return;
92  }
93  // spawn thread to detect when master becomes available
94  wait_for_master_dialog_ = new QMessageBox(QMessageBox::Question, QObject::tr("Waiting for ROS master"), QObject::tr("Could not find ROS master. Either start a 'roscore' or abort loading the plugin."), QMessageBox::Abort);
96  wait_for_master_thread_->start();
97  QObject::connect(wait_for_master_thread_, SIGNAL(master_found_signal(int)), wait_for_master_dialog_, SLOT(done(int)), Qt::QueuedConnection);
98  int button = wait_for_master_dialog_->exec();
99  // check if master existence was not detected by background thread
100  bool no_master = (button != QMessageBox::Ok);
101  if (no_master)
102  {
103  dynamic_cast<WaitForMasterThread*>(wait_for_master_thread_)->abort = true;
104  wait_for_master_thread_->wait();
105  }
106  wait_for_master_thread_->exit();
107  wait_for_master_thread_->deleteLater();
108  wait_for_master_dialog_->deleteLater();
110  if (no_master)
111  {
112  throw std::runtime_error("RosCppPluginProvider::init_node() could not find ROS master");
113  }
114 }
115 
117 {
118  // initialize ROS node once
119  if (!node_initialized_)
120  {
121  int argc = 0;
122  char** argv = 0;
123  std::stringstream name;
124  name << "rqt_gui_cpp_node_";
125  name << getpid();
126  qDebug("RosCppPluginProvider::init_node() initialize ROS node '%s'", name.str().c_str());
127  ros::init(argc, argv, name.str().c_str(), ros::init_options::NoSigintHandler);
128  wait_for_master();
129  ros::start();
130  node_initialized_ = true;
131  }
132  else
133  {
134  wait_for_master();
135  }
136 }
137 
139  : QThread(parent)
140  , abort(false)
141 {}
142 
144 {
145  while (true)
146  {
147  usleep(100000);
148  if (abort)
149  {
150  break;
151  }
152  if (ros::master::check())
153  {
154  emit(master_found_signal(QMessageBox::Ok));
155  break;
156  }
157  }
158 }
159 
160 }
161 
ROSCPP_DECL bool check()
ROSCPP_DECL void start()
virtual void * load(const QString &plugin_id, qt_gui_cpp::PluginContext *plugin_context)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
virtual Plugin * load_plugin(const QString &plugin_id, PluginContext *plugin_context)
virtual qt_gui_cpp::Plugin * load_plugin(const QString &plugin_id, qt_gui_cpp::PluginContext *plugin_context)
virtual void * load(const QString &plugin_id, PluginContext *plugin_context)
ROSCPP_DECL bool isStarted()
ROSCPP_DECL void shutdown()
virtual void set_plugin_providers(const QList< PluginProvider * > &plugin_providers)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)


rqt_gui_cpp
Author(s): Dirk Thomas
autogenerated on Sat Mar 16 2019 02:54:14