Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
drawView.py
Go to the documentation of this file.
1import sys
2from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem, QGraphicsRectItem, QGraphicsEllipseItem, QApplication, QGraphicsPixmapItem, QGraphicsLineItem, QRubberBand, QMenu
3from PyQt5.QtGui import QBrush, QContextMenuEvent, QPen, QPixmap, QImage, QResizeEvent, QTransform, QColor, QColorConstants, QPainter, QIcon
4from PyQt5.QtCore import Qt, QRect, QSize, QLine, QLineF, QEvent
5from PyQt5 import QtWidgets, QtCore
6from collections import OrderedDict
7
8import numpy as np
9
10import mapFile
11import guiLogic
12
13class CustomItem(QtWidgets.QGraphicsEllipseItem):
14 def __init__(self, *args, **kwargs):
15 super().__init__(*args, **kwargs)
16
17 self.setFlag(self.ItemIsSelectable)
18 self.setFlag(self.ItemIsMovable)
19 self.setFlag(self.ItemSendsGeometryChanges)
20 self.line = None
21 self.isPoint = None
22 self.setSelected(True)
23 self.setPos(QtCore.QPointF(10, 10))
24
26 def applyTransform(self):
27 a = self.rotation[0]
28 b = self.rotation[1]
29 c = self.rotation[2]
30 Rx = np.array([[1, 0, 0], [0, np.cos(a), -np.sin(a)], [0, np.sin(a), np.cos(a)]])
31 Ry = np.array([[np.cos(b), 0, np.sin(b)], [0, 1, 0], [-np.sin(b), 0, np.cos(b)]])
32 Rz = np.array([[np.cos(c), -np.sin(c), 0], [np.sin(c), np.cos(c), 0], [0, 0, 1]])
33 # matches with tf2 rotation order
34 R = Rz@Ry@Rx
35 T = self.translation
36 self.lineX = [T + R@self.pointsAxisX[0], T + R@self.pointsAxisX[1]]
37 self.lineY = [T + R@self.pointsAxisY[0], T + R@self.pointsAxisY[1]]
38 self.lineZ = [T + R@self.pointsAxisZ[0], T + R@self.pointsAxisZ[1]]
39 def setTransform(self, translation, rotation):
40 self.translation = translation
41 self.rotation = rotation
42 self.applyTransform()
43 def __init__(self, *args, **kwargs):
44 self.pointsAxisX = [np.array([0,0,0]),np.array([1,0,0])]
45 self.pointsAxisY = [np.array([0,0,0]),np.array([0,1,0])]
46 self.pointsAxisZ = [np.array([0,0,0]),np.array([0,0,1])]
47 self.lineX = [self.pointsAxisX[0], self.pointsAxisX[1]]
48 self.lineY = [self.pointsAxisY[0], self.pointsAxisY[1]]
49 self.lineZ = [self.pointsAxisZ[0], self.pointsAxisZ[1]]
50 self.translation = np.array([0,0,0])
51 self.rotation = np.array([0,0,0])
52 self.applyTransform()
53
54class ConeItem(QtWidgets.QGraphicsPixmapItem):
55 position = np.array([0,0])
56 def __init__(self, *args, **kwargs):
57 super().__init__(*args, **kwargs)
58 self.setFlag(self.ItemIsSelectable)
59 self.setFlag(self.ItemIsMovable)
60 self.setFlag(self.ItemSendsGeometryChanges)
61 self.line = None
62 self.isPoint = None
63 self.setSelected(False)
64 self.setShapeMode(QtWidgets.QGraphicsPixmapItem.ShapeMode.BoundingRectShape)
65
66 def setMovable(self, val):
67 self.setFlag(self.ItemIsMovable, enabled=val)
68
69 def itemChange(self, change , value):
70
71 if change == self.ItemPositionChange and self.scene():
72 newPos = value
73 self.position = np.array([newPos.x(), newPos.y()])
74
75 # self.moveLineToCenter(newPos)
76
77 return super(ConeItem, self).itemChange(change, value)
78
79class drawView(QGraphicsView):
80 def __init__(self, *args, **kwargs):
81 super().__init__(*args, **kwargs)
83 self.setScene(drawScene())
84 self.zoomLevel = 1
85 self.translatex = 0
86 self.translatey = 0
87 shiftPressed = False
88 self.lastMousePos = [0,0]
93 self.rubberBand = None
94 self.rubberBandUse = False
95 self.rubberBandUsed = False
96 self.mode = guiLogic.editorMode.ADD
97 self.landmarkType = guiLogic.landmarkType.BLUE
98 self.setRenderHint(QPainter.Antialiasing)
99 self.coneMap = {}
100 self.guiLogic = None
101
102 self.leftLineMap = OrderedDict()
103 self.rightLineMap = OrderedDict()
104 self.leftLines = []
105 self.rightLines = []
106
107 # self.timeKeepingMap = OrderedDict()
109
110 self.setBackgroundBrush(QBrush(QColor(230, 230, 230)))
111 self.mainWindow = None
112 # self.setTransformationAnchor(QGraphicsView.NoAnchor)
113
114 def getSelected(self):
115 ret = []
116 for i in self.items():
117 if(i.isSelected()):
118 ret.append(i)
119 return ret
120
121
123 for i in self.getSelected():
124 self.removeCone(i)
125
126 def changeSelectedType(self, type):
127 selected = self.getSelected()
128 for i in selected:
129 posOriginal = self.coneMap[i]
130 if(posOriginal[1] == guiLogic.landmarkType.TIMEKEEPING):
131 continue
132 pos = self.worldToPosition(self.coneMap[i][0])
133 if(type == guiLogic.landmarkType.BLUE):
134 posOriginal[1] = guiLogic.landmarkType.BLUE
135 self.scene().changeConeType(i,type)
136 elif(type == guiLogic.landmarkType.YELLOW):
137 posOriginal[1] = guiLogic.landmarkType.YELLOW
138 self.scene().changeConeType(i,type)
139 elif(type == guiLogic.landmarkType.ORANGE):
140 posOriginal[1] = guiLogic.landmarkType.ORANGE
141 self.scene().changeConeType(i,type)
142 elif(type == guiLogic.landmarkType.BIG_ORANGE):
143 posOriginal[1] = guiLogic.landmarkType.BIG_ORANGE
144 self.scene().changeConeType(i,type)
145 elif(type == guiLogic.landmarkType.UNDEFINED):
146 posOriginal[1] = guiLogic.landmarkType.UNDEFINED
147 self.scene().changeConeType(i,type)
148
149 def rightClickMenu(self, pos):
150 # if self.selectionModel().selection().indexes():
151 # for i in self.selectionModel().selection().indexes():
152 # row, column = i.row(), i.column()
153 anySelected = False
154 for i in self.items():
155 anySelected = anySelected or i.isSelected()
156 if (anySelected):
157 menu = QMenu()
158 submenuType = menu.addMenu("Change color")
159 blueAction = submenuType.addAction("Blue")
160 yellowAction = submenuType.addAction("Yellow")
161 orangeAction = submenuType.addAction("Orange")
162 bigOrangeAction = submenuType.addAction("Big orange")
163 unknownAction = submenuType.addAction("Unknown")
164 deleteAction = menu.addAction("&Delete")
165 # action = menu.exec_(self.mapToGlobal(event.pos()))
166 action = menu.exec_(pos)
167 if action == deleteAction:
168 self.delteteSelected()
169 elif action == blueAction:
170 self.changeSelectedType(guiLogic.landmarkType.BLUE)
171 elif action == yellowAction:
172 self.changeSelectedType(guiLogic.landmarkType.YELLOW)
173 elif action == orangeAction:
174 self.changeSelectedType(guiLogic.landmarkType.ORANGE)
175 elif action == bigOrangeAction:
176 self.changeSelectedType(guiLogic.landmarkType.BIG_ORANGE)
177 elif action == unknownAction:
178 self.changeSelectedType(guiLogic.landmarkType.UNDEFINED)
179
180
181 def on_scroll(self, event):
182 if event.modifiers() == Qt.ShiftModifier:
183 # zoomScale = max(1 + 1.0 * event.angleDelta().y() / 120,0.7)
184 self.translatex = event.angleDelta().x()
185 self.translatey = event.angleDelta().y()
186 elif event.modifiers() == Qt.AltModifier:
187 self.translatex = event.angleDelta().x()
188 else:
189 zoomScale = max(1 + 1.0 * event.angleDelta().y() / 120,0.7)
190 self.zoomLevel *= zoomScale
191 self.zoomLevel = max(0.08, self.zoomLevel)
192 self.zoomLevel = min(300, self.zoomLevel)
193 self.zoom_in(self.zoomLevel)
194 self.updateCompass()
195
196 def zoom_in(self,scale):
197 scale_tr = QTransform()
198 scale_tr.scale(scale, scale)
199 self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - self.translatex)
200 self.verticalScrollBar().setValue(self.verticalScrollBar().value() - self.translatey)
201 self.translatex = 0
202 self.translatey = 0
203
204 tr = scale_tr
205 self.setTransform(tr, combine=False)
206
207 def inSquare(self, start, end, point):
208 minX = min(start[0], end[0])
209 minY = min(start[1], end[1])
210 maxX = max(start[0], end[0])
211 maxY = max(start[1], end[1])
212 result = (point[0] >= minX and point[0] <= maxX and point[1] >= minY and point[1] <= maxY)
213 return result
214
216 for i in self.leftLines:
217 self.scene().removeItem(i)
218 for i in self.rightLines:
219 self.scene().removeItem(i)
220 # this is pretty hacky, the line also update visualization when called on mouseMoveEvent (only press or release)
221 for i in range(len(self.guiLogic.lanesConnectionLeft)-1):
222 start = self.worldToPosition(self.guiLogic.lanesConnectionLeft[i][0])
223 end = self.worldToPosition(self.guiLogic.lanesConnectionLeft[i+1][0])
224 l = QLineF(start, end)
225 self.leftLines[i].setLine(l)
226 self.scene().addItem(self.leftLines[i])
227 for i in range(len(self.guiLogic.lanesConnectionRight)-1):
228 start = self.worldToPosition(self.guiLogic.lanesConnectionRight[i][0])
229 end = self.worldToPosition(self.guiLogic.lanesConnectionRight[i+1][0])
230 l = QLineF(start, end)
231 self.rightLines[i].setLine(l)
232 self.scene().addItem(self.rightLines[i])
233
235 for i in self.timeKeepingLines:
236 self.scene().removeItem(i)
237 # this is pretty hacky, the line also update visualization when called on mouseMoveEvent (only press or release)
238 for i in range(len(self.guiLogic.timeKeepingGates)):
239 if(len(self.guiLogic.timeKeepingGates[i]) >= 2):
240 start = self.worldToPosition(self.guiLogic.timeKeepingGates[i][0][0])
241 end = self.worldToPosition(self.guiLogic.timeKeepingGates[i][1][0])
242 l = QLineF(start, end)
243 self.timeKeepingLines[i].setLine(l)
244 self.scene().addItem(self.timeKeepingLines[i])
245
246 def on_click(self, event):
247 super().mousePressEvent(event)
248 position = self.mapToScene(event.pos())
250 mouseButton = event.button()
251 self.updateLaneLines()
252 if(self.guiLogic.editorMode == guiLogic.editorMode.ADD or self.guiLogic.editorMode == guiLogic.editorMode.TIMEKEEPING_START):
253 self.originRB = event.pos()
254 self.rubberBandStart = self.mapToScene(event.pos())
255 self.currentMouseButton = mouseButton
256 if(event.modifiers() == QtCore.Qt.ControlModifier):
257 self.rubberBandUse = True
258 for c in self.coneMap:
259 c.setMovable(False)
260 if not self.rubberBand:
261 self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
262 self.rubberBand.setGeometry(QRect(self.originRB, QSize()))
263 self.rubberBand.show()
264
265 elif(event.modifiers() == QtCore.Qt.NoModifier):
266 anySelected = False
267 for i in self.items():
268 anySelected = anySelected or i.isSelected()
269 numberUnderMouse = 0
270 for i in self.items():
271 numberUnderMouse = numberUnderMouse + int(i.isUnderMouse())
272 anyUnderMouse = (numberUnderMouse >= 1)
273 # left
274 if(mouseButton == Qt.MouseButton.LeftButton):
275 if(self.rubberBandUsed):
276 self.rubberBandUsed = False
277 for c in self.coneMap:
278 c.setSelected(False)
279 return
280 if(self.guiLogic.editorMode == guiLogic.editorMode.ADD):
281 if(not anySelected):
282 if(self.guiLogic.landmarkType == guiLogic.landmarkType.UNDEFINED):
283 t = self.scene().addConeUnknown(position)
284 self.guiLogic.cones.append([self.positionToWorld(position), guiLogic.landmarkType.UNDEFINED])
285 self.coneMap[t] = self.guiLogic.cones[-1]
286 elif(self.guiLogic.landmarkType == guiLogic.landmarkType.BLUE):
287 t = self.scene().addConeLeft(position)
288 self.guiLogic.cones.append([self.positionToWorld(position), guiLogic.landmarkType.BLUE])
289 self.coneMap[t] = self.guiLogic.cones[-1]
290 elif(self.guiLogic.landmarkType == guiLogic.landmarkType.YELLOW):
291 t = self.scene().addConeRight(position)
292 self.guiLogic.cones.append([self.positionToWorld(position), guiLogic.landmarkType.YELLOW])
293 self.coneMap[t] = self.guiLogic.cones[-1]
294 elif(self.guiLogic.landmarkType == guiLogic.landmarkType.ORANGE):
295 t = self.scene().addConeOrange(position)
296 self.guiLogic.cones.append([self.positionToWorld(position), guiLogic.landmarkType.ORANGE])
297 self.coneMap[t] = self.guiLogic.cones[-1]
298 elif(self.guiLogic.landmarkType == guiLogic.landmarkType.BIG_ORANGE):
299 t = self.scene().addConeBigOrange(position)
300 self.guiLogic.cones.append([self.positionToWorld(position), guiLogic.landmarkType.BIG_ORANGE])
301 self.coneMap[t] = self.guiLogic.cones[-1]
302 elif(self.guiLogic.landmarkType == guiLogic.landmarkType.INVISIBLE):
303 t = self.scene().addConeInvisible(position)
304 self.guiLogic.cones.append([self.positionToWorld(position), guiLogic.landmarkType.INVISIBLE])
305 self.coneMap[t] = self.guiLogic.cones[-1]
306 elif(self.guiLogic.landmarkType == guiLogic.landmarkType.TIMEKEEPING):
307 t = self.scene().addConeTimeKeeping(position)
308 self.guiLogic.cones.append([self.positionToWorld(position), guiLogic.landmarkType.TIMEKEEPING])
309 self.coneMap[t] = self.guiLogic.cones[-1]
310
311 elif(self.guiLogic.editorMode == guiLogic.editorMode.TIMEKEEPING_START):
312 if(not anySelected):
313 duringLine = False
314 firstLine = len(self.guiLogic.timeKeepingGates) == 0
315 if(not firstLine):
316 duringLine = len(self.guiLogic.timeKeepingGates[-1]) == 1
317
318 t = self.scene().addConeTimeKeeping(position)
319 cone = [self.positionToWorld(position), guiLogic.landmarkType.TIMEKEEPING]
320 self.guiLogic.cones.append(cone)
321 self.coneMap[t] = self.guiLogic.cones[-1]
322 if(duringLine):
323 self.guiLogic.timeKeepingGates[-1].append(cone)
324 start = self.worldToPosition(self.guiLogic.timeKeepingGates[-1][0][0])
325 end = self.worldToPosition(self.guiLogic.timeKeepingGates[-1][1][0])
326 lineType = 0
327 if len(self.timeKeepingLines) == 0:
328 lineType = 1
329 # elif (len(self.timeKeepingLines) == 1):
330 # lineType = 2
331 t =self.scene().addTimeKeepingLine(start, end, lineType)
332 self.timeKeepingLines.append(t)
333 else:
334 self.guiLogic.timeKeepingGates.append([cone])
335
336 # right
337 elif(mouseButton == Qt.MouseButton.RightButton):
338 if(anySelected):
339 self.rightClickMenu(self.mapToGlobal(event.pos()))
340 elif (numberUnderMouse == 1):
341 for i in self.items():
342 if(i.isUnderMouse() and not (i in self.scene().gridLines)):
343 self.removeCone(i)
344 elif(self.guiLogic.editorMode == guiLogic.editorMode.LANE_CONNECT_LEFT):
345 clickedCones = []
346 for c in self.coneMap:
347 # c.setSelected(False)
348 c.setFlags(c.flags() & ~c.ItemIsMovable & ~c.ItemIsSelectable)
349 if(c.isUnderMouse()):
350 if(len(self.leftLineMap) >= 1):
351 # TODO check for plausibility
352 plausibleConnection = self.checkPlausibilityLaneConnection(self.coneMap[c])
353 if(len(self.leftLineMap) < 3 and (c is next(iter(self.leftLineMap)))):
354 plausibleConnection = False
355 if(plausibleConnection):
356 clickedCones.append(c)
357 self.leftLineMap[c] = self.coneMap[c]
358 self.guiLogic.lanesConnectionLeft.append(self.coneMap[c])
359 start = self.worldToPosition(self.guiLogic.lanesConnectionLeft[-2][0])
360 end = self.worldToPosition(self.guiLogic.lanesConnectionLeft[-1][0])
361 t =self.scene().addLeftConnectionLine(start, end)
362 self.leftLines.append(t)
363 else:
364 clickedCones.append(c)
365 self.leftLineMap[c] = self.coneMap[c]
366 self.guiLogic.lanesConnectionLeft.append(self.coneMap[c])
367
368 if(len(self.leftLineMap) >= 3):
369 done = (self.guiLogic.lanesConnectionLeft[0] is self.guiLogic.lanesConnectionLeft[-1])
370 if(done):
371 self.guiLogic.editorMode = guiLogic.editorMode.LANE_CONNECT_RIGHT
372
373 elif(self.guiLogic.editorMode == guiLogic.editorMode.LANE_CONNECT_RIGHT):
374 clickedCones = []
375 for c in self.coneMap:
376 c.setFlags(c.flags() & ~c.ItemIsMovable & ~c.ItemIsSelectable)
377 if(c.isUnderMouse()):
378 if(len(self.rightLineMap) >= 1):
379 plausibleConnection = self.checkPlausibilityLaneConnection(self.coneMap[c])
380 if(len(self.rightLineMap) < 3 and (c is next(iter(self.rightLineMap)))):
381 plausibleConnection = False
382 if(plausibleConnection):
383 clickedCones.append(c)
384 self.rightLineMap[c] = self.coneMap[c]
385 self.guiLogic.lanesConnectionRight.append(self.coneMap[c])
386 start = self.worldToPosition(self.guiLogic.lanesConnectionRight[-2][0])
387 end = self.worldToPosition(self.guiLogic.lanesConnectionRight[-1][0])
388 t =self.scene().addRightConnectionLine(start, end)
389 self.rightLines.append(t)
390 else:
391 clickedCones.append(c)
392 self.rightLineMap[c] = self.coneMap[c]
393 self.guiLogic.lanesConnectionRight.append(self.coneMap[c])
394
395 if(len(self.rightLineMap) >= 3):
396 done = (self.guiLogic.lanesConnectionRight[0] is self.guiLogic.lanesConnectionRight[-1])
397 if done:
398 self.addModeInit()
399
400
402 alreadyInLane = False
403 startIndLeft = min(1,len(self.guiLogic.lanesConnectionLeft)) if self.guiLogic.editorMode == guiLogic.editorMode.LANE_CONNECT_LEFT else 0
404 startIndRight = min(1,len(self.guiLogic.lanesConnectionRight)) if self.guiLogic.editorMode == guiLogic.editorMode.LANE_CONNECT_RIGHT else 0
405 for i in range(startIndLeft, len(self.guiLogic.lanesConnectionLeft)):
406 alreadyInLane = alreadyInLane or (self.guiLogic.lanesConnectionLeft[i] is c)
407 for i in range(startIndRight, len(self.guiLogic.lanesConnectionRight)):
408 alreadyInLane = alreadyInLane or (self.guiLogic.lanesConnectionRight[i] is c)
409 return not alreadyInLane
410
411 def addModeInit(self):
412 self.guiLogic.editorMode = guiLogic.editorMode.ADD
413 self.guiLogic.landmarkType = guiLogic.landmarkType.UNDEFINED
414 for c in self.coneMap:
415 c.setFlag(c.ItemIsSelectable)
416 c.setFlag(c.ItemIsMovable)
417 self.mainWindow.ui.goBackToAdd()
418
420 selected = self.getSelected()
421 if len(selected) == 1:
422 globalPos = self.positionToWorld(selected[0])
423 self.mainWindow.ui.updateMousePositionDisplay(str(globalPos[0:2]))
424 else:
425 self.mainWindow.ui.updateMousePositionDisplay("")
426
427
428 def on_click_release(self, event):
429 self.updatePositions()
431 self.updateLaneLines()
432 # if(self.guiLogic.editorMode == guiLogic.editorMode.ADD):
433
435 # print(self.coneMap)
436 # print(self.guiLogic.cones)
437 super().mouseReleaseEvent(event)
438 mouseButton = event.button()
439 self.currentMouseButton = mouseButton
440 if(self.rubberBandUse):
441 self.rubberBandUsed = True
442 self.rubberBand.hide()
443 self.rubberBandEnd = self.mapToScene(event.pos())
444 scene = self.scene()
445 minX = min(self.rubberBandStart.x(), self.rubberBandEnd.x())
446 minY = min(self.rubberBandStart.y(), self.rubberBandEnd.y())
447 maxX = max(self.rubberBandStart.x(), self.rubberBandEnd.x())
448 maxY = max(self.rubberBandStart.y(), self.rubberBandEnd.y())
449 for i in scene.items(minX, minY, maxX-minX, maxY-minY, Qt.IntersectsItemBoundingRect, Qt.AscendingOrder):
450 i.setSelected(True)
451 self.rubberBandUse = False
452 for c in self.coneMap:
453 c.setMovable(True)
454 self.releasedShiftKlick = True
456 # def mousePos()
457 def mouseMoveEvent(self, event):
458 super().mouseMoveEvent(event)
459 mouseButton = event.button()
460 # if(event.modifiers() == QtCore.Qt.ControlModifier):
461 if(self.rubberBandUse):
462 self.rubberBand.setGeometry(QRect(self.originRB, event.pos()).normalized())
463 mousePos = [event.pos().x(), event.pos().y()]
464 if((event.modifiers() == QtCore.Qt.ShiftModifier or self.currentMouseButton == QtCore.Qt.MiddleButton) and (not self.releasedShiftKlick)):
465 movement = [mousePos[0] - self.lastMousePos[0], mousePos[1] - self.lastMousePos[1]]
466 self.translatex = movement[0]
467 self.translatey = movement[1]
468 self.zoom_in(self.zoomLevel)
469 self.updateCompass()
470 self.lastMousePos = mousePos
471 self.releasedShiftKlick = False
472
473 def addCone(self, cone):
474 t = None
475 c = QtCore.QPointF(-cone[0][0]*self.scene().pixelPerMeter, cone[0][1]*self.scene().pixelPerMeter)
476 if(cone[1] == guiLogic.landmarkType.UNDEFINED):
477 t = self.scene().addConeUnknown(c)
478 elif(cone[1] == guiLogic.landmarkType.BLUE):
479 t = self.scene().addConeLeft(c)
480 elif(cone[1] == guiLogic.landmarkType.YELLOW):
481 t = self.scene().addConeRight(c)
482 elif(cone[1] == guiLogic.landmarkType.ORANGE):
483 t = self.scene().addConeOrange(c)
484 elif(cone[1] == guiLogic.landmarkType.BIG_ORANGE):
485 t = self.scene().addConeBigOrange(c)
486 elif(cone[1] == guiLogic.landmarkType.INVISIBLE):
487 t = self.scene().addConeInvisible(c)
488 elif(cone[1] == guiLogic.landmarkType.TIMEKEEPING):
489 t = self.scene().addConeTimeKeeping(c)
490 else:
491 print("error adding cone")
492 return
493 self.coneMap[t] = cone
494 # print(self.coneMap)
495 def removeAllCones(self):
496 self.guiLogic.cones = []
497 for c in self.coneMap:
498 self.scene().removeItem(c)
499 self.coneMap = {}
500
501 def removeCone(self, c):
502 if c not in self.coneMap:
503 return
504 # weird way because remove() doesn't work with np.array
505 if c in self.leftLineMap.keys() or c in self.rightLineMap.keys():
507 if(self.coneMap[c][1] == guiLogic.landmarkType.TIMEKEEPING):
509 else:
510 self.guiLogic.cones = [i for i in self.guiLogic.cones if (i is not self.coneMap[c])]
511 del self.coneMap[c]
512 self.scene().removeItem(c)
513 # self.guiLogic.cones.remove(self.guiLogic.cones[cone])
514
515 def positionToWorld(self, p):
516 return np.array([-p.x()/self.scene().pixelPerMeter, p.y()/self.scene().pixelPerMeter, 0])
517
518 def worldToPosition(self, p):
519 return QtCore.QPointF(-p[0]*self.scene().pixelPerMeter, p[1]*self.scene().pixelPerMeter)
520
522 for i in self.coneMap:
523 worldPos = self.positionToWorld(i)
524 conePos = self.coneMap[i]
525 np.copyto(conePos[0], worldPos)
526
528 for i in self.leftLines:
529 self.scene().removeItem(i)
530 for i in self.rightLines:
531 self.scene().removeItem(i)
532 self.leftLineMap = OrderedDict()
533 self.rightLineMap = OrderedDict()
534 self.leftLines = []
535 self.rightLines = []
536 self.guiLogic.lanesConnectionLeft = []
537 self.guiLogic.lanesConnectionRight = []
538
540 for i in self.timeKeepingLines:
541 self.scene().removeItem(i)
542 self.timeKeepingLines = []
543 # for in self.time
544 newConeMap = {}
545 toRemove = []
546 for i in self.coneMap:
547 if(self.coneMap[i][1] != guiLogic.landmarkType.TIMEKEEPING):
548 newConeMap[i] = self.coneMap[i]
549 else:
550 toRemove.append(i)
551 self.coneMap = newConeMap
552 for i in toRemove:
553 self.scene().removeItem(i)
554 # self.guiLogic.cones = [i for i in self.guiLogic.cones if (i[0] is not self.coneMap[c])]
555 self.guiLogic.cones = [i for i in self.guiLogic.cones if (i[1] != guiLogic.landmarkType.TIMEKEEPING)]
556 # self.guiLogic.cones = [i for i in self.guiLogic.cones if (i[0] is not self.coneMap[c])]
557 self.guiLogic.timeKeepingGates = []
558
560 plausible = True
561 for i in self.guiLogic.timeKeepingGates:
562 plausible = plausible and len(i) == 2
563 if(not plausible):
565
566 def resetAll(self):
567 for i in self.coneMap:
568 self.removeCone(i)
571
572 def initFromLoad(self):
573 for c in self.guiLogic.cones:
574 self.addCone(c)
575 counter = 0
576 for i in self.guiLogic.timeKeepingGates:
577 lineType = 0
578 if counter == 0:
579 lineType = 1
580 elif counter == 1:
581 lineType = 2
582 counter += 1
583 start = self.worldToPosition(i[0][0])
584 end = self.worldToPosition(i[1][0])
585 t =self.scene().addTimeKeepingLine(start, end, lineType)
586 self.timeKeepingLines.append(t)
587 for i in range(0, len(self.guiLogic.lanesConnectionLeft)):
588 cone = [c for c in self.coneMap.keys() if (self.coneMap[c] is self.guiLogic.lanesConnectionLeft[i])]
589 self.leftLineMap[cone[0]] = self.guiLogic.lanesConnectionLeft[i]
590 if(i != 0):
591 start = self.worldToPosition(self.guiLogic.lanesConnectionLeft[i-1][0])
592 end = self.worldToPosition(self.guiLogic.lanesConnectionLeft[i][0])
593 t =self.scene().addLeftConnectionLine(start, end)
594 self.leftLines.append(t)
595 for i in range(0, len(self.guiLogic.lanesConnectionRight)):
596 cone = [c for c in self.coneMap.keys() if (self.coneMap[c] is self.guiLogic.lanesConnectionRight[i])]
597 self.rightLineMap[cone[0]] = self.guiLogic.lanesConnectionRight[i]
598 if(i != 0):
599 start = self.worldToPosition(self.guiLogic.lanesConnectionRight[i-1][0])
600 end = self.worldToPosition(self.guiLogic.lanesConnectionRight[i][0])
601 t =self.scene().addRightConnectionLine(start, end)
602 self.rightLines.append(t)
603
604 self.updateLaneLines()
605
606 def updateCompass(self):
607 a = self.size()
608 # a = self.viewport().geometry()
609 relScale = 0.3
610 centerPoint = relScale * np.array([64,64])
611 # centerPoint = np.array([0,0])
612 c = -self.guiLogic.originENURotation[2] - np.pi/2
613 Rz = np.array([[np.cos(c), -np.sin(c)], [np.sin(c), np.cos(c)]])
614 centerPointRotated = Rz@centerPoint
615 a = self.mapToScene(int(-centerPointRotated[0]+centerPoint[0]), int(-centerPointRotated[1]+centerPoint[1]))
616 self.scene().compass.setScale(relScale*1/self.zoomLevel)
617 self.scene().compass.setRotation(c * 180.0 / np.pi)
618 self.scene().compass.setPos(a)
619
620
621class drawScene(QGraphicsScene):
622 def __init__(self, *args, **kwargs):
623 super().__init__(*args, **kwargs)
624 # self.mode = editorMode.ADD
625 # self.landmarkType = landmarkType.BLUE
628
631 self.compassHeight = 128
632
633 self.scalingMode = Qt.TransformationMode.SmoothTransformation # Qt.TransformationMode.FastTransformation
634 self.imageBlue = QImage("icons/coneBlue.png").scaledToHeight(self.normalConeHeight, mode=self.scalingMode)
635 self.imageYellow = QImage("icons/coneYellow.png").scaledToHeight(self.normalConeHeight, mode=self.scalingMode)
636 self.imageOrange = QImage("icons/coneOrange.png").scaledToHeight(self.normalConeHeight, mode=self.scalingMode)
637 self.imageBigOrange = QImage("icons/coneBigOrange.png").scaledToHeight(self.bigConeHeight, mode=self.scalingMode)
638 self.imageUnknown = QImage("icons/coneUnknown.png").scaledToHeight(self.normalConeHeight, mode=self.scalingMode)
639 self.imageInvisible = QImage("icons/coneInvisible.png").scaledToHeight(self.normalConeHeight, mode=self.scalingMode)
640 self.imageTimeKeeping = QImage("icons/timeKeeping.png").scaledToHeight(self.bigConeHeight, mode=self.scalingMode)
641 self.imageCompass = QImage("icons/compass.png")
642 self.compass = QtWidgets.QGraphicsPixmapItem(QPixmap.fromImage(self.imageCompass).scaledToHeight(self.compassHeight, mode=self.scalingMode))
643 self.compass.setPos(0,0)
644 self.compass.setZValue(2)
645 self.addItem(self.compass)
646
648 gridPenRough = QPen(QColor(Qt.gray),1.0)
649 originPen = QPen(QColor(Qt.gray),3.0)
650
651 self.gridLines = []
652 gridSize = 30
653 gridCellSize = 10.0
654
658
662 # self.originCar.setTransform(np.array([2,2,0]),np.zeros(3))
663 # self.updateOriginLines(self.originCar)
664 for i in range(-gridSize,gridSize):
665 line = QGraphicsLineItem(gridCellSize*i*self.pixelPerMeter, -gridCellSize*gridSize*self.pixelPerMeter, gridCellSize*i*self.pixelPerMeter, gridCellSize*gridSize*self.pixelPerMeter)
666 line.setPen(gridPenRough)
667 line.setZValue(0)
668 self.addItem(line)
669 self.gridLines.append(line)
670 for i in range(-gridSize,gridSize):
671 line = QGraphicsLineItem(-gridCellSize*gridSize*self.pixelPerMeter, gridCellSize*i*self.pixelPerMeter, gridCellSize*gridSize*self.pixelPerMeter, gridCellSize*i*self.pixelPerMeter)
672 line.setPen(gridPenRough)
673 line.setZValue(0)
674 self.addItem(line)
675 self.gridLines.append(line)
676
677 line = QGraphicsLineItem(0, -gridCellSize*i*self.pixelPerMeter, 0, gridCellSize*gridSize*self.pixelPerMeter)
678 line.setPen(originPen)
679 line.setZValue(0)
680 self.addItem(line)
681
682 line = QGraphicsLineItem(-gridCellSize*i*self.pixelPerMeter, 0, gridCellSize*gridSize*self.pixelPerMeter, 0)
683 line.setPen(originPen)
684 line.setZValue(0)
685 self.addItem(line)
686
687 def drawOriginLines(self, origin, lines):
688 penX = QPen(QColor(Qt.red),5.0)
689 penX.setCapStyle(Qt.FlatCap)
690 lineX = QGraphicsLineItem(-origin.lineX[0][0]*self.pixelPerMeter, origin.lineX[0][1]*self.pixelPerMeter, -origin.lineX[1][0]*self.pixelPerMeter, origin.lineX[1][1]*self.pixelPerMeter)
691 lineX.setPen(penX)
692 lineX.setZValue(1)
693 self.addItem(lineX)
694 self.gridLines.append(lineX)
695 lines.append(lineX)
696
697 penY = QPen(QColor(Qt.green),5.0)
698 penY.setCapStyle(Qt.FlatCap)
699 lineY = QGraphicsLineItem(-origin.lineY[0][0]*self.pixelPerMeter, origin.lineY[0][1]*self.pixelPerMeter, -origin.lineY[1][0]*self.pixelPerMeter, origin.lineY[1][1]*self.pixelPerMeter)
700 lineY.setPen(penY)
701 lineY.setZValue(1)
702 self.addItem(lineY)
703 self.gridLines.append(lineY)
704 lines.append(lineY)
705
706 penZ = QPen(QColor(Qt.blue),5.0)
707 penZ.setCapStyle(Qt.FlatCap)
708 lineZ = QGraphicsLineItem(-origin.lineZ[0][0]*self.pixelPerMeter, origin.lineZ[0][1]*self.pixelPerMeter, -origin.lineZ[1][0]*self.pixelPerMeter, origin.lineZ[1][1]*self.pixelPerMeter)
709 lineZ.setPen(penZ)
710 lineZ.setZValue(1)
711 self.addItem(lineZ)
712 self.gridLines.append(lineZ)
713 lines.append(lineZ)
714
716 origin = self.originCar
717 lines = self.carOriginLines
718 if(len(lines) == 0):
719 self.drawOriginLines(origin, lines)
720 else:
721 lines[0].setLine(-origin.lineX[0][0]*self.pixelPerMeter, origin.lineX[0][1]*self.pixelPerMeter, -origin.lineX[1][0]*self.pixelPerMeter, origin.lineX[1][1]*self.pixelPerMeter)
722 lines[1].setLine(-origin.lineY[0][0]*self.pixelPerMeter, origin.lineY[0][1]*self.pixelPerMeter, -origin.lineY[1][0]*self.pixelPerMeter, origin.lineY[1][1]*self.pixelPerMeter)
723 lines[2].setLine(-origin.lineZ[0][0]*self.pixelPerMeter, origin.lineZ[0][1]*self.pixelPerMeter, -origin.lineZ[1][0]*self.pixelPerMeter, origin.lineZ[1][1]*self.pixelPerMeter)
724
725 def addCone(self, c):
726 t = ConeItem(QPixmap.fromImage(self.imageUnknown))
727 t.setOffset(-8, -8)
728 t.setPos(-c[0][0]*self.pixelPerMeter, c[0][1]*self.pixelPerMeter)
729 self.addItem(t)
730 return t
731
732 def on_click(self, event):
733 # to prevent that cones are unselected when only clicking middle button (drag view)
734 if(event.button() == Qt.MouseButton.MiddleButton or event.button() == Qt.MouseButton.RightButton):
735 return
736 super().mousePressEvent(event)
737
738 def on_click_release(self, event):
739 super().mouseReleaseEvent(event)
740
741 def mouseMoveEvent(self, event):
742 super().mouseMoveEvent(event)
743
744 def changeConeType(self, c, type):
745 if(type == guiLogic.landmarkType.UNDEFINED):
746 c.setPixmap(QPixmap.fromImage(self.imageUnknown))
747 elif(type == guiLogic.landmarkType.BLUE):
748 c.setPixmap(QPixmap.fromImage(self.imageBlue))
749 elif(type == guiLogic.landmarkType.YELLOW):
750 c.setPixmap(QPixmap.fromImage(self.imageYellow))
751 elif(type == guiLogic.landmarkType.ORANGE):
752 c.setPixmap(QPixmap.fromImage(self.imageOrange))
753 elif(type == guiLogic.landmarkType.BIG_ORANGE):
754 c.setPixmap(QPixmap.fromImage(self.imageBigOrange))
755 elif(type == guiLogic.landmarkType.INVISIBLE):
756 c.setPixmap(QPixmap.fromImage(self.imageInvisible))
757
758 def addConeUnknown(self, position):
759 t = ConeItem(QPixmap.fromImage(self.imageUnknown))
760 t.setOffset(-0.5*self.imageUnknown.size().width(), -0.5*self.imageUnknown.size().height())
761 t.setPos(position)
762 t.setZValue(2)
763 self.addItem(t)
764 return t
765
766 def addConeInvisible(self, position):
767 t = ConeItem(QPixmap.fromImage(self.imageInvisible))
768 t.setOffset(-0.5*self.imageInvisible.size().width(), -0.5*self.imageInvisible.size().height())
769 t.setPos(position)
770 t.setZValue(2)
771 self.addItem(t)
772 return t
773
774 def addConeLeft(self, position):
775 t = ConeItem(QPixmap.fromImage(self.imageBlue))
776 t.setOffset(-0.5*self.imageBlue.size().width(), -0.5*self.imageBlue.size().height())
777 t.setPos(position)
778 t.setZValue(2)
779 self.addItem(t)
780 return t
781
782 def addConeRight(self, position):
783 t = ConeItem(QPixmap.fromImage(self.imageYellow))
784 t.setOffset(-0.5*self.imageYellow.size().width(), -0.5*self.imageYellow.size().height())
785 t.setPos(position)
786 t.setZValue(2)
787 self.addItem(t)
788 return t
789
790 def addConeOrange(self, position):
791 t = ConeItem(QPixmap.fromImage(self.imageOrange))
792 t.setOffset(-0.5*self.imageOrange.size().width(), -0.5*self.imageOrange.size().height())
793 t.setPos(position)
794 t.setZValue(2)
795 self.addItem(t)
796 return t
797
798 def addConeBigOrange(self, position):
799 t = ConeItem(QPixmap.fromImage(self.imageBigOrange))
800 t.setOffset(-0.5*self.imageBigOrange.size().width(), -0.5*self.imageBigOrange.size().height())
801 t.setPos(position)
802 t.setZValue(2)
803 self.addItem(t)
804 return t
805
806 def addConeTimeKeeping(self, position):
807 t = ConeItem(QPixmap.fromImage(self.imageTimeKeeping))
808 t.setOffset(-0.5*self.imageTimeKeeping.size().width(), -0.5*self.imageTimeKeeping.size().height())
809 t.setPos(position)
810 t.setZValue(2)
811 self.addItem(t)
812 return t
813
814 def addLeftConnectionLine(self, start, end):
815 l = QLineF(start, end)
816 pen = QPen(QColor(Qt.blue),4.0)
817 t = self.addLine(l, pen)
818 return t
819
820 def addRightConnectionLine(self, start, end):
821 l = QLineF(start, end)
822 pen = QPen(QColor(Qt.darkYellow),4.0)
823 t = self.addLine(l, pen)
824 return t
825
826 def addTimeKeepingLine(self, start, end, type):
827 l = QLineF(start, end)
828 pen = QPen(QColor(Qt.magenta),5.0)
829 if(type == 1):
830 pen = QPen(QColor(Qt.green),5.0, Qt.DashLine)
831 elif(type == 2):
832 pen = QPen(QColor(Qt.red),5.0, Qt.DashLine)
833 t = self.addLine(l, pen)
834 return t
835 def zoom_in(self,scale):
836 scale_tr = QTransform()
837 scale_tr.scale(scale, scale)
838 scale_tr.translate(self.translatex, 0)
839
840 tr = scale_tr
841 self.views()[0].setTransform(tr, combine=False)
842
843 def zoom_out(self, scale):
844 scale_tr = QTransform()
845 scale_tr.scale(scale, scale)
846 scale_tr.translate(self.translatex, 0)
847
848 scale_inverted, invertible = scale_tr.inverted()
849
850 if invertible:
851 tr = scale_inverted
852 self.views()[0].setTransform(tr, combine=False)
itemChange(self, change, value)
Definition drawView.py:69
setMovable(self, val)
Definition drawView.py:66
__init__(self, *args, **kwargs)
Definition drawView.py:56
__init__(self, *args, **kwargs)
Definition drawView.py:14
addConeBigOrange(self, position)
Definition drawView.py:798
__init__(self, *args, **kwargs)
Definition drawView.py:622
addConeOrange(self, position)
Definition drawView.py:790
changeConeType(self, c, type)
Definition drawView.py:744
on_click_release(self, event)
Definition drawView.py:738
addTimeKeepingLine(self, start, end, type)
Definition drawView.py:826
mouseMoveEvent(self, event)
Definition drawView.py:741
addConeTimeKeeping(self, position)
Definition drawView.py:806
addConeInvisible(self, position)
Definition drawView.py:766
addConeLeft(self, position)
Definition drawView.py:774
addLeftConnectionLine(self, start, end)
Definition drawView.py:814
addConeRight(self, position)
Definition drawView.py:782
on_click(self, event)
Definition drawView.py:732
addConeUnknown(self, position)
Definition drawView.py:758
drawOriginLines(self, origin, lines)
Definition drawView.py:687
updateOriginLines(self)
Definition drawView.py:715
addRightConnectionLine(self, start, end)
Definition drawView.py:820
zoom_out(self, scale)
Definition drawView.py:843
zoom_in(self, scale)
Definition drawView.py:835
zoom_in(self, scale)
Definition drawView.py:196
resetLaneConnections(self)
Definition drawView.py:527
delteteSelected(self)
Definition drawView.py:122
on_scroll(self, event)
Definition drawView.py:181
updateLaneLines(self)
Definition drawView.py:215
worldToPosition(self, p)
Definition drawView.py:518
addCone(self, cone)
Definition drawView.py:473
mouseMoveEvent(self, event)
Definition drawView.py:457
inSquare(self, start, end, point)
Definition drawView.py:207
checkPlausibilityLaneConnection(self, c)
Definition drawView.py:401
checkTimeKeepingLines(self)
Definition drawView.py:559
resetTimeKeepingLines(self)
Definition drawView.py:539
positionToWorld(self, p)
Definition drawView.py:515
__init__(self, *args, **kwargs)
Definition drawView.py:80
changeSelectedType(self, type)
Definition drawView.py:126
on_click(self, event)
Definition drawView.py:246
removeCone(self, c)
Definition drawView.py:501
rightClickMenu(self, pos)
Definition drawView.py:149
updateTimeKeepingLines(self)
Definition drawView.py:234
updatePositions(self)
Definition drawView.py:521
on_click_release(self, event)
Definition drawView.py:428
updateLMPositionDisplay(self)
Definition drawView.py:419
setTransform(self, translation, rotation)
Definition drawView.py:39
__init__(self, *args, **kwargs)
Definition drawView.py:43