plugins.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 from geometry_msgs.msg import PoseWithCovarianceStamped
00004 from multi_level_map_msgs.msg import LevelMetaData, MultiLevelMapData
00005 from multi_level_map_msgs.srv import ChangeCurrentLevel
00006 import rospy
00007 
00008 from python_qt_binding.QtCore import SIGNAL
00009 from python_qt_binding.QtGui import QLabel, QPushButton, QVBoxLayout, QWidget
00010 from qt_gui.plugin import Plugin
00011 
00012 from .utils import frameIdFromLevelId
00013 
00014 class LevelSelectorPlugin(Plugin):
00015 
00016     def __init__(self, context):
00017         super(LevelSelectorPlugin, self).__init__(context)
00018         # Give QObjects reasonable names
00019         self.setObjectName('LevelSelectorPlugin')
00020 
00021         # Create QWidget
00022         self._widget = QWidget()
00023         # self._widget.setFont(QFont("Times", 15, QFont.Bold))
00024         self._button_layout = QVBoxLayout(self._widget)
00025 
00026         self.buttons = []
00027         self.text_label = QLabel("Waiting for MultiLevelMapData...", self._widget)
00028         self._button_layout.addWidget(self.text_label)
00029 
00030         self._widget.setObjectName('LevelSelectorPluginUI')
00031         if context.serial_number() > 1:
00032             self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))
00033         context.add_widget(self._widget)
00034 
00035         self.connect(self._widget, SIGNAL("update_buttons"), self.update_buttons)
00036         self.connect(self._widget, SIGNAL("update_button_status"), self.update_button_status)
00037 
00038         # Subcribe to the multi level map data to get information about all the maps.
00039         self.multimap_subscriber = rospy.Subscriber("map_metadata", MultiLevelMapData, self.process_multimap)
00040         self.levels = []
00041         self.current_level = None
00042 
00043         # Subscribe to the current level we are on.
00044         self.status_subscriber = None
00045 
00046         # Create a service proxy to change the current level.
00047         self.level_selector_proxy = rospy.ServiceProxy("level_mux/change_current_level", ChangeCurrentLevel)
00048 
00049     def process_multimap(self, msg):
00050         self.levels = msg.levels
00051         self._widget.emit(SIGNAL("update_buttons"))
00052 
00053     def update_buttons(self):
00054         self.clean()
00055         for index, level in enumerate(self.levels):
00056             self.text_label.setText("Choose Level: ")
00057             button = QPushButton(level.level_id, self._widget)
00058             button.clicked[bool].connect(self.handle_button)
00059             button.setCheckable(True)
00060             self._button_layout.addWidget(button)
00061             self.buttons.append(button)
00062 
00063         # Subscribe to the current level we are on.
00064         if self.status_subscriber is None:
00065             self.status_subscriber = rospy.Subscriber("level_mux/current_level", LevelMetaData, self.process_level_status)
00066 
00067     def update_button_status(self):
00068         for index, level in enumerate(self.levels):
00069             if self.current_level == level.level_id:
00070                 self.buttons[index].setChecked(True)
00071             else:
00072                 self.buttons[index].setChecked(False)
00073 
00074     def process_level_status(self, msg):
00075         level_found = False
00076         for level in self.levels:
00077             if msg.level_id == level.level_id:
00078                 self.current_level = level.level_id
00079                 level_found = True
00080                 break
00081         if not level_found:
00082             self.current_level = None
00083         self._widget.emit(SIGNAL("update_button_status"))
00084 
00085     def handle_button(self):
00086         source = self.sender()
00087 
00088         if source.text() == self.current_level:
00089             source.setChecked(True)
00090             return
00091 
00092         # Construct a identity pose. The level selector cannot be used to choose the initialpose, as it does not have
00093         # the interface for specifying the position. The position should be specified via rviz.
00094         origin_pose = PoseWithCovarianceStamped()
00095         origin_pose.header.frame_id = frameIdFromLevelId(source.text())
00096         origin_pose.pose.pose.orientation.w = 1    # Makes the origin quaternion valid.
00097         origin_pose.pose.covariance[0] = 1.0
00098         origin_pose.pose.covariance[7] = 1.0
00099         origin_pose.pose.covariance[14] = 1.0
00100         origin_pose.pose.covariance[21] = 1.0
00101         origin_pose.pose.covariance[28] = 1.0
00102         origin_pose.pose.covariance[35] = 1.0
00103 
00104         # Don't actually publish the initial pose via the level selector. It doesn't know any better.
00105         self.level_selector_proxy(source.text(), False, origin_pose)
00106 
00107     def clean(self):
00108         while self._button_layout.count():
00109             item = self._button_layout.takeAt(0)
00110             item.widget().deleteLater()
00111 
00112     def save_settings(self, plugin_settings, instance_settings):
00113         pass
00114 
00115     def restore_settings(self, plugin_settings, instance_settings):
00116         pass
00117 


multi_level_map_utils
Author(s): Piyush Khandelwal, Jake Menashe
autogenerated on Fri Aug 28 2015 11:36:50