diff --git a/README.rst b/README.rst index a1ed087..ebd019c 100644 --- a/README.rst +++ b/README.rst @@ -18,7 +18,7 @@ SimPyLC does not attempt to mimic any particular PLC instruction set or graphica What it is ---------- -SimPyLC functionally behaves like a PLC or a set of interconnected PLC's and controlled systems. It is a very powerful tool to gain insight in the behaviour of real time controls and controlled systems. It allows you to force values, to freeze time, to draw timing charts and to visualize your system. This is all done in a very simple and straightforward way. But make no mistake, simulating systems in this way has a track record of reducing months of commissioning time to mere days. SimPyLC is Form Follows Function at its best, it does what it has to do in a robust no-nonsense way. Its sourcecode is tiny and fully open to understanding. The accompanying document *simpylc_howto* condenses decenia of practical experience in control systems in a few clear design rules that can save you lots of trouble and prevent accidents. In addition to this SimPyLC can generate C code for the Arduino processor boards. +SimPyLC functionally behaves like a PLC or a set of interconnected PLC's and controlled systems. It is a very powerful tool to gain insight in the behaviour of real time controls and controlled systems. It allows you to force values, to freeze time, to draw timing charts and to visualize your system. This is all done in a very simple and straightforward way. But make no mistake, simulating systems in this way has a track record of reducing months of commissioning time to mere days. SimPyLC is Form Follows Function at its best, it does what it has to do in a robust no-nonsense way. Its sourcecode is tiny and fully open to understanding. The accompanying document `SimPyLCHowTo `_ condenses decenia of practical experience in control systems in a few clear design rules that can save you lots of trouble and prevent accidents. In addition to this SimPyLC can generate C code for the Arduino processor boards. .. figure:: http://www.qquick.org/simpylc/arduinodue.jpg :alt: Picture of Arduino Due @@ -58,7 +58,7 @@ Bugs fixed Installation ------------ -Installation for Windows, Linux and OSX is described in the *sympylc_howto* document. +Installation for Windows, Linux and OSX is described in `SimPyLCHowTo `_. Usage ----- @@ -83,7 +83,7 @@ For a test run of oneArmedRobot 1. Enter setpoints in degrees for the joint angles (e.g. torAngSet for the torso of the robot) on the movement control page. 2. After that set 'go' to 1 and watch what happens. -If you want to experiment yourself, read `SimPyLCHowTo `_ +If you want to experiment yourself, read `SimPyLCHowTo `_ .. figure:: http://www.qquick.org/simpylc/robotsimulationsource.jpg :alt: A sample SimPyLC program diff --git a/build/lib/simpylc/__init__.py b/build/lib/simpylc/__init__.py deleted file mode 100644 index 83ef84f..0000000 --- a/build/lib/simpylc/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -from .base import * -from .engine import * -from .graphics import * -from .quaternions import * - diff --git a/build/lib/simpylc/__main__.py b/build/lib/simpylc/__main__.py deleted file mode 100644 index 2ff49b3..0000000 --- a/build/lib/simpylc/__main__.py +++ /dev/null @@ -1,58 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -import argparse as ap -import distutils.dir_util as du -import os -import webbrowser as wb - -simulationsSubdirName = 'simulations' -accessoriesSubdirName = 'accessories' -howtoFileName = 'simpylc_howto.html' - -class CommandArgs : - def __init__ (self): - self.argParser = ap.ArgumentParser () - self.argParser.add_argument ('-a', '--acc', help = "Copy accessories to current directory", action = 'store_true') - self.argParser.add_argument ('-d', '--doc', help = "Show documentation in default browser", action = 'store_true') - self.argParser.add_argument ('-s', '--sim', help = "Copy example simulations to directory", action = 'store_true') - self.__dict__.update (self.argParser.parse_args () .__dict__) - - -commandArgs = CommandArgs () - -simulatorDir = os.path.dirname (os.path.realpath (__file__)) -currentDir = os.getcwd () - -if commandArgs.acc: - du.copy_tree (simulatorDir + '/' + accessoriesSubdirName, currentDir + '/' + accessoriesSubdirName) -elif commandArgs.sim: - du.copy_tree (simulatorDir + '/' + simulationsSubdirName, currentDir + '/' + simulationsSubdirName) -elif commandArgs.doc: - wb.open (simulatorDir + '/' + howtoFileName) -else: - commandArgs.argParser.print_help () - diff --git a/build/lib/simpylc/accessories/QuartzMS.TTF b/build/lib/simpylc/accessories/QuartzMS.TTF deleted file mode 100644 index 9f7d50e..0000000 Binary files a/build/lib/simpylc/accessories/QuartzMS.TTF and /dev/null differ diff --git a/build/lib/simpylc/accessories/freeglut.dll b/build/lib/simpylc/accessories/freeglut.dll deleted file mode 100644 index 1ad0f7a..0000000 Binary files a/build/lib/simpylc/accessories/freeglut.dll and /dev/null differ diff --git a/build/lib/simpylc/base.py b/build/lib/simpylc/base.py deleted file mode 100644 index 8790661..0000000 --- a/build/lib/simpylc/base.py +++ /dev/null @@ -1,159 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -import os -from math import * -from inspect import * - -programName = 'SimPyLC' -programVersion = '3.8.01' -programNameAndVersion = '{0} {1}'.format (programName, programVersion) -programDir = os.getcwd () .replace ('\\', '/') .rsplit ('/', 3) [-1] - -def getTitle (name): - return '{0} - {1} - {2}' .format (programDir, name, programNameAndVersion) - -def evaluate (anObject): - if hasattr (anObject, '__call__'): - return anObject () - else: - return anObject - -def tEva (v): - return tuple (evaluate (entry) for entry in v) - -def tNeg (v): - return tuple (-entry for entry in v) - -def tAdd (v0, v1): - return tuple (entry0 + entry1 for entry0, entry1 in zip (v0, v1)) - -def tSub (v0, v1): - return tuple (entry0 - entry1 for entry0, entry1 in zip (v0, v1)) - -def tMul (v0, v1): - return tuple (entry0 * entry1 for entry0, entry1 in zip (v0, v1)) - -def tsMul (v, x): - return tuple (entry * x for entry in v) - -def tDiv (v, x): - return tuple (entry0 / entry1 for entry0, entry1 in zip (v0, v1)) - -def tsDiv (v, x): - return tuple (entry / x for entry in v) - -def tNor (v): - return sqrt (sum (entry * entry for entry in v)) - -def tUni (v): - return tsDiv (v, tNor (v)) - -class ColorsHex: - def __init__ (self): - self.panelBackgroundColor = '#000000' - - self.pageCaptionForegroundColor = '#bbffbb' - self.pageCaptionBackgroundColor = self.panelBackgroundColor - - self.groupCaptionForegroundColor = '#bbffbb' - self.groupCaptionBackgroundColor = self.panelBackgroundColor - - self.labelForegroundColor = '#aaaaaa' - self.labelBackgroundColor = self.panelBackgroundColor - - self.entryReleasedForegroundColor = '#00ff00' - self.entryReleasedBackgroundColor = '#002200' - self.entryEditForegroundColor = '#bbbbff' - self.entryEditBackgroundColor = '#000022' - self.entryForcedForegroundColor = '#ffaa00' - self.entryForcedBackgroundColor = '#331100' - - self.white = '#ffffff' - self.silver = '#c0c0c0' - self.gray = '#808080' - self.black = '#000000' - self.red = '#ff0000' - self.maroon = '#800000' - self.yellow = '#ffff00' - self.olive = '#808000' - self.lime = '#00ff00' - self.green = '#008000' - self.aqua = '#00ffff' - self.teal = '#008080' - self.blue = '#0000ff' - self.navy = '#000080' - self.fuchsia = '#ff00ff' - self.purple = '#800080' - -colorsHex = ColorsHex () - -for varName in vars (colorsHex): - vars () [varName + 'Hex'] = getattr (colorsHex, varName) - -for varName in vars (colorsHex): - colorHex = getattr (colorsHex, varName) [1:] - vars () [varName] = (int (colorHex [0:2], 16) / 255., int (colorHex [2:4], 16) / 255., int (colorHex [4:6], 16) / 255.) - -def hexFromRgb (rgb): - rgb = (int (255 * rgb [0]), int (255 * rgb [1]), int (255 * rgb [2])) - return '#{:02x}{:02x}{:02x}'.format (*rgb) - -backgroundColorFactor = 0.25 - -def backgroundFromRgb (rgb): - return (backgroundColorFactor * rgb [0], backgroundColorFactor * rgb [1], backgroundColorFactor * rgb [2]) - -def decapitalize (aString): - return aString [0] .lower () + aString [1:] if aString else '' - -def getFileLineClause (frame): - frameInfo = getframeinfo (frame) - return f'in file {frameInfo.filename}, line {frameInfo.lineno}:' - -def abort (): - input () - exit () - -def abortUnderConstruction (frame): - print () - print ('ERROR', getFileLineClause (frame), 'This simulation is under construction') - print () - abort () - -def warnDeprecated (frame, featureOld, featureNew = None): - print () - print ('WARNING', getFileLineClause (frame), featureOld [0].upper () + featureOld [1:], 'will be removed in future versions of', programName, end = '') - if featureNew: - print (', please use', featureNew, 'instead') - else: - print () - -def warnAsyncTrack (frame): - print () - print ('WARNING', getFileLineClause (frame), 'Instance recycling in display function may cause \'jumpy\' camera tracking') - - diff --git a/build/lib/simpylc/chart.py b/build/lib/simpylc/chart.py deleted file mode 100644 index 7d95a81..0000000 --- a/build/lib/simpylc/chart.py +++ /dev/null @@ -1,176 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -from time import * -from collections import deque -from itertools import islice -from copy import copy -import builtins - -from OpenGL.GL import * -from OpenGL.GLUT import * -from OpenGL.GLU import * - -from .base import * - -class Entry: - def __init__ (self, chart, index, height): - self.chart = chart - self.index = index - self.height = height - self.top = self.chart.entries [-1] .bottom if self.chart.entries else 0 - self.bottom = self.top + self.height - - def adapt (self): - pass - - def _render (self): - pass - -class Group (Entry): - def __init__ (self, chart, index, text, height): - Entry.__init__ (self, chart, index, height) - self.text = text - -class Channel (Entry): - def __init__ (self, chart, index, circuit, min, max, height): - Entry.__init__ (self, chart, index, height) - self.circuit = circuit - - self.min = float (evaluate (min)) - self.max = float (evaluate (max)) - self.mean = (self.min + self.max) / 2 - - self.ceiling = self.top + 2 - self.floor = self.bottom - 2 - self.middle = (self.floor + self.ceiling) / 2 - - self.scale = (self.floor - self.ceiling) / (self.max - self.min) - self.values = deque () - - def adapt (self): - if self.values: - self.values.rotate (-1) - self.values [-1] = self.circuit () - - def _render (self): - values = copy (self.values) - - glColor (*backgroundFromRgb (self.circuit.color)) - glBegin (GL_QUADS) - glVertex (0, self.floor) - glVertex (self.chart.width, self.floor) - glVertex (self.chart.width, self.ceiling) - glVertex (0, self.ceiling) - glEnd () - - glColor (*self.circuit.color) - glBegin (GL_LINE_STRIP) - for iValue, value in enumerate (values): - if value != None: - value = max (min (value, self.max), self.min) - glVertex (1 * iValue, self.middle - self.scale * (value - self.mean)) - glEnd () - - glRasterPos (2, self.middle + 5) - glutBitmapString (GLUT_BITMAP_HELVETICA_12, self.circuit._name.encode ('ascii')) - -class Chart: - def __init__ (self, name = None, width = 600, height = 400): - self.name = name if name else self.__class__.__name__.lower () - self.width = width - self.height = height - self.entries = [] - - def _createWindow (self): - glutInitWindowSize (self.width, self.height) - self.window = glutCreateWindow (getTitle (self.name) .encode ('ascii')) - - glEnable (GL_LINE_SMOOTH) - glEnable(GL_BLEND); - glEnable (GL_MULTISAMPLE) - - glShadeModel (GL_SMOOTH) - glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glLineWidth (1.5) - - glDisable (GL_LIGHTING) - - glutDisplayFunc (self._display) - glutReshapeFunc (self._reshape) - - def update (self): - for entry in self.entries: - entry.adapt () - - def _render (self): - glColor (1, 1, 1) - - for entry in self.entries: - entry._render () - - def _display (self): - glMatrixMode (GL_MODELVIEW) - glLoadIdentity () - glClearColor (* (panelBackgroundColor + (0,))) - - glClear (GL_COLOR_BUFFER_BIT) - - glPushMatrix () - glLineWidth (1) - self._render () - glPopMatrix () - - glFlush () - - glutSwapBuffers () - - def _reshape (self, width, height): - self.width = width - self.height = height - - glViewport (0, 0, width, height) - glMatrixMode (GL_PROJECTION); - glLoadIdentity () - glOrtho (0, self.width, self.height, 0, 0, 1) - - for entry in self.entries: - if isinstance (entry, Channel): - if self.width > len (entry.values): - entry.values = deque ([None for i in range (self.width - len (entry.values))] + list (entry.values)) - else: - start = len (entry.values) - self.width - stop = None - entry.values = deque (islice (entry.values, start, stop)) - - def group (self, text = '', height = 10): - self.entries.append (Group (self, len (self.entries), text, height)) - - def channel (self, circuit, color = None, minimum = 0, maximum = 1, height = 15): - circuit.color = color - self.entries.append (Channel (self, len (self.entries), circuit, minimum, maximum, height)) - diff --git a/build/lib/simpylc/coder.py b/build/lib/simpylc/coder.py deleted file mode 100644 index 5041cb4..0000000 --- a/build/lib/simpylc/coder.py +++ /dev/null @@ -1,535 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -from sys import * -from ast import * -from _ast import * -from datetime import * -import os -from os.path import * -from re import * - -from .base import programDir, decapitalize, programNameAndVersion - -def generateCode (world): - return coder.code (world) - -class Coder: - def __init__ (self): - self.symbolTable = {} - - def code (self, world): - modules = world._modules - - try: - self.nativeCode = sub (r'/\*\*.*?\*\*/', '', open ('native.cpp') .read (), flags = DOTALL) - except: - print ("File 'native.cpp' missing") - return - - if len (argv) < 2: - return False - - print ('Code generation started') - tailArgs = argv [1:] - - self.moduleNames = ( - [module.__module__ for module in modules] - if ('*' in tailArgs or 'world.py' in tailArgs) else - [arg for arg in tailArgs if not '=' in arg] - ) - ''' - Linux will expand '*' to all file names in the current directory, this is called 'globbing'. - By checking on 'world.py' we know that globbing took place, and pretend we saw the '*' instead. - This may give problems if SimPyLC is not run from the source directory of the user code. - It's possible add a check for that if it proves to be a problem in practice. - ''' - - argDict = dict ([arg.split ('=') for arg in tailArgs if '=' in arg]) - self.plcPrefix = '{0}_'.format (argDict ['prefix']) if 'prefix' in argDict else '' - self.device = argDict ['device'] if 'device' in argDict else 'arduino' - self.addModulePrefix = len (self.moduleNames) > 1 - - self.cSymbols = { - UnaryOp: {Not: '!', UAdd: '+', USub: '-'}, - BinOp: {Add: '+', Sub: '-', Mult: '*', Div: '/', Mod: '%'}, - BoolOp: {And: '&&', Or: '||'}, - Compare: {Eq: '==', NotEq: '!=', Lt: '<', LtE: '<=', Gt: '>', GtE: '>='} - } - - self.parse () - # self.dump ('original') # Leave in for debugging purposes - self.transform () - # self.dump ('transformed') # Leave in for debugging purposes - self.generate () - - print ('Code generation ready') - return True - - def parse (self): - def getContent (fileName): - with open (fileName) as file: - return file.read () - - self.moduleFileNames = ['{0}.py'.format (moduleName) for moduleName in self.moduleNames] -# self.sourceCodes = [getContent (moduleFileName) .replace ('sp.', '') for moduleFileName in self.moduleFileNames] - self.sourceCodes = [getContent (moduleFileName) for moduleFileName in self.moduleFileNames] - self.parseTrees = [parse (sourceCode) for sourceCode in self.sourceCodes] - - def dump (self, fileNamePostfix): - def walk (name, value, tabLevel, fragments): - fragments .append ('\n{0}{1}: {2} '.format (tabLevel * '\t', name, type (value).__name__ )) - if isinstance (value, AST): - for field in iter_fields (value): - walk (field [0], field [1], tabLevel + 1, fragments) - elif isinstance (value, list): - for element in value: - walk ('element', element, tabLevel + 1, fragments) - else: - fragments.append ('= {0}'.format (value)) - - fragments = [] - for parseTree in self.parseTrees: - walk ('file', parseTree, 0, fragments) - - self.targetFile = open (f'{programDir}_{fileNamePostfix}.tree', 'w') - self.targetFile.write (''.join (fragments) [1:]) - self.targetFile.close () - - def transform (self): - [TransformingVisitor (parseTree) for parseTree in self.parseTrees] - - def generate (self): - initCode = '\n'.join ([GeneratingVisitor (parseTree, True) .code for parseTree in self.parseTrees]) - sweepCode = '\n'.join ([GeneratingVisitor (parseTree, False) .code for parseTree in self.parseTrees]) - - generatedCode = ( - self.getPrologue () + ( -''' - - -// ____________ PLC variables ____________ - -''' - ) + - initCode + ( -''' - - -// ____________ PLC cycle ____________ - -void {0}cycle () {{ - -''' - ).format (self.plcPrefix) + - sweepCode + - ( -''' - // ______ System ______ - - {0}update (); -}} -''' - ).format (self.plcPrefix) + - self.getEpilogue () - ) - - generationRoot = 'generated' - generationDir = '{0}/{1}'.format (generationRoot, programDir) - - if not exists (generationDir): - os.makedirs (generationDir) - - self.targetFile = open ('{0}/{1}.{2}'.format (generationDir, programDir, 'ino'), 'w') - self.targetFile.write (generatedCode + self.nativeCode) - self.targetFile.close () - - def getPrologue (self): - return ( -'''// ======================== BEGIN OF GENERATED CODE ======================== - - - -// ====== BEGIN OF License COMMENT BLOCK, INCLUDE IN ANY COPY OF THIS GENERATED CODE AND DO NOT REMOVE ====== -// -// I M P O R T A N T S A F E T Y N O T I C E -// -// THIS CODE IS INTENDED SOLELY FOR EDUCATIONAL PURPOSES AND IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS. -// IT IS STRICKTLY PROHIBITED TO USE THIS GENERATED CODE IN ANY SITUATION THAT ENTAILS RISK OF DAMAGE OR INJURIES. -// -// USE OF THIS CODE IS GOVERNED BY THE QQUICK LICENSE (WWW.QQUICK.ORG/LICENSE). -// YOUR LICENSE TO USE THIS GENERATED CODE AUTOMATICALLY ENDS IF YOU REMOVE OR LEAVE OUT THIS LICENSE COMMENT BLOCK OR THE CODE THAT GENERATED IT. -// -// ====== END OF License COMMENT BLOCK, INCLUDE IN COPY OF THIS GENERATED CODE AND DO NOT REMOVE ====== - - - -// Generator: {1} -// Generated: {2} -// Target platform: {3} - - - -// ____________ General includes ____________ - -#include - - - -// ____________ {3} macros ____________ -{4} - - -// ____________ General macros ____________ - -// Circuit operations - -#define {0}mark4(marker, trueValue, condition, falseValue) marker = (condition) ? (trueValue) : (falseValue) -#define {0}mark3(marker, trueValue, condition) if (condition) marker = (trueValue) -#define {0}mark2(marker, trueValue) marker = (trueValue) -#define {0}mark1(marker) marker = {0}True - -#define {0}trigger2(oneshot, condition) oneshot.value = oneshot.memo; oneshot.memo = (condition); oneshot.value = !oneshot.value and oneshot.memo -#define {0}trigger1(oneshot) oneshot.value = !oneshot.memo; oneshot.memo = {0}True -#define {0}spiked1(oneshot) (oneshot.value) - -#define {0}latch2(latch, condition) if (condition) latch = {0}True -#define {0}latch1 (latch) latch = {0}True - -#define {0}unlatch2(latch, condition) if (condition) latch = {0}False -#define {0}unlatch1 (latch) latch = {0}False - -#define {0}set4(register, trueValue, condition, falseValue) register = (condition) ? (trueValue) : (falseValue) -#define {0}set3(register, trueValue, condition) if (condition) register = (trueValue) -#define {0}set2(register, trueValue) register = (trueValue) -#define {0}set1(register) register = 1 - -#define {0}reset2(timer, condition) if (condition) {{timer.exact = {0}nowExact; timer.inexact = {0}nowInexact;}} -#define {0}reset1(timer) timer.exact = {0}nowExact; timer.inexact = {0}nowInexact -#define {0}elapsed1(timer) (({0}nowInexact - timer.inexact) < 3.6e6 ? 1e-6 * ({0}nowExact - timer.exact) : 1e-3 * ({0}nowInexact - timer.inexact)) - -// Support operations - -#define {0}update()\\ - {0}thenExact = {0}nowExact; {0}nowExact = {0}getNowExact(); {0}period = 1e-6 * ({0}nowExact - {0}thenExact);\\ - {0}nowInexact = {0}getNowInexact();\\ - {0}first = {0}False; - -// Types - -#define {0}False 0 -#define {0}True 1 -#define {0}Bool bool -#define {0}UInt unsigned long -#define {0}Int long -#define {0}Float double -#define {0}Marker int -#define {0}Oneshot struct {{int value; int memo;}} -#define {0}Latch int -#define {0}Register double -#define {0}Timer struct {{unsigned long exact; unsigned long inexact;}} - -// Math operations - -#define {0}abs1(value) fabs (value) -#define {0}max2(value0, value1) fmax (value0, value1) -#define {0}min2(value0, value1) fmin (value0, value1) -#define {0}limit3(value, aLimit0, aLimit1) min (max (value, aLimit0), aLimit1) -#define {0}limit2(value, aLimit) {0}limit3 (value, -aLimit, aLimit) -#define {0}digit2(value, index) getDigit (int (value), index) - -// ____________ General functions ____________ - -int {0}getDigit (int value, int index) {{ - return (index == 0) ? value % 10 : {0}getDigit (value / 10, --index); -}} - -// ____________ General variables ____________ - -{0}UInt {0}nowExact = 0; -{0}UInt {0}thenExact = 0; -{0}UInt {0}nowInexact = 0; -{0}Float {0}period = 1; -{0}Bool {0}first = {0}True; -''' - ).format (self.plcPrefix, programNameAndVersion, datetime.now (), self.device.capitalize (), self.getPlatformMacros ()) - - def getEpilogue (self): - return ( -''' - - -// ======================== END OF GENERATED CODE ======================== - -''' - ) - - def getPlatformMacros (self): - return ( -''' -#define {0}getNowExact() micros () -#define {0}getNowInexact() millis () -''' - ).format (self.plcPrefix) - - -coder = Coder () - -class TransformingVisitor (NodeTransformer): - def __init__ (self, tree): - self.visit (tree) - - def visit_Attribute (self, node): # Remove 'sp.' prefix - if type (node) == Attribute and type (node.value) == Name and node.value.id == 'sp': - return Name (id = node.attr, ctx = node.ctx) - else: - self.generic_visit (node) - return node - -class GeneratingVisitor (NodeVisitor): - def __init__ (self, tree, init): - self.fragments = [] - - self.indentLevel = 0 - self.init = init - self.visit (tree) - - def emit (self, fragment): - self.fragments.append (fragment) - - def indent (self): - self.indentLevel += 1 - - def unIndent (self): - self.indentLevel -= 1 - - def getIndent (self): - return self.indentLevel * '\t' - - def getModulePrefix (self, moduleName): - return ( - '' - if not coder.addModulePrefix or moduleName == 'world' else - '{0}_'.format (self.moduleName) - if moduleName == 'self' else - '{0}_'.format (moduleName) - ) - - def getError (self, node, text): - return 'Error in module \'{0}\', line {1}: {2}'.format (self.moduleName, node.lineno, text) - - def visit_ClassDef (self, node): - self.moduleName = decapitalize (node.name) - for statement in node.body: - self.visit (statement) - if self.init: - self.code = ''.join (['// ______ Module: {0} ______'.format (self.moduleName)] + self.fragments) - else: - self.code = ''.join (['\t// ______ Module: {0} ______\n'.format (self.moduleName)] + self.fragments) - - def visit_FunctionDef (self, node): - def visitBody (): - for element in node.body: - self.surpressSemicolon = False - self.surpressNewline = False - self.visit (element) - if not self.surpressSemicolon: - self.emit (';') - if not self.surpressNewline: - self.emit ('\n') - - if self.init: - if node.name == '__init__': - visitBody () - else: - if node.name != '__init__': - self.indent () - self.emit ('\n{0}// ___ {1} ___\n'.format (self.getIndent (), node.name.capitalize ())) - visitBody () - self.unIndent () - - def visit_Expr (self, node): - if self.init: - if len (node.value.args): - if node.value.func.attr == 'page': - self.emit ('\n{0}// Page: {1}'.format (self.getIndent (), node.value.args [0] .s)) - elif node.value.func.attr == 'group': - self.emit ('\n{0}// Group: {1}\n'.format (self.getIndent (), node.value.args [0] .s)) - self.surpressSemicolon = True - else: - self.generic_visit (node) - - def visit_Assign (self, node): - if self.init: - if type (node.value.func) == Attribute: - aType = node.value.func.attr - else: # Free function - aType = node.value.func.id - - if aType == 'Runner': - self.surpressSemicolon = True - self.surpressNewline = True - else: - coder.symbolTable ['{0}{1}{2}'.format (coder.plcPrefix, self.getModulePrefix (node.targets[0] .value.id), node.targets [0] .attr)] = aType - self.emit ('{0}{1}{2} {1}{3}{4}'.format ( - self.getIndent (), - coder.plcPrefix, - aType, - self.getModulePrefix (node.targets [0] .value.id), - node.targets [0] .attr - )) - self.emit (' = ') - - if aType in ('Marker', 'Latch'): - if node.value.args: - self.emit ('{0}{1}'.format (coder.plcPrefix, node.value.args [0] .value)) - else: - self.emit ('{0}False'.format (coder.plcPrefix)) - elif aType == 'Oneshot': - if node.value.args: - self.emit ('{{0}{1}, {0}{False}}'.format (coder.plcPrefix, node.value.args [0] .id)) - else: - self.emit ('{{{0}False, {0}False}}'.format (coder.plcPrefix)) - elif aType == 'Register': - if node.value.args: - self.emit ('{0}'.format (node.value.args [0] .n)) - else: - self.emit ('0') - elif aType == 'Timer': - self.emit ('{{{0}nowExact, {0}nowInexact}}'.format (coder.plcPrefix)) - else: - raise Exception (self.getError (node, 'Element {0} not allowed here'.format (aType))) - else: - raise Exception (self.getError (node, 'Operator = not allowed here')) - - def visit_Call (self, node): - if node.func.__class__ == Attribute: # Member function - if node.func.attr == 'part': - self.emit ('\n{0}// Part: {1}\n'.format (self.getIndent (), node.args [0] .s)) - self.surpressSemicolon = True - else: - if ( - type (node.func.value) == Attribute and node.func.value.value.id in coder.moduleNames + ['self'] - and ( - not node.args - or - type (node.args [0]) != Attribute - or - type (node.args [0].value) != Attribute - or - node.args [0].value.attr in coder.moduleNames + ['self'] - ) - ): - self.emit ('{0}'.format (self.getIndent ())) - self.emit ('{0}{1}{2} ('.format (coder.plcPrefix, node.func.attr, len (node.args) + 1)) - self.emit ('{0}{1}{2}'.format ( - coder.plcPrefix, - self.getModulePrefix (node.func.value.value.id), - node.func.value.attr - )) - for arg in node.args: - self.emit (', ') - self.visit (arg) - self.emit (')') - else: - self.surpressSemicolon = True - self.surpressNewline = True - - else: # Free function - self.emit ('{0}{1}{2} ('.format (coder.plcPrefix, node.func.id, len (node.args))) - for index, arg in enumerate (node.args): - if index: - self.emit (', ') - self.visit (arg) - self.emit (')') - - def visit_Attribute (self, node): - objectName = ( - node.value.attr - if type (node.value) == Attribute else - node.value.id - ) - - qualifiedName = '{0}{1}{2}'.format (coder.plcPrefix, self.getModulePrefix (objectName), node.attr) - - if qualifiedName == '{0}period'.format (coder.plcPrefix): - self.emit (qualifiedName) - elif coder.symbolTable [qualifiedName] == 'Timer': - self.emit ('{0}elapsed1 ({1})'.format (coder.plcPrefix, qualifiedName)) - elif coder.symbolTable [qualifiedName] == 'Oneshot': - self.emit ('{0}spiked1 ({1})'.format (coder.plcPrefix, qualifiedName)) - else: - self.emit (qualifiedName) - - def visit_Pass (self, node): - self.emit ('{0}'.format (self.getIndent ())) - - def visit_Num (self, node): - self.emit (repr (node.n)) - - def visit_Name (self, node): - self.emit (node.id if not node.id in (True, False) else '{0}{1}'.format (coder.plcPrefix, node.id)) - - def visit_NameConstant (self, node): - self.emit ('{0}'.format (node.value)) - - def visit_UnaryOp (self, node): - self.emit('(') - self.emit ('{0}'.format (coder.cSymbols [UnaryOp][type (node.op)])) - self.visit (node.operand) - self.emit (')') - - def visit_BinOp (self, node): - self.emit ('(') - if type (node.op) == Mod: - self.emit ('({0}Int) '.format (coder.plcPrefix)) - self.visit (node.left) - self.emit (' {0} '.format (coder.cSymbols [BinOp][type (node.op)])) - if type (node.op) == Mod: - self.emit ('({0}Int) '.format (coder.plcPrefix)) - self.visit (node.right) - self.emit (')') - - def visit_BoolOp (self, node): - self.emit ('(') - for index, value in enumerate (node.values): - if index: - self.emit (' {0} '.format (coder.cSymbols [BoolOp][type (node.op)])) - self.visit (value) - self.emit (')') - - def visit_Compare (self, node): - self.emit ('(') - left = node.left - for index, (operand, right) in enumerate (zip (node.ops, node.comparators)): - if index: - self.emit (' && ') - self.visit (left) - self.emit (' {0} '.format (coder.cSymbols [Compare][type (operand)])) - self.visit (right) - left = right - self.emit(')') - diff --git a/build/lib/simpylc/collisions.py b/build/lib/simpylc/collisions.py deleted file mode 100644 index 96cb540..0000000 --- a/build/lib/simpylc/collisions.py +++ /dev/null @@ -1,102 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -''' -A beam can have a collision id. -Beams with the same collision id are accumulated in a group. -Each group obtains a bounding sphere to avoid some needless work. - -As soon as the bounding spheres of two groups overlap, -the OBB SAT method is applied to all their beams. - -Separation axes are - 3 edges for A - 3 edges for B - 3 x 3 cross products between those edges -''' - -from .vectors import * - -class Box: - def __init__ (self): - # OpenGL uses row vectors - - self.startPositionVec = (0, 0, 0, 1) - - self.startBaseVecs = msMul (( - (0, 0, 1), - (0, 1, 0), - (1, 0, 0) - ), 0.5) [:3] - - - self.startEdgeVecs = msMul (( - ( 1, 1, 1), - ( 1, 1, -1), - ( 1, -1, 1), - (-1, 1, 1) - ), 0.5) - - def computeCollisionFields (self): - self.positionVec = mMul (self.startPositionVec, self.modelViewMatrix) - - rotationMatrix = self.modelViewMatrix [:3] # Leave out translation row (OpenGL uses row vectors - self.baseVecs = mMul (self.startBaseVecs, rotationMatrix) - self.edgeVecs = mMul (self.startEdgeVecs, rotationMatrix) - -def _separate (distanceVec, separAxisVec, boxPair): - projectedDistance = abs (vIpr (distanceVec, separAxisVec)) # Factor |separAxisVec| cancels out below - - for edgeVec0 in boxPair [0] .edgeVecs: - for edgeVec1 in boxPair [1] .edgeVecs: - - # Test for >= rather than >, since if baseVecs are parallel, separAxisVec will be 0 vec, so inner prods all 0 - - if abs (vIpr (edgeVec0, separAxisVec)) + abs (vIpr (edgeVec1, separAxisVec)) >= projectedDistance: - return False - else: - return True - -def collision (*boxPair): - distanceVec = vSub (boxPair [1] .positionVec, boxPair [0] .positionVec) - - # Try 2 x 3 base vectors as possible separation axes - - for box in boxPair: - for baseVec in box.baseVecs: - if _separate (distanceVec, baseVec, boxPair): - return False - - # Try 3 x 3 outer products of base vectors as possible separation axes - - for baseVec0 in boxPair [0] .baseVecs: - for baseVec1 in boxPair [1] .baseVecs: - if _separate (distanceVec, vOpr (baseVec0, baseVec1), boxPair): - return False - - # None of the possible separation axes held up, so it's a collision - return True - diff --git a/build/lib/simpylc/engine.py b/build/lib/simpylc/engine.py deleted file mode 100644 index 966bcab..0000000 --- a/build/lib/simpylc/engine.py +++ /dev/null @@ -1,509 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -from datetime import * -from time import * -from threading import * -from traceback import * -import math -import builtins -import curses as cs -import sys as ss - -from .base import * -from .gui import * -from .graphics import * -from .scene import * -from .chart import * -from .coder import * - -class _Functor: - def __init__ (self, state): - self._state = evaluate (state) - - def __call__ (self): - return self._state - - def __lt__ (self, other): - return self () < evaluate (other) - - def __le__ (self, other): - return self () <= evaluate (other) - - def __gt__ (self, other): - return self () > evaluate (other) - - def __ge__ (self, other): - return self () >= evaluate (other) - - def __eq__ (self, other): - return self () == evaluate (other) - - def __ne__ (self, other): - return self () != evaluate (other) - - def __neg__ (self): - return -self () - - def __add__ (self, other): - return self () + evaluate (other) - - def __radd__ (self, other): - return evaluate (other) + self () - - def __sub__ (self, other): - return self () - evaluate (other) - - def __rsub__ (self, other): - return evaluate (other) - self () - - def __mul__ (self, other): - return self () * evaluate (other) - - def __rmul__ (self, other): - return evaluate (other) * self () - - def __truediv__ (self, other): - return self () / evaluate (other) - - def __rtruediv__ (self, other): - return float (evaluate (other)) / self () - - def __mod__ (self, other): - return self () % evaluate (other) - - def __rmod__ (self, other): - return evaluate (other) % self () - - def __bool__ (self): - return not not self () - -class _Element: - def __init__ (self): - self.color = None - if not Module._current is None: - self._setPosition () - Module._current._pages [self._pageIndex] ._elements.append (self) - - def _setPosition (self): - self._pageIndex, self._rowIndex, self._columnIndex = Module._pageIndex, Module._rowIndex, Module._columnIndex - Module._current._maxNrOfRows = max (Module._current._maxNrOfRows, self._rowIndex + 2) # Leave room for page caption - Module._current._maxNrOfColumns = max (Module._current._maxNrOfColumns, self._columnIndex + 1) - - def _isA (self, *classNames): - for className in classNames: - if isinstance (self, eval (className)): - return True - return False - -class _Caption (_Element): - def __init__ (self, text): - self._text = text - _Element.__init__ (self) - -class _GroupCaption (_Caption): - def __init__ (self, text, top = False): - self._top = top - _Caption.__init__ (self, text) - - def _setPosition (self): - if self._top: - Module._columnIndex += 1 - Module._rowIndex = 0 - elif self._text: - Module._rowIndex += 1 - _Caption._setPosition (self) - - def __call__ (self): - return '{0}'.format (self._text) if self._text and self._text [0] != ' ' else '' - -class _PageCaption (_Caption): - def __init__ (self, text): - _Caption.__init__ (self, text) - - def _setPosition (self): - Module._pageIndex += 1 - Module._current._pages.append (_Page ()) - Module._columnIndex = -1 - Module._rowIndex = -1 - _Caption._setPosition (self) - - def __call__ (self): - return 'Page {0}: {1}'.format (self._pageIndex + 1, self._text) - -class _Circuit (_Element, _Functor): - def __init__ (self, state): - _Element.__init__ (self) - _Functor .__init__ (self, state) - self._forced = False - - def _write (self, value): - self._state = value - - def _force (self): - self._forced = True - - def _release (self): - self._forced = False - - def _setPosition (self): - if Module._pageIndex == -1: # No _Captions, so just one long list of _Circuits - Module._current._defaultFormat = True - Module._pageIndex = 0 - Module._current._pages.append (_Page ()) - Module._columnIndex = 0 - Module._rowIndex = -1 # Use position of missing _PageCaption for first _Circuit - - Module._rowIndex += 1 - _Element._setPosition (self) - -class _Follower (_Circuit): - def __init__ (self, value): - _Circuit.__init__ (self, value) - - def _follow (self, trueValue, condition = True, falseValue = None): - if self._forced: - return - if evaluate (condition): - self._state = evaluate (trueValue) - else: - if not falseValue is None: - self._state = evaluate (falseValue) - -class Marker (_Follower): - def __init__ (self, value = False): - _Follower.__init__ (self, value) - - def mark (self, trueValue = True, condition = True, falseValue = None): - _Follower._follow (self, trueValue, condition, falseValue) - -class Runner (Marker): - def __init__ (self, value = True): - Marker.__init__ (self, value) - World.runner = self - -class Oneshot (_Circuit): - def __init__ (self, value = False): - _Circuit.__init__ (self, value) - self._oldCondition = False - - def trigger (self, condition = True): - if self._forced: - return - - self._state = evaluate (condition) and not self._oldCondition - self._oldCondition = evaluate (condition) - -class Latch (_Circuit): - def __init__ (self, value = False): - _Circuit.__init__ (self, value) - - def latch (self, condition = True): - if self._forced: - return - if evaluate (condition): - self._state = True - - def unlatch (self, condition = True): - if self._forced: - return - if evaluate (condition): - self._state = False - -class Register (_Follower): - def __init__ (self, value = 0): - _Follower.__init__ (self, value) - - def set (self, trueValue = 1, condition = True, falseValue = None): - _Follower._follow (self, trueValue, condition, falseValue) - -class Timer (_Circuit): - def __init__ (self): - _Circuit.__init__ (self, self._stateFromValue (0.)) - self._value = 0. # Seconds as float - - def _stateFromValue (self, value): # State is time when timer semantic value was 0 - return World.time () - value - - def _valueFromState (self, state): # Value is timer semantic value for a certain state (stored time) - return World.time () - state - - def reset (self, condition = True): - if self._forced: - return - if evaluate (condition): - self._state = self._stateFromValue (0) - - def _force (self): - self._forced = True - self._value = self._valueFromState (self._state) - - def _release (self): - self._forced = False - self._state = self._stateFromValue (self._value) - - def __call__ (self): - return self._value if self._forced else self._valueFromState (self._state) - - def _write (self, value): - if self._forced: - self._value = value - else: - self._state = self._stateFromValue (value) - -class _Page: - def __init__ (self): - self._elements = [] - -class Module: - _current = None # Place elements outside any module - _id = -1 - - def _getId (self): - Module._id += 1 - return str (Module._id) - - def __init__ (self, name = None): - Module._current = self # Place elements in this module - self._name = name if name else decapitalize (self.__class__.__name__) - Module._pageIndex = -1 - self._pages = [] - self._maxNrOfRows = 0 - self._maxNrOfColumns = 0 - self._defaultFormat = False - - def input (self): - pass - - def sweep (self): - pass - - def output (self): - pass - - def group (self, text = '', top = False): - setattr (self, Module._getId (self), _GroupCaption (' ', top)) # Note the blank, so it won't be compressed - setattr (self, Module._getId (self), _GroupCaption (text)) - - def page (self, text = ''): - setattr (self, Module._getId (self), _PageCaption (text)) - - def part (self, text = ''): - pass - - def _setPublicElementNames (self): - for var in vars (self): - if not var.startswith ('_'): - getattr (self, var) ._name = var - -import inspect - -class World (Thread): - time = Register (0) # Early because needed in Timer constructors - startDateTime = datetime.now () - runner = True # May be replaced by a Runner - - def __init__ (self, *parameters): - Thread.__init__ (self) - - World._modules = [] - World._scenes = [] - World._charts = [] - World._Agents = [] - - for parameter in parameters: - if issubclass (parameter, Module): - World._modules.append (parameter ()) - - for parameter in parameters: - if issubclass (parameter, Scene): - World._scenes.append (parameter ()) - - for parameter in parameters: - if issubclass (parameter, Chart): - World._charts.append (parameter ()) - - Module._current = None # Place further elements outside any module - - if generateCode (self): - exit (0) - - World.period = Timer () - World.period._name = 'period' - World._instance = self - - for module in World._modules: - setattr (World, module._name, module) - module._setPublicElementNames () - - for scene in World._scenes: - setattr (World, scene.name, scene) - scene._registerWithCamera () - scene._registerWithThings () - - for chart in World._charts: - chart.define () - - # Construct agents last, since they may depend on any other parameters because they have least restrictions - for parameter in parameters: - if not (issubclass (parameter, Module) or issubclass (parameter, Scene) or issubclass (parameter, Chart)): - World._Agents.append (parameter) - - World.first = Marker (True) - World.sleep = Register (0.02) - World.refresh = Register (0.013) - World.period.reset (True) - - World.elapsed = Register (0) - World.offset = Register (0) - - self.daemon = True - self.start () - - Graphics (World) - - for Agent in self._Agents: - AgentThread (Agent) - - Gui (World) # Main thread, so this thread, so last - - def run (self): # Module constructors called here, placing elements inside modules - self._cycle () - - def _cycle (self): - while True: - World.elapsed.set ((datetime.now () - World.startDateTime) .total_seconds ()) - - if World.runner: - World.time.set (World.elapsed () - World.offset ()) - - for module in World._modules: - module.input () - module.sweep () - module.output () - - for scene in World._scenes: - scene.update () - - for chart in World._charts: - chart.update () - - World.first.mark (False) - else: - World.offset.set (World.elapsed () - World.time ()) - - World.period.reset (True) - sleep (World.sleep ()) - -world = World # Pretend this class is a singleton object - -class AgentThread (Thread): - def __init__ (self, Agent): - Thread.__init__ (self) - self.Agent = Agent - self.start () - - def run (self): - cs.wrapper (self.main) - - def main (self, window): - def print (*args): - window.addstr (' '.join (str (arg) for arg in args) + '\n') - - def getKey (): - try: - return window.getkey () - except: - return '' - - window.nodelay (True) - agentModule = ss.modules [self.Agent.__module__] - agentModule.print = print - agentModule.sp.getKey = getKey - self.Agent () - -finity = 1e20 - -pi = math.pi -radiansPerDegree = math.pi / 180 -degreesPerRadian = 180 / math.pi - -def abs (anObject): - return builtins.abs (evaluate (anObject)) - -def max (object0, object1): - return builtins.max (evaluate (object0), evaluate (object1)) - -def min (object0, object1): - return builtins.min (evaluate (object0), evaluate (object1)) - -def pow (object0, object1): - return math.pow (evaluate (object0), evaluate (object1)) - -def sqrt (anObject): - return math.sqrt (evaluate (anObject)) - -def exp (anObject): - return math.exp (evaluate (anObject)) - -def log (anObject): - return math.log (evaluate (anObject)) - -def log10 (anObject): - return math.log10 (evaluate (anObject)) - -def sin (anObject): - return math.sin (evaluate (anObject) * radiansPerDegree) - -def cos (anObject): - return math.cos (evaluate (anObject) * radiansPerDegree) - -def tan (anObject): - return math.tan (evaluate (anObject) * radiansPerDegree) - -def asin (anObject): - return math.asin (evaluate (anObject)) * degreesPerRadian - -def acos (anObject): - return math.acos (evaluate (anObject)) * degreesPerRadian - -def atan (anObject): - return math.atan (evaluate (anObject)) * degreesPerRadian - -def atan2 (object0, object1): - return math.atan2 (evaluate (object0), evaluate (object1)) * degreesPerRadian - -def limit (anObject, limit0, limit1 = None): - if limit1 is None: - limit1 = limit0 - limit0 = -limit0 - return min (max (anObject, limit0), limit1) - -def snap (anObject, target, margin): - return target if abs (anObject - target) < margin else anObject - -def digit (anObject, index): - return int (('000000000000' + str (int (evaluate (anObject)))) [-evaluate (index + 1)]) diff --git a/build/lib/simpylc/graphics.py b/build/lib/simpylc/graphics.py deleted file mode 100644 index aff9425..0000000 --- a/build/lib/simpylc/graphics.py +++ /dev/null @@ -1,70 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -from threading import Thread -from time import * -import builtins - -from OpenGL.GL import * -from OpenGL.GLUT import * -from OpenGL.GLU import * - -from .base import * - -class Graphics (Thread): - def __init__ (self, world): - if world._scenes or world._charts: - Thread.__init__ (self) - self.world = world - self.daemon = True - self.start () - - def idle (self): - for scene in self.world._scenes: - glutSetWindow (scene.window) - glutPostRedisplay () - - for chart in self.world._charts: - glutSetWindow (chart.window) - glutPostRedisplay () - - sleep (self.world.refresh ()) - - def run (self): - glutInit () - glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE) - - for scene in self.world._scenes: - scene._graphics= self - scene._createWindow () - - for chart in self.world._charts: - chart._graphics = self - chart._createWindow () - - glutIdleFunc (self.idle) - glutMainLoop () - diff --git a/build/lib/simpylc/gui.py b/build/lib/simpylc/gui.py deleted file mode 100644 index 4812ec1..0000000 --- a/build/lib/simpylc/gui.py +++ /dev/null @@ -1,216 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 -2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -import sys -import traceback - -from time import * -from tkinter import * - -from .base import * - -class Cell: - pageCaption, groupCaption, circuit, filler = range (4) - - def __init__ (self, moduleWindow, module, element): - self.moduleWindow = moduleWindow - self.module = module - self.element = element - - if self.element._isA ('_PageCaption'): - self.kind = Cell.pageCaption - self.label = Label (self.moduleWindow, text = self.element (), justify = CENTER, width = Gui.windowWidth) - self.label.grid (row = 0, column = 0, columnspan = 2 * self.module._maxNrOfColumns) - self.label.configure (foreground = pageCaptionForegroundColorHex, background = pageCaptionBackgroundColorHex) - self.label.bind ('', lambda event: self.moduleWindow.goPage (self.moduleWindows.pageIndex - 1)) - self.label.bind ('', lambda event: self.moduleWindow.goPage (self.moduleWindows.pageIndex + 1)) - - elif self.element._isA ('_GroupCaption'): - self.kind = Cell.groupCaption - self.label = Label (self.moduleWindow, text = self.element (), justify = CENTER, width = Gui.labelWidth + Gui.entryWidth) - self.label.grid (row = self.element._rowIndex + 1, column = 2 * self.element._columnIndex, columnspan = 2) - self.label.configure (foreground = groupCaptionForegroundColorHex, background = groupCaptionBackgroundColorHex) - - elif self.element._isA ('_Circuit'): - self.kind = Cell.circuit - self.label = Label (self.moduleWindow, text = self.element._name, anchor = 'e', justify = RIGHT, width = Gui.labelWidth) - - self.entry = Entry (self.moduleWindow, font = Gui.entryFont, width = Gui.entryWidth) - - self.entry.bind ('', self.force) - self.entry.bind ('', self.select) # Selecting (highlighting) text at ButtonPress-1 has no effect, since it's too early - self.entry.bind ('', self.forceAndSelect) # Select so it will be ready to be overwritten - - self.entry.bind ('', self.edit) - - self.entry.bind ('', self.release) - self.entry.bind ('', self.release) - - self.entry.bind ('', self.set1) - self.entry.bind ('', self.set0) - - if sys.platform in {'win32', 'darwin'}: - self.entry.bind ('', lambda event: self.adapt (1 if event.delta > 0 else -1)) # Windows, OsX - elif sys.platform in {'linux'}: - self.entry.bind ('', self.adapt (1)) # Linux - self.entry.bind( '', self.adapt (-1)) # Linux - else: - print ('Error: Unknown platform') - sys.exit (1) - - self.label.grid (row = self.element._rowIndex + 1, column = 2 * self.element._columnIndex, ipadx= 0.5, sticky = 'NEW') - self.entry.grid (row = self.element._rowIndex + 1, column = 2 * self.element._columnIndex + 1, sticky = 'NEW') - - self.entry.configure (foreground = entryReleasedForegroundColorHex, background = entryReleasedBackgroundColorHex) - self.label.configure (foreground = hexFromRgb (self.element.color) if self.element.color else labelForegroundColorHex, background = labelBackgroundColorHex) - - elif self.element._isA ('_Filler'): - self.kind = Cell.filler - self.label0 = Label (self.moduleWindow, text = '', width = Gui.labelWidth) - self.label1 = Label (self.moduleWindow, text = '', width = Gui.entryWidth) - self.label0.grid (row = self.element._rowIndex + 1, column = 2 * self.element._columnIndex, sticky = 'NEW') - self.label1.grid (row = self.element._rowIndex + 1, column = 2 * self.element._columnIndex + 1, sticky = 'NEW') - self.label0.configure (foreground = panelBackgroundColorHex, background = panelBackgroundColorHex) - self.label1.configure (foreground = panelBackgroundColorHex, background = panelBackgroundColorHex) - - def force (self, event): - self.entry.configure (foreground = entryForcedForegroundColorHex, background = entryForcedBackgroundColorHex) - if self.element._forced: - self.element._write (eval (self.entry.get ())) - else: - self.element._force () - - def select (self, event): - if self.element._forced: - self.entry.selection_range (0, END) - - def forceAndSelect (self, event): - self.force (event) - self.select (event) - - def edit (self, event): - if self.element._forced and event.char.isalnum (): - self.entry.configure (foreground = entryEditForegroundColorHex, background = entryEditBackgroundColorHex) - - def release (self, event): - self.element._write (eval (self.entry.get ())) - self.element._release () - self.entry.configure (foreground = entryReleasedForegroundColorHex, background = entryReleasedBackgroundColorHex) - - def set1 (self, event): - if self.element._isA ('Marker', 'Runner', 'Oneshot', 'Latch'): - self.element._write (1) - - def set0 (self, event): - if self.element._isA ('Marker', 'Runner', 'Oneshot', 'Latch'): - self.element._write (0) - - def adapt (self, delta): - if self.element._isA ('Register', 'Timer'): - try: - self.element._write (round (eval (self.entry.get ())) + delta) - except: # Why is this needed under Linux? - pass - # print (traceback.format_exc ()) - -class _Filler: - def __init__ (self, columnIndex): - self._columnIndex = columnIndex - self._rowIndex = 2 - - def _isA (self, *ClassNames): - return '_Filler' in ClassNames - -class ModuleWindow (Toplevel): - def __init__ (self, module): - Toplevel.__init__ (self) - self.module = module - self.title (getTitle (self.module._name)) - - self.pageIndex = 0 - self.bind ('', lambda event: self.goPage (self.pageIndex - 1)) - self.bind ('', lambda event: self.goPage (self.pageIndex + 1)) - - self.configure (background = panelBackgroundColorHex) - - for columnIndex in range (2 * self.module._maxNrOfColumns): - self.columnconfigure (columnIndex, weight = 1) - - if self.module._defaultFormat: - self.geometry("%dx%d%+d%+d" % (Gui.windowWidth / 4, 800, 0, 0)) - else: - self.geometry("%dx%d%+d%+d" % (Gui.windowWidth, self.module._maxNrOfRows * Gui.rowHeight, 0, 0)) - - self.pageIndex = None - self.goPage (0) - - def goPage (self, pageIndex): - for child in self.winfo_children (): - child.destroy () - - self.pageIndex = min (max (pageIndex, 0), len (self.module._pages) - 1) - - self.cells = [] - firstEmptyColumnIndex = 0 - for element in self.module._pages [self.pageIndex] ._elements: - self.cells.append (Cell (self, self.module, element)) - firstEmptyColumnIndex = 2 * element._columnIndex + 1 - - for fillerColumnIndex in range (firstEmptyColumnIndex, self.module._maxNrOfColumns): - self.cells.append (Cell (self, self.module, _Filler (fillerColumnIndex))) - - def readFromEngine (self): - for cell in self.cells: - if cell.kind == Cell.circuit and not cell.element._forced and cell.entry.get () != cell.element (): - cell.entry.delete (0, END) - cell.entry.insert (0, cell.element ()) - -class Gui: - entryFont = ('Quartz MS', 10) - - windowWidth = 800 - labelWidth = 20 - entryWidth = 10 - - rowHeight = 23 - - def __init__ (self, world): - self.world = world - self.root = Tk () - self.root.withdraw () - self.moduleWindows = [ModuleWindow (module) for module in self.world._modules] - - while True: - for moduleWindow in self.moduleWindows: - moduleWindow.readFromEngine () - - self.root.update () - - for moduleWindow in self.moduleWindows: - moduleWindow.update () - - sleep (0.1) - diff --git a/build/lib/simpylc/quaternions.py b/build/lib/simpylc/quaternions.py deleted file mode 100644 index d0c291b..0000000 --- a/build/lib/simpylc/quaternions.py +++ /dev/null @@ -1,78 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -import numpy - -from math import sqrt - -from .engine import * - -# All angles are in degrees -# All non-scalar variables are numpy arrays - -def normized (anArray): - return anArray / numpy.linalg.norm (anArray) - -def quatFromAxAng (axis, angle): - imag = axis * sin (angle / 2) - return numpy.array ((cos (angle / 2), imag [0], imag [1], imag [2])) - -def axAngFromQuat (q): - angle = 2 * acos (q [0]) - denom = math.sqrt (1 - q [0] * q [0]) - axis = (q [1:] / denom) if denom else numpy.array ((1, 0, 0)) - return axis, angle - -def quatMul (q0, q1): - return numpy.array (( - q0 [0] * q1 [0] - q0 [1] * q1 [1] - q0 [2] * q1 [2] - q0 [3] * q1 [3], - q0 [0] * q1 [1] + q0 [1] * q1 [0] + q0 [2] * q1 [3] - q0 [3] * q1 [2], - q0 [0] * q1 [2] - q0 [1] * q1 [3] + q0 [2] * q1 [0] + q0 [3] * q1 [1], - q0 [0] * q1 [3] + q0 [1] * q1 [2] - q0 [2] * q1 [1] + q0 [3] * q1 [0] - )) - -def quatInv (q): - return numpy.array ((q [0], -q [1], -q [2], -q [3])) - -def quatFromVec (v): - return numpy.array ((0, v [0], v [1], v [2])) - -def quatVecRot (q, v): - return (quatMul ( - quatMul ( - q, - quatFromVec (v) - ), - quatInv (q) - )) [1:] - -def rotMatFromQuat (q): - return numpy.array (( - (1 - 2 * q [2] * q [2] - 2 * q [3] * q [3], 2 * q [1] * q [2] - 2 * q [3] * q [0], 2 * q [1] * q [3] + 2 * q [2] * q [0]), - (2 * q [1] * q [2] + 2 * q [3] * q [0], 1 - 2 * q [1] * q [1] - 2 * q [3] * q [3], 2 * q [2] * q [3] - 2 * q [1] * q [0]), - (2 * q [1] * q [3] - 2 * q [2] * q [0], 2 * q [2] * q [3] + 2 * q [1] * q [0], 1 - 2 * q [1] * q [1] - 2 * q [2] * q [2]) - )) - diff --git a/build/lib/simpylc/scene.py b/build/lib/simpylc/scene.py deleted file mode 100644 index f61b9ee..0000000 --- a/build/lib/simpylc/scene.py +++ /dev/null @@ -1,358 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -from time import * -from inspect import * -from sys import * -import builtins - -from OpenGL.GL import * -from OpenGL.GLUT import * -from OpenGL.GLU import * - -# from numpy import * -from .base import * -from .collisions import * - -useTexture = False -if useTexture: - from PIL import Image - - -class Camera: - def __init__ (self, - position = (5, 0, 0), # Camera position - focus = (0, 0, 0.7), # Point looked at - up = (0, 0, 1), # Up in the image - tracking = True - ): - self.position = position - self.focus = focus - self.up = up - self.tracking = tracking - - def __call__ (self, position = None, focus = None, up = None): - - if position: - self.position = position - if focus: - self.focus = focus - if up: - self.up = up - - def _transform (self, forced): - if self.tracking or forced: - glMatrixMode (GL_PROJECTION) - glLoadIdentity() - gluPerspective (45, self.scene.width / float (self.scene.height), 1, 100) - gluLookAt (*self.position, *self.focus, *self.up) - glMatrixMode (GL_MODELVIEW) - -class Scene: - _dmCheck, _dmUpdate, _dmRender, _dmAsync = range (4) - - def __init__ (self, name = None, width = 600, height = 400): - self.name = name if name else self.__class__.__name__.lower () - self.width = width - self.height = height - self.camera = Camera (tracking = False) - self._displayMode = Scene._dmCheck - self._async = False - self.collided = False - - def _registerWithCamera (self): - self.camera.scene = self - - def _registerWithThings (self): - for thing in Thing.instances: - thing.scene = self - - if self._displayMode == Scene._dmCheck: - self.display () - if self._async: - self._displayMode = Scene._dmAsync - else: - self._displayMode = Scene._dmUpdate - else: - abortInvalidDisplayMode (currentframe ()) - - def _createWindow (self): - glutInitWindowSize (self.width, self.height) - self.window = glutCreateWindow (getTitle (self.name) .encode ('ascii')) - - glClearColor (0, 0, 0, 0) - - glEnable (GL_LINE_SMOOTH) - glEnable(GL_BLEND); - glEnable (GL_MULTISAMPLE) - glEnable (GL_DEPTH_TEST) - - glShadeModel (GL_SMOOTH) - glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glLineWidth (1.5) - - glEnable (GL_LIGHTING) - glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE) - glEnable (GL_COLOR_MATERIAL) - - glLight (GL_LIGHT0, GL_POSITION, (5, 5, 0, 0)) - glLight (GL_LIGHT0, GL_DIFFUSE, (0.2, 0.2, 0.2)) - glEnable (GL_LIGHT0) - - glLight (GL_LIGHT1, GL_POSITION, (5, -5, 0, 0)) - glLight (GL_LIGHT1, GL_DIFFUSE, (0, 0, 0.6)) - glEnable (GL_LIGHT1) - - glLight (GL_LIGHT3, GL_POSITION, (0, 0, 5, 0)) - glLight (GL_LIGHT3, GL_DIFFUSE, (0.1, 0.1, 0.5)) - glEnable (GL_LIGHT3) - - glLight (GL_LIGHT4, GL_POSITION, (0, 0, -1, 0)) - glLight (GL_LIGHT4, GL_DIFFUSE, (0.05, 0, 0)) - glEnable (GL_LIGHT4) - - glutDisplayFunc (self._display) - glutReshapeFunc (self._reshape) - - def _display (self): - # [object coords] -> (model view matrix) -> [eye coords] (projection matrix) -> [clip coords] - - # Operations related to projection matrix: gluPerspective, gluLookat - # They will work on the camera - - # Operations related to model view matrix: glTranslate, glRotate, glScale. - # They will work on the objects - - if self._displayMode in {Scene._dmRender, Scene._dmAsync}: - self.camera._transform (False) # Expensive so only if tracking, not forced - - glLoadIdentity () - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - glPushMatrix () - self.display () # Since we'll render in GL_MODELVIEW mode, operations in self.display () will move the objects - self._collide () - glPopMatrix () - - glFlush () - glutSwapBuffers () - - if self._displayMode == Scene._dmRender: - self._displayMode = Scene._dmUpdate - - def _reshape (self, width, height): - self.width = width - self.height = height - glViewport (0, 0, self.width, self.height) - self.camera () - self.camera._transform (True) - - def update (self): - if self._displayMode == Scene._dmUpdate: - self.display () - self._displayMode = Scene._dmRender - - def _collide (self): - self.collided = False - for colliderGroup in Thing.groups.values (): - for thing in colliderGroup: - thing.computeCollisionFields () - for collideeGroup in Thing.groups.values (): - if colliderGroup == collideeGroup: - break - for collider in colliderGroup: - for collidee in collideeGroup: - if collision (collider, collidee): - self.collided = True - return - -class Thing (Box): - instances = [] - groups = {} - - def __init__ ( - self, - size = (0, 0, 0), # Initial size of the initial bounding box - - center = (0, 0, 0), # Initial position of the center with respect to (0, 0, 0) or to the center of the containing element - axis = (0, 0, 1), # Initial attitude of the axis of inital rotation around the center - angle = 0, # Initial rotation angle - - joint = (0, 0, 0), # Initial position of the axis of dynamical rotation with respect to the center - pivot = (0, 0, 1), # Initial attitude of the axis of dynamical rotation around the joint - - rest = (0, 0, 0), # Inital position of the point that stays at rest when scaling dynamically - - color = (1, 1, 1), # Initial color - - group = None # Assigned to no collision group - ): - self.center = center - self.size = size - self.axis = axis - self.angle = angle - self.joint = joint - self.pivot = pivot - self.color = color - self.group = group - - super () .__init__ () - - Thing.instances.append (self) - - if self.group != None: - if self.group in Thing.groups: - Thing.groups [self.group] .append (self) - else: - Thing.groups [self.group] = [self] - - self.checked = False - - def _draw (self): - pass - - def __call__ ( - self, - pivot = None, - color = None, - position = (0, 0, 0), # Dynamic displacement of the center - shift = (0, 0, 0), # Dynamic shift of the joint in natural position, so before dynamic rotation - scale = (1, 1, 1), # Dynamic multiplication in natural position, so before dynamic rotation, with respect to the joint, done before the shift - rotation = 0, # Dynamic rotation angle around pivot through joint - attitude = None, # Dynamic 3 x 3 rotation matrix, may be used instead of pivot and rotation - angle = None, # Deprecated in favor of 'rotation' - - parts = lambda: None - ): - if self.scene._displayMode == Scene._dmCheck: - if self.checked: # If an instance Thing occurs twice in the display function - self.scene._async = True # then it has no identity and must be stateless, hence async rather than cached - - if self.scene.camera.tracking: - warnAsyncTrack (currentframe () .f_back) - else: - self.checked = True - - if angle != None: - warnDeprecated (currentframe () .f_back, "parameter 'angle' of 'Thing.__call__'", "parameter 'rotation'") - - parts () - - else: - if self.scene._displayMode in {Scene._dmUpdate, Scene._dmAsync}: - if pivot != None: # If there's a dynamical center - self.pivot = pivot # replace the original static center by it - - if color != None: # If there's a dynamical color - self.color = color # replace the original static color by it - - self.position = position - self.shift = shift - self.scale = scale - - if angle == None: - self.rotation = rotation - else: - self.rotation = angle - - self.attitude = attitude - - if self.scene._displayMode == Scene._dmUpdate: - parts () - - if self.scene._displayMode in {Scene._dmRender, Scene._dmAsync}: - # We are in GL_MODELVIEW mode, so the transformations conceptually are performed upon the objects - # - # If you think in the global coordinate system then: - # - Transformations appear in the code in opposite order, so the first transformation that affects the object is the nearest to drawing the object in the code - # - Transformations move the object in the normal direction - # - # If you think in the local coordinate system then: - # - Transformations appear in the code in normal order, so the last transformation that affecs the object is the nearest to drawing the object in the code - # - Transformations move the coordinate frame in the opposite direction - - glPushMatrix () # Remember transformation state before drawing this _thing - glTranslate (*tAdd (tAdd (self.center, self.position), self.joint)) # 8. First translate object to get shifted joint into right place - # (See scene_transformations.jpg) - if self.attitude is None: # Use 'is' to be NumPy compatible - glRotate (evaluate (self.rotation), *self.pivot) # 7b. Rotate object object over dynamic angle around the shifted joint vector - else: - glMultMatrixd (( # 7a. Rotate object according to dynamic attitude around shifted joint point - self.attitude [0][0], self.attitude [1][0], self.attitude [2][0], 0, - self.attitude [0][1], self.attitude [1][1], self.attitude [2][1], 0, - self.attitude [0][2], self.attitude [1][2], self.attitude [2][2], 0, - 0, 0, 0, 1 - )) - # (If arm shifts out, joint shifts in) - glTranslate (*tEva (self.shift)) # 6. Translate object to put shifted joint in the origin - glScale (*tEva (self.scale)) # 5. Scale with respect to joint that's in the origin - glTranslate (*tNeg (self.joint)) # 4. Translate object to put joint in the origin - - glPushMatrix () - glRotate (self.angle, *self.axis) # 3. Rotate object over initial angle to put it in natural position - glScale (*self.size) # 2. Scale to natural size - - self.modelViewMatrix = [[c for c in r] for r in glGetDouble (GL_MODELVIEW_MATRIX) ] # Save model view matrix for collision testing - - glColor (*self.color) - self._draw () # 1. Place object with center in origin - glPopMatrix () - - parts () # Draw parts in local coord frame - glPopMatrix () # Restore transformation state from before drawing this - - return 0 # Make concatenable, e.g. by the + operator - -class Beam (Thing): - def __init__ (self, **arguments): - Thing.__init__ (self, **arguments) - - def _draw (self): - glutSolidCube (1) - -class Cylinder (Thing): - def __init__ (self, **arguments): - Thing.__init__ (self, **arguments) - - def _draw (self): - glTranslate (0, 0, -0.5) - glutSolidCylinder (0.5, 1, 100, 1) - -class Ellipsoid (Thing): - def __init__ (self, **arguments): - Thing.__init__ (self, **arguments) - - def _draw (self): - glutSolidSphere (0.5, 100, 100) - -class Cone (Thing): - def __init__ (self, **arguments): - Thing.__init__ (self, **arguments) - - def _draw (self): - glTranslate (0, 0, -0.5) - glutSolidCone (0.5, 1, 100, 100) diff --git a/build/lib/simpylc/scene_transformations.jpg b/build/lib/simpylc/scene_transformations.jpg deleted file mode 100644 index f550933..0000000 Binary files a/build/lib/simpylc/scene_transformations.jpg and /dev/null differ diff --git a/build/lib/simpylc/simpylcprog.jpg b/build/lib/simpylc/simpylcprog.jpg deleted file mode 100644 index 4d0f621..0000000 Binary files a/build/lib/simpylc/simpylcprog.jpg and /dev/null differ diff --git a/build/lib/simpylc/simulations/arduino_led_timer/led_timer.py b/build/lib/simpylc/simulations/arduino_led_timer/led_timer.py deleted file mode 100644 index 5ad850d..0000000 --- a/build/lib/simpylc/simulations/arduino_led_timer/led_timer.py +++ /dev/null @@ -1,47 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class LedTimer (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.rampTimer = sp.Timer () - self.oneshot = sp.Oneshot () - self.direction = sp.Marker () - self.blinkTime = sp.Register () - self.blinkTimer = sp.Timer () - self.led = sp.Marker () - self.runner = sp.Runner () - - def sweep (self): - self.rampTimer.reset (self.rampTimer > 9) - self.oneshot.trigger (self.rampTimer < 0.1) - self.direction.mark (not self.direction, self.oneshot) - self.blinkTime.set (3 - self.rampTimer / 3, self.direction, self.rampTimer / 3) - self.blinkTimer.reset (self.blinkTimer > self.blinkTime) - self.led.mark (self.blinkTimer < 0.2) diff --git a/build/lib/simpylc/simulations/arduino_led_timer/native.cpp b/build/lib/simpylc/simulations/arduino_led_timer/native.cpp deleted file mode 100644 index 2627a32..0000000 --- a/build/lib/simpylc/simulations/arduino_led_timer/native.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (C) 2013 - 2020 GEATEC engineering - -This program is free software. -You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY, without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -See the QQuickLicence for details. - -The QQuickLicense can be accessed at: http://www.qquick.org/license.html - -__________________________________________________________________________ - - - THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! - -__________________________________________________________________________ - -It is meant for training purposes only. - -Removing this header ends your licence. -*/ - -void setup () { - pinMode (13, OUTPUT); -} - -void loop () { - cycle (); - digitalWrite (13, led); -} - diff --git a/build/lib/simpylc/simulations/arduino_led_timer/timing.py b/build/lib/simpylc/simulations/arduino_led_timer/timing.py deleted file mode 100644 index e67b78f..0000000 --- a/build/lib/simpylc/simulations/arduino_led_timer/timing.py +++ /dev/null @@ -1,40 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - self.channel (sp.world.ledTimer.rampTimer, sp.red, 0, 9, 180) - self.channel (sp.world.ledTimer.direction, sp.white, 0, 1, 20) - self.channel (sp.world.ledTimer.oneshot, sp.aqua, 0, 1, 20) - self.channel (sp.world.ledTimer.blinkTime, sp.blue, 0, 3, 60) - self.channel (sp.world.ledTimer.blinkTimer, sp.yellow, 0, 3, 60) - self.channel (sp.world.ledTimer.led, sp.green, 0, 1, 20) - diff --git a/build/lib/simpylc/simulations/arduino_led_timer/world.py b/build/lib/simpylc/simulations/arduino_led_timer/world.py deleted file mode 100644 index e47f10c..0000000 --- a/build/lib/simpylc/simulations/arduino_led_timer/world.py +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp -import led_timer as lt -import timing as tm - -sp.World (lt.LedTimer, tm.Timing) diff --git a/build/lib/simpylc/simulations/arduino_stove/control.py b/build/lib/simpylc/simulations/arduino_stove/control.py deleted file mode 100644 index 930fae6..0000000 --- a/build/lib/simpylc/simulations/arduino_stove/control.py +++ /dev/null @@ -1,203 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Control (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('Four plate stove control with cooking alarm') - - self.group ('General buttons', True) - self.powerButton = sp.Marker () - self.powerEdge = sp.Oneshot () - self.power = sp.Marker () - - self.group () - self.childLockButton = sp.Marker () - self.childLockChangeTimer = sp.Timer () - self.childLockEdge = sp.Oneshot () - self.childLock = sp.Marker () - self.unlocked = sp.Marker () - - self.group ('Plate selection') - self.plateSelectButton = sp.Marker () - self.plateSelectEdge = sp.Oneshot () - self.plateSelectDelta = sp.Register () - self.plateSelectNr = sp.Register () - self.tempDelta = sp.Register () - self.tempChange = sp.Marker () - - self.group ('Up/down buttons') - self.upButton = sp.Marker () - self.upEdge = sp.Oneshot () - self.group () - self.downButton = sp.Marker () - self.downEdge = sp.Oneshot () - - self.group ('Cooking plates', True) - self.plate0Temp = sp.Register () - self.plate0Selected = sp.Marker () - - self.group () - self.plate1Temp = sp.Register () - self.plate1Selected = sp.Marker () - - self.group () - self.plate2Temp = sp.Register () - self.plate2Selected = sp.Marker () - - self.group () - self.plate3Temp = sp.Register () - self.plate3Selected = sp.Marker () - - self.group ('Alarm selection button') - self.alarmSelectButton = sp.Marker () - self.alarmSelectEdge = sp.Oneshot () - self.alarmSelected = sp.Marker () - self.alarmTime = sp.Register () - self.alarmTimer = sp.Timer () - self.alarmOn = sp.Latch () - self.alarmEdge = sp.Oneshot () - self.alarmTimeLeft = sp.Register () - self.alarmChangeTimer = sp.Timer () - self.alarmChangeStep = sp.Register () - self.alarmDelta = sp.Register () - - self.group ('Numerical displays', True) - self.digitIndex = sp.Register () - self.plateDigitValue = sp.Register () - self.alarmDigitValue = sp.Register () - self.digitValue = sp.Register () - self.digitDot = sp.Marker () - - self.group ('Buzzer') - self.buzzerOnTime = sp.Register (6) - self.buzzerOnTimer = sp.Timer () - self.buzzerOn = sp.Latch () - self.buzzerBaseFreq = sp.Register (300.) - self.buzzerPitchTimer = sp.Timer () - self.buzzerFreq = sp.Register () - self.buzzerWaveTimer = sp.Timer () - self.buzzerEdge = sp.Oneshot () - self.buzzer = sp.Marker () - - self.group ('System') - self.sweepMin = sp.Register (1000) - self.sweepMax = sp.Register () - self.sweepWatch = sp.Timer () - self.run = sp.Runner () - - def sweep (self): - self.part ('Edge triggering of buttons') - self.powerEdge.trigger (self.powerButton) - self.power.mark (not self.power, not self.childLock and self.powerEdge) - - self.childLockChangeTimer.reset (not (self.power and self.childLockButton)) - self.childLockEdge.trigger (self.childLockChangeTimer > 5) - self.childLock.mark (not self.childLock, self.childLockEdge) - self.unlocked.mark (self.power and not self.childLock) - - self.plateSelectEdge.trigger (self.plateSelectButton) - self.plateSelectDelta.set (1, self.unlocked and self.plateSelectEdge, 0) - self.plateSelectNr.set ((self.plateSelectNr + self.plateSelectDelta) % 4, self.power, 0) - - self.upEdge.trigger (self.upButton) - self.downEdge.trigger (self.downButton) - - self.part ('Cooking alarm') - self.alarmSelectEdge.trigger (self.power and self.alarmSelectButton) - self.alarmSelected.mark (not self.alarmSelected, self.unlocked and self.alarmSelectEdge) - - self.alarmChangeTimer.reset (not (self.alarmSelected and (self.upButton or self.downButton))) - self.alarmChangeStep.set (1, self.alarmChangeTimer > 0, 0) - self.alarmChangeStep.set (10, self.alarmChangeTimer > 10) - self.alarmChangeStep.set (100, self.alarmChangeTimer > 20) - - self.alarmDelta.set (-self.alarmChangeStep, self.downButton, self.alarmChangeStep) - self.alarmTime.set (0, self.power and self.upButton and self.downButton, sp.limit (self.alarmTime + self.alarmDelta * sp.world.period, 0, 9999)) - - self.alarmOn.latch (self.alarmChangeTimer > 0) - self.alarmTimer.reset (not self.alarmOn or self.alarmChangeTimer > 0) - self.alarmEdge.trigger ( - self.alarmTimer > self.alarmTime - or - (self.childLock and (self.powerButton or self.plateSelectButton or self.alarmSelectButton or self.plateSelectButton or self.upButton or self.downButton)) - ) - self.alarmOn.unlatch (self.alarmEdge or self.alarmTime == 0) - - self.alarmTimeLeft.set (max ((self.alarmTime - self.alarmTimer), 0)) - - self.part ('Cooking plates') - self.plate0Selected.mark (self.plateSelectNr == 0) - self.plate1Selected.mark (self.plateSelectNr == 1) - self.plate2Selected.mark (self.plateSelectNr == 2) - self.plate3Selected.mark (self.plateSelectNr == 3) - - self.tempChange.mark (self.unlocked and not self.alarmSelected and (self.upEdge or self.downEdge)) - self.tempDelta.set (-1, not self.alarmSelected and self.downButton, 1) - - self.plate0Temp.set (sp.limit (self.plate0Temp + self.tempDelta, 0, 9), self.tempChange and self.plate0Selected) - self.plate1Temp.set (sp.limit (self.plate1Temp + self.tempDelta, 0, 9), self.tempChange and self.plate1Selected) - self.plate2Temp.set (sp.limit (self.plate2Temp + self.tempDelta, 0, 9), self.tempChange and self.plate2Selected) - self.plate3Temp.set (sp.limit (self.plate3Temp + self.tempDelta, 0, 9), self.tempChange and self.plate3Selected) - - self.part ('Buzzer tone generation and pitch bend') - self.buzzerOn.latch (self.alarmEdge) - self.buzzerOnTimer.reset (not self.buzzerOn) - self.buzzerOn.unlatch (self.buzzerOnTimer > self.buzzerOnTime) - - self.buzzerPitchTimer.reset (self.buzzerPitchTimer > 3) - self.buzzerFreq.set (self.buzzerBaseFreq * (1 + self.buzzerPitchTimer)) - self.buzzerWaveTimer.reset (self.buzzerWaveTimer > 0.5 / self.buzzerFreq) - self.buzzerEdge.trigger (self.buzzerWaveTimer == 0) - self.buzzer.mark (not self.buzzer, self.buzzerOn and self.buzzerEdge) - - self.part ('Numerical display') - self.digitIndex.set ((self.digitIndex + 1) % 4) - - self.plateDigitValue.set (self.plate0Temp, self.digitIndex == 3) - self.plateDigitValue.set (self.plate1Temp, self.digitIndex == 2) - self.plateDigitValue.set (self.plate2Temp, self.digitIndex == 1) - self.plateDigitValue.set (self.plate3Temp, self.digitIndex == 0) - - self.alarmDigitValue.set (sp.digit (self.alarmTimeLeft, self.digitIndex)) - self.digitValue.set (self.alarmDigitValue, self.alarmSelected, self.plateDigitValue) - - self.digitDot.mark (self.plate0Selected, self.digitIndex == 3) - self.digitDot.mark (self.plate1Selected, self.digitIndex == 2) - self.digitDot.mark (self.plate2Selected, self.digitIndex == 1) - self.digitDot.mark (self.plate3Selected, self.digitIndex == 0) - self.digitDot.mark (True, self.childLock) - self.digitDot.mark (False, self.alarmSelected) - - self.part ('Sweep time measurement') - self.sweepMin.set (sp.world.period, sp.world.period < self.sweepMin) - self.sweepMax.set (sp.world.period, sp.world.period > self.sweepMax) - self.sweepWatch.reset (self.sweepWatch > 2) - self.sweepMin.set (1000, not self.sweepWatch) - self.sweepMax.set (0, not self.sweepWatch) diff --git a/build/lib/simpylc/simulations/arduino_stove/native.cpp b/build/lib/simpylc/simulations/arduino_stove/native.cpp deleted file mode 100644 index f2fddb9..0000000 --- a/build/lib/simpylc/simulations/arduino_stove/native.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright (C) 2013 - 2020 GEATEC engineering - -This program is free software. -You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY, without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -See the QQuickLicence for details. - -The QQuickLicense can be accessed at: http://www.qquick.org/license.html - - __________________________________________________________________________ - - - THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! - -__________________________________________________________________________ - -It is meant for training purposes only. - -Removing this header ends your licence. -*/ - -// Pins configured for Arduino Due, adapt for Uno - -int dataPin = 22, clockPin = 24, latchPin = 26; -int powerPin = 28, childLockPin = 30, plateSelectPin = 32; -int upPin = 34, downPin = 36, alarmSelectPin = 38; -int plate0Pin = 2, plate1Pin = 3, plate2Pin = 4, plate3Pin = 5; -int buzzerPin = 40; - -int gain = 255 / 9; - -int dark = 0, g = 1, f = 2, e = 4, d = 8, c = 16, b = 32, a = 64, dot = 128; - -int segments [] = { - a + b + c + d + e + f, - b + c, - a + b + g + e + d, - a + b + g + c + d, - f + g + b + c, - a + f + g + c + d, - a + f + e + d + c + g, - a + b + c, - a + b + c + d + e + f + g, - g + f + a + b + c + d -}; - -void setup () { - pinMode (dataPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(latchPin, OUTPUT); - pinMode (powerPin, INPUT); pinMode (childLockPin, INPUT); pinMode (plateSelectPin, INPUT); - pinMode (upPin, INPUT); pinMode (downPin, INPUT); pinMode (alarmSelectPin, INPUT); - pinMode (plate0Pin, OUTPUT); pinMode (plate1Pin, OUTPUT); pinMode (plate2Pin, OUTPUT); pinMode (plate3Pin, OUTPUT); - pinMode (buzzerPin, OUTPUT); -} - -void readInputs () { - powerButton = digitalRead (powerPin); childLockButton = digitalRead (childLockPin); plateSelectButton = digitalRead (plateSelectPin); - upButton = digitalRead (upPin); downButton = digitalRead (downPin); alarmSelectButton = digitalRead (alarmSelectPin); -} - -void writeOutputs () { - analogWrite (plate0Pin, gain * plate0Temp); analogWrite (plate1Pin, gain * plate1Temp); - analogWrite (plate2Pin, gain * plate2Temp); analogWrite (plate3Pin, gain * plate3Temp); - digitalWrite (buzzerPin, buzzer); - - digitalWrite (latchPin, 0); - shiftOut (dataPin, clockPin, LSBFIRST, 1 << int (3 - digitIndex)); - shiftOut (dataPin, clockPin, LSBFIRST, ~(power ? (segments [int (digitValue)] + (digitDot ? dot : dark)) : dark)); // Active low - digitalWrite (latchPin, 1); -} - -void loop () { - readInputs (); - cycle (); - writeOutputs (); -} diff --git a/build/lib/simpylc/simulations/arduino_stove/timing.py b/build/lib/simpylc/simulations/arduino_stove/timing.py deleted file mode 100644 index 554b0b9..0000000 --- a/build/lib/simpylc/simulations/arduino_stove/timing.py +++ /dev/null @@ -1,43 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - self.channel (sp.world.control.digitIndex, sp.olive, 0, 3, 40) - self.channel (sp.world.control.digitValue, sp.olive) - self.channel (sp.world.control.digitDot, sp.olive, 0, 3, 40) - self.channel (sp.world.control.buzzerPitchTimer, sp.aqua, 0, 1, 40) - self.channel (sp.world.control.buzzer, sp.aqua) - self.channel (sp.world.control.upButton, sp.red) - self.channel (sp.world.control.downButton, sp.red) - self.channel (sp.world.control.plateSelectNr, sp.red, 0, 3, 40) - self.channel (sp.world.control.alarmTimeLeft, sp.green, 0, 300, 90) - diff --git a/build/lib/simpylc/simulations/arduino_stove/visualisation.py b/build/lib/simpylc/simulations/arduino_stove/visualisation.py deleted file mode 100644 index 7b98d0a..0000000 --- a/build/lib/simpylc/simulations/arduino_stove/visualisation.py +++ /dev/null @@ -1,91 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Visualisation (sp.Scene): - def __init__ (self): - sp.Scene.__init__ (self) - - self.frame = sp.Beam (size = (2, 2, 0.05), pivot = (0, 1, 0), color = (0.1, 0.1, 0.1)) - self.plate = sp.Cylinder (size = (0.6, 0.6, 0.1), center = (0, 0, 0.05)) - self.buzzer = sp.Cylinder (size = (0.2, 0.2, 0.2), center = (0, 0, 0.05)) - - self.aDisplay = sp.Beam (size = (1, 2.2, 0.05), center = (-2, 0, 2), pivot = (0, 1, 0), color = (0, 0.03, 0)) - self.digit = sp.Beam (size = (0.9, 0.45, 0.05), center = (0, 0, 0.05), color = (0, 0.05, 0)) - self.segment = sp.Beam (size = (0.30, 0.07, 0.05), center = (0, 0, 0.05), color = (0, 1, 0)) - self.dot = sp.Beam (size = (0.07, 0.07, 0.05), center = (0, 0, 0.1), color = (0, 1, 0)) - - self.segments = ( - (0, 2, 3, 4, 5, 6), - (5, 6), - (0, 1, 2, 4, 5), - (0, 1, 2, 5, 6), - (1, 3, 5, 6), - (0, 1, 2, 3, 6), - (0, 1, 2, 3, 4, 6), - (0, 5, 6), - (0, 1, 2, 3, 4, 5, 6), - (0, 1, 2, 3, 5, 6) - ) - - def display (self): - def getPlateColor (temperature): - return sp.tsMul ((1, 0.7, 0), (1 + temperature) / 10.) - - def getDigit (shift, digitValue, dotOn, active): - def getColor (on): - return (0, 1, 0) if sp.world.control.power and active and on else (0, 0.07, 0) - - def getSegmentColor (segmentNr): - return getColor (segmentNr in self.segments [digitValue ()]) - - return self.digit (shift = shift, parts = lambda: - self.segment (rotation = 90, shift = (0, 0.4, 0), color = getSegmentColor (0)) + - self.segment (rotation = 90, color = getSegmentColor (1)) + - self.segment (rotation = 90, shift = (0, -0.4, 0), color = getSegmentColor (2)) + - self.segment (shift = (-0.2, -0.17, 0), color = getSegmentColor (3)) + - self.segment (shift = (0.2, -0.17, 0), color = getSegmentColor (4)) + - self.segment (shift = (-0.2, 0.17, 0), color = getSegmentColor (5)) + - self.segment (shift = (0.2, 0.17, 0), color = getSegmentColor (6)) + - self.dot (shift = (0.5, 0.25, 0), color = getColor (dotOn ())) - ) - - self.frame (rotation = 30, parts = lambda: - self.plate (shift = (-0.6, -0.6, 0), color = getPlateColor (sp.world.control.plate0Temp)) + - self.plate (shift = (-0.6, 0.6, 0), color = getPlateColor (sp.world.control.plate1Temp)) + - self.plate (shift = (0.6, 0.6, 0), color = getPlateColor (sp.world.control.plate2Temp)) + - self.plate (shift = (0.6, -0.6, 0), color = getPlateColor (sp.world.control.plate3Temp)) + - self.buzzer (color = (1, 1, 1) if sp.world.control.buzzer else (0.1, 0.1, 0.1)) - ) - - self.aDisplay (rotation = 70, parts = lambda: - getDigit ((0, -0.75, 0), sp.world.control.digitValue, sp.world.control.digitDot, sp.world.control.digitIndex == 3) + - getDigit ((0, -0.25, 0), sp.world.control.digitValue, sp.world.control.digitDot, sp.world.control.digitIndex == 2) + - getDigit ((0, 0.25, 0), sp.world.control.digitValue, sp.world.control.digitDot, sp.world.control.digitIndex == 1) + - getDigit ((0, 0.75, 0), sp.world.control.digitValue, sp.world.control.digitDot, sp.world.control.digitIndex == 0) - ) - diff --git a/build/lib/simpylc/simulations/arduino_stove/world.py b/build/lib/simpylc/simulations/arduino_stove/world.py deleted file mode 100644 index 188c515..0000000 --- a/build/lib/simpylc/simulations/arduino_stove/world.py +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp -import control as ct -import timing as tm -import visualisation as vs - -sp.World (ct.Control, tm.Timing, vs.Visualisation) diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights/native.cpp b/build/lib/simpylc/simulations/arduino_traffic_lights/native.cpp deleted file mode 100644 index 1425fd0..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights/native.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (C) 2013 - 2020 GEATEC engineering - -This program is free software. -You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY, without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -See the QQuickLicence for details. - -The QQuickLicense can be accessed at: http://www.qquick.org/license.html -__________________________________________________________________________ - - -THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! - -__________________________________________________________________________ - -It is meant for training purposes only. - -Removing this header ends your licence. -*/ - -void setup () { - analogWriteResolution (12); - - pinMode (33, OUTPUT); pinMode (35, OUTPUT); pinMode (37, OUTPUT); pinMode (39, OUTPUT); - pinMode (41, OUTPUT); pinMode (43, OUTPUT); pinMode (45, OUTPUT); pinMode (47, OUTPUT); - pinMode (49, INPUT); pinMode (51, INPUT); -} - -void loop () { - modeButton = !digitalRead (49); brightButton = !digitalRead (51); - - cycle (); - - digitalWrite (39, northGreenLamp); digitalWrite (41, northRedLamp); - digitalWrite (35, eastGreenLamp); digitalWrite (37, eastRedLamp); - digitalWrite (47, southGreenLamp); digitalWrite (33, southRedLamp); - digitalWrite (43, westGreenLamp); digitalWrite (45, westRedLamp); - - analogWrite (DAC0, streetLamp); -} diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights/timing.py b/build/lib/simpylc/simulations/arduino_traffic_lights/timing.py deleted file mode 100644 index 574fe8a..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights/timing.py +++ /dev/null @@ -1,52 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - self.channel (sp.world.trafficLights.northGreenLamp, sp.green) - self.channel (sp.world.trafficLights.northRedLamp, sp.red) - self.channel (sp.world.trafficLights.eastGreenLamp, sp.green) - self.channel (sp.world.trafficLights.eastRedLamp, sp.red) - self.channel (sp.world.trafficLights.southGreenLamp, sp.green) - self.channel (sp.world.trafficLights.southRedLamp, sp.red) - self.channel (sp.world.trafficLights.westGreenLamp, sp.green) - self.channel (sp.world.trafficLights.westRedLamp, sp.red) - self.channel (sp.world.trafficLights.regularPhaseTimer, sp.aqua, 0, 20, 60) - self.channel (sp.world.trafficLights.cyclePhaseTimer, sp.aqua, 0, 40, 60) - self.channel (sp.world.trafficLights.blinkTimer, sp.aqua, 0, 0.3, 60) - self.channel (sp.world.trafficLights.modeButton, sp.white) - self.channel (sp.world.trafficLights.modePulse, sp.white) - self.channel (sp.world.trafficLights.modeStep, sp.white, 0, 3, 60) - self.channel (sp.world.trafficLights.brightButton, sp.yellow) - self.channel (sp.world.trafficLights.brightPulse, sp.yellow) - self.channel (sp.world.trafficLights.brightDirection, sp.yellow) - self.channel (sp.world.trafficLights.streetLamp, sp.yellow, 0, 5000, 60) - diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights/traffic_lights.py b/build/lib/simpylc/simulations/arduino_traffic_lights/traffic_lights.py deleted file mode 100644 index 10be718..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights/traffic_lights.py +++ /dev/null @@ -1,160 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class TrafficLights (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('Trafic lights') - - self.group ('Timers', True) - self.regularPhaseTimer = sp.Timer () - self.cyclePhaseTimer = sp.Timer () - self.tBlink = sp.Register (0.3) - self.blinkTimer = sp.Timer () - self.blinkPulse = sp.Oneshot () - self.blink = sp.Marker () - - self.group ('Mode switching') - self.modeButton = sp.Marker () - self.modePulse = sp.Oneshot () - self.modeStep = sp.Register () - self.regularMode = sp.Marker (True) - self.cycleMode = sp.Marker () - self.nightMode = sp.Marker () - self.offMode = sp.Marker () - - self.group ('Night blinking') - self.allowRed = sp.Marker () - - self.group ('Regular mode phases', True) - self.northSouthGreen = sp.Marker (True) - self.northSouthBlink = sp.Marker () - self.eastWestGreen = sp.Marker () - self.eastWestBlink = sp.Marker () - - self.group ('Cycle mode phases') - self.northGreen = sp.Marker () - self.northBlink = sp.Marker () - self.eastGreen = sp.Marker () - self.eastBlink = sp.Marker () - self.southGreen = sp.Marker () - self.southBlink = sp.Marker () - self.westGreen = sp.Marker () - self.westBlink = sp.Marker () - - self.group ('Lamps') - self.northGreenLamp = sp.Marker () - self.northRedLamp = sp.Marker () - self.eastGreenLamp = sp.Marker () - self.eastRedLamp = sp.Marker () - self.southGreenLamp = sp.Marker () - self.southRedLamp = sp.Marker () - self.westGreenLamp = sp.Marker () - self.westRedLamp = sp.Marker () - - self.group ('Regular phase end times', True) - self.tNorthSouthGreen = sp.Register (5) - self.tNorthSouthBlink = sp.Register (7) - self.tEastWestGreen = sp.Register (12) - self.tEastWestBlink = sp.Register (14) - - self.group ('Cycle phase end times') - self.tNorthGreen = sp.Register (5) - self.tNorthBlink = sp.Register (7) - self.tEastGreen = sp.Register (12) - self.tEastBlink = sp.Register (14) - self.tSouthGreen = sp.Register (19) - self.tSouthBlink = sp.Register (21) - self.tWestGreen = sp.Register (26) - self.tWestBlink = sp.Register (28) - - self.group ('Street illumination') - self.brightButton = sp.Marker () - self.brightPulse = sp.Oneshot () - self.brightDirection = sp.Marker (True) - self.brightMin = sp.Register (2047) - self.brightMax = sp.Register (4095) - self.brightFluxus = sp.Register (200) - self.brightDelta = sp.Register () - self.streetLamp = sp.Register (2047) - - self.group ('System') - self.runner = sp.Runner () - - def sweep (self): - self.part ('Timers') - self.regularPhaseTimer.reset (self.regularPhaseTimer > self.tEastWestBlink or self.cycleMode or self.nightMode or self.offMode) - self.cyclePhaseTimer.reset (self.cyclePhaseTimer > self.tWestBlink or self.regularMode or self.nightMode or self.offMode) - self.blinkTimer.reset (self.blinkTimer > self.tBlink) - self.blinkPulse.trigger (self.blinkTimer == 0) - self.blink.mark (not self.blink, self.blinkPulse) - - self.part ('Mode switching') - self.modePulse.trigger (self.modeButton) - self.modeStep.set ((self.modeStep + 1) % 4, self.modePulse) - self.regularMode.mark (self.modeStep == 0) - self.cycleMode.mark (self.modeStep == 1) - self.nightMode.mark (self.modeStep == 2) - self.offMode.mark (self.modeStep == 3) - - self.part ('Regular mode phases') - self.northSouthGreen.mark (0 < self.regularPhaseTimer < self.tNorthSouthGreen) - self.northSouthBlink.mark (self.tNorthSouthGreen < self.regularPhaseTimer < self.tNorthSouthBlink) - self.eastWestGreen.mark (self.tNorthSouthBlink < self.regularPhaseTimer < self.tEastWestGreen) - self.eastWestBlink.mark (self.tEastWestGreen < self.regularPhaseTimer) - - self.part ('Cycle mode phases') - self.northGreen.mark (0 < self.cyclePhaseTimer < self.tNorthGreen) - self.northBlink.mark (self.tNorthGreen < self.cyclePhaseTimer < self.tNorthBlink) - self.eastGreen.mark (self.tNorthBlink < self.cyclePhaseTimer < self.tEastGreen) - self.eastBlink.mark (self.tEastGreen < self.cyclePhaseTimer < self.tEastBlink) - self.southGreen.mark (self.tEastBlink < self.cyclePhaseTimer < self.tSouthGreen) - self.southBlink.mark (self.tSouthGreen < self.cyclePhaseTimer < self.tSouthBlink) - self.westGreen.mark (self.tSouthBlink < self.cyclePhaseTimer < self.tWestGreen) - self.westBlink.mark (self.tWestGreen < self.cyclePhaseTimer) - - self.part ('Night blinking') - self.allowRed.mark (self.regularMode or self.cycleMode or (self.nightMode and self.blink)) - - self.part ('Traffic lamps') - self.northGreenLamp.mark (self.northSouthGreen or self.northGreen or ((self.northSouthBlink or self.northBlink) and self.blink)) - self.northRedLamp.mark (not (self.northSouthGreen or self.northGreen or self.northSouthBlink or self.northBlink) and self.allowRed) - self.eastGreenLamp.mark (self.eastWestGreen or self.eastGreen or ((self.eastWestBlink or self.eastBlink) and self.blink)) - self.eastRedLamp.mark (not (self.eastWestGreen or self.eastGreen or self.eastWestBlink or self.eastBlink) and self.allowRed) - self.southGreenLamp.mark (self.northSouthGreen or self.southGreen or ((self.northSouthBlink or self.southBlink) and self.blink)) - self.southRedLamp.mark (not (self.northSouthGreen or self.southGreen or self.northSouthBlink or self.southBlink) and self.allowRed) - self.westGreenLamp.mark (self.eastWestGreen or self.westGreen or ((self.eastWestBlink or self.westBlink) and self.blink)) - self.westRedLamp.mark (not (self.eastWestGreen or self.westGreen or self.eastWestBlink or self.westBlink) and self.allowRed) - - self.part ('Street illumination') - self.brightPulse.trigger (self.brightButton) - self.brightDirection.mark (not self.brightDirection, self.brightPulse) - self.brightDelta.set (-self.brightFluxus * sp.world.period, self.brightDirection, self.brightFluxus * sp.world.period) - self.streetLamp.set (sp.limit (self.streetLamp + self.brightDelta, self.brightMin, self.brightMax), self.brightButton) - diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights/visualisation.py b/build/lib/simpylc/simulations/arduino_traffic_lights/visualisation.py deleted file mode 100644 index 04a7935..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights/visualisation.py +++ /dev/null @@ -1,90 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class TrafficLamp (sp.Cylinder): - def __init__ (self, green = False): - sp.Cylinder.__init__ (self, size = (0.1, 0.1, 0.2), center = (0, 0, 0.5) if green else (0, 0, 0.7), color = (0, 1, 0) if green else (1, 0, 0)) - self.originalColor = self.color - - def __call__ (self, on): - self.color = self.originalColor if on else sp.tsMul (self.originalColor, 0.2) - return sp.Cylinder.__call__ (self) - -class StreetLamp (sp.Cylinder): - def __init__ (self, green = False): - sp.Cylinder.__init__ (self, size = (0.4, 0.4, 0.4), center = (0, 0, 2), color = (1, 1, 0.2)) - self.originalColor = self.color - - def __call__ (self, brightness): - self.color = sp.tsMul (self.originalColor, 0.2 + 0.8 * brightness) - return sp.Cylinder.__call__ (self) - -class Visualisation (sp.Scene): - def __init__ (self): - sp.Scene.__init__ (self) - - self.crossing = sp.Beam (size = (3, 3, 0.1), pivot = (0, 1, 0), color = (0.1, 0.1, 0.1)) - self.sidewalk = sp.Beam (size = (1, 1, 0.1), center = (-1, -1, 0.1), joint = (1, 1, 0), color = (0, 0.3, 0)) - self.pole = sp.Cylinder (size = (0.05, 0.05, 1), center = (0, 0.45, 0.45), color = (1, 1, 1)) - - self.redLamp = TrafficLamp () - self.greenLamp = TrafficLamp (True) - self.streetLamp = StreetLamp () - - def display (self): - control = sp.world.trafficLights - - self.crossing (rotation = 30, parts = lambda: - self.sidewalk (rotation = 0, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.northRedLamp) + - self.greenLamp (control.northGreenLamp) - ) - ) + - self.sidewalk (rotation = -90, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.eastRedLamp) + - self.greenLamp (control.eastGreenLamp) - ) - - ) + - self.sidewalk (rotation = -180, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.southRedLamp) + - self.greenLamp (control.southGreenLamp) - ) - ) + - self.sidewalk (rotation = -270, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.westRedLamp) + - self.greenLamp (control.westGreenLamp) - ) - ) + - self.streetLamp ((control.streetLamp - control.brightMin) / (control.brightMax - control.brightMin)) - ) - diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights/world.py b/build/lib/simpylc/simulations/arduino_traffic_lights/world.py deleted file mode 100644 index 1a731bf..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights/world.py +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp -import traffic_lights as tl -import timing as tm -import visualisation as vs - -sp.World (tl.TrafficLights, tm.Timing, vs.Visualisation) diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/native.cpp b/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/native.cpp deleted file mode 100644 index 7eba8e1..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/native.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright (C) 2013 - 2020 GEATEC engineering - -This program is free software. -You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY, without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -See the QQuickLicence for details. - -The QQuickLicense can be accessed at: http://www.qquick.org/license.html -__________________________________________________________________________ - - -THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! - -__________________________________________________________________________ - -It is meant for training purposes only. - -Removing this header ends your licence. -*/ - -// Pin assignment for Arduino Uno - -void setup () { - pinMode (3, INPUT_PULLUP); pinMode (4, INPUT_PULLUP); - - pinMode (A0, OUTPUT); pinMode (A1, OUTPUT); pinMode (A2, OUTPUT); - pinMode (A3, OUTPUT); pinMode (A4, OUTPUT); pinMode (A5, OUTPUT); - pinMode (7, OUTPUT); pinMode (8, OUTPUT); pinMode (9, OUTPUT); - pinMode (10, OUTPUT); pinMode (11, OUTPUT); pinMode (12, OUTPUT); - - pinMode (5, OUTPUT); -} - -void loop () { - modeButton = !digitalRead (3); brightButton = !digitalRead (4); - - cycle (); - - digitalWrite (A0, northGreenLamp); digitalWrite (A1, northYellowLamp); digitalWrite (A2, northRedLamp); - digitalWrite (A3, eastGreenLamp); digitalWrite (A4, eastYellowLamp); digitalWrite (A5, eastRedLamp); - digitalWrite (7, southGreenLamp); digitalWrite (8, southYellowLamp); digitalWrite (9, southRedLamp); - digitalWrite (10, westGreenLamp); digitalWrite (11, westYellowLamp); digitalWrite (12, westRedLamp); - - analogWrite (5, (streetLamp - brightMin) / 16); - - -} diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/timing.py b/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/timing.py deleted file mode 100644 index 66f95a6..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/timing.py +++ /dev/null @@ -1,56 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - self.channel (sp.world.trafficLights.northGreenLamp, sp.green) - self.channel (sp.world.trafficLights.northYellowLamp, sp.yellow) - self.channel (sp.world.trafficLights.northRedLamp, sp.red) - self.channel (sp.world.trafficLights.eastGreenLamp, sp.green) - self.channel (sp.world.trafficLights.eastYellowLamp, sp.yellow) - self.channel (sp.world.trafficLights.eastRedLamp, sp.red) - self.channel (sp.world.trafficLights.southGreenLamp, sp.green) - self.channel (sp.world.trafficLights.southYellowLamp, sp.yellow) - self.channel (sp.world.trafficLights.southRedLamp, sp.red) - self.channel (sp.world.trafficLights.westYellowLamp, sp.yellow) - self.channel (sp.world.trafficLights.westGreenLamp, sp.green) - self.channel (sp.world.trafficLights.westRedLamp, sp.red) - self.channel (sp.world.trafficLights.regularPhaseTimer, sp.aqua, 0, 20, 60) - self.channel (sp.world.trafficLights.cyclePhaseTimer, sp.aqua, 0, 40, 60) - self.channel (sp.world.trafficLights.blinkTimer, sp.aqua, 0, 0.3, 60) - self.channel (sp.world.trafficLights.modeButton, sp.white) - self.channel (sp.world.trafficLights.modePulse, sp.white) - self.channel (sp.world.trafficLights.modeStep, sp.white, 0, 3, 60) - self.channel (sp.world.trafficLights.brightButton, sp.yellow) - self.channel (sp.world.trafficLights.brightPulse, sp.yellow) - self.channel (sp.world.trafficLights.brightDirection, sp.yellow) - self.channel (sp.world.trafficLights.streetLamp, sp.yellow, 0, 5000, 60) - diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/traffic_lights.py b/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/traffic_lights.py deleted file mode 100644 index 1542ca9..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/traffic_lights.py +++ /dev/null @@ -1,168 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class TrafficLights (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('Trafic lights') - - self.group ('Timers', True) - self.regularPhaseTimer = sp.Timer () - self.cyclePhaseTimer = sp.Timer () - self.tBlink = sp.Register (0.3) - self.blinkTimer = sp.Timer () - self.blinkPulse = sp.Oneshot () - self.blink = sp.Marker () - - self.group ('Mode switching') - self.modeButton = sp.Marker () - self.modePulse = sp.Oneshot () - self.modeStep = sp.Register () - self.regularMode = sp.Marker (True) - self.cycleMode = sp.Marker () - self.nightMode = sp.Marker () - self.offMode = sp.Marker () - - self.group ('Regular mode phases', True) - self.northSouthGreen = sp.Marker (True) - self.northSouthBlink = sp.Marker () - self.eastWestGreen = sp.Marker () - self.eastWestBlink = sp.Marker () - - self.group ('Cycle mode phases') - self.northGreen = sp.Marker () - self.northBlink = sp.Marker () - self.eastGreen = sp.Marker () - self.eastBlink = sp.Marker () - self.southGreen = sp.Marker () - self.southBlink = sp.Marker () - self.westGreen = sp.Marker () - self.westBlink = sp.Marker () - - self.group ('Lamps') - self.northGreenLamp = sp.Marker () - self.northYellowLamp = sp.Marker () - self.northRedLamp = sp.Marker () - self.eastGreenLamp = sp.Marker () - self.eastYellowLamp = sp.Marker () - self.eastRedLamp = sp.Marker () - self.southGreenLamp = sp.Marker () - self.southYellowLamp = sp.Marker () - self.southRedLamp = sp.Marker () - self.westGreenLamp = sp.Marker () - self.westYellowLamp = sp.Marker () - self.westRedLamp = sp.Marker () - - self.group ('Regular phase end times', True) - self.tNorthSouthGreen = sp.Register (5) - self.tNorthSouthBlink = sp.Register (7) - self.tEastWestGreen = sp.Register (12) - self.tEastWestBlink = sp.Register (14) - - self.group ('Cycle phase end times') - self.tNorthGreen = sp.Register (5) - self.tNorthBlink = sp.Register (7) - self.tEastGreen = sp.Register (12) - self.tEastBlink = sp.Register (14) - self.tSouthGreen = sp.Register (19) - self.tSouthBlink = sp.Register (21) - self.tWestGreen = sp.Register (26) - self.tWestBlink = sp.Register (28) - - self.group ('Street illumination') - self.brightButton = sp.Marker () - self.brightPulse = sp.Oneshot () - self.brightDirection = sp.Marker (True) - self.brightMin = sp.Register (2047) - self.brightMax = sp.Register (4095) - self.brightFluxus = sp.Register (200) - self.brightDelta = sp.Register () - self.streetLamp = sp.Register (2047) - - self.group ('System') - self.runner = sp.Runner () - - def sweep (self): - self.part ('Timers') - self.regularPhaseTimer.reset (self.regularPhaseTimer > self.tEastWestBlink or self.cycleMode or self.nightMode or self.offMode) - self.cyclePhaseTimer.reset (self.cyclePhaseTimer > self.tWestBlink or self.regularMode or self.nightMode or self.offMode) - self.blinkTimer.reset (self.blinkTimer > self.tBlink) - self.blinkPulse.trigger (self.blinkTimer == 0) - self.blink.mark (not self.blink, self.blinkPulse) - - self.part ('Mode switching') - self.modePulse.trigger (self.modeButton) - self.modeStep.set ((self.modeStep + 1) % 4, self.modePulse) - self.regularMode.mark (self.modeStep == 0) - self.cycleMode.mark (self.modeStep == 1) - self.nightMode.mark (self.modeStep == 2) - self.offMode.mark (self.modeStep == 3) - - self.part ('Regular mode phases') - self.northSouthGreen.mark (0 < self.regularPhaseTimer < self.tNorthSouthGreen) - self.northSouthBlink.mark (self.tNorthSouthGreen < self.regularPhaseTimer < self.tNorthSouthBlink) - self.eastWestGreen.mark (self.tNorthSouthBlink < self.regularPhaseTimer < self.tEastWestGreen) - self.eastWestBlink.mark (self.tEastWestGreen < self.regularPhaseTimer) - - self.part ('Cycle mode phases') - self.northGreen.mark (0 < self.cyclePhaseTimer < self.tNorthGreen) - self.northBlink.mark (self.tNorthGreen < self.cyclePhaseTimer < self.tNorthBlink) - - self.eastGreen.mark (self.tNorthBlink < self.cyclePhaseTimer < self.tEastGreen) - self.eastBlink.mark (self.tEastGreen < self.cyclePhaseTimer < self.tEastBlink) - - self.southGreen.mark (self.tEastBlink < self.cyclePhaseTimer < self.tSouthGreen) - self.southBlink.mark (self.tSouthGreen < self.cyclePhaseTimer < self.tSouthBlink) - - self.westGreen.mark (self.tSouthBlink < self.cyclePhaseTimer < self.tWestGreen) - self.westBlink.mark (self.tWestGreen < self.cyclePhaseTimer) - - self.part ('Traffic lamps') - self.northGreenLamp.mark (self.northSouthGreen or self.northGreen) - self.northYellowLamp.mark ((self.northSouthBlink or self.northBlink or self.nightMode) and self.blink) - self.northRedLamp.mark (not (self.northSouthGreen or self.northGreen or self.northSouthBlink or self.northBlink or self.nightMode or self.offMode)) - - self.eastGreenLamp.mark (self.eastWestGreen or self.eastGreen) - self.eastYellowLamp.mark ((self.eastWestBlink or self.eastBlink or self.nightMode) and self.blink) - self.eastRedLamp.mark (not (self.eastWestGreen or self.eastGreen or self.eastWestBlink or self.eastBlink or self.nightMode or self.offMode)) - - self.southGreenLamp.mark (self.northSouthGreen or self.southGreen) - self.southYellowLamp.mark ((self.northSouthBlink or self.southBlink or self.nightMode) and self.blink) - self.southRedLamp.mark (not (self.northSouthGreen or self.southGreen or self.northSouthBlink or self.southBlink or self.nightMode or self.offMode)) - - self.westGreenLamp.mark (self.eastWestGreen or self.westGreen) - self.westYellowLamp.mark ((self.eastWestBlink or self.westBlink or self.nightMode) and self.blink) - self.westRedLamp.mark (not (self.eastWestGreen or self.westGreen or self.eastWestBlink or self.westBlink or self.nightMode or self.offMode)) - - self.part ('Street illumination') - self.brightPulse.trigger (self.brightButton) - self.brightDirection.mark (not self.brightDirection, self.brightPulse) - self.brightDelta.set (-self.brightFluxus * sp.world.period, self.brightDirection, self.brightFluxus * sp.world.period) - self.streetLamp.set (sp.limit (self.streetLamp + self.brightDelta, self.brightMin, self.brightMax), self.brightButton) - diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/visualisation.py b/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/visualisation.py deleted file mode 100644 index f458a09..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/visualisation.py +++ /dev/null @@ -1,100 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -red, yellow, green = range (3) - -class TrafficLamp (sp.Cylinder): - colors = ((1, 0, 0), (1, 1, 0), (0, 1, 0)) - heights = (0.9, 0.7, 0.5) - - def __init__ (self, kind): - sp.Cylinder.__init__ (self, size = (0.1, 0.1, 0.2), center = (0, 0, self.heights [kind]), color = self.colors [kind]) - self.originalColor = self.color - - def __call__ (self, on): - self.color = self.originalColor if on else sp.tsMul (self.originalColor, 0.2) - return sp.Cylinder.__call__ (self) - -class StreetLamp (sp.Cylinder): - def __init__ (self, green = False): - sp.Cylinder.__init__ (self, size = (0.4, 0.4, 0.4), center = (0, 0, 2), color = (1, 1, 0.2)) - self.originalColor = self.color - - def __call__ (self, brightness): - self.color = sp.tsMul (self.originalColor, 0.2 + 0.8 * brightness) - return sp.Cylinder.__call__ (self) - -class Visualisation (sp.Scene): - def __init__ (self): - sp.Scene.__init__ (self) - - self.crossing = sp.Beam (size = (3, 3, 0.1), pivot = (0, 1, 0), color = (0.1, 0.1, 0.1)) - self.sidewalk = sp.Beam (size = (1, 1, 0.1), center = (-1, -1, 0.1), joint = (1, 1, 0), color = (0, 0.3, 0)) - self.pole = sp.Cylinder (size = (0.05, 0.05, 1), center = (0, 0.45, 0.45), color = (1, 1, 1)) - - self.redLamp = TrafficLamp (red) - self.yellowLamp = TrafficLamp (yellow) - self.greenLamp = TrafficLamp (green) - self.streetLamp = StreetLamp () - - def display (self): - control = sp.world.trafficLights - - self.crossing (rotation = 30, parts = lambda: - self.sidewalk (rotation = 0, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.northRedLamp) + - self.yellowLamp (control.northYellowLamp) + - self.greenLamp (control.northGreenLamp) - ) - ) + - self.sidewalk (rotation = -90, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.eastRedLamp) + - self.yellowLamp (control.eastYellowLamp) + - self.greenLamp (control.eastGreenLamp) - ) - - ) + - self.sidewalk (rotation = -180, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.southRedLamp) + - self.yellowLamp (control.southYellowLamp) + - self.greenLamp (control.southGreenLamp) - ) - ) + - self.sidewalk (rotation = -270, parts = lambda: - self.pole (parts = lambda: - self.redLamp (control.westRedLamp) + - self.yellowLamp (control.westYellowLamp) + - self.greenLamp (control.westGreenLamp) - ) - ) + - self.streetLamp ((control.streetLamp - control.brightMin) / (control.brightMax - control.brightMin)) - ) - diff --git a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/world.py b/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/world.py deleted file mode 100644 index 1a731bf..0000000 --- a/build/lib/simpylc/simulations/arduino_traffic_lights_with_yellow/world.py +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp -import traffic_lights as tl -import timing as tm -import visualisation as vs - -sp.World (tl.TrafficLights, tm.Timing, vs.Visualisation) diff --git a/build/lib/simpylc/simulations/blinking_light/blinking_light.py b/build/lib/simpylc/simulations/blinking_light/blinking_light.py deleted file mode 100644 index 140f578..0000000 --- a/build/lib/simpylc/simulations/blinking_light/blinking_light.py +++ /dev/null @@ -1,46 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class BlinkingLight (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - self.blinkingTimer = sp.Timer () - self.blinkingLight = sp.Marker () - self.pulse = sp.Oneshot () - self.counter = sp.Register () - self.run = sp.Runner () - - def input (self): - pass - - def sweep (self): - self.blinkingTimer.reset (self.blinkingTimer > 8) - self.blinkingLight.mark (not self.blinkingLight, not self.blinkingTimer) - self.pulse.trigger (self.blinkingTimer > 3) - self.counter.set (self.counter + 1, self.pulse) - diff --git a/build/lib/simpylc/simulations/blinking_light/timing.py b/build/lib/simpylc/simulations/blinking_light/timing.py deleted file mode 100644 index 97b2612..0000000 --- a/build/lib/simpylc/simulations/blinking_light/timing.py +++ /dev/null @@ -1,38 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - self.channel (sp.world.blinkingLight.blinkingTimer, sp.red, 0, 12, 50) - self.channel (sp.world.blinkingLight.blinkingLight, sp.lime, 0, 1, 50) - self.channel (sp.world.blinkingLight.pulse, sp.blue, 0, 1, 50) - self.channel (sp.world.blinkingLight.counter, sp.yellow, 0, 20, 100) - diff --git a/build/lib/simpylc/simulations/blinking_light/world.py b/build/lib/simpylc/simulations/blinking_light/world.py deleted file mode 100644 index 7cb5fbd..0000000 --- a/build/lib/simpylc/simulations/blinking_light/world.py +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp -import blinking_light as bl -import timing as tm - -sp.World (bl.BlinkingLight, tm.Timing) diff --git a/build/lib/simpylc/simulations/car/control.py b/build/lib/simpylc/simulations/car/control.py deleted file mode 100755 index c1c04de..0000000 --- a/build/lib/simpylc/simulations/car/control.py +++ /dev/null @@ -1,66 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -import parameters as pm - -class Control (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('motion control') - - self.group ('driver input', True) - self.targetVelocityStep = sp.Register (0) - self.steeringAngleStep = sp.Register (2) - - self.group ('control output') - self.targetVelocity = sp.Register () - self.steeringAngle = sp.Register () - - self.group ('sweep time measurement', True) - self.sweepMin = sp.Register (1000) - self.sweepMax = sp.Register () - self.sweepWatch = sp.Timer () - self.run = sp.Runner () - - def output (self): - sp.world.physics.targetVelocity.set (self.targetVelocity) - sp.world.physics.steeringAngle.set (self.steeringAngle) - - def sweep (self): - # Input to output - self.targetVelocity.set (0.2 * self.targetVelocityStep) - self.steeringAngle.set (10 * self.steeringAngleStep) - - # Sweep time measurement - self.sweepMin.set (sp.world.period, sp.world.period < self.sweepMin) - self.sweepMax.set (sp.world.period, sp.world.period > self.sweepMax) - self.sweepWatch.reset (self.sweepWatch > 2) - self.sweepMin.set (1000, not self.sweepWatch) - self.sweepMax.set (0, not self.sweepWatch) - diff --git a/build/lib/simpylc/simulations/car/keyboard_pilot.py b/build/lib/simpylc/simulations/car/keyboard_pilot.py deleted file mode 100644 index 649debf..0000000 --- a/build/lib/simpylc/simulations/car/keyboard_pilot.py +++ /dev/null @@ -1,69 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import time as tm - -import simpylc as sp - -class KeyboardPilot: - def __init__ (self): - print ('Use arrow keys to control speed and direction') - - while True: - self.input () - self.sweep () - self.output () - tm.sleep (0.02) - - def input (self): - key = sp.getKey () - - self.leftKey = key == 'KEY_LEFT' - self.rightKey = key == 'KEY_RIGHT' - self.upKey = key == 'KEY_UP' - self.downKey = key == 'KEY_DOWN' - - self.targetVelocityStep = sp.world.control.targetVelocityStep - self.steeringAngleStep = sp.world.control.steeringAngleStep - - def sweep (self): - if self.leftKey: - self.steeringAngleStep += 1 - print ('Steering angle step: ', self.steeringAngleStep) - elif self.rightKey: - self.steeringAngleStep -= 1 - print ('Steering angle step: ', self.steeringAngleStep) - elif self.upKey: - self.targetVelocityStep += 1 - print ('Target velocity step: ', self.targetVelocityStep) - elif self.downKey: - self.targetVelocityStep -= 1 - print ('Target velocity step: ', self.targetVelocityStep) - - def output (self): - sp.world.control.steeringAngleStep.set (self.steeringAngleStep) - sp.world.control.targetVelocityStep.set (self.targetVelocityStep) - diff --git a/build/lib/simpylc/simulations/car/lidar_pilot.py b/build/lib/simpylc/simulations/car/lidar_pilot.py deleted file mode 100644 index aa75f27..0000000 --- a/build/lib/simpylc/simulations/car/lidar_pilot.py +++ /dev/null @@ -1,85 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import time as tm -import traceback as tb - -import simpylc as sp - -class LidarPilot: - def __init__ (self): - print ('Use up arrow to start, down arrow to stop') - - self.driveEnabled = False - - while True: - self.input () - self.sweep () - self.output () - tm.sleep (0.02) - - def input (self): # Input from simulator - key = sp.getKey () - - if key == 'KEY_UP': - self.driveEnabled = True - elif key == 'KEY_DOWN': - self.driveEnabled = False - - self.lidarDistances = sp.world.visualisation.lidar.distances - self.lidarHalfApertureAngle = sp.world.visualisation.lidar.halfApertureAngle - - def sweep (self): # Control algorithm to be tested - self.nearestObstacleDistance = sp.finity - self.nearestObstacleAngle = 0 - - self.nextObstacleDistance = sp.finity - self.nextObstacleAngle = 0 - - for lidarAngle in range (-self.lidarHalfApertureAngle, self.lidarHalfApertureAngle): - lidarDistance = self.lidarDistances [lidarAngle] - - if lidarDistance < self.nearestObstacleDistance: - self.nextObstacleDistance = self.nearestObstacleDistance - self.nextObstacleAngle = self.nearestObstacleAngle - - self.nearestObstacleDistance = lidarDistance - self.nearestObstacleAngle = lidarAngle - - elif lidarDistance < self.nextObstacleDistance: - self.nextObstacleDistance = lidarDistance - self.nextObstacleAngle = lidarAngle - - self.targetObstacleDistance = (self.nearestObstacleDistance + self.nextObstacleDistance) / 2 - self.targetObstacleAngle = (self.nearestObstacleAngle + self.nextObstacleAngle) / 2 - - self.steeringAngle = self.targetObstacleAngle - self.targetVelocity = (sp.abs (90 - self.steeringAngle) / 80) if self.driveEnabled else 0 - - def output (self): # Output to simulator - sp.world.physics.steeringAngle.set (self.steeringAngle) - sp.world.physics.targetVelocity.set (self.targetVelocity) - diff --git a/build/lib/simpylc/simulations/car/lidar_pilot_sp.py b/build/lib/simpylc/simulations/car/lidar_pilot_sp.py deleted file mode 100644 index 848a390..0000000 --- a/build/lib/simpylc/simulations/car/lidar_pilot_sp.py +++ /dev/null @@ -1,92 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -import parameters as pm - -class LidarPilotSp (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('lidar control') - - self.group ('inputs', True) - - self.driveEnabled = sp.Marker () - - self.nearestObstacleDistance = sp.Register (sp.finity) - self.nearestObstacleAngle = sp.Register (0) - - self.nextObstacleDistance = sp.Register (sp.finity) - self.nextObstacleAngle = sp.Register (0) - - self.targetObstacleDistance = sp.Register (sp.finity) - self.targetObstacleAngle = sp.Register (0) - - self.velocity = sp.Register (0) - - self.group ('outputs') - - self.targetVelocity = sp.Register () - self.steeringAngle = sp.Register (30) - - def input (self): - self.nearestObstacleDistance.set (sp.finity) - self.nearestObstacleAngle.set (0) - - self.nextObstacleDistance.set (sp.finity) - self.nextObstacleAngle.set (0) - - lidar = sp.world.visualisation.lidar - - for lidarAngle in range (-lidar.halfApertureAngle, lidar.halfApertureAngle): - lidarDistance = lidar.distances [lidarAngle] - - if lidarDistance < self.nearestObstacleDistance: - self.nextObstacleDistance.set (self.nearestObstacleDistance) - self.nextObstacleAngle.set (self.nearestObstacleAngle) - - self.nearestObstacleDistance.set (lidarDistance) - self.nearestObstacleAngle.set (lidarAngle) - - elif lidarDistance < self.nextObstacleDistance: - self.nextObstacleDistance.set (lidarDistance) - self.nextObstacleAngle.set (lidarAngle) - - self.targetObstacleDistance.set ((self.nearestObstacleDistance + self.nextObstacleDistance) / 2) - self.targetObstacleAngle.set ((self.nearestObstacleAngle + self.nextObstacleAngle) / 2) - - self.velocity.set (sp.world.physics.velocity) - - def sweep (self): - self.steeringAngle.set (self.targetObstacleAngle) - self.targetVelocity.set (sp.abs (90 - self.steeringAngle) / 65, self.driveEnabled, 0) - - def output (self): - sp.world.physics.steeringAngle.set (self.steeringAngle) - sp.world.physics.targetVelocity.set (self.targetVelocity) - diff --git a/build/lib/simpylc/simulations/car/parameters.py b/build/lib/simpylc/simulations/car/parameters.py deleted file mode 100755 index 91bf650..0000000 --- a/build/lib/simpylc/simulations/car/parameters.py +++ /dev/null @@ -1,34 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.geatec.com/qqLicence.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -wheelDiameter = 0.10 -wheelRadius = wheelDiameter / 2 -displacementPerWheelAngle = sp.radiansPerDegree * wheelRadius - -wheelBase = 0.40 -wheelShift = wheelBase / 2 diff --git a/build/lib/simpylc/simulations/car/physics.py b/build/lib/simpylc/simulations/car/physics.py deleted file mode 100755 index de0d99b..0000000 --- a/build/lib/simpylc/simulations/car/physics.py +++ /dev/null @@ -1,91 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software./ -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -import parameters as pm - -class Physics (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('car physics') - - self.group ('wheels', True) - - self.acceleration = sp.Register (2) - self.targetVelocity= sp.Register () - self.velocity = sp.Register () - self.midWheelAngularVelocity = sp.Register () - self.midWheelAngle = sp.Register (30) - - self.steeringAngle = sp.Register () - self.midSteeringAngle = sp.Register () - - self.inverseMidCurveRadius = sp.Register (20) - self.midAngularVelocity = sp.Register () - - self.attitudeAngle = sp.Register (50) - self.courseAngle = sp.Register () - - self.tangentialVelocity = sp.Register () - self.velocityX = sp.Register () - self.velocityY = sp.Register () - - self.positionX = sp.Register () - self.positionY = sp.Register () - - self.radialAcceleration = sp.Register () - self.slipping = sp.Marker () - self.radialVelocity = sp.Register () - - def sweep (self): - self.page ('traction') - self.group ('wheels', True) - - self.velocity.set (self.velocity + self.acceleration * sp.world.period, self.velocity < self.targetVelocity, self.velocity - self.acceleration * sp.world.period) - self.midWheelAngularVelocity.set (self.velocity / pm.displacementPerWheelAngle) - self.midWheelAngle.set (self.midWheelAngle + self.midWheelAngularVelocity * sp.world.period) - self.tangentialVelocity.set (self.midWheelAngularVelocity * pm.displacementPerWheelAngle) - - self.midSteeringAngle.set (sp.atan (0.5 * sp.tan (self.steeringAngle))) - - self.inverseMidCurveRadius.set (sp.sin (self.midSteeringAngle) / pm.wheelShift) - self.midAngularVelocity.set (sp.degreesPerRadian * self.tangentialVelocity * self.inverseMidCurveRadius) - - self.attitudeAngle.set (self.attitudeAngle + self.midAngularVelocity * sp.world.period) - self.courseAngle.set (self.attitudeAngle + self.midSteeringAngle) - - self.radialAcceleration.set (sp.max (abs (self.tangentialVelocity * self.tangentialVelocity * self.inverseMidCurveRadius) - 0.5, 0)) - self.slipping.mark (sp.abs (self.radialAcceleration) > 0.55) - self.radialVelocity.set (self.radialVelocity + self.radialAcceleration * sp.world.period, self.slipping, 0) - - self.velocityX.set (self.tangentialVelocity * sp.cos (self.courseAngle) + self.radialVelocity * sp.sin (self.courseAngle)) - self.velocityY.set (self.tangentialVelocity * sp.sin (self.courseAngle) + self.radialVelocity * sp.cos (self.courseAngle)) - - self.positionX.set (self.positionX + self.velocityX * sp.world.period) - self.positionY.set (self.positionY + self.velocityY * sp.world.period) - diff --git a/build/lib/simpylc/simulations/car/timing.py b/build/lib/simpylc/simulations/car/timing.py deleted file mode 100755 index ddbdb06..0000000 --- a/build/lib/simpylc/simulations/car/timing.py +++ /dev/null @@ -1,41 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - self.channel (sp.world.physics.steeringAngle, sp.aqua, -90, 90, 100) - self.channel (sp.world.physics.targetVelocity, sp.white, -1, 2, 100) - self.channel (sp.world.physics.velocity, sp.yellow, -1, 2, 100) - self.channel (sp.world.physics.radialAcceleration, sp.lime, -4, 4, 100) - self.channel (sp.world.physics.slipping, sp.red) - - - diff --git a/build/lib/simpylc/simulations/car/visualisation.py b/build/lib/simpylc/simulations/car/visualisation.py deleted file mode 100644 index faaf3cc..0000000 --- a/build/lib/simpylc/simulations/car/visualisation.py +++ /dev/null @@ -1,220 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -''' - - z - | - o -- y - / - x - -''' - -import random as rd - -import simpylc as sp - -import parameters as pm - -normalFloorColor = (0, 0.003, 0) -collisionFloorColor = (1, 0, 0.3) -nrOfObstacles = 64 - -class Lidar: - # 0, ..., halfApertureAngle - 1, -halfApertureAngle, ..., -1 - - def __init__ (self, apertureAngle, obstacles): - self.apertureAngle = apertureAngle - self.halfApertureAngle = self.apertureAngle // 2 - self.obstacles = obstacles - self.distances = [sp.finity for angle in range (self.apertureAngle)] - - def scan (self, mountPosition, mountAngle): - self.distances = [sp.finity for angle in range (self.apertureAngle)] - all = [(sp.finity, angle) for angle in range (-180, 180)] - - for obstacle in self.obstacles: - relativePosition = sp.tSub (obstacle.center, mountPosition) - distance = sp.tNor (relativePosition) - absoluteAngle = sp.atan2 (relativePosition [1], relativePosition [0]) - relativeAngle = (round (absoluteAngle - mountAngle) + 180) % 360 - 180 - - if distance < all [relativeAngle][0]: - all [relativeAngle] = (distance, relativeAngle) # In case of coincidence, favor nearby obstacle - - if -self.halfApertureAngle <= relativeAngle < self.halfApertureAngle - 1: - self.distances [relativeAngle] = min (distance, self.distances [relativeAngle]) # In case of coincidence, favor nearby obstacle - - #print (all) - -class Line (sp.Cylinder): - def __init__ (self, **arguments): - super () .__init__ (size = (0.01, 0.01, 0), axis = (1, 0, 0), angle = 90, color = (0, 1, 1), **arguments) - - -class BodyPart (sp.Beam): - def __init__ (self, **arguments): - super () .__init__ (color = (1, 0, 0), **arguments) - -class Wheel: - def __init__ (self, **arguments): - self.suspension = sp.Cylinder (size = (0.01, 0.01, 0.001), axis = (1, 0, 0), angle = 90, pivot = (0, 0, 1), **arguments) - self.rim = sp.Beam (size = (0.08, 0.06, 0.02), pivot = (0, 1, 0), color = (0, 0, 0)) - self.tire = sp.Cylinder (size = (pm.wheelDiameter, pm.wheelDiameter, 0.04), axis = (1, 0, 0), angle = 90, color = (1, 1, 0)) - self.line = Line () - - def __call__ (self, wheelAngle, slipping, steeringAngle = 0): - return self.suspension (rotation = steeringAngle, parts = lambda: - self.rim (rotation = wheelAngle, parts = lambda: - self.tire (color = (rd.random (), rd.random (), rd.random ()) if slipping else (1, 1, 0)) + - self.line () - ) ) - -class Window (sp.Beam): - def __init__ (self, **arguments): - super () .__init__ (axis = (0, 1, 0), color = (0, 0, 1), **arguments) - -class Floor (sp.Beam): - side = 16 - spacing = 0.2 - halfSteps = round (0.5 * side / spacing) - - class Stripe (sp.Beam): - def __init__ (self, **arguments): - super () .__init__ (size = (0.01, Floor.side, 0.001), **arguments) - - def __init__ (self, **arguments): - super () .__init__ (size = (self.side, self.side, 0.0005), color = normalFloorColor) - self.xStripes = [self.Stripe (center = (0, nr * self.spacing, 0.0001), angle = 90, color = (1, 1, 1)) for nr in range (-self.halfSteps, self.halfSteps)] - self.yStripes = [self.Stripe (center = (nr * self.spacing, 0, 0), color = (0, 0, 0)) for nr in range (-self.halfSteps, self.halfSteps)] - - def __call__ (self, parts): - return super () .__call__ (color = collisionFloorColor if self.scene.collided else normalFloorColor, parts = lambda: - parts () + - sum (xStripe () for xStripe in self.xStripes) + - sum (yStripe () for yStripe in self.yStripes) - ) - -class Visualisation (sp.Scene): - def __init__ (self): - super () .__init__ () - - self.camera = sp.Camera () - - self.floor = Floor (scene = self) - - self.fuselage = BodyPart (size = (0.70, 0.16, 0.08), center = (0, 0, 0.07), pivot = (0, 0, 1), group = 0) - self.fuselageLine = Line () - self.cabin = BodyPart (size = (0.20, 0.16, 0.06), center = (-0.06, 0, 0.07)) - - self.wheelFrontLeft = Wheel (center = (pm.wheelShift, 0.08, -0.02)) - self.wheelFrontRight = Wheel (center = (pm.wheelShift, -0.08, -0.02)) - - self.wheelRearLeft = Wheel (center = (-pm.wheelShift, 0.08, -0.02)) - self.wheelRearRight = Wheel (center = (-pm.wheelShift, -0.08, -0.02)) - - self.windowFront = Window (size = (0.05, 0.14, 0.14), center = (0.14, 0, -0.025), angle = -60) - self.windowRear = Window (size = (0.05, 0.14, 0.18), center = (-0.18, 0, -0.025),angle = 72) - - self.roadCones = [] - track = open ('default.track') - - for rowIndex, row in enumerate (track): - for columnIndex, column in enumerate (row): - if column == '*': - self.roadCones.append (sp.Cone ( - size = (0.07, 0.07, 0.15), - center = (columnIndex / 4 - 8, rowIndex / 2 - 8, 0.15), - color = (1, 0.3, 0), - group = 1 - )) - elif column == "@": - self.startX = columnIndex / 4 - 8 - self.startY = rowIndex / 2 - 8 - self.init = True - - track.close () - - self.lidar = Lidar (120, self.roadCones) - - def display (self): - if self.init: - self.init = False - sp.world.physics.positionX.set (self.startX) - sp.world.physics.positionY.set (self.startY) - - - self.camera ( - position = sp.tEva ((sp.world.physics.positionX + 2, sp.world.physics.positionY, 2)), - focus = sp.tEva ((sp.world.physics.positionX + 0.001, sp.world.physics.positionY, 0)) - ) - ''' - self.camera ( - position = sp.tEva ((0.0000001, 0, 12)), - focus = sp.tEva ((0, 0, 0)) - ) - ''' - - self.floor (parts = lambda: - self.fuselage (position = (sp.world.physics.positionX, sp.world.physics.positionY, 0), rotation = sp.world.physics.attitudeAngle, parts = lambda: - self.cabin (parts = lambda: - self.windowFront () + - self.windowRear () - ) + - - self.wheelFrontLeft ( - wheelAngle = sp.world.physics.midWheelAngle, - slipping = sp.world.physics.slipping, - steeringAngle = sp.world.physics.steeringAngle - ) + - self.wheelFrontRight ( - wheelAngle = sp.world.physics.midWheelAngle, - slipping = sp.world.physics.slipping, - steeringAngle = sp.world.physics.steeringAngle - ) + - - self.wheelRearLeft ( - wheelAngle = sp.world.physics.midWheelAngle, - slipping = sp.world.physics.slipping - ) + - self.wheelRearRight ( - wheelAngle = sp.world.physics.midWheelAngle, - slipping = sp.world.physics.slipping - ) + - - self.fuselageLine () - ) + - - sum (roadCone () for roadCone in self.roadCones) - ) - - try: - self.lidar.scan (self.fuselage.position, self.fuselage.rotation) - except Exception as exception: # Initial check - pass - # print ('Visualisation.display:', exception) - diff --git a/build/lib/simpylc/simulations/car/world.py b/build/lib/simpylc/simulations/car/world.py deleted file mode 100755 index 75bdbcb..0000000 --- a/build/lib/simpylc/simulations/car/world.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp - -import control as ct -import keyboard_pilot as kp -import lidar_pilot as lp -import lidar_pilot_sp as ls -import physics as ps -import visualisation as vs -import timing as tm - -sp.World ( - # ct.Control, - # kp.KeyboardPilot, - lp.LidarPilot, - # ls.LidarPilotSp, - ps.Physics, - vs.Visualisation, - # tm.Timing -) diff --git a/build/lib/simpylc/simulations/oneArmedRobot/control.py b/build/lib/simpylc/simulations/oneArmedRobot/control.py deleted file mode 100644 index b421300..0000000 --- a/build/lib/simpylc/simulations/oneArmedRobot/control.py +++ /dev/null @@ -1,189 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Control (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('movement control') - - self.group ('torso drive control', True) - self.torVoltFac = sp.Register (0.8) - self.torVoltMax = sp.Register (10) - self.torVolt = sp.Register () - self.torEnab = sp.Marker () - - self.group ('torso angle') - self.torAngSet = sp.Register () - self.torAng = sp.Register () - self.torAngOld = sp.Register () - self.torAngDif = sp.Register () - self.torMarg = sp.Register (15) - self.torRound = sp.Marker () - self.torSpeedFac = sp.Register (0.5) - self.torSpeedMax = sp.Register (20) - self.torSpeedSet = sp.Register() - self.torSpeed = sp.Register () - self.torSpeedDif = sp.Register () - - self.group ('general') - self.go = sp.Marker () - - self.group ('upper arm drive control', True) - self.uppVoltFac = sp.Register (0.25) - self.uppVoltMax = sp.Register (10) - self.uppVolt = sp.Register () - self.uppEnab = sp.Marker () - - self.group ('upper arm angle') - self.uppAngSet = sp.Register () - self.uppAng = sp.Register () - self.uppAngOld = sp.Register () - self.uppAngDif = sp.Register () - self.uppMarg = sp.Register (15) - self.uppRound = sp.Marker () - self.uppSpeedFac = sp.Register (0.5) - self.uppSpeedMax = sp.Register (20) - self.uppSpeedSet = sp.Register () - self.uppSpeed = sp.Register () - self.uppSpeedDif = sp.Register () - - self.group ('fore arm drive control', True) - self.forVoltFac = sp.Register (0.25) - self.forVoltMax = sp.Register (10) - self.forVolt = sp.Register () - self.forEnab = sp.Marker () - - self.group ('fore arm angle') - self.forAngSet = sp.Register () - self.forAng = sp.Register () - self.forAngOld = sp.Register () - self.forAngDif = sp.Register () - self.forMarg = sp.Register (15) - self.forRound = sp.Marker () - self.forSpeedFac = sp.Register (0.5) - self.forSpeedMax = sp.Register (20) - self.forSpeedSet = sp.Register () - self.forSpeed = sp.Register () - self.forSpeedDif = sp.Register () - - self.group ('wrist drive control', True) - self.wriVoltFac = sp.Register (0.25) - self.wriVoltMax = sp.Register (10) - self.wriVolt = sp.Register () - self.wriEnab = sp.Marker () - - self.group ('wrist angle') - self.wriAngSet = sp.Register () - self.wriAng = sp.Register () - self.wriAngOld = sp.Register () - self.wriAngDif = sp.Register () - self.wriMarg = sp.Register (3) - self.wriRound = sp.Marker () - self.wriSpeedFac = sp.Register (0.5) - self.wriSpeedMax = sp.Register (20) - self.wriSpeedSet = sp.Register () - self.wriSpeed = sp.Register () - self.wriSpeedDif = sp.Register () - - self.group ('hand and fingers setpoints', True) - self.hanAngSet = sp.Register () - self.hanEnab = sp.Marker () - self.finAngSet = sp.Register () - self.finEnab = sp.Marker () - self.finDelay = sp.Register (1) - self.finTimer = sp.Timer () - self.finLatch = sp.Latch () - - self.group ('sweep time measurement') - self.sweepMin = sp.Register (1000) - self.sweepMax = sp.Register () - self.sweepWatch = sp.Timer () - self.run = sp.Runner () - - def input (self): - self.part ('true angles') - self.torAng.set (sp.world.robot.torAng) - self.uppAng.set (sp.world.robot.uppAng) - self.forAng.set (sp.world.robot.forAng) - self.wriAng.set (sp.world.robot.wriAng) - - def sweep (self): - self.part ('torso') - self.torAngDif.set (self.torAngSet - self.torAng) - self.torRound.mark (sp.abs (self.torAngDif) < self.torMarg) - self.torSpeedSet.set (sp.limit (self.torSpeedFac * self.torAngDif, self.torSpeedMax)) - self.torSpeed.set ((self.torAng - self.torAngOld) / sp.world.period) - self.torSpeedDif.set (self.torSpeedSet - self.torSpeed) - self.torVolt.set (sp.limit (self.torVoltFac * self.torSpeedDif, self.torVoltMax)) - self.torEnab.mark (self.go) - self.torAngOld.set (self.torAng) - - self.part ('upper arm') - self.uppAngDif.set (self.uppAngSet - self.uppAng) - self.uppRound.mark (sp.abs (self.uppAngDif) < self.uppMarg) - self.uppSpeedSet.set (sp.limit (self.uppSpeedFac * self.uppAngDif, self.uppSpeedMax)) - self.uppSpeed.set ((self.uppAng - self.uppAngOld) / sp.world.period) - self.uppSpeedDif.set (self.uppSpeedSet - self.uppSpeed) - self.uppVolt.set (sp.limit (self.uppVoltFac * self.uppSpeedDif, self.uppVoltMax)) - self.uppEnab.mark (self.go and self.torRound) - self.uppAngOld.set (self.uppAng) - - self.part ('fore arm') - self.forAngDif.set (self.forAngSet - self.forAng) - self.forRound.mark (sp.abs (self.forAngDif) < self.forMarg) - self.forSpeedSet.set (sp.limit (self.forSpeedFac * self.forAngDif, self.forSpeedMax)) - self.forSpeed.set ((self.forAng - self.forAngOld) / sp.world.period) - self.forSpeedDif.set (self.forSpeedSet - self.forSpeed) - self.forVolt.set (sp.limit (self.forVoltFac * self.forSpeedDif, self.forVoltMax)) - self.forEnab.mark (self.go and self.torRound and self.uppRound) - self.forAngOld.set (self.forAng) - - self.part ('wrist') - self.wriAngDif.set (self.wriAngSet - self.wriAng) - self.wriRound.mark (sp.abs (self.wriAngDif) < self.wriMarg) - self.wriSpeedSet.set (sp.limit (self.wriSpeedFac * self.wriAngDif, self.wriSpeedMax)) - self.wriSpeed.set ((self.wriAng - self.wriAngOld) / sp.world.period) - self.wriSpeedDif.set (self.wriSpeedSet - self.wriSpeed) - self.wriVolt.set (sp.limit (self.wriVoltFac * self.wriSpeedDif, self.wriVoltMax)) - self.wriEnab.mark (self.go and self.torRound and self.uppRound and self.forRound) - self.wriAngOld.set (self.wriAng) - - self.part ('hand and fingers') - self.hanEnab.mark (self.go and self.torRound and self.uppRound and self.forRound and self.wriRound) - self.finTimer.reset (not self.hanEnab) - self.finEnab.mark (self.finTimer > self.finDelay) - self.finLatch.latch (self.finTimer > 0.01) - - self.part ('sweep time measurement') - self.sweepMin.set (sp.world.period, sp.world.period < self.sweepMin) - self.sweepMax.set (sp.world.period, sp.world.period > self.sweepMax) - self.sweepWatch.reset (self.sweepWatch > 2) - self.sweepMin.set (1000, not self.sweepWatch) - self.sweepMax.set (0, not self.sweepWatch) - diff --git a/build/lib/simpylc/simulations/oneArmedRobot/robot.py b/build/lib/simpylc/simulations/oneArmedRobot/robot.py deleted file mode 100644 index 3566b34..0000000 --- a/build/lib/simpylc/simulations/oneArmedRobot/robot.py +++ /dev/null @@ -1,155 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software./ -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Robot (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('robot physics') - - self.group ('torso electronics', True) - self.torVolt = sp.Register () - self.torEnab = sp.Marker () - self.torGain = sp.Register (2) - self.torMax = sp.Register (20) - - self.group ('torso mechanics') - self.torInert = sp.Register (8) - self.torTorq = sp.Register () - self.torBrake = sp.Marker () - self.torAccel = sp.Register () - self.torSpeed = sp.Register () - self.torAng = sp.Register () - - self.group ('upper arm electronics', True) - self.uppVolt = sp.Register () - self.uppEnab = sp.Marker () - self.uppGain = sp.Register (2) - self.uppMax = sp.Register (20) - - self.group ('upper arm mechanics') - self.uppInert = sp.Register (4) - self.uppTorq = sp.Register () - self.uppBrake = sp.Marker () - self.uppAccel = sp.Register () - self.uppSpeed = sp.Register () - self.uppAng = sp.Register () - - self.group ('fore arm electronics', True) - self.forVolt = sp.Register () - self.forEnab = sp.Marker () - self.forGain = sp.Register (2) - self.forMax = sp.Register (20) - - self.group ('fore arm mechanics') - self.forInert = sp.Register (2) - self.forTorq = sp.Register () - self.forBrake = sp.Marker () - self.forAccel = sp.Register () - self.forSpeed = sp.Register () - self.forAng = sp.Register () - self.forShift = sp.Register () - - self.group ('wrist electronics', True) - self.wriVolt = sp.Register () - self.wriEnab = sp.Marker () - self.wriGain = sp.Register (2) - self.wriMax = sp.Register (20) - - self.group ('wrist mechanics') - self.wriInert = sp.Register (1) - self.wriTorq = sp.Register () - self.wriBrake = sp.Marker () - self.wriAccel = sp.Register () - self.wriSpeed = sp.Register () - self.wriAng = sp.Register () - - self.group ('hand and finger servos', True) - self.hanAngSet = sp.Register () - self.hanAng = sp.Register () - self.hanEnab = sp.Marker () - self.finAngSet = sp.Register () - self.finAng = sp.Register () - self.finEnab = sp.Marker () - - def input (self): - self.part ('torso') - self.torVolt.set (sp.world.control.torVolt) - self.torEnab.mark (sp.world.control.torEnab) - - self.part ('upper arm') - self.uppVolt.set (sp.world.control.uppVolt) - self.uppEnab.mark (sp.world.control.uppEnab) - - self.part ('fore arm') - self.forVolt.set (sp.world.control.forVolt) - self.forEnab.mark (sp.world.control.forEnab) - - self.part ('wrist') - self.wriVolt.set (sp.world.control.wriVolt) - self.wriEnab.mark (sp.world.control.wriEnab) - - self.part ('hand and fingers') - self.hanAngSet.set (sp.world.control.hanAngSet) - self.hanEnab.mark (sp.world.control.hanEnab) - self.finAngSet.set (sp.world.control.finAngSet) - self.finEnab.mark (sp.world.control.finEnab) - - def sweep (self): - self.part ('Torso') - self.torTorq.set (sp.limit (self.torGain * self.torVolt, self.torMax), self.torEnab, 0) - self.torBrake.mark (not self.torEnab) - self.torAccel.set (self.torSpeed / -sp.world.period, self.torBrake, self.torTorq / self.torInert) - self.torSpeed.set (self.torSpeed + self.torAccel * sp.world.period) - self.torAng.set (self.torAng + self.torSpeed * sp.world.period) - - self.part ('upper arm') - self.uppTorq.set (sp.limit (self.uppGain * self.uppVolt, self.uppMax), self.uppEnab, 0) - self.uppBrake.mark (not self.uppEnab) - self.uppAccel.set (self.uppSpeed / -sp.world.period, self.uppBrake, self.uppTorq / self.uppInert) - self.uppSpeed.set (self.uppSpeed + self.uppAccel * sp.world.period) - self.uppAng.set (self.uppAng + self.uppSpeed * sp.world.period) - - self.part ('fore arm') - self.forTorq.set (sp.limit (self.forGain * self.forVolt, self.forMax), self.forEnab, 0) - self.forBrake.mark (not self.forEnab) - self.forAccel.set (self.forSpeed / -sp.world.period, self.forBrake, self.forTorq / self.forInert) - self.forSpeed.set (self.forSpeed + self.forAccel * sp.world.period) - self.forAng.set (self.forAng + self.forSpeed * sp.world.period) - - self.part ('wrist') - self.wriTorq.set (sp.limit (self.wriGain * self.wriVolt, self.wriMax), self.wriEnab, 0) - self.wriBrake.mark (not self.wriEnab) - self.wriAccel.set (self.wriSpeed / -sp.world.period, self.wriBrake, self.wriTorq / self.wriInert) - self.wriSpeed.set (self.wriSpeed + self.wriAccel * sp.world.period) - self.wriAng.set (self.wriAng + self.wriSpeed * sp.world.period) - - self.part ('hand and fingers') - self.hanAng.set (self.hanAngSet, self.hanEnab) - self.finAng.set (self.finAngSet, self.finEnab) - diff --git a/build/lib/simpylc/simulations/oneArmedRobot/robot_plan.jpg b/build/lib/simpylc/simulations/oneArmedRobot/robot_plan.jpg deleted file mode 100644 index 696058a..0000000 Binary files a/build/lib/simpylc/simulations/oneArmedRobot/robot_plan.jpg and /dev/null differ diff --git a/build/lib/simpylc/simulations/oneArmedRobot/timing.py b/build/lib/simpylc/simulations/oneArmedRobot/timing.py deleted file mode 100644 index 19085f7..0000000 --- a/build/lib/simpylc/simulations/oneArmedRobot/timing.py +++ /dev/null @@ -1,60 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - self.channel (sp.world.robot.torEnab, sp.white) - self.channel (sp.world.robot.torVolt, sp.red, -10, 10, 20) - self.channel (sp.world.robot.torAng, sp.red, -220, 220, 70) - self.channel (sp.world.robot.torBrake, sp.red) - - self.channel (sp.world.robot.uppEnab, sp.white) - self.channel (sp.world.robot.uppVolt, sp.lime, -10, 10, 20) - self.channel (sp.world.robot.uppAng, sp.lime, -110, 110, 35) - self.channel (sp.world.robot.uppBrake, sp.lime) - - self.channel (sp.world.robot.forEnab, sp.white) - self.channel (sp.world.robot.forVolt, sp.blue, -10, 10, 20) - self.channel (sp.world.robot.forAng, sp.blue, -110, 110, 35) - self.channel (sp.world.robot.forBrake, sp.blue) - - self.channel (sp.world.robot.wriEnab, sp.white) - self.channel (sp.world.robot.wriVolt, sp.yellow, -10, 10, 20) - self.channel (sp.world.robot.wriAng, sp.yellow, -110, 110, 35) - self.channel (sp.world.robot.wriBrake, sp.yellow) - - self.channel (sp.world.robot.hanEnab, sp.white) - self.channel (sp.world.robot.hanAng, sp.aqua, -110, 110, 35) - - self.channel (sp.world.robot.finEnab, sp.white) - self.channel (sp.world.robot.finAng, sp.fuchsia, -55, 55, 35) - - diff --git a/build/lib/simpylc/simulations/oneArmedRobot/visualisation.py b/build/lib/simpylc/simulations/oneArmedRobot/visualisation.py deleted file mode 100644 index 5020f61..0000000 --- a/build/lib/simpylc/simulations/oneArmedRobot/visualisation.py +++ /dev/null @@ -1,72 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Visualisation (sp.Scene): - def __init__ (self): - sp.Scene.__init__ (self) - self.base = sp.Cylinder (size = (0.3, 0.3, 0.4), center = (0, 0, 0.2), pivot = (0, 0, 1), color = (1, 1, 0.2)) - self.torso = sp.Beam (size = (0.4, 0.4, 0.6), center = (0, 0, 0.5), pivot = (0, 0, 1), color = (0.5, 0.5, 0.5)) - - armColor = (0.7, 0.7, 0.7) - self.upperArm = sp.Beam (size = (1, 0.2, 0.2), center = (0.4, -0.3, 0.1), joint = (-0.4, 0, 0), pivot = (0, 1, 0), color = armColor) - self.foreArm = sp.Beam (size = (0.7, 0.15, 0.15), center = (0.65, 0.175, 0), joint = (-0.25, 0, 0), pivot = (0, 1, 0), color = armColor) - self.wrist = sp.Beam (size = (0.3, 0.1, 0.1), center = (0.40, -0.125, 0), joint = (-0.05, 0, 0), pivot = (0, 1, 0), color = armColor) - - handColor = (1, 0.01, 0.01) - handSideSize = (0.1, 0.1, 0.1) - self.handCenter = sp.Beam (size = (0.1, 0.09, 0.09), center = (0.15, 0, 0), pivot = (1, 0, 0), color = handColor) - self.handSide0 = sp.Beam (size = handSideSize, center = (0, -0.075, -0.075), color = handColor) - self.handSide1 = sp.Beam (size = handSideSize, center = (0, 0.075, -0.075), color = handColor) - self.handSide2 = sp.Beam (size = handSideSize, center = (0, 0.075, 0.075), color = handColor) - self.handSide3 = sp.Beam (size = handSideSize, center = (0, -0.075, 0.075), color = handColor) - - fingerColor = (0.01, 1, 0.01) - fingerSize = (0.3, 0.05, 0.05) - fingerJoint = (-0.125, 0, 0) - self.finger0 = sp.Beam (size = fingerSize, center = (0.15, 0, -0.1), joint = fingerJoint, pivot = (0, -1, 0), color = fingerColor) - self.finger1 = sp.Beam (size = fingerSize, center = (0.15, 0, 0.1), joint = fingerJoint, pivot = (0, 1, 0), color = fingerColor) - self.finger2 = sp.Beam (size = fingerSize, center = (0.15, -0.1, 0), joint = fingerJoint, pivot = (0, 0, 1), color = fingerColor) - self.finger3 = sp.Beam (size = fingerSize, center = (0.15, 0.1, 0), joint = fingerJoint, pivot = (0, 0, -1), color = fingerColor) - - def display (self): - self.base (parts = lambda: - self.torso (rotation = sp.world.robot.torAng, parts = lambda: - self.upperArm (rotation = sp.world.robot.uppAng, parts = lambda: - self.foreArm (rotation = sp.world.robot.forAng, shift = (sp.world.robot.forShift, 0, 0), parts = lambda: - self.wrist (rotation = sp.world.robot.wriAng, parts = lambda: - self.handCenter (rotation = sp.world.robot.hanAng, parts = lambda: - self.handSide0 () + - self.handSide1 () + - self.handSide2 () + - self.handSide3 () + - self.finger0 (rotation = sp.world.robot.finAng) + - self.finger1 (rotation = sp.world.robot.finAng) + - self.finger2 (rotation = sp.world.robot.finAng) + - self.finger3 (rotation = sp.world.robot.finAng) - ) ) ) ) ) ) - diff --git a/build/lib/simpylc/simulations/oneArmedRobot/world.py b/build/lib/simpylc/simulations/oneArmedRobot/world.py deleted file mode 100644 index 47475f8..0000000 --- a/build/lib/simpylc/simulations/oneArmedRobot/world.py +++ /dev/null @@ -1,40 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp -import robot as rb -import control as ct -import visualisation as vs -import timing as tm - -sp.World (ct.Control, rb.Robot, vs.Visualisation, tm.Timing) diff --git a/build/lib/simpylc/simulations/rocket/common.py b/build/lib/simpylc/simulations/rocket/common.py deleted file mode 100644 index 678be10..0000000 --- a/build/lib/simpylc/simulations/rocket/common.py +++ /dev/null @@ -1,54 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -useQuaternions = True -useGramSchmidt = True # Only matters if useQuaternions == False - -g = 10 - -earthMoonDist = 500 - -earthDiam = 50 -earthMass = 8e7 - -moonDiam = 15 -moonMass = 1e6 - -# Gravity made proportional to r^-0.5 instead of r^-2 to get a more "telling" simulation - -gamma = g * (earthDiam / 2) * (earthDiam / 2) / earthMass - -def getGravVec (mass0, mass1, diam, relPos): - relPos = sp.tEva (relPos) - dist = sp.tNor (relPos) - factor = -1 if dist > diam / 2 else 0.1 - return sp.tsMul (sp.tUni (relPos), factor * gamma * mass0 * mass1 / (dist * dist)) - - - - diff --git a/build/lib/simpylc/simulations/rocket/control.py b/build/lib/simpylc/simulations/rocket/control.py deleted file mode 100644 index e64ebb5..0000000 --- a/build/lib/simpylc/simulations/rocket/control.py +++ /dev/null @@ -1,80 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -class Control (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('rocket control') - - self.group ('gimbal angle controls blue/yellow', True) - self.toYellow = sp.Marker () - self.toBlue = sp.Marker () - - self.group ('gimbal angle state blue/yellow') - self.blueYellowDelta = sp.Register () - self.blueYellowAngle = sp.Register () - - self.group ('thruster angle controls green/red', True) - self.toRed = sp.Marker () - self.toGreen = sp.Marker () - - self.group ('thruster angle state green/red') - self.greenRedDelta = sp.Register () - self.greenRedAngle = sp.Register () - - self.group ('fuel throttle controls', True) - self.throttleOpen = sp.Marker () - self.throttleClose = sp.Marker () - - self.group ('fuel throttle state') - self.throttleDelta = sp.Register () - self.throttlePercent = sp.Register () - - def input (self): - self.part ('gimbal angle blue/yellow') - self.blueYellowAngle.set (sp.world.rocket.blueYellowAngle) - - self.part ('thruster angle green/red') - self.greenRedAngle.set (sp.world.rocket.greenRedAngle) - - self.part ('fuel throttle') - self.throttlePercent.set (sp.world.rocket.throttlePercent) - - def sweep (self): - self.part ('gimbal angle blue/yellow') - self.blueYellowDelta.set (-1 if self.toBlue else 1 if self.toYellow else 0) - - self.part ('thruster angle green/red') - self.greenRedDelta.set (-1 if self.toGreen else 1 if self.toRed else 0) - - self.part ('fuel throttle') - self.throttleDelta.set (-1 if self.throttleClose else 1 if self.throttleOpen else 0) - - - diff --git a/build/lib/simpylc/simulations/rocket/rocket.py b/build/lib/simpylc/simulations/rocket/rocket.py deleted file mode 100644 index a37a27d..0000000 --- a/build/lib/simpylc/simulations/rocket/rocket.py +++ /dev/null @@ -1,324 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software./ -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import numpy as np - -import simpylc as sp - -import common as cm - -import transforms as tf - -# General remarks: -# - The physical reality of precession indicates that rotation matrix cannot be -# found by applying angular acceleration in x, y and z direction successively. -# - To avoid gimbal lock, non-unique Euler angles and numerical instability of -# (modified) Gram Schmidt, the use of quaternions seems the simplest way to go. - -class Rocket (sp.Module): - def __init__ (self): - sp.Module.__init__ (self) - - self.page ('rocket physics') - - self.group ('gimbal angle blue/yellow', True) - self.blueYellowDelta = sp.Register () - self.blueYellowRoughAngle = sp.Register () - self.blueYellowAngle = sp.Register () - - self.group ('thruster angle green/red') - self.greenRedDelta = sp.Register () - self.greenRedRoughAngle = sp.Register () - self.greenRedAngle = sp.Register () - - self.group ('fuel throttle') - self.throttleDelta = sp.Register () - self.throttlePercent = sp.Register () - self.thrust = sp.Register () - - self.group ('ship') - self.shipMass = sp.Register (5000) - self.effectiveRadius = sp.Register (0.15) - self.effectiveHeight = sp.Register (1.5) - self.thrusterTiltSpeed = sp.Register (30) - self.thrusterMaxAngle = sp.Register (90) - self.throttleSpeed = sp.Register (20) - self.thrusterMaxForce = sp.Register (100000) - - self.group ('sweep time measurement') - self.sweepMin = sp.Register (1000) - self.sweepMax = sp.Register () - self.sweepWatch = sp.Timer () - self.run = sp.Runner () - - self.group ('linear accelleration', True) - self.linAccelX = sp.Register () - self.linAccelY = sp.Register () - self.linAccelZ = sp.Register () - - self.group ('linear velocity') - self.linVelocX = sp.Register () - self.linVelocY = sp.Register () - self.linVelocZ = sp.Register () - - self.group ('position') - self.positionX = sp.Register () - self.positionY = sp.Register () - self.positionZ = sp.Register (cm.earthDiam / 2) - - self.group ('thrust in ship frame') - self.forwardThrust = sp.Register () - self.blueYellowThrust = sp.Register () - self.greenRedThrust = sp.Register () - - self.group ('thrust in world frame') - self.thrustX = sp.Register () - self.thrustY = sp.Register () - self.thrustZ = sp.Register () - - self.group ('angular acceleration', True) - self.angAccelX = sp.Register () - self.angAccelY = sp.Register () - self.angAccelZ = sp.Register () - - self.group ('angular velocity') - self.angVelocX = sp.Register () - self.angVelocY = sp.Register () - self.angVelocZ = sp.Register () - - self.group ('torques in ship frame') - self.blueYellowTorque = sp.Register () - self.greenRedTorque = sp.Register () - - self.group ('torques in world frame') - self.torqueX = sp.Register () - self.torqueY = sp.Register () - self.torqueZ = sp.Register () - - if cm.useQuaternions: - self._shipRotQuat = sp.quatFromAxAng (np.array ((1, 0, 0)), 0) - - self.group ('ship rotation quaternion') - self.shipRotQuat0 = sp.Register () - self.shipRotQuat1 = sp.Register () - self.shipRotQuat2 = sp.Register () - self.shipRotQuat3 = sp.Register () - self._shipRotMat = sp.rotMatFromQuat (self._shipRotQuat) - else: - self._shipRotMat = np.array ([ # Columns are tangent (front), normal (up) and binormal (starboard) of ship - [1, 0, 0], - [0, 1, 0], - [0, 0, 1] - ]) - - self.group ('attitude') - self.attitudeX = sp.Register () - self.attitudeY = sp.Register () - self.attitudeZ = sp.Register () - - self.group ('earth gravity', True) - self.distEarthSurf = sp.Register () - self.earthGravX = sp.Register () - self.earthGravY = sp.Register () - self.earthGravZ = sp.Register () - - self.group ('moon gravity') - self.distMoonSurf = sp.Register () - self.moonGravX = sp.Register () - self.moonGravY = sp.Register () - self.moonGravZ = sp.Register () - - self.group ('total force') - self.totalForceX = sp.Register () - self.totalForceY = sp.Register () - self.totalForceZ = sp.Register () - - def input (self): - self.part ('gimbal angle blue/yellow') - self.blueYellowDelta.set (sp.world.control.blueYellowDelta) - - self.part ('thruster angle green/red') - self.greenRedDelta.set (sp.world.control.greenRedDelta) - - self.part ('fuel throttle') - self.throttleDelta.set (sp.world.control.throttleDelta) - - def sweep (self): - self.part ('gimbal angle blue/yellow') - self.blueYellowRoughAngle.set ( - sp.limit ( - self.blueYellowRoughAngle + self.blueYellowDelta * self.thrusterTiltSpeed * sp.world.period, - self.thrusterMaxAngle - ) - ) - self.blueYellowAngle.set (sp.snap (self.blueYellowRoughAngle, 0, 3)) - - self.part ('thruster angle green/red') - self.greenRedRoughAngle.set ( - sp.limit ( - self.greenRedRoughAngle + self.greenRedDelta * self.thrusterTiltSpeed * sp.world.period, - self.thrusterMaxAngle - ) - ) - self.greenRedAngle.set (sp.snap (self.greenRedRoughAngle, 0, 3)) - - self.part ('fuel throttle') - self.throttlePercent.set ( - sp.limit ( - self.throttlePercent + self.throttleDelta * self.throttleSpeed * sp.world.period, - 0, - 100 - ) - ) - self.thrust.set (self.throttlePercent * self.thrusterMaxForce / 100) - - self.part ('linear movement') - - thrusterForceVec = np.array ((0, 0, self.thrust ())) - - if cm.useQuaternions: - thrusterRotQuat = sp.quatMul ( - sp.quatFromAxAng (np.array ((1, 0, 0)), self.blueYellowAngle), - sp.quatFromAxAng (np.array ((0, 1, 0)), -self.greenRedAngle) - ) - shipForceVec = sp.quatVecRot (thrusterRotQuat, thrusterForceVec) - else: - # Local coord sys, so "forward" order - thrusterRotMat = tf.getRotXMat (self.blueYellowAngle) @ tf.getRotYMat (-self.greenRedAngle) - shipForceVec = thrusterRotMat @ thrusterForceVec - - self.forwardThrust.set (shipForceVec [2]) - self.blueYellowThrust.set (shipForceVec [1]) - self.greenRedThrust.set (shipForceVec [0]) - - if cm.useQuaternions: - worldForceVec = sp.quatVecRot (self._shipRotQuat, shipForceVec) - else: - worldForceVec = self._shipRotMat @ shipForceVec - - self.thrustX.set (worldForceVec [0]) - self.thrustY.set (worldForceVec [1]) - self.thrustZ.set (worldForceVec [2]) - - earthGravVec = cm.getGravVec (self.shipMass, cm.earthMass, cm.earthDiam, sp.tEva ((self.positionX, self.positionY, self.positionZ))) - self.earthGravX.set (earthGravVec [0]) - self.earthGravY.set (earthGravVec [1]) - self.earthGravZ.set (earthGravVec [2]) - - moonGravVec = cm.getGravVec (self.shipMass, cm.moonMass, cm.moonDiam, sp.tSub (sp.tEva ((self.positionX, self.positionY, self.positionZ)), (0, 0, cm.earthMoonDist))) - self.moonGravX.set (moonGravVec [0]) - self.moonGravY.set (moonGravVec [1]) - self.moonGravZ.set (moonGravVec [2]) - - self.totalForceX.set (self.thrustX + self.earthGravX + self.moonGravX) - self.totalForceY.set (self.thrustY + self.earthGravY + self.moonGravY) - self.totalForceZ.set (self.thrustZ + self.earthGravZ + self.moonGravZ) - - self.linAccelX.set (self.totalForceX / self.shipMass) - self.linAccelY.set (self.totalForceY / self.shipMass) - self.linAccelZ.set (self.totalForceZ / self.shipMass) - - self.linVelocX.set (self.linVelocX + self.linAccelX * sp.world.period) - self.linVelocY.set (self.linVelocY + self.linAccelY * sp.world.period) - self.linVelocZ.set (self.linVelocZ + self.linAccelZ * sp.world.period) - - self.positionX.set (self.positionX + self.linVelocX * sp.world.period) - self.positionY.set (self.positionY + self.linVelocY * sp.world.period) - self.positionZ.set (self.positionZ + self.linVelocZ * sp.world.period) - - self.part ('angular movement') - - rSq = self.effectiveRadius * self.effectiveRadius - hSq = self.effectiveHeight * self.effectiveHeight - - # Source: https://en.wikipedia.org/wiki/List_of_moments_of_inertia#List_of_3D_inertia_tensors - shipInertMat = self.shipMass () / 12 * np.array ( - ( - ((3 * rSq + hSq) / 12 , 0 , 0 ), - (0 , (3 * rSq + hSq) / 12 , 0 ), - (0 , 0 , rSq / 6) - ) - ) - invInertMat = np.linalg.inv (self._shipRotMat @ shipInertMat @ self._shipRotMat.T) - - self.blueYellowTorque.set (self.blueYellowThrust * self.effectiveHeight / 2) - self.greenRedTorque.set (-self.greenRedThrust * self.effectiveHeight / 2) - shipTorqueVec = np.array ((self.blueYellowTorque (), self.greenRedTorque (), 0)) - - if cm.useQuaternions: - rawTorqueVec = sp.quatVecRot (self._shipRotQuat, shipTorqueVec) - else: - rawTorqueVec = self._shipRotMat @ shipTorqueVec - self.torqueX.set (rawTorqueVec [0]) - self.torqueY.set (rawTorqueVec [1]) - self.torqueZ.set (rawTorqueVec [2]) - torqueVec = np.array ((self.torqueX (), self.torqueY (), self.torqueZ ())) - - rawAngAccelVec = sp.degreesPerRadian * invInertMat @ torqueVec - - self.angAccelX.set (rawAngAccelVec [0]) - self.angAccelY.set (rawAngAccelVec [1]) - self.angAccelZ.set (rawAngAccelVec [2]) - - self.angVelocX.set (self.angVelocX + self.angAccelX * sp.world.period) - self.angVelocY.set (self.angVelocY + self.angAccelY * sp.world.period) - self.angVelocZ.set (self.angVelocZ + self.angAccelZ * sp.world.period) - angVelocVec = sp.radiansPerDegree * np.array ((self.angVelocX (), self.angVelocY (), self.angVelocZ ())) - - # Actual integration over one timestep - # Source: Friendly F# and C++ (fun with game physics), by Dr Giuseppe Maggiore and Dino Dini, May 22, 2014 - if cm.useQuaternions: - # Quaternions are much more numerically stable - self._shipRotQuat = sp.normized (self._shipRotQuat + sp.quatMul (sp.quatFromVec (angVelocVec), self._shipRotQuat) / 2 * sp.world.period ()) - - self.shipRotQuat0.set (self._shipRotQuat [0]) - self.shipRotQuat1.set (self._shipRotQuat [1]) - self.shipRotQuat2.set (self._shipRotQuat [2]) - self.shipRotQuat3.set (self._shipRotQuat [3]) - - self._shipRotQuat [0] = self.shipRotQuat0 () - self._shipRotQuat [1] = self.shipRotQuat1 () - self._shipRotQuat [2] = self.shipRotQuat2 () - self._shipRotQuat [3] = self.shipRotQuat3 () - - self._shipRotMat = sp.rotMatFromQuat (self._shipRotQuat) - else: - # N.B. The rotation matrix cannot be found by applying angular velocity in x, y and z direction successively - self._shipRotMat = self._shipRotMat + np.cross (angVelocVec, self._shipRotMat, axisb = 0, axisc = 0) * sp.world.period () - if cm.useGramSchmidt: - tf.modifiedGramSchmidt (self._shipRotMat) - - rawAttitudeVec = tf.getXyzAngles (self._shipRotMat) - self.attitudeX.set (rawAttitudeVec [0]) - self.attitudeY.set (rawAttitudeVec [1]) - self.attitudeZ.set (rawAttitudeVec [2]) - - self.part ('sweep time measurement') - self.sweepMin.set (sp.world.period, sp.world.period < self.sweepMin) - self.sweepMax.set (sp.world.period, sp.world.period > self.sweepMax) - self.sweepWatch.reset (self.sweepWatch > 2) - self.sweepMin.set (1000, not self.sweepWatch) - diff --git a/build/lib/simpylc/simulations/rocket/thruster_rotation.jpg b/build/lib/simpylc/simulations/rocket/thruster_rotation.jpg deleted file mode 100644 index dd75fdc..0000000 Binary files a/build/lib/simpylc/simulations/rocket/thruster_rotation.jpg and /dev/null differ diff --git a/build/lib/simpylc/simulations/rocket/timing.py b/build/lib/simpylc/simulations/rocket/timing.py deleted file mode 100644 index c5610e1..0000000 --- a/build/lib/simpylc/simulations/rocket/timing.py +++ /dev/null @@ -1,47 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import simpylc as sp - -import common as cm - -class Timing (sp.Chart): - def __init__ (self): - sp.Chart.__init__ (self) - - def define (self): - ''' - if useQuaternions: - self.channel (sp.world.rocket.shipRotQuat0, sp.white, -1, 1, 100) - self.channel (sp.world.rocket.shipRotQuat1, sp.white, -1, 1, 100) - self.channel (sp.world.rocket.shipRotQuat2, sp.white, -1, 1, 100) - self.channel (sp.world.rocket.shipRotQuat3, sp.white, -1, 1, 100) - ''' - - self.channel (sp.world.rocket.attitudeX, sp.red, -180, 180, 100) - self.channel (sp.world.rocket.attitudeY, sp.green, -180, 180, 100) - self.channel (sp.world.rocket.attitudeZ, sp.blue, -180, 180, 100) - diff --git a/build/lib/simpylc/simulations/rocket/transforms.py b/build/lib/simpylc/simulations/rocket/transforms.py deleted file mode 100644 index 4c6baca..0000000 --- a/build/lib/simpylc/simulations/rocket/transforms.py +++ /dev/null @@ -1,99 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import numpy as np - -import simpylc as sp - -# Angles are in degrees, gonio functions are defined accordingly in SimPyLC, -# and will also call evaluate - -def getRotXMat (angleX): - c = sp.cos (angleX) - s = sp.sin (angleX) - return np.array ([ - [1, 0, 0], - [0, c, -s], - [0, s, c] - ]) - -def getRotYMat (angleY): - c = sp.cos (angleY) - s = sp.sin (angleY) - return np.array ([ - [c, 0, s], - [0, 1, 0], - [-s, 0, c] - ]) - -def getRotZMat (angleZ): - c = sp.cos (angleZ) - s = sp.sin (angleZ) - return np.array ([ - [c, -s, 0], - [s, c, 0], - [0, 0, 1] - ]) - -def isClose(x, y): - return abs (x - y) <= 1e-8 + 1e-5 * abs (y) - -def getXyzAngles (rotMat): # rotMat == rotMatZ @ rotMatY @ rotMatX - # Source: Computing Euler angles from a rotation matrix, by Gregory G. Slabaugh - # http://thomasbeatty.com/MATH%20PAGES/ARCHIVES%20-%20NOTES/Applied%20Math/euler%20angles.pdf - angleZ = 0 - if isClose (rotMat [2, 0], -1): - angleY = sp.pi / 2.0 - angleX = sp.atan2 (rotMat [0, 1], rotMat [0, 2]) - elif isClose (rotMat [2, 0], 1): - angleY = -sp.pi / 2 - angleX = sp.atan2 (-rotMat [0, 1], -rotMat [0, 2]) - else: - angleY = -sp.asin (rotMat [2, 0]) - cosAngleY = sp.cos (angleY) - angleX = sp.atan2 (rotMat [2, 1] / cosAngleY, rotMat [2, 2] / cosAngleY) - angleZ = sp.atan2 (rotMat [1, 0] / cosAngleY, rotMat [0, 0] / cosAngleY) - return np.array ([angleX, angleY, angleZ]) - -def modifiedGramSchmidt (rotMat): # Numpy QR factorization can't be used, since it gives a Q with a changed orientation - - # Create references to column vectors - t = rotMat [ : , 0] - n = rotMat [ : , 1] - b = rotMat [ : , 2] - - # Normalize T - t /= np.linalg.norm (t) - - # Remove projection of T from N and normalize - n -= t * np.dot (n, t) - n /= np.linalg.norm (n) - - # Compute B perpendicular to T and N with right orientation - # Remove projection of - b -= t * np.dot (b, t) - b -= n * np.dot (b, n) - b /= np.linalg.norm (b) diff --git a/build/lib/simpylc/simulations/rocket/visualisation.py b/build/lib/simpylc/simulations/rocket/visualisation.py deleted file mode 100644 index d4f56fc..0000000 --- a/build/lib/simpylc/simulations/rocket/visualisation.py +++ /dev/null @@ -1,98 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import random as rd - -import simpylc as sp - -import common as cm - -rd.seed () - -''' - - z - | - o -- y - / - x - -''' - - -class Visualisation (sp.Scene): - def __init__ (self): - sp.Scene.__init__ (self) - - self.camera = sp.Camera () - - self.earth = sp.Ellipsoid (size = 3 * (cm.earthDiam,), center = (0, 0, 0), color = (0, 0, 0.9)) - self.moon = sp.Ellipsoid (size = 3 * (cm.moonDiam,), center = (0, 0, cm.earthMoonDist), color = (0.6, 0.6, 0.6)) - - self.body = sp.Cylinder (size = (0.3, 0.3, 1), center = (0, 0, 0.85 + 0.4), pivot = (0, 0, 1), color = (1, 1, 0.2)) - self.nose = sp.Cone (size = (0.3, 0.3, 0.5), center = (0, 0, 0.75), color = (1, 1, 0.2)) - self.bracket = sp.Cylinder (size = (0.1, 0.1, 0.1), center = (0, 0, -0.55), color = (1, 1, 0.2)) - self.gimbal = sp.Ellipsoid (size = 3 * (0.12,), center = (0, 0, -0.05), pivot = (1, 0, 0), color = (1, 1, 0.2)) - self.thruster = sp.Cone (size = (0.2, 0.2, 0.3), pivot = (0, -1, 0), center = (0, 0, -0.09), joint = (0, 0, 0.09), color = (1, 1, 0.2)) # See thruster_rotation.jpg for pivot - # Center at -(0.3/2 - 0.12/2) - self.flame = sp.Cone (size = (0.1, 0.1, 1), center = (0, 0, -0.65), joint = (0, 0, 0.5), axis = (0, 1, 0), angle = 180, color = (1, 0.7, 0)) - self.tankRed = sp.Ellipsoid (size = 3 * (0.1,), center = (0.16, 0, 0), color = (1, 0, 0)) - self.tankGreen = sp.Ellipsoid (size = 3 * (0.1,), center = (-0.16, 0, 0), color = (0, 1, 0)) - self.tankYellow = sp.Ellipsoid (size = 3 * (0.1,), center = (0, 0.16, 0), color = (1, 1, 0)) - self.tankBlue = sp.Ellipsoid (size = 3 * (0.1,), center = (0, -0.16, 0), color = (0, 0, 1)) - - def display (self): - self.camera ( - position = sp.tEva ((sp.world.rocket.positionX + 4, sp.world.rocket.positionY, sp.world.rocket.positionZ)), - focus = sp.tEva ((sp.world.rocket.positionX, sp.world.rocket.positionY, sp.world.rocket.positionZ + 1.5)) - ) - - self.earth () - self.moon () - - self.body ( - position = sp.tEva ((sp.world.rocket.positionX, sp.world.rocket.positionY, sp.world.rocket.positionZ)), - attitude = sp.world.rocket._shipRotMat, - parts = lambda: - self.nose () + - self.bracket ( - parts = lambda: - self.tankGreen () + - self.tankRed () + - self.tankBlue () + - self.tankYellow () + - self.gimbal ( - rotation = sp.world.rocket.blueYellowAngle, - parts = lambda: - self.thruster ( - rotation = sp.world.rocket.greenRedAngle, - parts = lambda: - self.flame ( - scale = sp.tsMul ((1, 1, 1), - sp.world.rocket.thrust / sp.world.rocket.thrusterMaxForce * (0.9 + 0.1 * rd.random ())), - color = (1, 0.3 + 0.7 * rd.random (), 0)) - ) ) ) ) - diff --git a/build/lib/simpylc/simulations/rocket/world.py b/build/lib/simpylc/simulations/rocket/world.py deleted file mode 100644 index 02918ab..0000000 --- a/build/lib/simpylc/simulations/rocket/world.py +++ /dev/null @@ -1,40 +0,0 @@ -#! /usr/bin/python - -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicence. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicence for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your licence. -# - -import os -import sys as ss - -ss.path.append (os.path.abspath ('../..')) # If you want to store your simulations somewhere else, put SimPyLC in your PYTHONPATH environment variable - -import simpylc as sp -import rocket as rk -import control as ct -import visualisation as vs -import timing as tm - -sp.World (rk.Rocket, ct.Control, vs.Visualisation, tm.Timing) diff --git a/build/lib/simpylc/vectors.py b/build/lib/simpylc/vectors.py deleted file mode 100644 index 5d69b1a..0000000 --- a/build/lib/simpylc/vectors.py +++ /dev/null @@ -1,88 +0,0 @@ -# ====== Legal notices -# -# Copyright (C) 2013 - 2020 GEATEC engineering -# -# This program is free software. -# You can use, redistribute and/or modify it, but only under the terms stated in the QQuickLicense. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the QQuickLicense for details. -# -# The QQuickLicense can be accessed at: http://www.qquick.org/license.html -# -# __________________________________________________________________________ -# -# -# THIS PROGRAM IS FUNDAMENTALLY UNSUITABLE FOR CONTROLLING REAL SYSTEMS !! -# -# __________________________________________________________________________ -# -# It is meant for training purposes only. -# -# Removing this header ends your license. -# - -from numpy import * - -#from .engine import * - -# 3D vectors - -def vEva (v): - return (evaluate (v [0]), evaluate (v [1]), evaluate (v [2])) - -def vNeg (v): - return (-v [0], -v [1], -v [2]) - -def vAdd (v0, v1): - return (v0 [0] + v1 [0], v0 [1] + v1 [1], v0 [2] + v1 [2]) - -def vSub (v0, v1): - return (v0 [0] - v1 [0], v0 [1] - v1 [1], v0 [2] - v1 [2]) - -def vMul (v0, v1): - return (x [0] * v [0], x [1] * v [1], x [2] * v [2]) - -def vsMul (v, x): - return (v [0] * x, v [1] * x, v [2] * x) - -def vDiv (v0, v1): - return (v0 [0] / v1 [0], v0 [1] / v1 [1], v0 [2] / v1 [2]) - -def vsDiv (v, x): - return (v [0] / x, v [1] / x, v [2] / x) - -def vNor (v): - return sqrt (v [0] * v [0] + v [1] * v[1] + v [2] * v [2]) - -def vUni (v): - return divide (v, tNor (v)) - -def vIpr (v0, v1): - return v0 [0] * v1 [0] + v0 [1] * v1 [1] + v0 [2] * v1 [2] - -def vOpr (v0, v1): - return ( - v0 [1] * v1 [2] - v0 [2] * v1 [1], - v0 [2] * v1 [0] - v0 [0] * v1 [2], - v0 [0] * v1 [1] - v0 [1] * v1 [0] - ) - -# Square matrices - -''' -def mInv (m): - return invert (array (m)) .tolist () -''' - -def msMul (m, s): - return (array (m) * s) .tolist () - -def mMul (m0, m1): - return matmul (array (m0), array (m1)) .tolist () - -def mTra (m): - return transpose (array (m)) .tolist () - diff --git a/setup.py b/setup.py index b942b04..faaabb2 100644 --- a/setup.py +++ b/setup.py @@ -16,14 +16,18 @@ def read (*paths): read ('README.rst') + '\n\n' + read ('qQuickLicense.txt') ), - keywords = ['PLC', 'Arduino','simulator', 'SimPyLC', 'emulator', 'GEATEC', 'opy', 'eden'], + keywords = ['PLC', 'Arduino','simulator', 'SimPyLC', 'emulator', 'GEATEC'], url = 'http://www.qquick.org/educational', license = 'qQuickLicence', author = 'Jacques de Hooge', author_email = 'jacques.de.hooge@qquick.org', packages = ['simpylc'], include_package_data = True, - install_requires = ['numpy', 'pyopengl'], + install_requires = [ + 'numpy', + 'pyopengl', + 'windows-curses; platform_system == "Windows"' + ], entry_points = {}, classifiers = [ 'Development Status :: 5 - Production/Stable', @@ -33,6 +37,7 @@ def read (*paths): 'Topic :: Software Development :: Libraries :: Python Modules', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX :: Linux', + 'Operating System :: MacOS', 'Programming Language :: Python :: 3.8', ], ) diff --git a/simpylc/.~lock.simpylc_howto.odt# b/simpylc/.~lock.simpylc_howto.odt# index a19d30a..46eb3ed 100644 --- a/simpylc/.~lock.simpylc_howto.odt# +++ b/simpylc/.~lock.simpylc_howto.odt# @@ -1 +1 @@ -,jac,jac-pc,04.10.2020 20:43,file:///home/jac/.config/libreoffice/4; \ No newline at end of file +,jac,jac-pc,05.10.2020 14:48,file:///home/jac/.config/libreoffice/4; \ No newline at end of file diff --git a/simpylc/__main__.py b/simpylc/__main__.py index 2ff49b3..6ca4f89 100644 --- a/simpylc/__main__.py +++ b/simpylc/__main__.py @@ -31,7 +31,7 @@ simulationsSubdirName = 'simulations' accessoriesSubdirName = 'accessories' -howtoFileName = 'simpylc_howto.html' +howtoFileName = 'simpylc_howto.pdf' class CommandArgs : def __init__ (self): diff --git a/simpylc/accessories/freeglut_32.dll b/simpylc/accessories/freeglut32.vc14.dll similarity index 100% rename from simpylc/accessories/freeglut_32.dll rename to simpylc/accessories/freeglut32.vc14.dll diff --git a/simpylc/accessories/freeglut_64.dll b/simpylc/accessories/freeglut64.vc14.dll similarity index 100% rename from simpylc/accessories/freeglut_64.dll rename to simpylc/accessories/freeglut64.vc14.dll diff --git a/simpylc/base.py b/simpylc/base.py index 8790661..f9315f3 100644 --- a/simpylc/base.py +++ b/simpylc/base.py @@ -29,7 +29,7 @@ from inspect import * programName = 'SimPyLC' -programVersion = '3.8.01' +programVersion = '3.8.04' programNameAndVersion = '{0} {1}'.format (programName, programVersion) programDir = os.getcwd () .replace ('\\', '/') .rsplit ('/', 3) [-1] diff --git a/simpylc/simpylc_howto.odt b/simpylc/simpylc_howto.odt index ebbdc2c..43f73bb 100644 Binary files a/simpylc/simpylc_howto.odt and b/simpylc/simpylc_howto.odt differ diff --git a/simpylc/simpylc_howto.pdf b/simpylc/simpylc_howto.pdf index a798eca..9d360b8 100644 Binary files a/simpylc/simpylc_howto.pdf and b/simpylc/simpylc_howto.pdf differ