Skip to content

Commit b994992

Browse files
committed
Halfway lidar, non-functional
1 parent 09a8282 commit b994992

12 files changed

+256
-77
lines changed

simpylc/base.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,31 @@ def evaluate (anObject):
4343
return anObject
4444

4545
def tEva (v):
46-
return (evaluate (v [0]), evaluate (v [1]), evaluate (v [2]))
46+
return tuple (evaluate (entry) for entry in v)
4747

4848
def tNeg (v):
49-
return (-v [0], -v [1], -v [2])
49+
return tuple (-entry for entry in v)
5050

5151
def tAdd (v0, v1):
52-
return (v0 [0] + v1 [0], v0 [1] + v1 [1], v0 [2] + v1 [2])
52+
return tuple (entry0 + entry1 for entry0, entry1 in zip (v0, v1))
5353

5454
def tSub (v0, v1):
55-
return (v0 [0] - v1 [0], v0 [1] - v1 [1], v0 [2] - v1 [2])
55+
return tuple (entry0 - entry1 for entry0, entry1 in zip (v0, v1))
5656

5757
def tMul (v0, v1):
58-
return (x [0] * v [0], x [1] * v [1], x [2] * v [2])
58+
return tuple (entry0 * entry1 for entry0, entry1 in zip (v0, v1))
5959

6060
def tsMul (v, x):
61-
return (v [0] * x, v [1] * x, v [2] * x)
61+
return tuple (entry * x for entry in v)
6262

6363
def tDiv (v, x):
64-
return (v [0] / x [0], v [1] / x [1], v [2] / x [2])
64+
return tuple (entry0 / entry1 for entry0, entry1 in zip (v0, v1))
6565

6666
def tsDiv (v, x):
67-
return (v [0] / x, v [1] / x, v [2] / x)
67+
return tuple (entry / x for entry in v)
6868

6969
def tNor (v):
70-
return sqrt (v [0] * v [0] + v [1] * v[1] + v [2] * v [2])
70+
return sqrt (sum (entry * entry for entry in v))
7171

7272
def tUni (v):
7373
return tsDiv (v, tNor (v))
@@ -156,4 +156,4 @@ def warnAsyncTrack (frame):
156156
print ()
157157
print ('WARNING', getFileLineClause (frame), 'Instance recycling in display function may cause \'jumpy\' camera tracking')
158158

159-
159+

simpylc/engine.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,15 @@ def __init__ (self, *parameters):
336336
for parameter in parameters:
337337
if issubclass (parameter, Module):
338338
World._modules.append (parameter ())
339-
elif issubclass (parameter, Scene):
339+
340+
for parameter in parameters:
341+
if issubclass (parameter, Scene):
340342
World._scenes.append (parameter ())
341-
elif issubclass (parameter, Chart):
343+
344+
for parameter in parameters:
345+
if issubclass (parameter, Chart):
342346
World._charts.append (parameter ())
343-
else:
344-
World._Agents.append (parameter)
345-
347+
346348
Module._current = None # Place further elements outside any module
347349

348350
if generateCode (self):
@@ -357,12 +359,18 @@ def __init__ (self, *parameters):
357359
module._setPublicElementNames ()
358360

359361
for scene in World._scenes:
362+
setattr (World, scene.name, scene)
360363
scene._registerWithCamera ()
361364
scene._registerWithThings ()
362365

363366
for chart in World._charts:
364367
chart.define ()
365368

369+
# Construct agents last, since they may depend on any other parameters because they have least restrictions
370+
for parameter in parameters:
371+
if not (issubclass (parameter, Module) or issubclass (parameter, Scene) or issubclass (parameter, Chart)):
372+
World._Agents.append (parameter)
373+
366374
World.first = Marker (True)
367375
World.sleep = Register (0.02)
368376
World.refresh = Register (0.013)
@@ -425,6 +433,8 @@ def main (self, window):
425433
self.Agent.getKey = window.getkey # No typo
426434
self.Agent ()
427435

436+
finity = 1e20
437+
428438
pi = math.pi
429439
radiansPerDegree = math.pi / 180
430440
degreesPerRadian = 180 / math.pi
@@ -486,9 +496,11 @@ def snap (anObject, target, margin):
486496
def digit (anObject, index):
487497
return int (('000000000000' + str (int (evaluate (anObject)))) [-evaluate (index + 1)])
488498

499+
'''
489500
_print = print
490501
491502
def cursesCompatiblePrint (*args, **kwargs):
492503
_print (*args, **kwargs, end = '\n\r')
493504
494505
builtins.print = cursesCompatiblePrint
506+
'''
170 Bytes
Binary file not shown.

simpylc/simulations/car/control.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ def __init__ (self):
3535
self.page ('motion control')
3636

