10
0

add code loading feature

This commit is contained in:
Silver Kuusik 2019-02-10 21:07:38 +01:00
parent e1dd5ad89a
commit bea1220d8a
3 changed files with 99 additions and 50 deletions

View File

@ -2,7 +2,7 @@
"status_led_pin": 22, "status_led_pin": 22,
"battery_coeff": 2.25, "battery_coeff": 2.25,
"sumo_id": "xxxxxxxx", "sumo_id": "xxxxxxxx",
"firmware_version": "0.3.3", "firmware_version": "0.4.0",
"left_servo_tuning": 33, "left_servo_tuning": 33,
"right_servo_tuning": 33, "right_servo_tuning": 33,
"ultrasonic_distance": 40, "ultrasonic_distance": 40,

58
hal.py
View File

@ -31,6 +31,8 @@ class Sumorobot(object):
self.pwm_left = PWM(Pin(15), freq=50, duty=0) self.pwm_left = PWM(Pin(15), freq=50, duty=0)
self.pwm_right = PWM(Pin(4), freq=50, duty=0) self.pwm_right = PWM(Pin(4), freq=50, duty=0)
# LED sensor feedback
self.sensor_feedback = True
# Bottom status LED # Bottom status LED
self.status_led = Pin(self.config["status_led_pin"], Pin.OUT) self.status_led = Pin(self.config["status_led_pin"], Pin.OUT)
# Bottom status LED is in reverse polarity # Bottom status LED is in reverse polarity
@ -40,6 +42,17 @@ class Sumorobot(object):
self.left_line_led = Pin(17, Pin.OUT) self.left_line_led = Pin(17, Pin.OUT)
self.right_line_led = Pin(12, Pin.OUT) self.right_line_led = Pin(12, Pin.OUT)
# Scope with sensor data
self.sensor_scope = dict()
# WiFi connection
self.is_wifi_connected = False
# Python and Blockly code
self.python_code = ""
self.blockly_code = ""
self.compiled_python_code = ""
# Battery gauge # Battery gauge
self.bat_status = 4.3 self.bat_status = 4.3
self.move_counter = 0 self.move_counter = 0
@ -151,9 +164,9 @@ class Sumorobot(object):
with open("config.part", "w") as config_file: with open("config.part", "w") as config_file:
config_file.write(ujson.dumps(self.config)) config_file.write(ujson.dumps(self.config))
os.rename("config.part", "config.json") os.rename("config.part", "config.json")
# Function to update line threshold calibration and write it to the config file # Function to update line threshold calibration and write it to the config file
def calibrate_line_threshold(self, value): def set_line_threshold(self, value):
# Read the line sensor values # Read the line sensor values
self.config["left_line_threshold"] = value self.config["left_line_threshold"] = value
self.config["right_line_threshold"] = value self.config["right_line_threshold"] = value
@ -257,6 +270,47 @@ class Sumorobot(object):
self.set_servo(LEFT, -100) self.set_servo(LEFT, -100)
self.set_servo(RIGHT, 100) self.set_servo(RIGHT, 100)
def update_sensor_feedback(self):
if self.sensor_feedback:
# Execute to see LED feedback for sensors
self.is_opponent()
self.is_line(LEFT)
self.is_line(RIGHT)
def update_sensor_scope(self):
self.sensor_scope = dict(
left_line = self.get_line(LEFT),
right_line = self.get_line(RIGHT),
opponent = self.get_opponent_distance(),
battery_voltage = self.get_battery_voltage()
)
def get_python_code(self):
return dict(
type = "python_code",
val = self.python_code
)
def get_blockly_code(self):
return dict(
type = "blockly_code",
val = self.blockly_code
)
def get_sensor_scope(self):
temp = self.sensor_scope
temp['type'] = "sensor_scope"
return temp
def get_line_scope(self):
return dict(
type = "line_scope",
left_line_value = self.config["left_line_value"],
right_line_value = self.config["right_line_value"],
left_line_threshold = self.config["left_line_threshold"],
right_line_threshold = self.config["right_line_threshold"]
)
def sleep(self, delay): def sleep(self, delay):
# Check for valid delay # Check for valid delay
assert delay > 0 assert delay > 0

89
main.py
View File

