-
Notifications
You must be signed in to change notification settings - Fork 0
/
drive.py
executable file
·185 lines (156 loc) · 5.47 KB
/
drive.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env python
# ----------------------------------------------------------------------
# Numenta Platform for Intelligent Computing (NuPIC)
# Copyright (C) 2013, Numenta, Inc. Unless you have purchased from
# Numenta, Inc. a separate commercial license for this software code, the
# following terms and conditions apply:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# 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 GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses.
#
# http://numenta.org/licenses/
# ----------------------------------------------------------------------
"""A simple client to create a CLA model for the ski game."""
import time
import os
import RPi.GPIO as GPIO
import sys
import logging
import csv
from nupic.frameworks.opf.modelfactory import ModelFactory
from nupic.data.inference_shifter import InferenceShifter
import description
# set up pins for the a2d chip
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
# set up the SPI interface pins
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
# assign our photo cells measurement ports
PHOTO_RIGHT = 0
PHOTO_LEFT = 1
# assign port for controlling the car
GO_FORWARD = 4
TURN_LEFT = 22
TURN_RIGHT = 17
GPIO.setup(GO_FORWARD, GPIO.OUT)
GPIO.setup(TURN_LEFT, GPIO.OUT)
GPIO.setup(TURN_RIGHT, GPIO.OUT)
#-----------------------------------------------------------------------------
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
# photo cells are on 0, 1
#-----------------------------------------------------------------------------
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
GPIO.output(clockpin, False) # start clock low
GPIO.output(cspin, False) # bring CS low
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
for i in range(12):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, True)
adcout >>= 1 # first bit is 'null' so drop it
return adcout
#-----------------------------------------------------------------------------
# nupic functions
#-----------------------------------------------------------------------------
def createModel():
return ModelFactory.create(description.config)
def drive():
global PHOTO_RIGHT
global PHOTO_LEFT
global TURN_RIGHT
global TURN_LEFT
global GO_FORWARD
global SPICLK
global SPIMOSI
global SPIMISO
global SPICS
model = createModel()
model.enableInference({'predictionSteps': [1], 'predictedField': 'left'})
inf_shift = InferenceShifter();
# - Test stearing
print "================================= Stearing Test =================================="
print
GPIO.output(TURN_LEFT, True)
GPIO.output(TURN_RIGHT, False)
time.sleep(1)
GPIO.output(TURN_LEFT, False)
GPIO.output(TURN_RIGHT, True)
time.sleep(1)
GPIO.output(TURN_LEFT, False)
GPIO.output(TURN_RIGHT, False)
# - Then set it free to run on it's own
print "================================= Start Driving =================================="
print
try:
while True:
# read the sensors
left = readadc(PHOTO_LEFT, SPICLK, SPIMOSI, SPIMISO, SPICS)
right = readadc(PHOTO_RIGHT, SPICLK, SPIMOSI, SPIMISO, SPICS)
record = {'left': left, 'right': right}
result = inf_shift.shift(model.run(record))
# make driving decision
diff = left - right
if abs(diff > 10) and (left > right):
# turn left
GPIO.output(TURN_LEFT, True)
GPIO.output(TURN_RIGHT, False)
elif abs(diff > 10) and (right > left):
# turn right
GPIO.output(TURN_LEFT, False)
GPIO.output(TURN_RIGHT, True)
else:
# go straight
GPIO.output(TURN_LEFT, False)
GPIO.output(TURN_RIGHT, False)
# check anomaly score for speed
anomalyScore = result.inferences['anomalyScore']
if anomalyScore > 0.8:
# stop and wait for system to learn new light pattern
GPIO.output(GO_FORWARD, False)
else:
# proceed
GPIO.output(GO_FORWARD, True)
except:
print "================================= Stopping Car ==================================="
print
finally:
# shut everything down
GPIO.output(GO_FORWARD, False)
GPIO.output(TURN_LEFT, False)
GPIO.output(TURN_RIGHT, False)
if __name__ == "__main__":
drive()