forked from leenahere/ai-for-ev3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
digit_classifier_v1.py
125 lines (106 loc) · 4.69 KB
/
digit_classifier_v1.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
#!/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 line follower often fails some digits due to their sharp angles
However, this classifier works really well with the trained models and the collected data
!! models and data haven't been trained on number 2 !!
"""
# Import the EV3 library
from ev3dev.auto import *
from time import sleep
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'
def run():
sharp_left = False
sharp_right = False
left_sensor = 0
mid_sensor = 0
right_sensor = 0
left_motor_count = 0
right_motor_count = 0
while not ts.value():
# case: straight line, correct path
if col_left.value() > 40 and col_mid.value() < 10 and col_right.value() > 40:
right_motor.run_forever(speed_sp=80)
left_motor.run_forever(speed_sp=80)
# case: sharp left-hand turn ahead, assure that robot doesn't hang up while turning with boolean
elif col_left.value() < 10 and col_mid.value() < 10 and col_right.value() > 40:
right_motor.run_forever(speed_sp=100)
left_motor.run_forever(speed_sp=-100)
sharp_left = True
# case: sharp right-hand turn ahead, assure that robot doesn't hang up while turning with boolean
elif col_left.value() > 40 and col_mid.value() < 10 and col_right.value() < 10:
right_motor.run_forever(speed_sp=-100)
left_motor.run_forever(speed_sp=100)
sharp_right = True
# case: robot is a little off, ensure right path through slight correction to the right
elif col_left.value() < 40 and col_mid.value() < 10 and col_right.value() > 40:
right_motor.run_forever(speed_sp=80)
left_motor.run_forever(speed_sp=10)
# case: robot is a little off, ensure right path through slight correction to the left
elif col_left.value() > 40 and col_mid.value() < 10 and col_right.value() < 40:
right_motor.run_forever(speed_sp=10)
left_motor.run_forever(speed_sp=80)
# case: left-hand turn ahead
elif col_left.value() > 40 and col_mid.value() > 10 and col_right.value() < 40:
right_motor.run_forever(speed_sp=-100)
left_motor.run_forever(speed_sp=100)
# case: right-hand turn ahead
elif col_left.value() < 40 and col_mid.value() > 10 and col_right.value() > 40:
right_motor.run_forever(speed_sp=100)
left_motor.run_forever(speed_sp=-100)
# cases: assure that sharp turn is correctly driven
elif col_left.value() < 10 and col_mid.value() < 10 and col_right.value() < 10 and sharp_left:
right_motor.run_forever(speed_sp=100)
left_motor.run_forever(speed_sp=-100)
sharp_left = False
elif col_left.value() < 10 and col_mid.value() < 10 and col_right.value() < 10 and sharp_right:
right_motor.run_forever(speed_sp=-100)
left_motor.run_forever(speed_sp=100)
sharp_right = False
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
sleep(0.1)
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 / 533
mid_sensor = mid_sensor / 533
right_sensor = right_sensor / 533
left_motor_count = left_motor_count / 533
right_motor_count = right_motor_count / 533
X_new = [[left_sensor, mid_sensor, right_sensor, left_motor_count, right_motor_count]]
# Load model
loaded_model = pickle.load(open('./digit_models/trained_model.sav', 'rb'))
loaded_scaler = pickle.load(open('./digit_models/mlp_scaler.pkl', 'rb'))
# Apply scaler
X_new = loaded_scaler.transform(X_new)
# Classify new data
y_new = loaded_model.predict(X_new)
print(str(y_new[0]))
Sound.speak(str(y_new[0]))
run()