Skip to content
This repository was archived by the owner on Feb 21, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/tools/uav_viewer_py/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@


## INSTALL ##

# Install .py
FILE(GLOB_RECURSE HEADERS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*py)
FOREACH(header ${HEADERS_FILES})
INSTALL(FILES ${header} DESTINATION share/jderobot/python/uav_viewer_py/ COMPONENT tools)
ENDFOREACH(header)

# Install gui
INSTALL (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/gui DESTINATION share/jderobot/python/uav_viewer_py COMPONENT tools PATTERN .svn EXCLUDE)


9 changes: 9 additions & 0 deletions src/tools/uav_viewer_py/generateGUI
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
cd resources
pyrcc5 resources.qrc -o resources_rc.py
mv resources_rc.py ..

cd ../gui
pyuic5 ui_gui.ui > ui_gui.py
cd ..

168 changes: 168 additions & 0 deletions src/tools/uav_viewer_py/gui/GUI.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#
# Copyright (C) 1997-2016 JDE Developers Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
# Authors :
# Alberto Martin Florido <almartinflorido@gmail.com>
# Aitor Martinez Fernandez <aitor.martinez.fernandez@gmail.com>
#


from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtWidgets import QMainWindow
from gui.ui_gui import Ui_MainWindow
from gui.teleopWidget import TeleopWidget
from gui.cameraWidget import CameraWidget
from gui.communicator import Communicator
from gui.sensorsWidget import SensorsWidget


class MainWindow(QMainWindow, Ui_MainWindow):
updGUI = pyqtSignal()

def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.teleop = TeleopWidget(self)
self.tlLayout.addWidget(self.teleop)
self.teleop.setVisible(True)

self.record = False

self.updGUI.connect(self.updateGUI)

self.cameraCheck.stateChanged.connect(self.showCameraWidget)
self.sensorsCheck.stateChanged.connect(self.showSensorsWidget)

self.rotationDial.valueChanged.connect(self.rotationChange)
self.altdSlider.valueChanged.connect(self.altitudeChange)

self.cameraWidget = CameraWidget(self)
self.sensorsWidget = SensorsWidget(self)

self.cameraCommunicator = Communicator()
self.trackingCommunicator = Communicator()

self.stopButton.clicked.connect(self.stopClicked)
self.resetButton.clicked.connect(self.resetClicked)
self.takeoffButton.clicked.connect(self.takeOffClicked)
self.takeoff = False
self.reset = False

def getCamera(self):
return self.camera

def setCamera(self, camera):
self.camera = camera

def getNavData(self):
return self.navdata

def setNavData(self, navdata):
self.navdata = navdata

def getPose3D(self):
return self.pose

def setPose3D(self, pose):
self.pose = pose

def getCMDVel(self):
return self.cmdvel

def setCMDVel(self, cmdvel):
self.cmdvel = cmdvel

def getExtra(self):
return self.extra

def setExtra(self, extra):
self.extra = extra


def updateGUI(self):
self.cameraWidget.imageUpdate.emit()
self.sensorsWidget.sensorsUpdate.emit()

def stopClicked(self):
if self.record == True:
self.extra.record(False)
self.rotationDial.setValue(self.altdSlider.maximum() / 2)
self.altdSlider.setValue(self.altdSlider.maximum() / 2)
self.cmdvel.sendCMDVel(0, 0, 0, 0, 0, 0)
self.teleop.stopSIG.emit()

def takeOffClicked(self):
if (self.takeoff == True):
self.takeoffButton.setText("Take Off")
self.extra.land()
self.takeoff = False
else:
self.takeoffButton.setText("Land")
self.extra.takeoff()
self.takeoff = True

def resetClicked(self):
if self.reset == True:
self.resetButton.setText("Reset")
self.extra.reset()
self.reset = False
else:
self.resetButton.setText("Unreset")
self.extra.reset()
self.reset = True

def showCameraWidget(self, state):
if state == Qt.Checked:
self.cameraWidget.show()
else:
self.cameraWidget.close()

def closeCameraWidget(self):
self.cameraCheck.setChecked(False)

def showSensorsWidget(self, state):
if state == Qt.Checked:
self.sensorsWidget.show()
else:
self.sensorsWidget.close()

def closeSensorsWidget(self):
self.sensorsCheck.setChecked(False)

def rotationChange(self, value):
value = (1.0 / (self.rotationDial.maximum() / 2)) * (value - (self.rotationDial.maximum() / 2))
self.rotValue.setText('%.2f' % value)
self.cmdvel.setYaw(value)
self.cmdvel.sendVelocities()

def altitudeChange(self, value):
value = (1.0 / (self.altdSlider.maximum() / 2)) * (value - (self.altdSlider.maximum() / 2))
self.altdValue.setText('%.2f' % value)
self.cmdvel.setVZ(value)
self.cmdvel.sendVelocities()

def setXYValues(self, newX, newY):
self.XValue.setText('%.2f' % newX)
self.YValue.setText('%.2f' % newY)
self.cmdvel.setVX(-newY)
self.cmdvel.setVY(-newX)
self.cmdvel.sendVelocities()

