Compare View

switch
from
...
to
 
Commits (2)
robots/little_john/telemetry/code/monitor/version1/colours.py
... ... @@ -2,4 +2,4 @@ WHITE = (255, 255, 255, 255)
2 2 BLACK = (0, 0, 0, 255)
3 3 RED = (255, 0, 0, 255)
4 4 GREEN = (0, 255, 0, 255)
5 5 -BLUE = (0, 0, 255, 255)
  6 +BLUE = (0, 0, 255, 255)
6 7 \ No newline at end of file
... ...
robots/little_john/telemetry/code/monitor/version1/getdata.py
... ... @@ -5,18 +5,17 @@
5 5 import logging
6 6 import os
7 7 import time
8   -import serial
9   -
  8 +import math
10 9  
11 10 def getData(starttime, datafeed, testseries, testseries2, fake=False):
12 11 """Check serial port for incoming data"""
13 12 # Note: 'elapsed' is time since last call of this function
14   - # This works, but it might be better for performance to have two
15   - # seperate functions, only one of which is run.
  13 + # This works, but it might be better for performance to have
  14 + # two seperate functions, only one of which is run.
16 15 if fake:
17 16 timefromstart = (time.time()-starttime)
18 17 values = [timefromstart, 100*math.sin(timefromstart)]
19   - # logging.info("Generated test data: " + str(values))
  18 + #logging.info("Generated test data: " + str(values))
20 19 testseries.addpoint(values)
21 20 testseries2.addpoint(values)
22 21 else:
... ... @@ -24,9 +23,9 @@ def getData(starttime, datafeed, testseries, testseries2, fake=False):
24 23 incoming = datafeed.readline()
25 24 except:
26 25 logging.error("Failed to read input data")
27   -
  26 +
28 27 try:
29   - if os == 'Windows':
  28 + if os=='Windows':
30 29 values = incoming.strip().split(b", ")
31 30 else:
32 31 values = incoming.strip()
... ... @@ -34,13 +33,15 @@ def getData(starttime, datafeed, testseries, testseries2, fake=False):
34 33 except:
35 34 logging.error("Failed to parse input data")
36 35 return
37   -
  36 +
38 37 try:
39 38 for n, value in enumerate(values):
40 39 values[n] = float(value)
41 40 except:
42 41 logging.error("Failed to convert input to float")
43 42 return
44   - # logging.info("Recieved data: " + str(values))
  43 + #logging.info("Recieved data: " + str(values))
45 44 testseries.addpoint([time.time()-starttime] + values)
46 45 testseries2.addpoint(values)
  46 +
  47 +
... ...
robots/little_john/telemetry/code/monitor/version1/main.py
... ... @@ -7,15 +7,16 @@
7 7  
8 8 # This code is incomplete, and is missing core features
9 9  
10   -import math
  10 +# import math
11 11 import time
  12 +# import serial
12 13  
13 14 import pyglet
14   -import numpy
  15 +# import numpy
15 16 import os
16 17 import platform
17 18 import sys
18   -import easygui
  19 +# import easygui
19 20 import logging
20 21  
21 22 from serialselect import selectserial
... ... @@ -30,40 +31,40 @@ starttime = time.time()
30 31  
31 32 datafeed = selectserial()
32 33  
33   -if datafeed is None:
  34 +if datafeed == None:
34 35 logging.critical("Failed to open serial port")
35 36 sys.exit()
36 37  
37 38 if platform.system() == 'Windows':
38   - os = 'Windows'
  39 + os='Windows'
39 40 else:
40   - os = 'Other'
  41 + os='Other'
41 42 logging.info('OS = ' + os)
42 43  
43 44  
44 45 testseries = Series(points=150, xauto=True, ylimits=(0, 1024),
45   - title="Data from serial (time)",
46   - xname="Time (s)", yname="ADC output")
  46 + title="Data from serial (time)", xname="Time (s)", yname="ADC output")
47 47 testseries2 = Series(points=150, xlimits=(0, 1024), ylimits=(0, 1024),
48   - title="Data from serial (xy)",
49   - xname="ADC0 output", yname="ADC7 output")
  48 + title="Data from serial (xy)", xname="ADC0 output", yname="ADC7 output")
