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         self.level_selector_proxy.wait_for_service()
00049 
00050     def process_multimap(self, msg):
00051         self.levels = msg.levels
00052         self._widget.emit(SIGNAL("update_buttons"))
00053 
00054     def update_buttons(self):
00055         self.clean()
00056         for index, level in enumerate(self.levels):
00057             self.text_label.setText("Choose Level: ")
00058             button = QPushButton(level.level_id, self._widget)
00059             button.clicked[bool].connect(self.handle_button)
00060             button.setCheckable(True)
00061             self._button_layout.addWidget(button)
00062             self.buttons.append(button)
00063 
00064         # Subscribe to the current level we are on.
00065         if self.status_subscriber is None:
00066             self.status_subscriber = rospy.Subscriber("level_mux/current_level", LevelMetaData, self.process_level_status)
00067 
00068     def update_button_status(self):
00069         for index, level in enumerate(self.levels):
00070             if self.current_level == level.level_id:
00071                 self.buttons[index].setChecked(True)
00072             else:
00073                 self.buttons[index].setChecked(False)
00074 
00075     def process_level_status(self, msg):
00076         level_found = False
00077         for level in self.levels:
00078             if msg.level_id == level.level_id:
00079                 self.current_level = level.level_id
00080                 level_found = True
00081                 break
00082         if not level_found:
00083             self.current_level = None
00084         self._widget.emit(SIGNAL("update_button_status"))
00085 
00086     def handle_button(self):
00087         source = self.sender()
00088 
00089         if source.text() == self.current_level:
00090             source.setChecked(True)
00091             return
00092 
00093         # Construct a identity pose. The level selector cannot be used to choose the initialpose, as it does not have
00094         # the interface for specifying the position. The position should be specified via rviz.
00095         origin_pose = PoseWithCovarianceStamped()
00096         origin_pose.header.frame_id = frameIdFromLevelId(source.text())
00097         origin_pose.pose.pose.orientation.w = 1    # Makes the origin quaternion valid.
00098         origin_pose.pose.covariance[0] = 1.0
00099         origin_pose.pose.covariance[7] = 1.0
00100         origin_pose.pose.covariance[14] = 1.0
00101         origin_pose.pose.covariance[21] = 1.0
00102         origin_pose.pose.covariance[28] = 1.0
00103         origin_pose.pose.covariance[35] = 1.0
00104 
00105         # Don't actually publish the initial pose via the level selector. It doesn't know any better.
00106         self.level_selector_proxy(source.text(), False, origin_pose)
00107 
00108     def clean(self):
00109         while self._button_layout.count():
00110             item = self._button_layout.takeAt(0)
00111             item.widget().deleteLater()
00112 
00113     def save_settings(self, plugin_settings, instance_settings):
00114         pass
00115 
00116     def restore_settings(self, plugin_settings, instance_settings):
00117         pass
00118 


multi_level_map_utils
Author(s): Piyush Khandelwal, Jake Menashe
autogenerated on Thu Jun 6 2019 17:58:09