rosout_panel.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2008, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of Willow Garage, Inc. nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 ********************************************************************/
00034 
00035 #include "rosout_panel.h"
00036 #include "rosout_setup_dialog.h"
00037 #include "rosout_list_control.h"
00038 
00039 #include <wx/wx.h>
00040 #include <wx/artprov.h>
00041 
00042 #include <ros/ros.h>
00043 #include <ros/package.h>
00044 
00045 #include <sstream>
00046 #include <algorithm>
00047 
00048 #include <boost/bind.hpp>
00049 
00050 #include "rosout_text_filter.h"
00051 #include "rosout_text_filter_control.h"
00052 #include "rosout_severity_filter.h"
00053 #include "rosout_severity_filter_control.h"
00054 
00055 namespace rxtools
00056 {
00057 
00058 RosoutPanel::RosoutPanel(wxWindow* parent, int id, wxPoint pos, wxSize size, int style)
00059 : RosoutPanelBase(parent, id, pos, size, style)
00060 , enabled_(false)
00061 , message_id_counter_(0)
00062 , max_messages_(20000)
00063 , needs_refilter_(false)
00064 , refilter_timer_(0.0f)
00065 , pause_(false)
00066 , logger_level_frame_(0)
00067 , connected_(true)
00068 , shutdown_thread_(false)
00069 , RECONNECTED_TO_MASTER_EVENT_(wxNewEventType())
00070 , DISCONNECTED_FROM_MASTER_EVENT_(wxNewEventType())
00071 {
00072   wxInitAllImageHandlers();
00073 
00074   nh_.setCallbackQueue(&callback_queue_);
00075 
00076   Connect(RECONNECTED_TO_MASTER_EVENT_, (wxObjectEventFunction)&RosoutPanel::onMasterReconnected, 0, this);
00077   Connect(DISCONNECTED_FROM_MASTER_EVENT_, (wxObjectEventFunction)&RosoutPanel::onMasterDisconnected, 0, this);
00078   check_master_thread_ = new boost::thread(boost::bind(&RosoutPanel::checkForMaster, this));
00079 
00080   process_timer_ = new wxTimer(this);
00081   process_timer_->Start(250);
00082 
00083   Connect(process_timer_->GetId(), wxEVT_TIMER, wxTimerEventHandler(RosoutPanel::onProcessTimer), NULL, this);
00084 
00085   table_->setModel(this);
00086 
00087   setTopic("/rosout_agg");
00088   setEnabled(true);
00089 
00090   std::string icon_path = ros::package::getPath("rxtools") + "/icons/";
00091   delete_filter_bitmap_ = wxBitmap(wxString::FromAscii((icon_path + "delete-filter-16.png").c_str()), wxBITMAP_TYPE_PNG);
00092 
00093   wxBitmap add_bitmap(wxString::FromAscii((icon_path + "add-16.png").c_str()), wxBITMAP_TYPE_PNG);
00094   add_filter_button_->SetBitmapLabel(add_bitmap);
00095 
00096   add_filter_button_->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RosoutPanel::onAddFilterPressed), NULL, this);
00097 
00098   {
00099     RosoutSeverityFilterPtr filter(new RosoutSeverityFilter);
00100     RosoutSeverityFilterControl* control = new RosoutSeverityFilterControl(this, filter);
00101     severity_filter_ = filter;
00102     severity_sizer_->Add(control, 0, wxEXPAND);
00103     severity_filter_->getChangedSignal().connect(boost::bind(&RosoutPanel::onFilterChanged, this, _1));
00104   }
00105 
00106   createTextFilter();
00107 
00108   filters_window_->SetMinSize(wxSize(-1, filters_[0].panel->GetSize().GetHeight() + add_filter_button_->GetSize().GetHeight() + 5));
00109 }
00110 
00111 RosoutPanel::~RosoutPanel()
00112 {
00113   shutdown_thread_ = true;
00114   check_master_thread_->join();
00115   delete check_master_thread_;
00116 
00117   unsubscribe();
00118 
00119   Disconnect(process_timer_->GetId(), wxEVT_TIMER, wxTimerEventHandler(RosoutPanel::onProcessTimer), NULL, this);
00120 
00121   delete process_timer_;
00122 
00123   clear();
00124 }
00125 
00126 void RosoutPanel::clear()
00127 {
00128   table_->SetItemCount(0);
00129   messages_.clear();
00130   ordered_messages_.clear();
00131 }
00132 
00133 void RosoutPanel::setEnabled(bool enabled)
00134 {
00135   if (enabled_ == enabled)
00136   {
00137     return;
00138   }
00139 
00140   enabled_ = enabled;
00141   if (enabled)
00142   {
00143     subscribe();
00144   }
00145   else
00146   {
00147     unsubscribe();
00148   }
00149 }
00150 
00151 void RosoutPanel::subscribe()
00152 {
00153   if (!enabled_ || topic_.empty())
00154   {
00155     return;
00156   }
00157 
00158   sub_ = nh_.subscribe(topic_, 0, &RosoutPanel::incomingMessage, this);
00159 }
00160 
00161 void RosoutPanel::unsubscribe()
00162 {
00163   sub_.shutdown();
00164 }
00165 
00166 void RosoutPanel::setTopic(const std::string& topic)
00167 {
00168   if (topic == topic_)
00169   {
00170     return;
00171   }
00172 
00173   unsubscribe();
00174 
00175   topic_ = topic;
00176 
00177   subscribe();
00178 }
00179 
00180 void RosoutPanel::setMessages(const M_IdToMessage& messages)
00181 {
00182   messages_ = messages;
00183 
00184   if (messages.empty())
00185   {
00186     message_id_counter_ = 0;
00187   }
00188   else
00189   {
00190     message_id_counter_ = messages.rbegin()->first;
00191   }
00192 
00193   refilter();
00194 }
00195 
00196 RosoutFrame* RosoutPanel::createNewFrame()
00197 {
00198   RosoutFrame* frame = new RosoutFrame(0);
00199   frame->rosout_panel_->setMessages(messages_);
00200   frame->Show();
00201   frame->Raise();
00202 
00203   return frame;
00204 }
00205 
00206 void RosoutPanel::onNewWindow(wxCommandEvent& event)
00207 {
00208   createNewFrame();
00209 }
00210 
00211 void RosoutPanel::onLoggerLevelsClose(wxCloseEvent& event)
00212 {
00213   logger_level_frame_->Show(false);
00214   event.Veto();
00215 }
00216 
00217 void RosoutPanel::onLoggerLevels(wxCommandEvent& event)
00218 {
00219   if (!logger_level_frame_)
00220   {
00221     logger_level_frame_ = new LoggerLevelFrame(this);
00222     logger_level_frame_->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(RosoutPanel::onLoggerLevelsClose), NULL, this);
00223   }
00224 
00225   logger_level_frame_->Show();
00226   logger_level_frame_->Raise();
00227 }
00228 
00229 bool filterEnabledCheckboxEqual(wxWindowID id, const RosoutPanel::FilterInfo& info)
00230 {
00231   return info.enabled_cb && info.enabled_cb->GetId() == id;
00232 }
00233 
00234 void RosoutPanel::onFilterEnableChecked(wxCommandEvent& event)
00235 {
00236   V_FilterInfo::iterator it = std::find_if(filters_.begin(), filters_.end(), boost::bind(filterEnabledCheckboxEqual, event.GetId(), _1));
00237   if (it != filters_.end())
00238   {
00239     FilterInfo& info = *it;
00240     info.filter->setEnabled(event.IsChecked());
00241     refilter();
00242   }
00243 }
00244 
00245 bool filterDeleteButtonEqual(wxWindowID id, const RosoutPanel::FilterInfo& info)
00246 {
00247   return info.delete_button && info.delete_button->GetId() == id;
00248 }
00249 
00250 void RosoutPanel::onFilterDelete(wxCommandEvent& event)
00251 {
00252   V_FilterInfo::iterator it = std::find_if(filters_.begin(), filters_.end(), boost::bind(filterDeleteButtonEqual, event.GetId(), _1));
00253   if (it != filters_.end())
00254   {
00255     FilterInfo& info = *it;
00256     removeFilter(info.filter);
00257   }
00258 }
00259 
00260 bool filterUpButtonEqual(wxWindowID id, const RosoutPanel::FilterInfo& info)
00261 {
00262   return info.up_button && info.up_button->GetId() == id;
00263 }
00264 
00265 void RosoutPanel::onFilterMoveUp(wxCommandEvent& event)
00266 {
00267   V_FilterInfo::iterator it = std::find_if(filters_.begin(), filters_.end(), boost::bind(filterUpButtonEqual, event.GetId(), _1));
00268   if (it != filters_.end() && it != filters_.begin())
00269   {
00270     FilterInfo& info = *it;
00271 
00272     filters_sizer_->Detach(info.panel);
00273     size_t new_index = it - filters_.begin() - 1;
00274     filters_sizer_->Insert(new_index, info.panel, 0, wxEXPAND|wxBOTTOM, 1);
00275     filters_sizer_->Layout();
00276     std::swap(*it, *(it - 1));
00277 
00278     resizeFiltersPane();
00279     updateFilterBackgrounds();
00280   }
00281 }
00282 
00283 bool filterDownButtonEqual(wxWindowID id, const RosoutPanel::FilterInfo& info)
00284 {
00285   return info.down_button && info.down_button->GetId() == id;
00286 }
00287 
00288 void RosoutPanel::onFilterMoveDown(wxCommandEvent& event)
00289 {
00290   V_FilterInfo::iterator it = std::find_if(filters_.begin(), filters_.end(), boost::bind(filterDownButtonEqual, event.GetId(), _1));
00291   if (it != filters_.end() && it != filters_.end() - 1)
00292   {
00293     FilterInfo& info = *it;
00294 
00295     filters_sizer_->Detach(info.panel);
00296     size_t new_index = it - filters_.begin() + 1;
00297     filters_sizer_->Insert(new_index, info.panel, 0, wxEXPAND|wxBOTTOM, 1);
00298     filters_sizer_->Layout();
00299     std::swap(*it, *(it + 1));
00300 
00301     resizeFiltersPane();
00302     updateFilterBackgrounds();
00303   }
00304 }
00305 
00306 void RosoutPanel::updateFilterBackgrounds()
00307 {
00308   for (size_t i = 0; i < filters_.size(); ++i)
00309   {
00310     FilterInfo& info = filters_[i];
00311     if (i % 2 == 0)
00312     {
00313       info.panel->SetBackgroundColour(*wxLIGHT_GREY);
00314       info.control->SetBackgroundColour(*wxLIGHT_GREY);
00315     }
00316     else
00317     {
00318       info.panel->SetBackgroundColour(wxNullColour);
00319       info.control->SetBackgroundColour(wxNullColour);
00320     }
00321   }
00322 }
00323 
00324 void RosoutPanel::addFilter(const RosoutFilterPtr& filter, wxWindow* control)
00325 {
00326   table_->preItemChanges();
00327 
00328   FilterInfo info;
00329   info.filter = filter;
00330   info.control = control;
00331 
00332   info.panel = new wxPanel(filters_window_, wxID_ANY);
00333   filters_sizer_->Add(info.panel, 0, wxEXPAND|wxBOTTOM, 1);
00334   info.panel->SetPosition(wxPoint(0, info.panel->GetSize().GetHeight() * filters_.size()));
00335 
00336   if (filters_.size() % 2 == 0)
00337   {
00338     info.panel->SetBackgroundColour(*wxLIGHT_GREY);
00339     info.control->SetBackgroundColour(*wxLIGHT_GREY);
00340   }
00341   else
00342   {
00343     info.panel->SetBackgroundColour(wxNullColour);
00344     info.control->SetBackgroundColour(wxNullColour);
00345   }
00346 
00347   control->Reparent(info.panel);
00348 
00349   info.sizer = new wxBoxSizer(wxHORIZONTAL);
00350   info.panel->SetSizer(info.sizer);
00351 
00352 
00353 #if 01
00354   //if (disableable)
00355   {
00356     info.enabled_cb = new wxCheckBox(info.panel, wxID_ANY, wxT("Enabled"));
00357     info.enabled_cb->SetValue(filter->isEnabled());
00358     info.sizer->Add(info.enabled_cb, 0, wxALIGN_CENTER_VERTICAL);
00359     info.enabled_cb->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(RosoutPanel::onFilterEnableChecked), NULL, this);
00360   }
00361 #endif
00362 
00363   info.sizer->Add(control, 1, wxALIGN_CENTER_VERTICAL);
00364 
00365   info.delete_button = 0;
00366   //if (removable)
00367   {
00368     info.delete_button = new wxBitmapButton(info.panel, wxID_ANY, delete_filter_bitmap_);
00369     info.sizer->Add(info.delete_button, 0, wxALIGN_CENTER_VERTICAL);
00370     info.delete_button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RosoutPanel::onFilterDelete), NULL, this);
00371 
00372     info.down_button = new wxBitmapButton(info.panel, wxID_ANY, wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, wxSize(16, 16)));
00373     info.sizer->Add(info.down_button, 0, wxALIGN_CENTER_VERTICAL);
00374     info.down_button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RosoutPanel::onFilterMoveDown), NULL, this);
00375 
00376     info.up_button = new wxBitmapButton(info.panel, wxID_ANY, wxArtProvider::GetBitmap(wxART_GO_UP, wxART_OTHER, wxSize(16, 16)));
00377     info.sizer->Add(info.up_button, 0, wxALIGN_CENTER_VERTICAL);
00378     info.up_button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RosoutPanel::onFilterMoveUp), NULL, this);
00379   }
00380 
00381   filters_.push_back(info);
00382 
00383   resizeFiltersPane();
00384 
00385   filters_window_->Scroll(-1, 100000);
00386 
00387   filter->getChangedSignal().connect(boost::bind(&RosoutPanel::onFilterChanged, this, _1));
00388 
00389   needs_refilter_ = true;
00390 
00391   table_->postItemChanges();
00392 }
00393 
00394 void RosoutPanel::resizeFiltersPane()
00395 {
00396   filters_window_->Layout();
00397 
00398   wxSize sizer_size = filters_window_->GetSizer()->GetMinSize();
00399   if (sizer_size.GetHeight() > 150)
00400   {
00401     filters_window_->SetMinSize(wxSize(-1, 150));
00402     filters_window_->GetSizer()->FitInside(filters_window_);
00403   }
00404   else
00405   {
00406     filters_window_->SetMinSize(wxSize(-1, sizer_size.GetHeight()));
00407   }
00408 
00409   Layout();
00410   Refresh();
00411 }
00412 
00413 bool filterEquals(const RosoutFilterPtr& filter, const RosoutPanel::FilterInfo& info)
00414 {
00415   return info.filter == filter;
00416 }
00417 
00418 void RosoutPanel::removeFilter(const RosoutFilterPtr& filter)
00419 {
00420   V_FilterInfo::iterator it = std::find_if(filters_.begin(), filters_.end(), boost::bind(filterEquals, filter, _1));
00421   if (it != filters_.end())
00422   {
00423     FilterInfo& info = *it;
00424     info.panel->Destroy();
00425     filters_.erase(it);
00426 
00427     resizeFiltersPane();
00428     updateFilterBackgrounds();
00429 
00430     refilter();
00431   }
00432 }
00433 
00434 void RosoutPanel::clearFilters()
00435 {
00436   while (!filters_.empty())
00437   {
00438     removeFilter(filters_.front().filter);
00439   }
00440 }
00441 
00442 void RosoutPanel::onFilterChanged(const RosoutFilter*)
00443 {
00444   needs_refilter_ = true;
00445 }
00446 
00447 template<class T>
00448 void printStuff(const std::string& name, T* win)
00449 {
00450   wxPoint point = win->GetPosition();
00451   wxSize size = win->GetSize();
00452   ROS_INFO("%s: x: %d, y: %d,      w: %d, h: %d", name.c_str(), point.x, point.y, size.GetWidth(), size.GetHeight());
00453 }
00454 
00455 #define PRINT_STUFF(description) \
00456   ROS_INFO(description); \
00457   printStuff("  filters_sizer_", filters_sizer_); \
00458   printStuff("  filters_window_->GetSizer()", filters_window_->GetSizer()); \
00459   printStuff("  filters_window_", filters_window_); \
00460   for (size_t i = 0; i < filters_.size(); ++i) \
00461   { \
00462     { \
00463       std::stringstream ss; \
00464       ss << "    panel " << i; \
00465       printStuff(ss.str(), filters_[i].panel); \
00466     } \
00467     { \
00468       std::stringstream ss; \
00469       ss << "    sizer " << i; \
00470       printStuff(ss.str(), filters_[i].sizer); \
00471     } \
00472   }
00473 
00474 void RosoutPanel::onProcessTimer(wxTimerEvent& evt)
00475 {
00476   if (connected_)
00477   {
00478     callback_queue_.callAvailable(ros::WallDuration());
00479   }
00480 
00481   processMessages();
00482 
00483   refilter_timer_ += 0.25f;
00484   if (needs_refilter_ && refilter_timer_ > 0.5f)
00485   {
00486     refilter_timer_ = 0.0f;
00487     needs_refilter_ = false;
00488     refilter();
00489   }
00490 
00491   //PRINT_STUFF("onProcessTimer");
00492 }
00493 
00494 RosoutTextFilterPtr RosoutPanel::createTextFilter()
00495 {
00496   RosoutTextFilterPtr filter(new RosoutTextFilter);
00497   RosoutTextFilterControl* control = new RosoutTextFilterControl(filters_window_, filter);
00498   addFilter(filter, control);
00499 
00500   return filter;
00501 }
00502 
00503 void RosoutPanel::onAddFilterPressed(wxCommandEvent& event)
00504 {
00505   createTextFilter();
00506 }
00507 
00508 void RosoutPanel::onClear(wxCommandEvent& event)
00509 {
00510   clear();
00511 }
00512 
00513 void RosoutPanel::addMessageToTable(const rosgraph_msgs::Log::ConstPtr& message, uint32_t id)
00514 {
00515   ordered_messages_.push_back(id);
00516 }
00517 
00518 rosgraph_msgs::LogConstPtr RosoutPanel::getMessageByIndex(uint32_t index) const
00519 {
00520   if (index >= ordered_messages_.size())
00521   {
00522     return rosgraph_msgs::LogConstPtr();
00523   }
00524 
00525   M_IdToMessage::const_iterator it = messages_.find(ordered_messages_[index]);
00526   ROS_ASSERT(it != messages_.end());
00527 
00528   return it->second;
00529 }
00530 
00531 bool RosoutPanel::filter(uint32_t id) const
00532 {
00533   // No filters, always include
00534   if (filters_.empty())
00535   {
00536     return true;
00537   }
00538 
00539   M_IdToMessage::const_iterator it = messages_.find(id);
00540   ROS_ASSERT(it != messages_.end());
00541 
00542   const rosgraph_msgs::LogConstPtr& message = it->second;
00543 
00544   // First run through the severity filter
00545   if (!severity_filter_->filter(message))
00546   {
00547     return false;
00548   }
00549 
00550   {
00551     V_FilterInfo::const_iterator it = filters_.begin();
00552     V_FilterInfo::const_iterator end = filters_.end();
00553     for (; it != end; ++it)
00554     {
00555       const FilterInfo& info = *it;
00556       const RosoutFilterPtr& filter = info.filter;
00557       if (filter->isEnabled() && filter->isValid())
00558       {
00559         if (!filter->filter(message))
00560         {
00561           return false;
00562         }
00563       }
00564     }
00565   }
00566 
00567   return true;
00568 }
00569 
00570 void RosoutPanel::validateOrderedMessages()
00571 {
00572 #if VALIDATE_FILTERING
00573   typedef std::set<uint32_t> S_u32;
00574   S_u32 s;
00575   V_u32::iterator it = ordered_messages_.begin();
00576   V_u32::iterator end = ordered_messages_.end();
00577   for (; it != end; ++it)
00578   {
00579     uint32_t id = *it;
00580     if (!s.insert(id).second)
00581     {
00582       ROS_BREAK();
00583     }
00584   }
00585 #endif
00586 }
00587 
00588 void RosoutPanel::refilter()
00589 {
00590   table_->preItemChanges();
00591 
00592   ordered_messages_.clear();
00593   M_IdToMessage::iterator it = messages_.begin();
00594   M_IdToMessage::iterator end = messages_.end();
00595   for (; it != end; ++it)
00596   {
00597     uint32_t id = it->first;
00598     rosgraph_msgs::Log::ConstPtr& message = it->second;
00599 
00600     if (filter(id))
00601     {
00602       addMessageToTable(message, id);
00603     }
00604   }
00605 
00606   validateOrderedMessages();
00607 
00608   table_->SetItemCount(ordered_messages_.size());
00609 
00610   table_->postItemChanges();
00611 }
00612 
00613 void RosoutPanel::popMessage()
00614 {
00615   M_IdToMessage::iterator it = messages_.begin();
00616   if (!ordered_messages_.empty() && ordered_messages_.front() == it->first)
00617   {
00618 
00619     ordered_messages_.erase(ordered_messages_.begin());
00620     table_->SetItemCount(ordered_messages_.size());
00621 
00622     // Removing early messages means subtracting 1 from the current selection
00623     const S_int32& selection = table_->getSelection();
00624     S_int32 new_selection;
00625 
00626     S_int32::const_iterator it = selection.begin();
00627     S_int32::const_iterator end = selection.end();
00628     for (; it != end; ++it)
00629     {
00630       int32_t new_index = *it - 1;
00631       if (new_index >= 0)
00632       {
00633         new_selection.insert(new_index);
00634       }
00635     }
00636 
00637     table_->setSelection(new_selection);
00638   }
00639 
00640   messages_.erase(it);
00641 }
00642 
00643 void RosoutPanel::processMessage(const rosgraph_msgs::Log::ConstPtr& message)
00644 {
00645   uint32_t id = message_id_counter_++;
00646 
00647   messages_.insert(std::make_pair(id, message));
00648 
00649   if (filter(id))
00650   {
00651     addMessageToTable(message, id);
00652   }
00653 
00654   validateOrderedMessages();
00655 
00656   if (messages_.size() > max_messages_)
00657   {
00658     popMessage();
00659   }
00660 }
00661 
00662 void RosoutPanel::processMessages()
00663 {
00664   if (message_queue_.empty())
00665   {
00666     return;
00667   }
00668 
00669   table_->preItemChanges();
00670 
00671   V_Log::iterator it = message_queue_.begin();
00672   V_Log::iterator end = message_queue_.end();
00673   for (; it != end; ++it)
00674   {
00675     rosgraph_msgs::Log::ConstPtr& message = *it;
00676 
00677     processMessage(message);
00678   }
00679 
00680   message_queue_.clear();
00681 
00682   table_->SetItemCount(ordered_messages_.size());
00683 
00684   table_->postItemChanges();
00685 }
00686 
00687 void RosoutPanel::incomingMessage(const rosgraph_msgs::Log::ConstPtr& msg)
00688 {
00689   if (!pause_)
00690   {
00691     message_queue_.push_back(msg);
00692   }
00693 }
00694 
00695 void RosoutPanel::onPause(wxCommandEvent& evt)
00696 {
00697   pause_ = evt.IsChecked();
00698 }
00699 
00700 void RosoutPanel::onSetup(wxCommandEvent& evt)
00701 {
00702   RosoutSetupDialog dialog(this, topic_, max_messages_);
00703 
00704   if (dialog.ShowModal() == wxOK)
00705   {
00706     setTopic(dialog.getTopic());
00707     setBufferSize(dialog.getBufferSize());
00708   }
00709 }
00710 
00711 void RosoutPanel::setBufferSize(uint32_t size)
00712 {
00713   max_messages_ = size;
00714   while (messages_.size() >= max_messages_)
00715   {
00716     popMessage();
00717   }
00718 }
00719 
00720 RosoutMessageSummary RosoutPanel::getMessageSummary(double duration) const
00721 {
00722   RosoutMessageSummary summary;
00723   ros::Time search_end(0);
00724 
00725   if (ros::Time::now().toSec() - duration > 0)
00726   {
00727     search_end = ros::Time::now() - ros::Duration(duration);
00728   }
00729 
00730   M_IdToMessage::const_reverse_iterator it = messages_.rbegin();
00731   M_IdToMessage::const_reverse_iterator end = messages_.rend();
00732   for (; it != end; ++it)
00733   {
00734     const rosgraph_msgs::Log::ConstPtr& msg = it->second;
00735 
00736     if (msg->header.stamp < search_end)
00737     {
00738       break;
00739     }
00740 
00741     switch (msg->level)
00742     {
00743     case rosgraph_msgs::Log::DEBUG:
00744       ++summary.debug;
00745       break;
00746     case rosgraph_msgs::Log::INFO:
00747       ++summary.info;
00748       break;
00749     case rosgraph_msgs::Log::WARN:
00750       ++summary.warn;
00751       break;
00752     case rosgraph_msgs::Log::ERROR:
00753       ++summary.error;
00754       break;
00755     case rosgraph_msgs::Log::FATAL:
00756       ++summary.fatal;
00757       break;
00758     }
00759   }
00760 
00761   return summary;
00762 }
00763 
00764 void RosoutPanel::checkForMaster()
00765 {
00766   while (!shutdown_thread_)
00767   {
00768     if (ros::master::check())
00769     {
00770       if (!connected_)
00771       {
00772         connected_ = true;
00773         ROS_INFO("Reconnected to ROS master");
00774         wxCommandEvent event(RECONNECTED_TO_MASTER_EVENT_);
00775         wxPostEvent(this, event);
00776       }
00777     }
00778     else if (connected_)
00779     {
00780       connected_ = false;
00781       ROS_INFO("Disconnected from ROS master");
00782       wxCommandEvent event(DISCONNECTED_FROM_MASTER_EVENT_);
00783       wxPostEvent(this, event);
00784     }
00785     boost::this_thread::sleep(boost::posix_time::milliseconds(500));
00786   }
00787 }
00788 
00789 void RosoutPanel::onMasterReconnected(wxEvent& event)
00790 {
00791   Enable(1);
00792   nh_.setCallbackQueue(&callback_queue_);
00793   subscribe();
00794 }
00795 
00796 void RosoutPanel::onMasterDisconnected(wxEvent& event)
00797 {
00798   Enable(0);
00799   nh_.shutdown();
00800 }
00801 
00802 } // namespace rxtools


rxtools
Author(s): Josh Faust, Rob Wheeler, Ken Conley
autogenerated on Mon Oct 6 2014 07:25:59