50 49  
51 50 plots = []
52 51 plots.append(Plot(testseries))
53 52 plots.append(Plot(testseries2))
54 53  
  54 +''' Yes I know these are absurd placeholder names. I'm leaving it like that
  55 +for the moment because I'm not sure if this is really the only (or best) way
  56 +to achive the desired result. clock.schedule_interval takes a function,
  57 +not the result of the function as its argument, so how can you pass arguments
  58 +to it?'''
  59 +
55 60  
56 61 def shrubbery(ni):
57   - """ Yes I know these are absurd placeholder names. I'm leaving it like
58   - that for the moment because I'm not sure if this is really the only
59   - (or best) way to achive the desired result. clock.schedule_interval takes
60   - a function, not the result of the function as its argument, so how can
61   - you pass arguments to it? """
62 62 getData(starttime, datafeed, testseries, testseries2)
63 63  
64 64  
65 65 # Pyglet looks after the main event loop,
66   -# but this ensures that data keeps being read
67   -pyglet.clock.schedule_interval(shrubbery, 0.01)
  66 +# but this ensures that data keeps being read in
  67 +
  68 +pyglet.clock.schedule_interval(shrubbery, 0.1)
68 69  
69 70 pyglet.app.run()
... ...
robots/little_john/telemetry/code/monitor/version1/plot.py
... ... @@ -6,28 +6,26 @@ import pyglet
6 6 import numpy
7 7 import logging
8 8 from colours import *
9   -
  9 +import sys
10 10  
11 11 class Plot(pyglet.window.Window):
12 12 def __init__(self, series):
13 13 """Setup a the details of a plot, and create a corresponding window"""
14 14 pyglet.window.Window.__init__(self, resizable=True)
15 15 self.set_icon(pyglet.image.load('32x32.png'))
16   - self.set_minimum_size(320, 320)
  16 + self.set_minimum_size(320,320)
17 17 self.series = series
18 18 self.font = 'Arkhip'
19   - self.margins = (0.09, 0.08) # Fractions of window size
  19 + self.margins = (0.09, 0.08) # Fractions of window size
20 20 self.lines = (10, 8)
21   - # self.resizable = True
  21 + #self.resizable = True
22 22 self.set_caption(self.series.title)
23 23  
24 24 def on_resize(self, width, height):
25 25 """Handle a resize event from the pyglet event loop"""
26 26 try:
27   - self.bounds = ((int(self.width * self.margins[0]),
28   - int(self.width * (1 - self.margins[0]))),
29   - (int(self.height * self.margins[1]),
30   - int(self.height * (1 - self.margins[1]))))
  27 + self.bounds = ((int(self.width * self.margins[0]), int(self.width * (1 - self.margins[0]))),
  28 + (int(self.height * self.margins[1]), int(self.height * (1 - self.margins[1]))))
31 29 except Exception as e:
32 30 logging.critical(str(e))
33 31 self.close()
... ... @@ -39,6 +37,7 @@ class Plot(pyglet.window.Window):
39 37 # ('AttributeError: 'Plot' object has no attribute 'margins')
40 38 # when started for a second time from the same instance.
41 39 # Interesting. Causes the plot windows to freeze
  40 +
42 41 pyglet.window.Window.on_resize(self, width, height)
43 42  
44 43 def on_draw(self):
... ... @@ -51,56 +50,51 @@ class Plot(pyglet.window.Window):
51 50  
52 51 def drawBackground(self):
53 52 """Draw the graph background, currently a plain colour"""
54   - whitepattern = pyglet.image.SolidColorImagePattern(WHITE)
55   - whitepattern.create_image(self.width, self.height).blit(0, 0)
56   - #pyglet.image.SolidColorImagePattern(WHITE).create_image(self.width, self.height).blit(0, 0)
  53 + pyglet.image.SolidColorImagePattern(WHITE).create_image(
  54 + self.width, self.height).blit(0, 0)
57 55  
58 56 def drawHeading(self):
59   - """Draw a title for the graph (duplicated in the window titlebar"""
  57 + """Draw a title for the graph (duplicated in the window titlebar, if present"""
