Skip to content

Commit

Permalink
pylint: linted some of the files
Browse files Browse the repository at this point in the history
  • Loading branch information
dervelakos committed Jan 2, 2025
1 parent 34ff229 commit 4ff7a0a
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 106 deletions.
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ property-classes=abc.abstractproperty
#typevar-rgx=

# Naming style matching correct variable names.
variable-naming-style=snake_case
variable-naming-style=camelCase

# Regular expression matching correct variable names. Overrides variable-
# naming-style. If left empty, variable names will be checked with the set
Expand Down
8 changes: 8 additions & 0 deletions scenarios/campain-1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,11 @@ objects:
loc:
- 999.0
- 368.0
- alias: Car
angle: -91.43209618416465
dim:
- 80.0
- 150.0
loc:
- 389.0
- 779.0
99 changes: 51 additions & 48 deletions src/GraphicalWindow.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
"""
Module handling all Qt5 and graphical interface functionality
"""
import math

from PyQt5.QtWidgets import QApplication, QMainWindow, QAction, QWidget, QScrollArea, QHBoxLayout, QListWidget
from PyQt5.QtWidgets import (
QMainWindow, QAction, QWidget,
QScrollArea, QHBoxLayout, QListWidget)
from PyQt5.QtGui import QPainter, QMouseEvent, QColor
from PyQt5.QtCore import Qt, QTimer, QPoint, QLineF
from PyQt5.QtCore import Qt, QTimer, QPoint

from SimEngine import RenderEngine

class UIController:
"""
Class hanlding the control state machine for all graphical interfaces
"""
def __init__(self, mainArea, simEngine, renderEngine, aliases):
self.mainArea = mainArea
self.simEngine = simEngine
Expand All @@ -27,10 +35,16 @@ def selectListObject(self, item):
self.selectedListObject = item.text()

def createObject(self):
"""
Creates and spawns a new object under the cursor
"""
if not self.editMode:
return

delta = QPoint(self.drawArea.dragPosition - self.drawArea.dragStartPosition)
p1 = self.drawArea.dragStartPosition
p2 = self.drawArea.dragPosition

delta = QPoint(p2 - p1)
angle = math.degrees(math.atan2(delta.y(), delta.x()))

length = math.hypot(delta.x(), delta.y())
Expand All @@ -41,32 +55,33 @@ def createObject(self):
dy = -width * math.cos(math.radians(angle)) # Change in y for height

# Calculate bottom corners
x1 = self.drawArea.dragStartPosition.x()
y1 = self.drawArea.dragStartPosition.y()
x2 = self.drawArea.dragPosition.x()
y2 = self.drawArea.dragPosition.y()
x4, y4 = x2 - dx, y2 - dy # bottom-right
x4, y4 = p2.x() - dx, p2.y() - dy # bottom-right

center_x = int((x1 + x4) / 2)
center_y = int((y1 + y4) / 2)

print (center_x, center_y, angle+90, length, width)
centerX = int((p1.x() + x4) / 2)
centerY = int((p1.y() + y4) / 2)
print (centerX, centerY, angle+90, length, width)

if self.editMode:
alias = self.aliases[self.selectedListObject]
tmp = alias.genObject([center_x, center_y],
angle)
tmp = alias.genObject([centerX, centerY], angle)
if tmp.isResizable():
tmp.setDimensions(width, length)
tmp.setAlias(alias)
self.simEngine.registerStaticObject(tmp)
self.renderEngine.registerObject(alias.genRender(tmp))

def drawSelectionShadow(self, painter):
"""
Draw a shadow of the object we will create
"""
if (self.drawArea.dragStartPosition is None or
self.drawArea.dragPosition is None):
return
delta = QPoint(self.drawArea.dragPosition - self.drawArea.dragStartPosition)
self.drawArea.dragPosition is None):
return

p1 = self.drawArea.dragStartPosition
p2 = self.drawArea.dragPosition

delta = QPoint(p2 - p1)
angle = math.degrees(math.atan2(delta.y(), delta.x()))

length = math.hypot(delta.x(), delta.y())
Expand All @@ -77,12 +92,8 @@ def drawSelectionShadow(self, painter):
painter.setPen(Qt.black)
painter.setBrush(QColor(255, 0, 0, 64))

#painter.rotate(self.parent.angle)

# Draw rectangle centered at origin