3737
self.group ('driver input', True)
38-
self.velocityStepper = sp.Register (0)
39-
self.steeringStepper = sp.Register (2)
38+
self.targetVelocityStep = sp.Register (0)
39+
self.steeringAngleStep = sp.Register (2)
4040

4141
self.group ('control output')
42-
self.velocity = sp.Register ()
42+
self.targetVelocity = sp.Register ()
4343
self.steeringAngle = sp.Register ()
4444

4545
self.group ('sweep time measurement', True)
@@ -48,13 +48,14 @@ def __init__ (self):
4848
self.sweepWatch = sp.Timer ()
4949
self.run = sp.Runner ()
5050

51-
def input (self):
52-
pass
51+
def output (self):
52+
sp.world.physics.targetVelocity.set (self.targetVelocity)
53+
sp.world.physics.steeringAngle.set (self.steeringAngle)
5354

5455
def sweep (self):
5556
# Input to output
56-
self.velocity = 0.2 * self.velocityStepper
57-
self.steeringAngle = 10 * self.steeringStepper
57+
self.targetVelocity.set (0.2 * self.targetVelocityStep)
58+
self.steeringAngle.set (10 * self.steeringAngleStep)
5859

5960
# Sweep time measurement
6061
self.sweepMin.set (sp.world.period, sp.world.period < self.sweepMin)