60 58 heading = pyglet.text.Label(self.series.title, color=BLACK,
61   - font_name=self.font,
62   - font_size=self.height*self.margins[0]*0.5,
63   - x=self.width/2,
64   - y=self.height-(self.margins[1]),
65   - anchor_x='center', anchor_y='top')
  59 + font_name=self.font, font_size=self.height*self.margins[0]*0.5,
  60 + x=self.width/2, y=self.height-(self.margins[1]),
  61 + anchor_x='center', anchor_y='top')
66 62 heading.draw()
67 63  
68 64 def drawLines(self, series):
69   - xscale = float(self.series.xlimits[1]-self.series.xlimits[0] / (self.bounds[0][1]-self.bounds[0][0]))
70   - yscale = float(self.series.ylimits[1]-self.series.ylimits[0] / (self.bounds[1][1]-self.bounds[1][0]))
71   -
  65 + xscale = float(self.series.xlimits[1]-self.series.xlimits[0])/(
  66 + self.bounds[0][1]-self.bounds[0][0])
  67 + yscale = float(self.series.ylimits[1]-self.series.ylimits[0])/(
  68 + self.bounds[1][1]-self.bounds[1][0])
72 69 lmar = int(self.width * self.margins[0])
73 70 rmar = int(self.width * self.margins[1])
74 71 tmar = int(self.height * self.margins[0])
75 72 bmar = int(self.height * self.margins[1])
76   -
  73 +
77 74 pyglet.gl.glLineWidth(2)
78 75  
79   - linecolours = [(255, 0, 0, 255, 0, 0),
80   - (0, 220, 0, 0, 220, 0),
81   - (0, 0, 255, 0, 0, 255)]
82   -
  76 + linecolours = [(255, 0, 0, 255, 0, 0), (0, 220, 0, 0, 220, 0), (0, 0, 255, 0, 0, 255)]
  77 +
83 78 try:
84 79 for m in range(len(series.data[0])-1):
85 80 for n in range(len(series.data) - 1):
86   - x1 = series.data[n][0]-series.xlimits[0]
87   - y1 = series.data[n][m+1]-series.ylimits[0]
88   - x2 = series.data[n+1][0]-series.xlimits[0]
89   - y2 = series.data[n+1][m+1]-series.ylimits[0]
  81 + x1, y1 = series.data[n][0]-series.xlimits[0], series.data[n][m+1]-series.ylimits[0]
  82 + x2, y2 = series.data[n+1][0]-series.xlimits[0], series.data[n+1][m+1]-series.ylimits[0]
90 83 x1 = int((x1/xscale)+lmar)
91 84 y1 = int((y1/yscale)+bmar)
92 85 x2 = int((x2/xscale)+lmar)
93 86 y2 = int((y2/yscale)+bmar)
94 87 pyglet.graphics.draw(2, pyglet.gl.GL_LINES,
95   - ('v2i', (x1, y1, x2, y2)),
96   - ('c3B', linecolours[m]))
  88 + ('v2i', (x1, y1, x2, y2)),
  89 + ('c3B', linecolours[m]))
97 90 except:
98   - logging.error("Failed to plot lines: corrupt/missing data?")
99   -
  91 + logging.error("Failed to plot lines, possibly due to corrupt/missing data. (This happens at startup)")
  92 +
100 93 pyglet.gl.glLineWidth(1)
101 94  
102 95 def drawAxis(self, axis): # axis=0 is x, 1 is y
103   - """Draw gridlines & labels for one axis, specified as an argument"""
  96 + """Draw the gridlines and labels for one axis,
  97 + specified in the last argument"""
104 98 limita = self.bounds[1-axis][1]
105 99 limitb = self.bounds[1-axis][0]
106 100 start = self.bounds[axis][0]
... ... @@ -110,38 +104,31 @@ class Plot(pyglet.window.Window):
110 104 # Using fp arithmetic to avoid intermittent fencepost errors
111 105 pos = int(pos)
112 106 if axis == 0: # x axis, vertical lines
113   - scale = float(self.series.xlimits[1]-self.series.xlimits[0])
114   - scale /= (stop-start)
  107 + scale = float(self.series.xlimits[1]-self.series.xlimits[0])/(
  108 + stop-start)