@ -2,33 +2,15 @@ import _thread
import ubinascii import ubinascii
import uwebsockets import uwebsockets
# Code to execute
ast = ""
# Scope, info to be sent to the client
scope = dict()
def step(): def step():
global scope
while True: while True:
# Execute to see LED feedback for sensors # Execute to see LED feedback for sensors
sumorobot.is_opponent() sumorobot.update_sensor_feedback()
sumorobot.is_line(LEFT) # Update sensor scope
sumorobot.is_line(RIGHT) sumorobot.update_sensor_scope()
# Update scope # Try to execute the Python code
scope = dict(
left_line = sumorobot.get_line(LEFT),
right_line = sumorobot.get_line(RIGHT),
opponent = sumorobot.get_opponent_distance(),
battery_voltage = sumorobot.get_battery_voltage(),
left_line_value = sumorobot.config["left_line_value"],
right_line_value = sumorobot.config["right_line_value"],
left_line_threshold = sumorobot.config["left_line_threshold"],
right_line_threshold = sumorobot.config["right_line_threshold"]
)
# Execute code
try: try:
exec(ast) exec(sumorobot.compiled_python_code)
except: except:
pass pass
# When robot was stopped # When robot was stopped
@ -41,19 +23,16 @@ def step():
sleep_ms(50) sleep_ms(50)
def ws_handler(): def ws_handler():
global ast
global has_wifi_connection
while True: while True:
# When WiFi has just been reconnected # When WiFi has just been reconnected
if wlan.isconnected() and not has_wifi_connection: if wlan.isconnected() and not sumorobot.is_wifi_connected:
#conn = uwebsockets.connect(url) #conn = uwebsockets.connect(url)
sumorobot.set_led(STATUS, True) sumorobot.set_led(STATUS, True)
has_wifi_connection = True sumorobot.is_wifi_connected = True
# When WiFi has just been disconnected # When WiFi has just been disconnected
elif not wlan.isconnected() and has_wifi_connection: elif not wlan.isconnected() and sumorobot.is_wifi_connected:
sumorobot.set_led(STATUS, False) sumorobot.set_led(STATUS, False)
has_wifi_connection = False sumorobot.is_wifi_connected = False
elif not wlan.isconnected(): elif not wlan.isconnected():
# Continue to wait for a WiFi connection # Continue to wait for a WiFi connection
continue continue
@ -69,36 +48,50 @@ def ws_handler():
# Continue to receive data # Continue to receive data
continue continue
elif b'forward' in data: elif b'forward' in data:
ast = "" sumorobot.compiled_python_code = ""
sumorobot.move(FORWARD) sumorobot.move(FORWARD)
elif b'backward' in data: elif b'backward' in data:
ast = "" sumorobot.compiled_python_code = ""
sumorobot.move(BACKWARD) sumorobot.move(BACKWARD)
elif b'right' in data: elif b'right' in data:
ast = "" sumorobot.compiled_python_code = ""
sumorobot.move(RIGHT) sumorobot.move(RIGHT)
elif b'left' in data: elif b'left' in data:
ast = "" sumorobot.compiled_python_code = ""
sumorobot.move(LEFT) sumorobot.move(LEFT)
elif b'ping' in data:
conn.send(repr(scope).replace("'", '"'))
elif b'code' in data:
data = ujson.loads(data)
data['val'] = data['val'].replace(";;", "\n")
#print("main.py code=", data['val'])
ast = compile(data['val'], "snippet", "exec")
elif b'stop' in data: elif b'stop' in data:
ast = "" sumorobot.compiled_python_code = ""
sumorobot.move(STOP) sumorobot.move(STOP)
# for terminating delays in code # for terminating delays in code
sumorobot.terminate = True sumorobot.terminate = True
elif b'get_line_scope' in data:
conn.send(ujson.dumps(sumorobot.get_line_scope()))
elif b'get_sensor_scope' in data:
conn.send(ujson.dumps(sumorobot.get_sensor_scope()))
elif b'get_python_code' in data:
print(sumorobot.get_python_code())
conn.send(ujson.dumps(sumorobot.get_python_code()))
elif b'get_blockly_code' in data:
print(sumorobot.get_blockly_code())
conn.send(ujson.dumps(sumorobot.get_blockly_code()))
elif b'set_blockly_code' in data:
data = ujson.loads(data)
print(data)
sumorobot.blockly_code = data['val']
elif b'set_python_code' in data:
data = ujson.loads(data)
print(data)
sumorobot.python_code = data['val']
data['val'] = data['val'].replace(";;", "\n")
#print("main.py code=", data['val'])
sumorobot.compiled_python_code = compile(data['val'], "snippet", "exec")
elif b'calibrate_line_value' in data: elif b'calibrate_line_value' in data:
sumorobot.calibrate_line_value() sumorobot.calibrate_line_value()
#print('main.py: calibrate_line_value') #print('main.py: calibrate_line_value')
elif b'calibrate_line_threshold' in data: elif b'set_line_threshold' in data:
data = ujson.loads(data) data = ujson.loads(data)
sumorobot.calibrate_line_threshold(int(data['val'])) sumorobot.set_line_threshold(int(data['val']))
#print('main.py: calibrate_line_threshold') #print('main.py: set_line_threshold')
elif b'Gone' in data: elif b'Gone' in data:
print("main.py: server said 410 Gone, attempting to reconnect...") print("main.py: server said 410 Gone, attempting to reconnect...")
#conn = uwebsockets.connect(url) #conn = uwebsockets.connect(url)
@ -108,7 +101,9 @@ def ws_handler():
# Try to load the user code # Try to load the user code
try: try:
with open("code.py", "r") as code: with open("code.py", "r") as code:
ast = compile(code.read(), "snippet", "exec") temp = code.read()
sumorobot.python_code = temp
sumorobot.compiled_python_code = compile(temp, "snippet", "exec")
except: except:
print("main.py: error loading code.py file") print("main.py: error loading code.py file")
@ -130,7 +125,7 @@ conn.settimeout(1)
timer.deinit() timer.deinit()
# WiFi is connected # WiFi is connected
has_wifi_connection = True sumorobot.is_wifi_connected = True
# Indicate that the WebSocket is connected # Indicate that the WebSocket is connected
sumorobot.set_led(STATUS, True) sumorobot.set_led(STATUS, True)