painter.drawRect(int(self.drawArea.dragStartPosition.x()),
int(self.drawArea.dragStartPosition.y()),
painter.drawRect(int(p1.x()),
int(p1.y()),
int(delta.x()),
int(delta.y()))

Expand All @@ -91,42 +102,29 @@ def drawSelectionShadow(self, painter):
painter.save()
painter.setPen(Qt.black)
painter.setBrush(QColor(0, 255, 0, 64))
line = QLineF(self.drawArea.dragStartPosition, self.drawArea.dragPosition)
painter.translate(int(self.drawArea.dragStartPosition.x()),
int(self.drawArea.dragStartPosition.y()))
painter.translate(int(p1.x()), int(p1.y()))
painter.rotate(angle)
painter.drawRect(0, 0, int(length), int(width))
painter.restore()

center = QPoint(self.drawArea.dragPosition + self.drawArea.dragStartPosition)/2
# Calculate the perpendicular vector for height
# Rotate 90 degrees clockwise
dx = width * math.sin(math.radians(angle)) # Change in x for height
dy = -width * math.cos(math.radians(angle)) # Change in y for height

# Calculate bottom corners
x1 = self.drawArea.dragStartPosition.x()
y1 = self.drawArea.dragStartPosition.y()
x2 = self.drawArea.dragPosition.x()
y2 = self.drawArea.dragPosition.y()
x4, y4 = x2 - dx, y2 - dy # bottom-right

center_x = int((x1 + x4) / 2)
center_y = int((y1 + y4) / 2)

painter.drawEllipse(QPoint(center_x, center_y), 1, 1)
#print (center_x, center_y, angle+90, length, width)

#if self.editMode:
# alias = self.aliases["Wall"]
# tmp = alias.genObject([center_x, center_y],
# angle+90,
# [length, width])
# tmp.setAlias(alias)
# self.simEngine.registerStaticObject(tmp)
# self.renderEngine.registerObject(alias.genRender(tmp))
x4, y4 = p2.x() - dx, p2.y() - dy # bottom-right

centerX = int((p1.x() + x4) / 2)
centerY = int((p1.y() + y4) / 2)

painter.drawEllipse(QPoint(centerX, centerY), 1, 1)

class DrawWidget(QWidget):
"""
This is the canvas for drawing the scenario. Do not add Qt5 elements
in here.
"""
def __init__(self, vehicle, renderEngine, controller):
super().__init__()
self.setMinimumSize(2000,2000)
Expand Down Expand Up @@ -164,6 +162,9 @@ def mouseMoveEvent(self, event: QMouseEvent):
self.dragPosition = event.pos()

def mouseReleaseEvent(self, event: QMouseEvent):
"""
Handles mouse release events
"""
if event.button() == Qt.LeftButton:
print(self.controller)
self.controller.createObject()
Expand All @@ -180,14 +181,16 @@ class MainWindow(QMainWindow):
def __init__(self, vehicle, scenario, simEngine):
super().__init__()
self.setGeometry(100, 100, 800, 800)
self.angle = 0 # Initial rotation anglea

self.vehicle = vehicle
self.scenario = scenario
self.simEngine = simEngine

self.renderEngine = RenderEngine()

#Pylint is right this class contains a lot of attributes I need to
#refactor all theses classes (the upper ones above as well)

menuBar = self.menuBar()
fileMenu = menuBar.addMenu("&File")

Expand Down
71 changes: 35 additions & 36 deletions src/Sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import time
import threading

def line_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4):
def lineLineIntersection(x1, y1, x2, y2, x3, y3, x4, y4):
# Line-line intersection formula
denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
if denom == 0:
Expand All @@ -12,67 +12,65 @@ def line_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4):
u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denom

if 0 <= t <= 1 and 0 <= u <= 1:
intersection_x = x1 + t * (x2 - x1)
intersection_y = y1 + t * (y2 - y1)
return (intersection_x, intersection_y)
intersectionX = x1 + t * (x2 - x1)
intersectionY = y1 + t * (y2 - y1)
return (intersectionX, intersectionY)

return None

def distance_between_points(x1, y1, x2, y2):
def distanceBetweenPoints(x1, y1, x2, y2):
return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

