Skip to content

Commit 06f1a95

Browse files
committed
Car simulations joined
1 parent bec98c3 commit 06f1a95

15 files changed

+893
-202
lines changed

simpylc/.~lock.simpylc_howto.odt#

Lines changed: 0 additions & 1 deletion
This file was deleted.

simpylc/simulations/car/lidar_pilot.py renamed to simpylc/simulations/car/alternatives/lidar_pilot.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import time as tm
2828
import traceback as tb
29+
import math as mt
2930

3031
import simpylc as sp
3132

@@ -77,7 +78,7 @@ def sweep (self): # Control algorithm to be tested
7778
self.targetObstacleAngle = (self.nearestObstacleAngle + self.nextObstacleAngle) / 2
7879

7980
self.steeringAngle = self.targetObstacleAngle
80-
self.targetVelocity = (sp.abs (90 - self.steeringAngle) / 80) if self.driveEnabled else 0
81+
self.targetVelocity = ((90 - abs (self.steeringAngle)) / 60) if self.driveEnabled else 0
8182

8283
def output (self): # Output to simulator
8384
sp.world.physics.steeringAngle.set (self.steeringAngle)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# ====== Legal notices
2+
#
3+
# Copyright (C) 2013 - 2020 GEATEC engineering
4+
#
5+
# This program is free software.
6+
# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY, without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
# See the QQuickLicence for details.
12+
#
13+
# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html
14+
#
15+
# __________________________________________________________________________
16+
#
17+
#
18+
# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !!
19+
#
20+
# __________________________________________________________________________
21+
#
22+
# It is meant for training purposes only.
23+
#
24+
# Removing this header ends your licence.
25+
#
26+
27+
import time as tm
28+
import traceback as tb
29+
import math as mt
30+
31+
import timer as tr
32+
import pid_controller as pc
33+
34+
class LidarPilotBase:
35+
def __init__ (self):
36+
self.driveEnabled = False
37+
self.steeringAngle = 0
38+
39+
self.timer = tr.Timer ()
40+
self.steeringPidController = pc.PidController (1.05, 0, -0.03)
41+
42+
while True:
43+
self.timer.tick ()
44+
self.input ()
45+
self.sweep ()
46+
self.output ()
47+
tm.sleep (0.02)
48+
49+
def sweep (self): # Control algorithm to be tested
50+
self.nearestObstacleDistance = self.finity
51+
self.nearestObstacleAngle = 0
52+
53+
self.nextObstacleDistance = self.finity
54+
self.nextObstacleAngle = 0
55+
56+
for lidarAngle in range (-self.lidarHalfApertureAngle, self.lidarHalfApertureAngle):
57+
lidarDistance = self.lidarDistances [lidarAngle]
58+
59+
if lidarDistance < self.nearestObstacleDistance:
60+
self.nextObstacleDistance = self.nearestObstacleDistance
61+
self.nextObstacleAngle = self.nearestObstacleAngle
62+
63+
self.nearestObstacleDistance = lidarDistance
64+
self.nearestObstacleAngle = lidarAngle
65+
66+
elif lidarDistance < self.nextObstacleDistance:
67+
self.nextObstacleDistance = lidarDistance
68+
self.nextObstacleAngle = lidarAngle
69+
70+
self.targetObstacleDistance = (self.nearestObstacleDistance + self.nextObstacleDistance) / 2
71+
self.targetObstacleAngle = (self.nearestObstacleAngle + self.nextObstacleAngle) / 2
72+
73+
self.steeringAngle = self.steeringPidController.getY (self.timer.deltaTime, self.targetObstacleAngle, 0)
74+
# print (f'{self.targetObstacleAngle:5.3f} {self.steeringAngle:5.3f}', '\r')
75+
# self.steeringAngle = self.targetObstacleAngle
76+
self.targetVelocity = ((90 - abs (self.steeringAngle)) / 60) if self.driveEnabled else 0
77+
78+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# ====== Legal notices
2+
#
3+
# Copyright (C) 2013 - 2020 GEATEC engineering
4+
#
5+
# This program is free software.
6+
# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY, without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
# See the QQuickLicence for details.
12+
#
13+
# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html
14+
#
15+
# __________________________________________________________________________
16+
#
17+
#
18+
# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !!
19+
#
20+
# __________________________________________________________________________
21+
#
22+
# It is meant for training purposes only.
23+
#
24+
# Removing this header ends your licence.
25+
#
26+
27+
import lidar_pilot_base as lb
28+
29+
class LidarPilotRealIo (lb.LidarPilotBase):
30+
31+
def __init__ (self):
32+
self.finity = 1_000_000_000
33+
super () .__init__ ()
34+
35+
def input (self): # Input from hardware
36+
pass
37+
38+
def output (self): # Output to hardware
39+
pass
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# ====== Legal notices
2+
#
3+
# Copyright (C) 2013 - 2020 GEATEC engineering
4+
#
5+
# This program is free software.
6+
# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY, without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
# See the QQuickLicence for details.
12+
#
13+
# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html
14+
#
15+
# __________________________________________________________________________
16+
#
17+
#
18+
# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !!
19+
#
20+
# __________________________________________________________________________
21+
#
22+
# It is meant for training purposes only.
23+
#
24+
# Removing this header ends your licence.
25+
#
26+
27+
import simpylc as sp
28+
import lidar_pilot_base as lb
29+
30+
class LidarPilotSimulatedIo (lb.LidarPilotBase):
31+
def __init__ (self):
32+
print ('Use up arrow to start, down arrow to stop')
33+
self.finity = sp.finity
34+
super () .__init__ ()
35+
36+
def input (self): # Input from simulator
37+
key = sp.getKey ()
38+
39+
if key == 'KEY_UP':
40+
self.driveEnabled = True
41+
elif key == 'KEY_DOWN':
42+
self.driveEnabled = False
43+
44+
self.lidarDistances = sp.world.visualisation.lidar.distances
45+
self.lidarHalfApertureAngle = sp.world.visualisation.lidar.halfApertureAngle
46+
47+
def output (self): # Output to simulator
48+
sp.world.physics.steeringAngle.set (self.steeringAngle)
49+
sp.world.physics.targetVelocity.set (self.targetVelocity)
50+
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# ====== Legal notices
2+
#
3+
# Copyright (C) 2013 - 2020 GEATEC engineering
4+
#
5+
# This program is free software./
6+
# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY, without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
# See the QQuickLicence for details.
12+
#
13+
# The QQuickLicense can be accessed at: http://www.qquick.org/license.html
14+
#
15+
# __________________________________________________________________________
16+
#
17+
#
18+
# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !!
19+
#
20+
# __________________________________________________________________________
21+
#
22+
# It is meant for training purposes only.
23+
#
24+
# Removing this header ends your licence.
25+
#
26+
27+
'''
28+
Requirements:
29+
=============
30+
31+
Given a timedependent reference signal and a timedependent feedback sensor input,
32+
the PID controller should minimize the difference between them.
33+
To this end it's output will be the sum of:
34+
- A term proportional to this difference
35+
- A term proportional the time integral of this difference
36+
- A term proportional to the time derivative of this difference
37+
The weight of this terms should be freely choosable when creating a PID controller.
38+
The PID controller will function in a control loop with known, but varying cycle time.
39+
40+
Testspec:
41+
=========
42+
43+
A number known time dependent signals will be fed to the PID controller.
44+
They will be shown graphically together with the output of the controller,
45+
allowing visual validation.
46+
47+
Design:
48+
=======
49+
50+
The PID controller will be coded as a class,
51+
receiving the p, i and d factors at construction time.
52+
Construction happens prior to entering the control loop.
53+
In the control loop, the output signal will be computed by a method of the controller,
54+
receiving:
55+
- The most recent cycle time
56+
- The reference signal
57+
- The feedback signal from the sensor
58+
'''
59+
60+
class PidController:
61+
def __init__ (self, p, i, d):
62+
self.p = p
63+
self.i = i
64+
self.d = d
65+
self.yI = 0
66+
self.xErrorOld = 0
67+
68+
def getY (self, deltaT, xSetpoint, xActual):
69+
70+
# Deviation between setpoint and actual signal
71+
xError = xSetpoint - xActual
72+
73+
# Proportional term
74+
yP = self.p * xError
75+
76+
# Integrating term
77+
self.yI += self.i * xError * deltaT
78+
79+
# Differentiating term
80+
yD = self.d * (xError - self.xErrorOld) / deltaT
81+
self.xErrorOld = xError
82+
83+
# Summation
84+
return yP + self.yI + yD
85+

