time_panel.cpp
Go to the documentation of this file.
00001 
00002 /*
00003  * Copyright (c) 2008, Willow Garage, Inc.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00015  *       contributors may be used to endorse or promote products derived from
00016  *       this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028  * POSSIBILITY OF SUCH DAMAGE.
00029  */
00030 
00031 #include <QLabel>
00032 #include <QLineEdit>
00033 #include <QPushButton>
00034 #include <QHBoxLayout>
00035 #include <QButtonGroup>
00036 #include <QCheckBox>
00037 #include <QSlider>
00038 #include <QComboBox>
00039 
00040 #include "visualization_manager.h"
00041 #include "frame_manager.h"
00042 
00043 #include "display_group.h"
00044 
00045 #include "time_panel.h"
00046 
00047 namespace rviz
00048 {
00049 
00050 TimePanel::TimePanel( QWidget* parent )
00051   : Panel( parent )
00052 {
00053   wall_time_label_ = makeTimeLabel();
00054   wall_elapsed_label_ = makeTimeLabel();
00055   ros_time_label_ = makeTimeLabel();
00056   ros_elapsed_label_ = makeTimeLabel();
00057 
00058   experimental_cb_ = new QCheckBox("Experimental");
00059   experimental_cb_->setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum) );
00060 
00061   pause_button_ = new QPushButton( "Pause" );
00062   pause_button_->setToolTip("Freeze ROS time.");
00063   pause_button_->setCheckable(true);
00064 
00065   sync_mode_selector_ = new QComboBox(this);
00066   sync_mode_selector_->addItem( "Off" );
00067   sync_mode_selector_->addItem( "Exact" );
00068   sync_mode_selector_->addItem( "Approximate" );
00069   sync_mode_selector_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
00070   sync_mode_selector_->setToolTip("Allows you to synchronize the ROS time and Tf transforms to a given source.");
00071 
00072   // choose time sync signal
00073   sync_source_selector_ = new QComboBox(this);
00074   sync_source_selector_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
00075   sync_source_selector_->setToolTip("Time source to use for synchronization.");
00076 
00077   experimental_widget_ = new QWidget(this);
00078   QHBoxLayout* experimental_layout = new QHBoxLayout(this);
00079   experimental_layout->addWidget( pause_button_ );
00080   experimental_layout->addWidget( new QLabel( "Synchronization:" ));
00081   experimental_layout->addWidget( sync_mode_selector_ );
00082   experimental_layout->addWidget( new QLabel( "Source:" ));
00083   experimental_layout->addWidget( sync_source_selector_ );
00084   experimental_layout->addSpacing(20);
00085   experimental_layout->setContentsMargins( 0, 0, 20, 0 );
00086   experimental_widget_->setLayout(experimental_layout);
00087 
00088   old_widget_ = new QWidget(this);
00089   QHBoxLayout* old_layout = new QHBoxLayout(this);
00090   old_layout->addWidget( new QLabel( "ROS Elapsed:" ));
00091   old_layout->addWidget( ros_elapsed_label_ );
00092   old_layout->addWidget( new QLabel( "Wall Time:" ));
00093   old_layout->addWidget( wall_time_label_ );
00094   old_layout->addWidget( new QLabel( "Wall Elapsed:" ));
00095   old_layout->addWidget( wall_elapsed_label_ );
00096   old_layout->setContentsMargins( 0, 0, 20, 0 );
00097   old_widget_->setLayout(old_layout);
00098 
00099   QHBoxLayout* layout = new QHBoxLayout(this);
00100 
00101   layout->addWidget(experimental_widget_);
00102   layout->addWidget( new QLabel( "ROS Time:" ));
00103   layout->addWidget( ros_time_label_ );
00104   layout->addWidget(old_widget_);
00105   layout->addStretch(100);
00106   layout->addWidget( experimental_cb_ );
00107 
00108   layout->addStretch();
00109   layout->setContentsMargins( 11, 5, 11, 5 );
00110 
00111   connect( experimental_cb_, SIGNAL( toggled( bool )), this, SLOT( experimentalToggled( bool ) ));
00112   connect( pause_button_, SIGNAL( toggled( bool )), this, SLOT( pauseToggled( bool ) ));
00113   connect( sync_mode_selector_, SIGNAL( activated( int )), this, SLOT( syncModeSelected( int ) ));
00114   connect( sync_source_selector_, SIGNAL( activated( int )), this, SLOT( syncSourceSelected( int ) ));
00115 }
00116 
00117 void TimePanel::onInitialize()
00118 {
00119   connect( vis_manager_, SIGNAL( preUpdate() ), this, SLOT( update() ));
00120 
00121   DisplayGroup *display_group = vis_manager_->getRootDisplayGroup();
00122   onDisplayAdded(display_group);
00123 
00124   syncModeSelected(0);
00125   pauseToggled(false);
00126 }
00127 
00128 void TimePanel::load( const Config& config )
00129 {
00130   Panel::load(config);
00131   int sync_mode;
00132   if( config.mapGetInt( "SyncMode", &sync_mode ))
00133   {
00134     sync_mode_selector_->setCurrentIndex(sync_mode);
00135     syncModeSelected(sync_mode);
00136   }
00137   config.mapGetString( "SyncSource", &config_sync_source_ );
00138   bool experimental = false;
00139   config.mapGetBool( "Experimental", &experimental );
00140   experimental_cb_->setChecked(experimental);
00141   experimentalToggled(experimental);
00142 }
00143 
00144 void TimePanel::save( Config config ) const
00145 {
00146   Panel::save(config);
00147   config.mapSetValue( "SyncMode", sync_mode_selector_->currentIndex() );
00148   config.mapSetValue( "SyncSource", sync_source_selector_->currentText() );
00149   config.mapSetValue( "Experimental", experimental_cb_->checkState() == Qt::Checked );
00150 }
00151 
00152 void TimePanel::onDisplayAdded( Display* display )
00153 {
00154   DisplayGroup* display_group = qobject_cast<DisplayGroup*>( display );
00155   if( display_group )
00156   {
00157     connect( display_group, SIGNAL( displayAdded( rviz::Display* ) ), this, SLOT( onDisplayAdded( rviz::Display* ) ));
00158     connect( display_group, SIGNAL( displayRemoved( rviz::Display* ) ), this, SLOT( onDisplayRemoved( rviz::Display* ) ));
00159 
00160     for( int i = 0; i < display_group->numDisplays(); i++ )
00161     {
00162       rviz::Display* display = display_group->getDisplayAt( i );
00163       onDisplayAdded( display );
00164     }
00165   }
00166   else
00167   {
00168     connect( display, SIGNAL( timeSignal( rviz::Display*, ros::Time ) ), this, SLOT( onTimeSignal( rviz::Display*, ros::Time ) ));
00169   }
00170 }
00171 
00172 void TimePanel::onDisplayRemoved( Display* display )
00173 {
00174   QString name = display->getName();
00175   int index = sync_source_selector_->findData( QVariant( (qulonglong)display ) );
00176   if ( index >= 0 )
00177   {
00178     sync_source_selector_->removeItem( index );
00179   }
00180 }
00181 
00182 void TimePanel::onTimeSignal( Display* display, ros::Time time )
00183 {
00184   QString name = display->getName();
00185   int index = sync_source_selector_->findData( QVariant( (qulonglong)display ) );
00186 
00187   // if we loaded the sync source name from the config, we need to
00188   // switch to it as soon as we get a signal
00189   if ( index < 0 && name == config_sync_source_ )
00190   {
00191     sync_source_selector_->addItem( name, QVariant( (qulonglong)display ) );
00192     index = sync_source_selector_->findData( QVariant( (qulonglong)display ) );
00193     sync_source_selector_->setCurrentIndex(index);
00194     config_sync_source_.clear();
00195   }
00196 
00197   if ( index < 0 )
00198   {
00199     sync_source_selector_->addItem( name, QVariant( (qulonglong)display ) );
00200   }
00201   else
00202   {
00203     sync_source_selector_->setItemText( index, name );
00204     if ( sync_source_selector_->currentIndex() == index )
00205     {
00206       vis_manager_->getFrameManager()->syncTime( time );
00207     }
00208   }
00209 }
00210 
00211 QLineEdit* TimePanel::makeTimeLabel()
00212 {
00213   QLineEdit* label = new QLineEdit;
00214   label->setReadOnly( true );
00215   return label;
00216 }
00217 
00218 void TimePanel::fillTimeLabel( QLineEdit* label, double time )
00219 {
00220   label->setText( QString::number( time, 'f', 2 ));
00221 }
00222 
00223 void TimePanel::update()
00224 {
00225   fillTimeLabel( ros_time_label_, vis_manager_->getROSTime() );
00226   fillTimeLabel( ros_elapsed_label_, vis_manager_->getROSTimeElapsed() );
00227   fillTimeLabel( wall_time_label_, vis_manager_->getWallClock() );
00228   fillTimeLabel( wall_elapsed_label_, vis_manager_->getWallClockElapsed() );
00229 }
00230 
00231 void TimePanel::pauseToggled( bool checked )
00232 {
00233   vis_manager_->getFrameManager()->setPause( checked );
00234 }
00235 
00236 void TimePanel::experimentalToggled( bool checked )
00237 {
00238   old_widget_->setVisible(!checked);
00239   experimental_widget_->setVisible(checked);
00240   if ( vis_manager_ && vis_manager_->getFrameManager() )
00241   {
00242     if ( !checked )
00243     {
00244       pauseToggled(false);
00245       syncModeSelected(0);
00246     }
00247     else
00248     {
00249       pauseToggled(pause_button_->isChecked());
00250       syncModeSelected(sync_mode_selector_->currentIndex());
00251     }
00252   }
00253 }
00254 
00255 void TimePanel::syncSourceSelected( int index )
00256 {
00257   // clear whatever was loaded from the config
00258   config_sync_source_.clear();
00259   vis_manager_->notifyConfigChanged();
00260 }
00261 
00262 void TimePanel::syncModeSelected( int mode )
00263 {
00264   vis_manager_->getFrameManager()->setSyncMode( (FrameManager::SyncMode)mode );
00265   sync_source_selector_->setEnabled( mode != FrameManager::SyncOff );
00266   vis_manager_->notifyConfigChanged();
00267 }
00268 
00269 } // namespace rviz
00270 


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Mon Oct 6 2014 07:26:36