add code loading feature
This commit is contained in:
parent
e1dd5ad89a
commit
bea1220d8a
@ -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
58
hal.py
@ -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
89
main.py
@ -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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user