Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "roscpp_plugin_provider.h"
00034
00035 #include "nodelet_plugin_provider.h"
00036 #include <rqt_gui_cpp/plugin.h>
00037
00038 #include <qt_gui_cpp/plugin_provider.h>
00039
00040 #include <nodelet/nodelet.h>
00041 #include <pluginlib/class_list_macros.h>
00042 #include <ros/ros.h>
00043
00044 #include <stdexcept>
00045 #include <sys/types.h>
00046 #include <unistd.h>
00047 #include <iostream>
00048
00049 namespace rqt_gui_cpp {
00050
00051 RosCppPluginProvider::RosCppPluginProvider()
00052 : qt_gui_cpp::CompositePluginProvider()
00053 , node_initialized_(false)
00054 , wait_for_master_dialog_(0)
00055 , wait_for_master_thread_(0)
00056 {
00057 QList<PluginProvider*> plugin_providers;
00058 plugin_providers.append(new NodeletPluginProvider("rqt_gui", "rqt_gui_cpp::Plugin"));
00059 set_plugin_providers(plugin_providers);
00060 }
00061
00062 RosCppPluginProvider::~RosCppPluginProvider()
00063 {
00064 if (ros::isStarted())
00065 {
00066 ros::shutdown();
00067 }
00068 }
00069
00070 void* RosCppPluginProvider::load(const QString& plugin_id, qt_gui_cpp::PluginContext* plugin_context)
00071 {
00072 init_node();
00073 return qt_gui_cpp::CompositePluginProvider::load(plugin_id, plugin_context);
00074 }
00075
00076 qt_gui_cpp::Plugin* RosCppPluginProvider::load_plugin(const QString& plugin_id, qt_gui_cpp::PluginContext* plugin_context)
00077 {
00078 init_node();
00079 return qt_gui_cpp::CompositePluginProvider::load_plugin(plugin_id, plugin_context);
00080 }
00081
00082 void RosCppPluginProvider::wait_for_master()
00083 {
00084
00085 if (ros::master::check())
00086 {
00087 return;
00088 }
00089
00090 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);
00091 wait_for_master_thread_ = new WaitForMasterThread(wait_for_master_dialog_);
00092 wait_for_master_thread_->start();
00093 QObject::connect(wait_for_master_thread_, SIGNAL(master_found_signal(int)), wait_for_master_dialog_, SLOT(done(int)), Qt::QueuedConnection);
00094 int button = wait_for_master_dialog_->exec();
00095
00096 bool no_master = (button != QMessageBox::Ok);
00097 if (no_master)
00098 {
00099 dynamic_cast<WaitForMasterThread*>(wait_for_master_thread_)->abort = true;
00100 wait_for_master_thread_->wait();
00101 }
00102 wait_for_master_thread_->exit();
00103 wait_for_master_thread_->deleteLater();
00104 wait_for_master_dialog_->deleteLater();
00105 wait_for_master_dialog_ = 0;
00106 if (no_master)
00107 {
00108 throw std::runtime_error("RosCppPluginProvider::init_node() could not find ROS master");
00109 }
00110 }
00111
00112 void RosCppPluginProvider::init_node()
00113 {
00114
00115 if (!node_initialized_)
00116 {
00117 int argc = 0;
00118 char** argv = 0;
00119 std::stringstream name;
00120 name << "rqt_gui_cpp_node_";
00121 name << getpid();
00122 qDebug("RosCppPluginProvider::init_node() initialize ROS node '%s'", name.str().c_str());
00123 ros::init(argc, argv, name.str().c_str(), ros::init_options::NoSigintHandler);
00124 wait_for_master();
00125 ros::start();
00126 node_initialized_ = true;
00127 }
00128 else
00129 {
00130 wait_for_master();
00131 }
00132 }
00133
00134 WaitForMasterThread::WaitForMasterThread(QObject* parent)
00135 : QThread(parent)
00136 , abort(false)
00137 {}
00138
00139 void WaitForMasterThread::run()
00140 {
00141 while (true)
00142 {
00143 usleep(100000);
00144 if (abort)
00145 {
00146 break;
00147 }
00148 if (ros::master::check())
00149 {
00150 emit(master_found_signal(QMessageBox::Ok));
00151 break;
00152 }
00153 }
00154 }
00155
00156 }
00157
00158 PLUGINLIB_EXPORT_CLASS(rqt_gui_cpp::RosCppPluginProvider, qt_gui_cpp::PluginProvider)