def project_ray(ray_origin, ray_direction, axis):
def projectRay(rayOrigin, rayDirection, axis):
"""Project a ray onto an axis."""
# Normalize the ray direction
length = math.sqrt(ray_direction[0]**2 + ray_direction[1]**2)
normalized_direction = (ray_direction[0] / length, ray_direction[1] / length)
length = math.sqrt(rayDirection[0]**2 + rayDirection[1]**2)
normalizedDirection = (rayDirection[0] / length, rayDirection[1] / length)

# Project the ray origin onto the axis
dot_product = ray_origin[0] * axis[0] + ray_origin[1] * axis[1]
projection_origin = dot_product
dotProduct = rayOrigin[0] * axis[0] + rayOrigin[1] * axis[1]
projectionOrigin = dotProduct

# Project the ray direction onto the axis
dot_product = normalized_direction[0] * axis[0] + normalized_direction[1] * axis[1]
projection_direction = dot_product
dotProduct = normalizedDirection[0] * axis[0] + normalizedDirection[1] * axis[1]
projectionDirection = dotProduct

# Return the projection range (min, max)
if projection_direction >= 0:
return (projection_origin, float('inf')) # Ray extends infinitely in the positive direction
else:
return (float('-inf'), projection_origin) # Ray extends infinitely in the negative direction
if projectionDirection >= 0:
# Ray extends infinitely in the positive direction
return (projectionOrigin, float('inf'))

# Ray extends infinitely in the negative direction
return (float('-inf'), projectionOrigin)

def calculateIntersection(x, y, dirX, dirY, obj):
corners = obj.getCorners()
lidar_end = (x + dirX, y + dirY)
lidarEnd = (x + dirX, y + dirY)

min_distance = float('inf')
collision_point = None
minDistance = float('inf')
collisionPoint = None
#axis1 = (-axis[1], axis[0])

for i in range(4):
edge_start = corners[i]
edge_end = corners[(i + 1) % 4]

#edgeX = end[0] - start[0]
#edgeY = end[1] - start[1]
edgeStart = corners[i]
edgeEnd = corners[(i + 1) % 4]

intersection = line_line_intersection(
intersection = lineLineIntersection(
x, y,
lidar_end[0], lidar_end[1],
edge_start[0], edge_start[1],
edge_end[0], edge_end[1]
lidarEnd[0], lidarEnd[1],
edgeStart[0], edgeStart[1],
edgeEnd[0], edgeEnd[1]
)

if intersection:
dist = distance_between_points(x, y, intersection[0], intersection[1])
if dist < min_distance and dist <= 1000: #maxLen
min_distance = dist
collision_point = intersection
dist = distanceBetweenPoints(x, y, intersection[0], intersection[1])
if dist < minDistance and dist <= 1000: #maxLen
minDistance = dist
collisionPoint = intersection

if collision_point:
return min_distance
else:
return None
if collisionPoint:
return minDistance
return None

class Lidar:
def __init__(self, simEngine, vehicle, rosNode=None,
Expand All @@ -94,6 +92,7 @@ def scan(self, x, y, angle, objects, ignoreObjects=[]):
rayAngleRad = math.radians(angle + i * self.rayAngleIncrement)

#Ray Direction
#1000 is the maximum length of the lidar
dirX = math.cos(rayAngleRad) * 1000
dirY = math.sin(rayAngleRad) * 1000

Expand Down
15 changes: 15 additions & 0 deletions src/SimEngine.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
"""
Module running all the physics of the simulation
"""
import threading
import time

from Utils import Vector2D

class SimEngine:
"""
The physics engine
"""
def __init__(self, interval=1.0/60):
self.staticObjects = []
self.dynamicObjects = []
Expand All @@ -19,6 +25,9 @@ def registerDynamicObject(self, obj):
self.dynamicObjects.append(obj)

def tickEngine(self, dt):
"""
Main tick that updates all objects in the scenario
"""
for obj in self.dynamicObjects:
obj.tick(dt)

Expand Down Expand Up @@ -58,6 +67,9 @@ def startThreaded(self):
self.thread.start()

class RenderEngine:
"""
Render Engine that contains all the drawable objects
"""
def __init__(self):
self.objects = []
self.vehicles = []
Expand All @@ -69,6 +81,9 @@ def registerVehicle(self, obj):
self.vehicles.append(obj)

def draw(self, painter):
"""
Method that will draw all the object on the canvas
"""
for obj in self.objects:
obj.drawMain(painter)

Expand Down
Loading

0 comments on commit 4ff7a0a

Please sign in to comment.