115 109 tagvalue = ((pos-start) * scale) + self.series.xlimits[0]
116 110 tagtext = str(int(tagvalue))
117   - pyglet.graphics.draw(2, pyglet.gl.GL_LINES,
118   - ('v2i', (pos, limita, pos, limitb)),
119   - ('c3B', (0, 0, 0, 0, 0, 0)))
  111 + pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2i', (pos, limita, pos, limitb)),
  112 + ('c3B', (0, 0, 0, 0, 0, 0)))
120 113 tag = pyglet.text.Label(tagtext, color=BLACK,
121   - font_name=self.font,
122   - font_size=self.tag_size,
  114 + font_name=self.font, font_size=self.tag_size,
123 115 x=pos, y=self.height*self.margins[1],
124 116 anchor_x='left', anchor_y='top')
125 117 axistitle = pyglet.text.Label(self.series.xname, color=BLACK,
126   - font_name=self.font,
127   - font_size=self.tag_size,
128   - x=self.width/2, y=0,
129   - anchor_x='center',
130   - anchor_y='bottom')
  118 + font_name=self.font, font_size=self.tag_size,
  119 + x=self.width/2, y=0,
  120 + anchor_x='center', anchor_y='bottom')
131 121 axistitle.draw()
132 122 if axis == 1: # y axis, horizontal lines
133   - scale = float(self.series.ylimits[1]-self.series.ylimits[0])
134   - scale /= (stop-start)
  123 + scale = float(self.series.ylimits[1]-self.series.ylimits[0])/(
  124 + stop-start)
135 125 tagvalue = ((pos-start) * scale) + self.series.ylimits[0]
136 126 tagtext = str(int(tagvalue))
137   - pyglet.graphics.draw(2, pyglet.gl.GL_LINES,
138   - ('v2i', (limita, pos, limitb, pos)),
139   - ('c3B', (0, 0, 0, 0, 0, 0)))
  127 + pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2i', (limita, pos, limitb, pos)),
  128 + ('c3B', (0, 0, 0, 0, 0, 0)))
140 129 tag = pyglet.text.Label(tagtext, color=BLACK,
141   - font_name=self.font,
142   - font_size=self.tag_size,
143   - x=self.width*self.margins[0]*0.9,
144   - y=pos,
  130 + font_name=self.font, font_size=self.tag_size,
  131 + x=self.width*self.margins[0]*0.9, y=pos,
145 132 anchor_x='right', anchor_y='center')
146 133 axistitle = pyglet.text.Label(self.series.yname, color=BLACK,
147 134 font_name=self.font,
... ... @@ -149,9 +136,9 @@ class Plot(pyglet.window.Window):
149 136 x=0, y=self.height/2,
150 137 anchor_x='center',
151 138 anchor_y='top')
152   - # Set up a new context to avoid confusing the main one
153 139 pyglet.gl.glPushMatrix()
154   - # Tranformation to move label to the right place
  140 + # Set up a new context to avoid confusing the main one
  141 + # Tranformation to rotate label
