-
Notifications
You must be signed in to change notification settings - Fork 6
/
shapes_classifier.py
129 lines (106 loc) · 4.13 KB
/
shapes_classifier.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
#!/usr/bin/env python3
"""
This line follower can be used to classify digits
To collect train and test data, use the counterpart line follower
This is the better line following algorithm, but:
The trained models and the train and test data in the data folder were collected with the v1 line follower
Therefore, when working with this classifier, it's best to collect your own data with the counterpart line follower v2
"""
# Import the EV3-robot library
from ev3dev.auto import *
import pickle
# Connect motors
left_motor = LargeMotor(OUTPUT_B)
assert left_motor.connected
right_motor = LargeMotor(OUTPUT_C)
assert right_motor.connected
# Connect touch sensor and color sensors
ts = TouchSensor()
assert ts.connected
col_left = ColorSensor('in1')
assert col_left.connected
col_mid = ColorSensor('in2')
assert col_mid.connected
col_right = ColorSensor('in4')
assert col_right.connected
# Change color sensor mode
col_left.mode = 'COL-REFLECT'
col_mid.mode = 'COL-REFLECT'
col_right.mode = 'COL-REFLECT'
screen = Screen()
def run():
left = []
middle = []
right = []
left_sensor = 0
mid_sensor = 0
right_sensor = 0
left_motor_count = 0
right_motor_count = 0
while not ts.value():
# Add sensor values to respective list
left.append(col_left.value())
middle.append(col_mid.value())
right.append(col_right.value())
# As long as the color sensor in the middle is on the black line, the robot should drive straight
if middle[-1] < 10:
right_motor.run_forever(speed_sp=90)
left_motor.run_forever(speed_sp=90)
# Once all three sensors only see white surface, iterate through the right and left sensor list
if left[-1] > 40 and middle[-1] > 40 and right[-1] > 40:
found = False
iterator = -2
while not found:
# Depending on the sensor that last saw the black line, turn right or left
if left[iterator] < 10:
right_motor.run_forever(speed_sp=100)
left_motor.run_forever(speed_sp=-100)
found = True
if right[iterator] < 10:
right_motor.run_forever(speed_sp=-100)
left_motor.run_forever(speed_sp=100)
found = True
iterator -= 1
# Make sure that list index isn't out of range
if abs(iterator) > len(left) or abs(iterator) > len(right):
break
left_sensor += col_left.value()
mid_sensor += col_mid.value()
right_sensor += col_right.value()
left_motor_count += left_motor.speed
right_motor_count += right_motor.speed
left_motor.stop()
right_motor.stop()
# Assure that values are comparable to train and test data by dividing the input by the longest data set from the
# train and test data
# This is kind of hacky and the 533 is specific to the data in the data folder
# You need to alter this when you work with your own data
left_sensor = left_sensor / 1883
mid_sensor = mid_sensor / 1883
right_sensor = right_sensor / 1883
left_motor_count = left_motor_count / 1883
right_motor_count = right_motor_count / 1883
X_new = [[left_sensor, mid_sensor, right_sensor, left_motor_count, right_motor_count]]
# Load model and scaler
loaded_model = pickle.load(open('./binary_models/trained_model.sav', 'rb'))
loaded_scaler = pickle.load(open('./binary_models/mlp_scaler.pkl', 'rb'))
# Apply scaler
X_new = loaded_scaler.transform(X_new)
# Classify new data
y_new = loaded_model.predict(X_new)
if y_new[0] == 0:
screen.clear()
# Screen.draw returns a PIL.ImageDraw handle
screen.draw.line((30, 50, 80, 100))
screen.draw.line((80, 100, 148, 50))
screen.draw.arc((30, 30, 90, 70), 180, 0)
screen.draw.arc((90, 30, 148, 70), 180, 0)
screen.update()
Sound.speak("Heart")
elif y_new[0] == 1:
screen.clear()
lines = [(80,20),(20,100),(158,100)]
screen.draw.polygon(lines)
screen.update()
Sound.speak("Triangle")
run()