-
Notifications
You must be signed in to change notification settings - Fork 0
/
bikecomputer.py
145 lines (128 loc) · 5.91 KB
/
bikecomputer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import time
import math
class BikeComputer():
MM_IN_AN_INCH = 25.4
MM_IN_A_MILE = 1609344
MM_IN_A_KILOMETER = 1000000
SECONDS_IN_AN_HOUR = 3600
SECONDS_IN_A_MINUTE = 60
MS_IN_A_SECOND = 1000.0000
displayFormat = 'metric'
displayInterval = 1000 # Update display every 1 second
clicks = 0
tripBegin = 0
lastClick = 0
lastDisplay = 0
hertz = 0.0
displayVelocity = 0.0
velocity = 0.0
avgVelocity = 0.0
maxVelocity = 0.0
distance = 0.0
wheelCircumference = 2136.0
wheelDiameter = 680.0
def __init__(self, displayFormat):
self.displayFormat = displayFormat
self.clicks = 0
self.lastDisplay = int(time.time() * BikeComputer.MS_IN_A_SECOND)
self.lastClick = int(time.time() * BikeComputer.MS_IN_A_SECOND)
self.tripBegin = int(time.time() * BikeComputer.MS_IN_A_SECOND)
self.hertz = 0.0
self.index = 0
self.displayVelocity = 0.0
self.velocity = 0.0
self.avgVelocity = 0.0
self.maxVelocity = 0.0
self.distance = 0.0
self.wheelCircumference = 2136.0 # 700c x 28 according to a Bell cycling computer chart
self.wheelDiameter = self.wheelCircumference / math.pi
def update(self, currentTime, pinState):
# get the delta from our last click
clickDelta = max((currentTime - self.lastClick), 1)
# get the delta from our last display
displayDelta = max((currentTime - self.lastDisplay), 1)
if(pinState == True):
self.clicks += 1
# calculate the instantaneous speed
self.hertz = BikeComputer.MS_IN_A_SECOND / clickDelta
# Velocity = hertz * wheel circumference, in mm/s
self.velocity = (self.hertz * self.wheelCircumference)
self.maxVelocity = max(self.velocity,self.maxVelocity)
# Distance travelled = clicks * wheel circumference, in mm
self.distance = self.clicks * self.wheelCircumference
# Update the last click
self.lastClick = currentTime
else:
# decay the speed. We know that you aren't going fast enough to have done the next click yet
self.hertz = min((BikeComputer.MS_IN_A_SECOND / clickDelta), self.hertz)
self.velocity = self.hertz * self.wheelCircumference
# Distance travelled = clicks * wheel circumference, in mm
self.distance = self.clicks * self.wheelCircumference
# If we haven't updated the display in a while, do that now
if(displayDelta > self.displayInterval):
self.updateDisplayVelocity(currentTime);
self.lastDisplay = currentTime
def updateDisplayVelocity(self,currentTime):
self.displayVelocity = self.velocity
self.avgVelocity = self.distance / (((currentTime-self.tripBegin)+1)/1000.00)
if(self.displayFormat == 'metric' and (self.displayVelocity / BikeComputer.MM_IN_A_KILOMETER * BikeComputer.SECONDS_IN_AN_HOUR) < 1.0):
self.displayVelocity = 0.0
if(self.displayFormat == 'imperial' and (self.displayVelocity / BikeComputer.MM_IN_A_MILE * BikeComputer.SECONDS_IN_AN_HOUR) < 1.0):
self.displayVelocity = 0.0
def getClicks(self):
return str(self.clicks)
def getVelocity(self):
if(self.displayFormat == 'metric'):
return (self.velocity / BikeComputer.MM_IN_A_KILOMETER) * BikeComputer.SECONDS_IN_AN_HOUR
else:
return (self.velocity / BikeComputer.MM_IN_A_MILE) * BikeComputer.SECONDS_IN_AN_HOUR
def getDisplayVelocity(self):
if(self.displayFormat == 'metric'):
return (self.displayVelocity / BikeComputer.MM_IN_A_KILOMETER) * BikeComputer.SECONDS_IN_AN_HOUR
else:
return (self.displayVelocity / BikeComputer.MM_IN_A_MILE) * BikeComputer.SECONDS_IN_AN_HOUR
def getAverageVelocity(self):
if(self.displayFormat == 'metric'):
return (self.avgVelocity / BikeComputer.MM_IN_A_KILOMETER) * BikeComputer.SECONDS_IN_AN_HOUR
else:
return (self.avgVelocity / BikeComputer.MM_IN_A_MILE) * BikeComputer.SECONDS_IN_AN_HOUR
def getMaxVelocity(self):
if(self.displayFormat == 'metric'):
return (self.maxVelocity / BikeComputer.MM_IN_A_KILOMETER) * BikeComputer.SECONDS_IN_AN_HOUR
else:
return (self.maxVelocity / BikeComputer.MM_IN_A_MILE) * BikeComputer.SECONDS_IN_AN_HOUR
def getDistance(self):
if(self.displayFormat == 'metric'):
return (self.distance / BikeComputer.MM_IN_A_KILOMETER)
else:
return (self.distance / BikeComputer.MM_IN_A_MILE)
def getFormattedWheelCircumference(self):
if(self.displayFormat == 'metric'):
return str(self.wheelCircumference) + ' mm'
else:
return str(round(self.wheelCircumference / BikeComputer.MM_IN_AN_INCH,3)) + ' in'
def getFormattedWheelDiameter(self):
if(self.displayFormat == 'metric'):
return str(self.wheelDiameter) + ' mm'
else:
return str(round(self.wheelDiameter / BikeComputer.MM_IN_AN_INCH,3)) + ' in'
def getFormattedVelocity(self):
if(self.displayFormat == 'metric'):
return str(round((self.velocity / BikeComputer.MM_IN_A_KILOMETER) * BikeComputer.SECONDS_IN_AN_HOUR, 1)) + 'kmph'
else:
return str(round((self.velocity / BikeComputer.MM_IN_A_MILE) * BikeComputer.SECONDS_IN_AN_HOUR, 1)) + 'mph'
def getFormattedDisplayVelocity(self):
if(self.displayFormat == 'metric'):
return str(round((self.displayVelocity / BikeComputer.MM_IN_A_KILOMETER) * BikeComputer.SECONDS_IN_AN_HOUR, 1)) + 'kmph'
else:
return str(round((self.displayVelocity / BikeComputer.MM_IN_A_MILE) * BikeComputer.SECONDS_IN_AN_HOUR, 1)) + 'mph'
def getFormattedAvgVelocity(self):
if(self.displayFormat == 'metric'):
return str(round((self.avgVelocity / BikeComputer.MM_IN_A_KILOMETER) * BikeComputer.SECONDS_IN_AN_HOUR, 1)) + 'kmph'
else:
return str(round((self.avgVelocity / BikeComputer.MM_IN_A_MILE) * BikeComputer.SECONDS_IN_AN_HOUR, 1)) + 'mph'
def getFormattedDistance(self):
if(self.displayFormat == 'metric'):
return str(round((self.distance / BikeComputer.MM_IN_A_KILOMETER),1))+'km'
else:
return str(round((self.distance / BikeComputer.MM_IN_A_MILE),3))+'mi'