Cannon - Code
From RoboWiki
Return back to project page: Avalanche Cannon - Jakub Vojtek
Python code for the Avalanche Cannon:
from buildhat import Motor
import time
import app
import serial
import threading
motor_aim = None
motor_lift = None
motor_trigger = None
latest_pitch = None
setup_done = False
ammo = 0
# serial connection to Arduino
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
time.sleep(5) # allow time for serial connection to stabilize
ser.reset_input_buffer() # clear input buffer
def setup():
global motor_aim, motor_lift, motor_trigger
motor_aim = Motor('C')
motor_lift = Motor('D')
motor_trigger = Motor('A')
def read_serial():
global latest_pitch
while True:
if ser.in_waiting > 0:
print(latest_pitch)
latest_pitch = ser.readline().decode('utf-8').rstrip()
serial_thread = threading.Thread(target=read_serial)
serial_thread.daemon = True
serial_thread.start()
@app.button_click_signal.connect
def handle_button_click(sender, button_id):
global setup_done
if not setup_done:
setup()
setup_done = True
if button_id in ['cnn-left', 'cnn-right']:
motor_aim.stop()
elif button_id in ['lower', 'lift']:
motor_lift.stop()
if latest_pitch is not None:
app.change_label_text('angle', latest_pitch)
elif button_id == 'cnn-trigger':
shoot()
elif button_id == 'load-canvas':
canvas_setup()
else:
print("This button has no onClick function")
@app.button_hold_signal.connect
def handle_button_hold(sender, button_id):
global setup_done
if not setup_done:
setup()
setup_done = True
if button_id == 'cnn-left':
motor_aim.start(10)
elif button_id == 'cnn-right':
motor_aim.start(-10)
elif button_id == 'lower':
motor_lift.start(-30)
elif button_id == 'lift':
motor_lift.start(30)
else:
print("This button has no onHold function.")
def pitch_to_y(pitch):
return 360 - (float(pitch) * 5)
def shoot():
global ammo
if ammo < 4:
motor_trigger.run_for_degrees(360)
motor_trigger.run_to_position(0)
ammo += 1
app.change_label_text('ammo', 3 - ammo)
print(latest_pitch)
if latest_pitch is not None:
y = pitch_to_y(latest_pitch)
app.draw_rectangle("myCanvas", 15 + (ammo * 100), 360, 25 + (ammo * 100), y)
else:
app.change_label_text('ammo', "Out of ammo!!!")
def canvas_setup():
print("drawing")
app.draw_line("myCanvas", 20, 360, 380, 360) # x line
app.draw_line("myCanvas", 40, 380, 40, 20) # y line
app.add_text("myCanvas", 5, 355, "shot")
app.add_text("myCanvas", 30, 390, "angle")
# Horizontal scale lines and numbers
app.draw_line("myCanvas", 120, 355, 120, 365)
app.draw_line("myCanvas", 220, 355, 220, 365)
app.draw_line("myCanvas", 320, 355, 320, 365)
app.add_text("myCanvas", 116, 375, "1")
app.add_text("myCanvas", 216, 375, "2")
app.add_text("myCanvas", 316, 375, "3")
# Vertical scale lines and numbers
vertical_steps = [310, 260, 210, 160, 110, 60] # Y positions for 10, 20, 30, 40, 50
for i, y in enumerate(vertical_steps, start=1):
app.draw_line("myCanvas", 35, y, 45, y) # Small horizontal lines
app.add_text("myCanvas", 10, y + 5, str(i * 10)) # Text for 10, 20, 30, 40, 50
if __name__ == '__main__':
app.add_css_file('static/cannon.css')
modified_img_src = app.set_img_src_to_camera('/video_feed', 0)
app.run_app("templates/index.html")