blob: 3a0161d8c487fb764efe0208a732a9694b039d94 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# A simple GUI to remotely actuate the Vehicle HAL via the eumalator
import sys
from threading import Thread
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import VehicleHalProto_pb2
from vhal_emulator import Vhal
import vhal_consts_2_0 as c
# Define a simple thread that receives messages from a vhal object (v) and prints them
def rxThread(v):
while(1):
msg = v.rxMsg()
if (msg.msg_type == VehicleHalProto_pb2.SET_PROPERTY_RESP):
if msg.status == 0:
print "Success ("+str(msg.status)+")"
else:
print "Error ("+str(msg.status)+")"
else:
print msg;
# Main window setup
def window():
app = QApplication(sys.argv)
widget = QWidget()
widget.setWindowTitle("VHal Driver")
widget.setGeometry(100,100,200,50)
topLevelLayout = QHBoxLayout()
widget.setLayout(topLevelLayout)
shiftLayout = QVBoxLayout()
topLevelLayout.addLayout(shiftLayout)
gearTitle = QLabel(widget)
gearTitle.setText("Gear Shift")
shiftLayout.addWidget(gearTitle);
gearDisplay = QLabel(widget)
shiftLayout.addWidget(gearDisplay);
slider = QSlider(Qt.Vertical)
slider.setMinimum(0)
slider.setMaximum(2)
slider.setInvertedAppearance(True)
slider.valueChanged.connect(lambda:sliderMove(slider, gearDisplay))
shiftLayout.addWidget(slider)
sliderMove(slider, gearDisplay)
buttonLayout = QVBoxLayout()
topLevelLayout.addLayout(buttonLayout)
signalButtonGroup = QButtonGroup()
bNoSignal = QPushButton("None")
bNoSignal.setCheckable(True)
bNoSignal.setChecked(True)
buttonLayout.addWidget(bNoSignal)
signalButtonGroup.addButton(bNoSignal)
bHazards = QPushButton("Hazards")
bHazards.setCheckable(True)
buttonLayout.addWidget(bHazards)
signalButtonGroup.addButton(bHazards)
bLeft = QPushButton("Left")
bLeft.setCheckable(True)
buttonLayout.addWidget(bLeft)
signalButtonGroup.addButton(bLeft)
bRight = QPushButton("Right")
bRight.setCheckable(True)
buttonLayout.addWidget(bRight)
signalButtonGroup.addButton(bRight)
signalButtonGroup.buttonClicked.connect(lambda:onSignalClicked(signalButtonGroup))
widget.show()
sys.exit(app.exec_())
def onSignalClicked(group):
print "signal "+group.checkedButton().text()+" is active"
try:
vhal.setProperty(c.VEHICLEPROPERTY_TURN_SIGNAL_STATE, 0, group.checkedId())
except:
print "Ignoring error setting property 0x{:08X}".format(c.VEHICLEPROPERTY_TURN_SIGNAL_STATE)
def sliderMove(slider, gearDisplay):
if slider.value() == 0:
gearName = 'park'
vhal.setProperty(c.VEHICLEPROPERTY_GEAR_SELECTION, 0, c.VEHICLEGEAR_GEAR_PARK)
elif slider.value() == 1:
gearName = 'reverse'
vhal.setProperty(c.VEHICLEPROPERTY_GEAR_SELECTION, 0, c.VEHICLEGEAR_GEAR_REVERSE)
elif slider.value() == 2:
gearName = 'drive'
vhal.setProperty(c.VEHICLEPROPERTY_GEAR_SELECTION, 0, c.VEHICLEGEAR_GEAR_DRIVE)
else:
gearName = "UNK"
print "slider "+slider.objectName()+" requested "+str(slider.value())+" = "+gearName
gearDisplay.setText(gearName)
if __name__ == '__main__':
print "Starting VHal driver GUI"
vhal = Vhal(c.vhal_types_2_0)
# Start a receive thread to consume any replies from the vhal
print "Starting receiver thread"
rx = Thread(target=rxThread, args=(vhal,))
rx.setDaemon(True)
rx.start()
# Put the car in park so we start in a known state (consistent with the GUI default state)
vhal.setProperty(c.VEHICLEPROPERTY_GEAR_SELECTION, 0, c.VEHICLEGEAR_GEAR_PARK)
# Start the main UI -- never returns
window()