-
Notifications
You must be signed in to change notification settings - Fork 36
/
drive.py
112 lines (95 loc) · 3.7 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
import argparse
import base64
import json
import cv2
import numpy as np
import socketio
import eventlet
import eventlet.wsgi
import time
from PIL import Image
from PIL import ImageOps
from flask import Flask, render_template
from io import BytesIO
from keras.models import model_from_json
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array
# Fix error with Keras and TensorFlow
import tensorflow as tf
tf.python.control_flow_ops = tf
# import preprocess from model.py
#from model import preprocess_image
sio = socketio.Server()
app = Flask(__name__)
model = None
prev_image_array = None
def preprocess_image(img):
'''
Method for preprocessing images: this method is the same used in drive.py, except this version uses
BGR to YUV and drive.py uses RGB to YUV (due to using cv2 to read the image here, where drive.py images are
received in RGB)
'''
# original shape: 160x320x3, input shape for neural net: 66x200x3
# crop to 105x320x3
#new_img = img[35:140,:,:]
# crop to 40x320x3
new_img = img[50:140,:,:]
# apply subtle blur
new_img = cv2.GaussianBlur(new_img, (3,3), 0)
# scale to 66x200x3 (same as nVidia)
new_img = cv2.resize(new_img,(200, 66), interpolation = cv2.INTER_AREA)
# scale to ?x?x3
#new_img = cv2.resize(new_img,(80, 10), interpolation = cv2.INTER_AREA)
# convert to YUV color space (as nVidia paper suggests)
####### REMEMBER: IMAGES FROM SIMULATOR COME IN RGB!!!!!! #######
new_img = cv2.cvtColor(new_img, cv2.COLOR_RGB2YUV)
return new_img
@sio.on('telemetry')
def telemetry(sid, data):
# The current steering angle of the car
steering_angle = data["steering_angle"]
# The current throttle of the car
throttle = data["throttle"]
# The current speed of the car
speed = data["speed"]
# The current image from the center camera of the car
imgString = data["image"]
image = Image.open(BytesIO(base64.b64decode(imgString)))
image_array = np.asarray(image)
img = preprocess_image(image_array)
transformed_image_array = img[None, :, :, :]
# This model currently assumes that the features of the model are just the images. Feel free to change this.
steering_angle = float(model.predict(transformed_image_array, batch_size=1))
# The driving model currently just outputs a constant throttle. Feel free to edit this.
throttle = 0.2
if float(speed) < 10:
throttle = 1
send_control(steering_angle, throttle)
@sio.on('connect')
def connect(sid, environ):
print("connect ", sid)
send_control(0, 0)
def send_control(steering_angle, throttle):
sio.emit("steer", data={
'steering_angle': steering_angle.__str__(),
'throttle': throttle.__str__()
}, skip_sid=True)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Remote Driving')
parser.add_argument('model', type=str,
help='Path to model definition json. Model weights should be on the same path.')
args = parser.parse_args()
with open(args.model, 'r') as jfile:
# NOTE: if you saved the file by calling json.dump(model.to_json(), ...)
# then you will have to call:
#
# model = model_from_json(json.loads(jfile.read()))\
#
# instead.
model = model_from_json(jfile.read())
model.compile("adam", "mse")
weights_file = args.model.replace('json', 'h5')
model.load_weights(weights_file)
# wrap Flask application with engineio's middleware
app = socketio.Middleware(sio, app)
# deploy as an eventlet WSGI server
eventlet.wsgi.server(eventlet.listen(('', 4567)), app)