simpylc/simulations/car/timer.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# ====== Legal notices
2+
#
3+
# Copyright (C) 2013 - 2020 GEATEC engineering
4+
#
5+
# This program is free software./
6+
# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY, without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
# See the QQuickLicence for details.
12+
#
13+
# The QQuickLicense can be accessed at: http://www.qquick.org/license.html
14+
#
15+
# __________________________________________________________________________
16+
#
17+
#
18+
# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !!
19+
#
20+
# __________________________________________________________________________
21+
#
22+
# It is meant for training purposes only.
23+
#
24+
# Removing this header ends your licence.
25+
#
26+
27+
import time as tm
28+
29+
class Timer:
30+
def __init__ (self):
31+
self.time = tm.time ()
32+
33+
def tick (self):
34+
self._oldTime = self.time
35+
self.time = tm.time ()
36+
self.deltaTime = self.time - self._oldTime
37+

simpylc/simulations/car/world.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,12 @@
3333

3434
import simpylc as sp
3535

36-
import control as ct
37-
import keyboard_pilot as kp
38-
import lidar_pilot as lp
39-
import lidar_pilot_sp as ls
36+
import lidar_pilot_simulated_io as ls
4037
import physics as ps
4138
import visualisation as vs
42-
import timing as tm
4339

4440
sp.World (
45-
# ct.Control,
46-
# kp.KeyboardPilot,
47-
lp.LidarPilot,
48-
# ls.LidarPilotSp,
41+
ls.LidarPilotSimulatedIo,
4942
ps.Physics,
50-
vs.Visualisation,
51-
# tm.Timing
43+
vs.Visualisation
5244
)

0 commit comments

Comments
 (0)