def closeEvent(self, event):
self.camera.stop()
self.navdata.stop()
self.pose.stop()
event.accept()

Empty file.
156 changes: 156 additions & 0 deletions src/tools/uav_viewer_py/gui/attitudeIndicator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#
# Copyright (C) 1997-2015 JDE Developers Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
# Authors :
# Alberto Martin Florido <almartinflorido@gmail.com>
#
import math
from PyQt4 import Qt
import PyQt4.Qwt5 as Qwt

def enumList(enum, sentinel):
'''
'''
return [enum(i) for i in range(sentinel)]

colorGroupList = enumList(
Qt.QPalette.ColorGroup, Qt.QPalette.NColorGroups)
colorRoleList = enumList(
Qt.QPalette.ColorRole, Qt.QPalette.NColorRoles)
handList = enumList(
Qwt.QwtAnalogClock.Hand, Qwt.QwtAnalogClock.NHands)

class AttitudeIndicatorNeedle(Qwt.QwtDialNeedle):

def __init__(self, color):
Qwt.QwtDialNeedle.__init__(self)
palette = Qt.QPalette()
for colourGroup in colorGroupList:
palette.setColor(colourGroup, Qt.QPalette.Text, color)
self.setPalette(palette)

# __init__()

def draw(self, painter, center, length, direction, cg):
direction *= math.pi / 180.0
triangleSize = int(round(length * 0.1))

painter.save()

p0 = Qt.QPoint(center.x() + 1, center.y() + 1)
p1 = Qwt.qwtPolar2Pos(p0, length - 2 * triangleSize - 2, direction)

pa = Qt.QPolygon([
Qwt.qwtPolar2Pos(p1, 2 * triangleSize, direction),
Qwt.qwtPolar2Pos(p1, triangleSize, direction + math.pi/2),
Qwt.qwtPolar2Pos(p1, triangleSize, direction - math.pi/2),
])

color = self.palette().color(cg, Qt.QPalette.Text)
painter.setBrush(color)
painter.drawPolygon(pa)

painter.setPen(Qt.QPen(color, 3))
painter.drawLine(
Qwt.qwtPolar2Pos(p0, length - 2, direction + math.pi/2),
Qwt.qwtPolar2Pos(p0, length - 2, direction - math.pi/2))

painter.restore()

# draw()

# class AttitudeIndicatorNeedle


class AttitudeIndicator(Qwt.QwtDial):

def __init__(self, *args):
Qwt.QwtDial.__init__(self, *args)
self.__gradient = 0.0
self.setMode(Qwt.QwtDial.RotateScale)
self.setWrapping(True)
self.setOrigin(270.0)
self.setScaleOptions(Qwt.QwtDial.ScaleTicks)
self.setScale(0, 0, 30.0)
self.setNeedle(AttitudeIndicatorNeedle(
self.palette().color(Qt.QPalette.Text)))

# __init__()

def angle(self):
return self.value()

# angle()

def setAngle(self, angle):
self.setValue(angle)

# setAngle()

def gradient(self):
return self.__gradient

# gradient()

def setGradient(self, gradient):
self.__gradient = gradient

# setGradient()

def keyPressEvent(self, event):
if event.key() == Qt.Qt.Key_Plus:
self.setGradient(self.gradient() + 0.05)
elif event.key() == Qt.Qt.Key_Minus:
self.setGradient(self.gradient() - 0.05)
else:
Qwt.QwtDial.keyPressEvent(self, event)

# keyPressEvent()

def drawScale(self, painter, center, radius, origin, minArc, maxArc):
dir = (360.0 - origin) * math.pi / 180.0
offset = 4
p0 = Qwt.qwtPolar2Pos(center, offset, dir + math.pi)

w = self.contentsRect().width()

# clip region to swallow 180 - 360 degrees
pa = []
pa.append(Qwt.qwtPolar2Pos(p0, w, dir - math.pi/2))
pa.append(Qwt.qwtPolar2Pos(pa[-1], 2 * w, dir + math.pi/2))
pa.append(Qwt.qwtPolar2Pos(pa[-1], w, dir))
pa.append(Qwt.qwtPolar2Pos(pa[-1], 2 * w, dir - math.pi/2))

painter.save()
painter.setClipRegion(Qt.QRegion(Qt.QPolygon(pa)))
Qwt.QwtDial.drawScale(
self, painter, center, radius, origin, minArc, maxArc)
painter.restore()

# drawScale()

def drawScaleContents(self, painter, center, radius):
dir = 360 - int(round(self.origin() - self.value()))
arc = 90 + int(round(self.gradient() * 90))
skyColor = Qt.QColor(38, 151, 221)
painter.save()
painter.setBrush(skyColor)
painter.drawChord(
self.scaleContentsRect(), (dir - arc)*16, 2*arc*16)
painter.restore()

# drawScaleContents()

# class AttitudeIndicator
Loading