marble_plugin.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 /* -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 
00005 Copyright (c) 2013, TB
00006 All rights reserved.
00007 
00008 Redistribution and use in source and binary forms are permitted
00009 provided that the above copyright notice and this paragraph are
00010 duplicated in all such forms and that any documentation,
00011 advertising materials, and other materials related to such
00012 distribution and use acknowledge that the software was developed
00013 by TB. The name of the
00014 TB may not be used to endorse or promote products derived
00015 from this software without specific prior written permission.
00016 THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00017 IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00019 
00020   -- END LICENSE BLOCK ----------------------------------------------*/
00021 
00022 //----------------------------------------------------------------------
00029 //----------------------------------------------------------------------
00030 
00031 
00032 // Qt Includes
00033 #include <QLineEdit>
00034 #include <QFileInfo>
00035 #include <QFileDialog>
00036 #include <QStringList>
00037 #include <QStandardItemModel>
00038 #include <QModelIndex>
00039 
00040 // Own Includes
00041 #include "marble_plugin.h"
00042 
00043 // ROS Plugin Includes
00044 #include <pluginlib/class_list_macros.h>
00045 
00046 // Marble Includes
00047 #include <marble/MarbleWidget.h>
00048 #include <marble/MarbleModel.h>
00049 #include <marble/MapThemeManager.h>
00050 #include <marble/GeoPainter.h>
00051 
00052 #include <ros/package.h>
00053 
00054 // @TODO: setDistance does not work on reloading
00055 // @TODO: ComboBox for the MarbleWidget projection method
00056 // @TOOD: Draw icon on the current gps pos (MarbleWidget needs to be subclassed (custom paint))
00057 
00058 namespace marble_plugin {
00059 
00060 MarblePlugin::MarblePlugin()
00061   : rqt_gui_cpp::Plugin()
00062   , widget_(0)
00063 {
00064   // give QObjects reasonable names
00065   setObjectName("MarbleWidgetPlugin");
00066 }
00067 
00068 void MarblePlugin::initPlugin(qt_gui_cpp::PluginContext& context)
00069 {
00070   // access standalone command line arguments
00071   QStringList argv = context.argv();
00072 
00073   // create QWidget
00074   widget_ = new QWidget();
00075 
00076   // add widget to the user interface
00077   ui_.setupUi( widget_ );
00078   ui_.MarbleWidget->setMapThemeId("earth/openstreetmap/openstreetmap.dgml");
00079   ui_.MarbleWidget->setProjection( Marble::Mercator );
00080   ui_.MarbleWidget->centerOn( 115.87164 , -31.93452 , false );  // My Happy Place: The Scotto
00081   ui_.MarbleWidget->setDistance(0.05);
00082 
00083   context.addWidget(widget_);
00084   ui_.comboBox_theme->setModel( ui_.MarbleWidget->model()->mapThemeManager()->mapThemeModel() );
00085 
00086 
00087   //set refresh icon
00088   QIcon refresh_icon;
00089   std::string path = ros::package::getPath("marble_plugin")+"/etc/refresh.png";
00090   QString icon_path(path.c_str());
00091   refresh_icon.addFile(icon_path);
00092   ui_.refreshButton->setIcon(refresh_icon);
00093 
00094   FindGPSTopics();
00095 
00096   // Connections
00097   connect(ui_.comboBox, SIGNAL(activated (const QString &)), this, SLOT (ChangeGPSTopic(const QString &)));
00098   connect(ui_.refreshButton, SIGNAL(clicked()), this, SLOT(FindGPSTopics()));
00099 
00100   connect( this , SIGNAL(NewGPSPosition(qreal,qreal)) , ui_.MarbleWidget , SLOT(centerOn(qreal,qreal)) );
00101 //  connect( ui_.lineEdit_topic , SIGNAL(editingFinished()) , this , SLOT( ChangeGPSTopic()) );
00102   connect( ui_.lineEdit_kml , SIGNAL(returnPressed()) , this, SLOT( SetKMLFile() ));
00103   connect( ui_.comboBox_theme , SIGNAL(currentIndexChanged(int)) , this , SLOT(ChangeMarbleModelTheme(int)));
00104 
00105   // AutoNavigation Connections ... soon
00106   /*
00107   m_autoNavigation = new Marble::AutoNavigation( ui_.MarbleWidget->model(), ui_.MarbleWidget->viewport(), this );
00108 
00109   connect( m_autoNavigation, SIGNAL( zoomIn( FlyToMode ) ),
00110                        ui_.MarbleWidget, SLOT( zoomIn() ) );
00111   connect( m_autoNavigation, SIGNAL( zoomOut( FlyToMode ) ),
00112                        ui_.MarbleWidget, SLOT( zoomOut() ) );
00113   connect( m_autoNavigation, SIGNAL( centerOn( const GeoDataCoordinates &, bool ) ),
00114                        ui_.MarbleWidget, SLOT( centerOn( const GeoDataCoordinates & ) ) );
00115 
00116   connect( ui_.MarbleWidget , SIGNAL( visibleLatLonAltBoxChanged() ),
00117                         m_autoNavigation, SLOT( inhibitAutoAdjustments() ) );
00118     */
00119 }
00120 
00121 void MarblePlugin::FindGPSTopics()
00122 {
00123     using namespace ros::master;
00124     std::vector<TopicInfo> topic_infos;
00125     getTopics(topic_infos);
00126 
00127     ui_.comboBox->clear();
00128     for(std::vector<TopicInfo>::iterator it=topic_infos.begin(); it!=topic_infos.end();it++)
00129     {
00130         TopicInfo topic = (TopicInfo)(*it);
00131         if(topic.datatype.compare("sensor_msgs/NavSatFix")==0)
00132         {
00133 //            std::cout << "found " << topic.name << std::endl;
00134             QString lineEdit_string(topic.name.c_str());
00135             ui_.comboBox->addItem(lineEdit_string);
00136         }
00137     }
00138 }
00139 
00140 void MarblePlugin::shutdownPlugin()
00141 {
00142   // unregister all publishers here
00143   m_sat_nav_fix_subscriber.shutdown();
00144 }
00145 
00146 void MarblePlugin::ChangeMarbleModelTheme(int idx )
00147 {
00148     QStandardItemModel* model = ui_.MarbleWidget->model()->mapThemeManager()->mapThemeModel();
00149     QModelIndex index = model->index( idx , 0 );
00150     QString theme = model->data( index , Qt::UserRole+1  ).toString();
00151 
00152     ui_.MarbleWidget->setMapThemeId( theme );
00153 }
00154 
00155 void MarblePlugin::ChangeGPSTopic(const QString &topic_name)
00156 {
00157     m_sat_nav_fix_subscriber.shutdown();
00158     m_sat_nav_fix_subscriber = getNodeHandle().subscribe< sensor_msgs::NavSatFix >(
00159                 topic_name.toStdString().c_str() , 10 , &MarblePlugin::GpsCallback, this );
00160 }
00161 
00162 void MarblePlugin::SetKMLFile( bool envoke_file_dialog )
00163 {
00164     QFileInfo fi( ui_.lineEdit_kml->text() );
00165 
00166     if( !fi.isFile() && envoke_file_dialog )
00167     {
00168         QString fn = QFileDialog::getOpenFileName( 0 ,
00169                                      tr("Open Geo Data File"), tr("") , tr("Geo Data Files (*.kml)"));
00170         fi.setFile( fn );
00171     }
00172 
00173     if( fi.isFile() )
00174     {
00175         ui_.MarbleWidget->model()->addGeoDataFile( fi.absoluteFilePath() );
00176 
00177         ui_.lineEdit_kml->setText( fi.absoluteFilePath() );
00178     }
00179     else
00180     {
00181         ui_.lineEdit_kml->setText( "" );
00182     }
00183 }
00184 
00185 void MarblePlugin::GpsCallback( const sensor_msgs::NavSatFixConstPtr& gpspt )
00186 {
00187     // std::cout << "GPS Callback " << gpspt->longitude << " " << gpspt->latitude << std::endl;
00188     assert( widget_ );
00189 
00190     // Emit NewGPSPosition only, if it changes significantly. Has to be somehow related to the zoom
00191     static qreal _x = -1;
00192     static qreal _y = -1;
00193 
00194     qreal x;
00195     qreal y;
00196 
00197     // Recenter if lat long is not on screen
00198     bool recenter = !ui_.MarbleWidget->screenCoordinates(gpspt->longitude,gpspt->latitude , x , y );
00199     recenter |= ui_.checkBox_center->isChecked();
00200 
00201     // Recenter if lat long within <threshold> pixels away from center
00202     qreal threshold = 20;
00203     recenter |=  ((x - _x) * (x - _x) + (y - _y) * (y - _y)) > threshold;
00204 
00205     if( recenter )
00206     {
00207         emit NewGPSPosition( gpspt->longitude , gpspt->latitude );
00208         ui_.MarbleWidget->screenCoordinates(gpspt->longitude,gpspt->latitude , _x , _y );
00209     }
00210 }
00211 
00212 void MarblePlugin::saveSettings(qt_gui_cpp::Settings& plugin_settings, qt_gui_cpp::Settings& instance_settings) const
00213 {
00214   // save intrinsic configuration, usually using:
00215     QString topic(m_sat_nav_fix_subscriber.getTopic().c_str());
00216     instance_settings.setValue( "marble_plugin_topic", topic );
00217     instance_settings.setValue( "marble_plugin_kml_file" , ui_.lineEdit_kml->text().replace("." , "___dot_replacement___" ) );
00218     instance_settings.setValue( "marble_plugin_zoom" , ui_.MarbleWidget->distance() );
00219     instance_settings.setValue( "marble_theme_index" , ui_.comboBox_theme->currentIndex() );
00220     instance_settings.setValue( "marble_center" , ui_.checkBox_center->isChecked() );
00221 }
00222 
00223 void MarblePlugin::restoreSettings(const qt_gui_cpp::Settings& plugin_settings, const qt_gui_cpp::Settings& instance_settings)
00224 {
00225   // restore intrinsic configuration, usually using:
00226     const QString topic = instance_settings.value("marble_plugin_topic").toString();
00227     ChangeGPSTopic(topic);
00228 
00229     ui_.lineEdit_kml->setText( instance_settings.value("marble_plugin_kml_file" , "" ).toString().replace("___dot_replacement___",".") );
00230     ui_.comboBox_theme->setCurrentIndex( instance_settings.value( "marble_theme_index" , 0 ).toInt() );
00231     ui_.checkBox_center->setChecked( instance_settings.value( "marble_center" , true ).toBool());
00232 
00233   // std::cout << "Set distance " << instance_settings.value( "marble_plugin_zoom" ).toReal() << std::endl;
00234 
00235   SetKMLFile(false);
00236 
00237   // @TODO: Does not work since the KML loading changes the zoom
00238   ui_.MarbleWidget->setDistance( instance_settings.value( "marble_plugin_zoom" , 0.05 ).toReal() );
00239 }
00240 
00241 /*bool hasConfiguration() const
00242 {
00243   return true;
00244 }
00245 
00246 void triggerConfiguration()
00247 {
00248   // Usually used to open a dialog to offer the user a set of configuration
00249 }*/
00250 
00251 } // namespace
00252 PLUGINLIB_DECLARE_CLASS(marble_plugin, MarblePlugin, marble_plugin::MarblePlugin, rqt_gui_cpp::Plugin)
00253 
 All Classes Namespaces Files Functions Variables


marble_plugin
Author(s): Tobias Bär (baer@fzi.de)
autogenerated on Wed Oct 23 2013 10:14:24