simpylc/simulations/car/default.track

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2+
- - - - - - - * - - - * - - - - - - - - - - - - - - - - - - - -
3+
- - - - - - - - - - - - - - * - - - - - - - - - - - * - - - - -
4+
- - - * - - - * - - * - - - - - - - * - - - * - - - - - - - * -
5+
- - - - - * - - - - - - - * - - - - - - @ - - - - * - - - - - -
6+
- - - - - - - - - - - - - - - - - * - - - - * - - - - - * - - -
7+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8+
- * - * - - - - - - - - - - - - - - - - - - - - - - - - - - * -
9+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - -
10+
- - - - - - - - - * - - - * - - - - - - - - - - - - - - - - - -
11+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12+
- - * - * - - * - - - - * - - - - * - - - - - - - - - - * - * -
13+
- - - - - - - - - * - - - - - * - - - - - - - - - - - - - - - -
14+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15+
- * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - -
16+
- - - - - - - * - * - - - - - - - * - * - - - - - - - * - * - -
17+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
18+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19+
- * - * - - - - * - * - - - - - - - - - - - - - - - - - - - - -
20+
- - - - - - - - - - - - - - - - - * - * - - - - - - * - * - - -
21+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22+
- - - - - - - - - * - * - - - - - - - - - - - - - - - - - - - -
23+
* - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
24+
- - - - - - - - - - - - - - - - - * - * - - - - - - * - * - - -
25+
- - - - - - - - - * - * - - - - - - - - - - - - - - - - - - - -
26+
- - - * - - - - - - - - - - - - - - - - - - - - - - - - - - - -
27+
- * - - - - - - - - - - - - - - - - - - * - - - - - - - - - - -
28+
- - - - * - - - - * - - - - - - - - * - - - - - - - - * - * - -
29+
- - - - - - * - * - - * - - - - - - - - - * - - - - - - - - - -
30+
- - - * - - - - - - - - - - - - - - - - - - - * - - * - - - - -
31+
- - - - - - * - - * - - - - - - - - - - * - - - - - - - * - - -
32+
- - - - - - - - - - - - - - - - - - - - - - - - * - - - - - - -
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class KeyboardPilot:
2+
def __init__ (self):
3+
while True:
4+
self.readInputs ()
5+
self.sweep ()
6+
self.writeOutputs ()
7+
8+
def readInputs (self):
9+
key = self.getKey ()
10+
11+
self.upKey = key == 'KEY_UP'
12+
self.downKey = key == 'KEY_DOWN'
13+
self.leftKey = key == 'KEY_LEFT'
14+
self.rightKey = key == 'KEY_RIGHT'
15+
16+
self.targetVelocityStep = self.world.control.targetVelocityStep
17+
self.steeringAngleStep = self.world.control.steeringAngleStep
18+
19+
def sweep (self):
20+
if self.upKey:
21+
self.targetVelocityStep += 1
22+
print ('Target velocity step: ', self.targetVelocityStep)
23+
elif self.downKey:
24+
self.targetVelocityStep -= 1
25+
print ('Target velocity step: ', self.targetVelocityStep)
26+
elif self.leftKey:
27+
self.steeringAngleStep += 1
28+
print ('Steering angle step: ', self.steeringAngleStep)
29+
elif self.rightKey:
30+
self.steeringAngleStep -= 1
31+
print ('Steering angle step: ', self.steeringAngleStep)
32+
33+
def writeOutputs (self):
34+
self.world.control.targetVelocityStep.set (self.targetVelocityStep)
35+
self.world.control.steeringAngleStep.set (self.steeringAngleStep)
36+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#! /usr/bin/python
2+
3+
# ====== Legal notices
4+
#
5+
# Copyright (C) 2013 - 2018 GEATEC engineering
6+
#
7+
# This program is free software.
8+
# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY, without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13+
# See the QQuickLicence for details.
14+
#
15+
# The QQuickLicense can be accessed at: http://www.qquick.org/license.html
16+
#
17+
# __________________________________________________________________________
18+
#
19+
#
20+
# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !!
21+
#
22+
# __________________________________________________________________________
23+
#
24+
# It is meant for training purposes only.
25+
#
26+
# Removing this header ends your licence.
27+
#
28+
29+
import os
30+
import sys as ss
31+
32+
ss.path.append (os.path.abspath ('../../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable
33+
34+
import simpylc as sp
35+
import keyboard_pilot as lp
36+
import control as ct
37+
import physics as ps
38+
import visualisation as vs
39+
import timing as tm
40+
41+
sp.World (lp.KeyboardPilot, ct.Control, ps.Physics, vs.Visualisation) # , tm.Timing)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'''
2+
Inputs:
3+
4+
- A lidar distance array with a resolution of 1 degree
5+
- An x, y position and course angle of the car
6+
7+
Outpus:
8+
9+
- Acceleration stepper output
10+
11+
'''
12+
13+
import time as tm
14+
15+
import simpylc as sp
16+
17+
class LidarPilot:
18+
noObstacle = (sp.finity, 0)
19+
20+
def __init__ (self):
21+
self.lidar = self.world.visualisation.lidar
22+
23+
while True:
24+
self.readInputs ()
25+
self.sweep ()
26+
self.writeOutputs ()
27+
tm.sleep (0.02)
28+
29+
30+
def readInputs (self):
31+
self.nearestObstacles = [self.noObstacle, self.noObstacle]
32+
33+
for lidarAngle in range (-self.lidar.halfApertureAngle, self.lidar.halfApertureAngle):
34+
lidarDistance = self.lidar.distances [lidarAngle]
35+
if lidarDistance < self.nearestObstacles [0][0]:
36+
self.nearestObstacles [0] = (lidarDistance, lidarAngle)
37+
elif lidarDistance < self.nearestObstacles [1][0]:
38+
self.nearestObstacles [1] = (lidarDistance, lidarAngle)
39+
40+
self.targetObstacle = sp.tsDiv (sp.tAdd (*self.nearestObstacles), 2)
41+
42+
self.velocity = self.world.physics.velocity
43+
self.steeringAngle = self.world.physics.steeringAngle
44+
45+
def sweep (self):
46+
self.steeringAngle = self.targetObstacle [1]
47+
48+
def writeOutputs (self):
49+
self.world.physics.steeringAngle.set (self.steeringAngle)
50+

simpylc/simulations/car/world.py renamed to simpylc/simulations/car/lidar_world.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
ss.path.append (os.path.abspath ('../../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable
3333

3434
import simpylc as sp
35-
import pilot as pl
35+
import lidar_pilot as lp
3636
import control as ct
3737
import physics as ps
3838
import visualisation as vs
3939
import timing as tm
4040

41-
sp.World (pl.Pilot, ct.Control, ps.Physics, vs.Visualisation) # , tm.Timing)
41+
sp.World (lp.LidarPilot, ps.Physics, vs.Visualisation) # , tm.Timing)

simpylc/simulations/car/physics.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ def __init__ (self):
3636

3737
self.group ('wheels', True)
3838

39+
self.acceleration = sp.Register (2)
40+
self.targetVelocity= sp.Register ()
3941
self.velocity = sp.Register ()
4042
self.midWheelAngularVelocity = sp.Register ()
4143
self.midWheelAngle = sp.Register (30)
@@ -60,15 +62,12 @@ def __init__ (self):
6062
self.slipping = sp.Marker ()
6163
self.radialVelocity = sp.Register ()
6264

63-
def input (self):
64-
self.velocity = sp.world.control.velocity
65-
self.steeringAngle = sp.world.control.steeringAngle
66-
6765
def sweep (self):
6866
self.page ('traction')
6967
self.group ('wheels', True)
7068

71-
self.midWheelAngularVelocity = self.velocity / pm.displacementPerWheelAngle
69+
self.velocity.set (self.velocity + self.acceleration * sp.world.period, self.velocity < self.targetVelocity, self.velocity - self.acceleration * sp.world.period)
70+
self.midWheelAngularVelocity.set (self.velocity / pm.displacementPerWheelAngle)
7271
self.midWheelAngle.set (self.midWheelAngle + self.midWheelAngularVelocity * sp.world.period)
7372
self.tangentialVelocity.set (self.midWheelAngularVelocity * pm.displacementPerWheelAngle)
7473

simpylc/simulations/car/pilot.py

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)