155 142 pyglet.gl.glTranslatef(self.height//2, self.height//2, 0.0)
156 143 pyglet.gl.glRotatef(90.0, 0.0, 0.0, 1.0)
157 144 # Draw the axis title using the rotated coordinate system
... ...
robots/little_john/telemetry/code/monitor/version1/serialselect.py
... ... @@ -2,29 +2,27 @@
2 2 # Written as a telemetry tool by:
3 3 # The UoN Robot Wars Project, 2018
4 4  
5   -
6 5 def selectserial():
7   - """Cross-platform function to find appropriate serial ports, query the
8   - user if necessary, and open one of them"""
  6 + """Cross-platform function to find appropriate serial ports, query the user if necessary, and open one of them"""
9 7 import platform
10 8 import serial
11 9 import os
12 10 import easygui
13 11 import logging
14   -
  12 +
15 13 devpatterns = ['ttyACM', 'ttyUSB', 'rfcomm']
16 14 targetdevs = []
17   - if platform.system() == 'Windows':
  15 + if platform.system()=='Windows':
18 16 com_ports = ['COM%s' % (i + 1) for i in range(256)]
19 17 for port in com_ports:
20 18 try:
21 19 s = serial.Serial(port)
22 20 s.close()
23 21 targetdevs.append(port)
24   - # Temporarily broadened exception to make this work on uni PCs
25   - except: # (OSError, serial.SerialException):
  22 + # Temporarily broadened exception in attempt to make this work on uni PCs
  23 + except: # (OSError, serial.SerialException):
26 24 pass
27   - os = 'Windows' # may be useful
  25 + os='Windows' #may be useful
28 26 else:
29 27 alldevs = os.listdir("/dev/")
30 28 targetdevs = []
... ... @@ -32,7 +30,7 @@ def selectserial():
32 30 for pattern in devpatterns:
33 31 if pattern in dev:
34 32 targetdevs.append("/dev/" + dev)
35   - os = 'Other' # may be useful
  33 + os='Other' #may be useful
36 34  
37 35 if len(targetdevs) == 0:
38 36 logging.info("No serial device found.")
... ... @@ -44,22 +42,22 @@ def selectserial():
44 42 message = "Please choose a serial port to recieve data through:"
45 43 title = "Found multiple serial ports!"
46 44 serialport = easygui.choicebox(message, title, targetdevs)
47   - if serialport is None:
  45 + if serialport == None:
48 46 logging.info("User cancelled selection dialogue")
49 47 return None
50 48 else:
51 49 logging.info("Only found one likely serial device: " + targetdevs[0])
52 50 serialport = targetdevs[0]
53   -
  51 +
54 52 try:
55 53 datafeed = serial.Serial(
56   - port=serialport,
57   - baudrate=9600,
58   - parity=serial.PARITY_NONE,
59   - stopbits=serial.STOPBITS_ONE,
60   - bytesize=serial.EIGHTBITS,
61   - timeout=1
62   - )
  54 + port=serialport,
  55 + baudrate=9600,
  56 + parity=serial.PARITY_NONE,
  57 + stopbits=serial.STOPBITS_ONE,
  58 + bytesize=serial.EIGHTBITS,
  59 + timeout=1
  60 + )
63 61  
64 62 logging.info("Sucessfully opened " + serialport + " as data source!")
65 63 return datafeed
... ...
robots/little_john/telemetry/code/monitor/version1/series.py
... ... @@ -4,12 +4,10 @@
4 4  
5 5 import logging
6 6  
7   -
8 7 class Series:
9 8 def __init__(self, points=100, xlimits=(0, 100), ylimits=(0, 100),
10 9 xauto=False, yauto=False,
11   - title="Series title",
12   - xname="x-axis name", yname="y-axis name"):
  10 + title="Series title", xname="x-axis name", yname="y-axis name"):
13 11 """Set up an object to store a 2D data series"""
14 12 # Proposal:
15 13 # In order to neatly handle multiple lines on the same graph
... ... @@ -30,9 +28,9 @@ class Series:
30 28 self.points = points
31 29 self.xauto = xauto
32 30 self.yauto = yauto
33   -
  31 +
34 32 logging.info("Created series: " + title)
35   -
  33 +
36 34 def addpoint(self, point):
37 35 """Add a point to the dataset, and remove the oldest, if necessary"""
38 36 self.data.append(point)
... ... @@ -45,15 +43,15 @@ class Series:
45 43 self.autoscale(1)
46 44 except:
47 45 logging.error("Series autoscale failed")
48   -
49   - def autoscale(self, axis): # axis=0 is x, 1 is y
  46 +
  47 + def autoscale(self, axis): # axis=0 is x, 1 is y
50 48 minval = self.data[0][axis]
51 49 maxval = self.data[0][axis]
52 50 for value in self.data:
53 51 if value[axis] < minval:
54 52 minval = value[axis]
55 53 if value[axis] > maxval:
56   - maxval = value[axis]
  54 + maxval = value[axis]
57 55 if axis == 0:
58 56 self.xlimits = (minval, maxval)
59 57 else:
... ...