forked from vhoulbreque/ironcar
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
212 lines (147 loc) · 5.68 KB
/
main.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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import socket
import json
from flask import Flask, render_template, send_file, jsonify
from app import app, socketio
from ironcar import *
with open(CONFIG) as json_file:
config = json.load(json_file)
MODELS_PATH = config['models_path']
# ------- WEB PAGES --------
@app.route('/')
def main():
"""Switches to the `Main` tab on the dashboard"""
models = []
if os.path.isdir(MODELS_PATH):
models = [os.path.join(MODELS_PATH, f) for f in os.listdir(MODELS_PATH) if f.endswith('.hdf5')]
print('SERVER : models : ', models)
return render_template('index.html', models=models)
@app.route('/commands')
def commands():
"""Switches to `Commands` tab on the dashboard"""
commands = ironcar.commands
print('SERVER : commands : ', commands)
return render_template('commands.html', commands=commands)
@app.route('/help')
def help():
"""Switches to `Help` tab on the dashboard"""
return render_template('help.html')
@app.route('/picture')
def picture():
"""Takes a picture, saves it, and sends it to the client"""
path_picture = ironcar.picture()
print('path_picture : ', path_picture)
if path_picture:
r = send_file(path_picture, as_attachment=True)
r.headers["Pragma"] = "no-cache"
r.headers["Expires"] = "0"
r.headers['Cache-Control'] = 'public, max-age=0'
return r
return None
@app.route('/car_state')
def mode_update():
"""Sends the state of the car"""
print('Sending the current state of the car')
all_state = dict()
all_state['mode'] = ironcar.mode
all_state['speed_mode'] = ironcar.speed_mode
all_state['started'] = ironcar.started
all_state['current_model'] = ironcar.current_model
all_state['max_speed_rate'] = ironcar.max_speed_rate
all_state['commands'] = ironcar.commands
return jsonify(all_state)
# ------- SOCKETS ----------
@socketio.on('mode_update')
def mode_update(mode):
"""Changes the driving mode of the car"""
print('SERVER : mode switch from {} to {}'.format(ironcar.mode, mode))
ironcar.switch_mode(mode)
@socketio.on('model_update')
def model_update(model):
"""Changes the machine learning model used by the car"""
print('SERVER : model update: ' + model)
ironcar.select_model(model)
@socketio.on('starter')
def handle_starter(value):
"""Starts/stops the car"""
if value is None:
value = not ironcar.started
print('SERVER : starter switch from {} to {}'.format(ironcar.started, value))
ironcar.started = value
socketio.emit('starter_switch', {'activated': ironcar.started}, namespace='/car')
@socketio.on('speed_mode_update')
def speed_mode_update(speed_mode):
"""Lets the user selects the speed mode"""
print('SERVER : speed mode received: ' + str(speed_mode))
ironcar.switch_speed_mode(speed_mode)
msg = 'Changed the speed mode to {}'.format(speed_mode)
socketio.emit('msg2user', {'type': 'success', 'msg': msg}, namespace='/car')
@socketio.on('max_speed_update')
def update_max_speed(speed):
"""Lets the user defines a max speed for the car"""
print('SERVER : max speed update received: ' + str(speed))
ironcar.max_speed_update(speed)
socketio.emit('max_speed_update_callback', {
'speed': ironcar.max_speed_rate}, namespace='/car')
@socketio.on('gas')
def handle_gas(gas):
"""Sends a gas order for manual mode"""
print('SERVER : gas order: ' + str(gas))
ironcar.on_gas(gas)
@socketio.on('dir')
def handle_dir(direction):
"""Sends a dir order"""
print('SERVER : dir : ' + str(direction))
ironcar.on_dir(direction)
@socketio.on('streaming_starter')
def handle_streaming():
"""To start/stop the streaming mode"""
print('SERVER : streaming switch from {} to {}'.format(ironcar.streaming_state, not ironcar.streaming_state))
ironcar.switch_streaming()
socketio.emit('stream_switch', {'activated': ironcar.streaming_state},
namespace='/car')
@socketio.on('command_update')
def handle_config(data):
"""Handles the changes in the commands of the car and reloads the config
parameters.
"""
command = data['command']
value = data['value']
# Check for wrong inputs
try:
value = int(value)
except Exception as e:
print('`{}` cannot be cast to int'.format(value))
return
# Modify the config file
with open(CONFIG) as json_file:
config = json.load(json_file)
# Save the original config file
base_config = 'base_config.json'
if not os.path.isfile(base_config):
with open(base_config, 'w') as fp:
fp.write(json.dumps(config, indent=4) + '\n')
# Check for wrong command
if command not in config['commands']:
print('The command `{}` is not available in config'.format(command))
return
print('Updating `{}` from {} to {}'.format(command, config['commands'][command], int(value)))
config['commands'][command] = int(value)
with open(CONFIG, 'w') as fp:
fp.write(json.dumps(config, indent=4) + '\n')
# Load the modified config file in ironcar
ironcar.load_config()
if __name__ == '__main__':
# Get the IP of the raspi
try:
ip1 = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")]
ip2 = [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]
IP = (( ip1 or ip2 ) + ["no IP found"])[0]
except:
IP = "no IP found"
PORT = 5000
print('#' * 50)
print('# IRONCAR SERVER')
print('# Go to the url: {}:{}'.format(IP, PORT))
print('#' * 50)
ironcar = Ironcar()
socketio.run(app, host='0.0.0.0')