map_view.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2012, 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
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 
00033 import rospy
00034 import tf
00035 from tf.transformations import quaternion_from_euler
00036 
00037 import numpy
00038 import random
00039 from math import sqrt, atan, pi, degrees
00040 
00041 import nav_msgs.msg as nav_msgs
00042 
00043 from python_qt_binding.QtCore import Signal, Slot,  pyqtSlot, Qt, SIGNAL
00044 from python_qt_binding.QtGui import QPixmap, QImage, QGraphicsView, QGraphicsScene, qRgb
00045 
00046 from rqt_py_common.topic_helpers import get_field_type
00047 
00048 
00049 class QMapView(QGraphicsView):
00050     map_changed = Signal()
00051 
00052     def __init__(self, parent=None):
00053         super(QMapView, self).__init__()
00054         self._parent = parent
00055         self._scene = QGraphicsScene()
00056 
00057         self.map_changed.connect(self._update_map)
00058         self.destroyed.connect(self.close)
00059 
00060         # ScrollHandDrag
00061         self.setDragMode(QGraphicsView.ScrollHandDrag)
00062 
00063         self._map = None
00064         self.w = 0
00065         self.h = 0        
00066         self._map_item = {}
00067 
00068         self._polygons = {}
00069         self._colors = [(238, 34, 116), (68, 134, 252), (236, 228, 46), (102, 224, 18), (242, 156, 6), (240, 64, 10), (196, 30, 250)]
00070 
00071         self.setScene(self._scene)
00072 
00073     def add_dragdrop(self, item):
00074         # Add drag and drop functionality to all the items in the view
00075         def c(x, e):
00076             self.dragEnterEvent(e)
00077 
00078         def d(x, e):
00079             self.dropEvent(e)
00080         item.setAcceptDrops(True)
00081         item.dragEnterEvent = c
00082         item.dropEvent = d
00083 
00084     def dragEnterEvent(self, e):
00085         if self._parent:
00086             self._parent.dragEnterEvent(e)
00087 
00088     def dropEvent(self, e):
00089         if self._parent:
00090             self._parent.dropEvent(e)
00091 
00092     def wheelEvent(self, event):
00093         event.ignore()
00094         if event.delta() > 0:
00095             self.scale(1.15, 1.15)
00096         else:
00097             self.scale(0.85, 0.85)
00098 
00099     @pyqtSlot(nav_msgs.OccupancyGrid, name='map_received')
00100     def map_cb(self, msg):
00101         self.resolution = msg.info.resolution
00102         self.w = msg.info.width
00103         self.h = msg.info.height
00104 
00105         a = numpy.array(msg.data, dtype=numpy.uint8, copy=False, order='C')
00106         a = a.reshape((self.h, self.w))
00107         if self.w % 4:
00108             e = numpy.empty((self.h, 4 - self.w % 4), dtype=a.dtype, order='C')
00109             a = numpy.append(a, e, axis=1)
00110         image = QImage(a.reshape((a.shape[0] * a.shape[1])), self.w, self.h, QImage.Format_Indexed8)
00111 
00112         for i in reversed(range(101)):
00113             image.setColor(100 - i, qRgb(i * 2.55, i * 2.55, i * 2.55))
00114         image.setColor(101, qRgb(255, 0, 0))  # not used indices
00115         image.setColor(255, qRgb(200, 200, 200))  # color for unknown value -1
00116         self._map = image
00117         self.setSceneRect(0, 0, self.w, self.h)
00118         self.map_changed.emit()
00119 
00120     def _update_map(self):
00121         if self._map_item:
00122             self._scene.removeItem(self._map_item)
00123 
00124         pixmap = QPixmap.fromImage(self._map)
00125         self._map_item = self._scene.addPixmap(pixmap)
00126 
00127         # Everything must be mirrored
00128         self._mirror(self._map_item)
00129 
00130         # Add drag and drop functionality
00131         self.add_dragdrop(self._map_item)
00132 
00133         self.centerOn(self._map_item)
00134         self.show()
00135 
00136     def _mirror(self, item):
00137         item.scale(-1, 1)
00138         item.translate(-self.w, 0)
00139 
00140     def save_settings(self, plugin_settings, instance_settings):
00141         # TODO add any settings to be saved
00142         pass
00143 
00144     def restore_settings(self, plugin_settings, instance_settings):
00145         # TODO add any settings to be restored
00146         pass


rocon_qt_library
Author(s): Donguk Lee
autogenerated on Fri Feb 12 2016 02:50:13