Difference between revisions of "Cannon - Code"
From RoboWiki
m |
|||
Line 4: | Line 4: | ||
<syntaxhighlight lang=python> | <syntaxhighlight lang=python> | ||
− | from buildhat import Motor | + | import cv2 |
+ | import numpy as np | ||
+ | import pytesseract | ||
+ | from buildhat import Motor, ForceSensor | ||
import time | import time | ||
+ | import re | ||
+ | import serial | ||
import app | import app | ||
− | |||
− | |||
motor_aim = None | motor_aim = None | ||
Line 15: | Line 18: | ||
latest_pitch = None | latest_pitch = None | ||
setup_done = False | setup_done = False | ||
− | |||
ammo = 0 | ammo = 0 | ||
− | # | + | # Serial connection to Arduino |
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1) | ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1) | ||
− | time.sleep(5) # | + | time.sleep(5) # Allow time for serial connection to stabilize |
− | ser.reset_input_buffer() # | + | ser.reset_input_buffer() # Clear input buffer |
Line 33: | Line 35: | ||
def read_serial(): | def read_serial(): | ||
global latest_pitch | global latest_pitch | ||
− | while | + | while ser.in_waiting > 0: |
− | + | latest_pitch = ser.readline().decode('utf-8').rstrip() | |
− | + | print(latest_pitch) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Line 50: | Line 46: | ||
setup() | setup() | ||
setup_done = True | setup_done = True | ||
+ | |||
+ | read_serial() | ||
if button_id in ['cnn-left', 'cnn-right']: | if button_id in ['cnn-left', 'cnn-right']: | ||
Line 99: | Line 97: | ||
y = pitch_to_y(latest_pitch) | y = pitch_to_y(latest_pitch) | ||
app.draw_rectangle("myCanvas", 15 + (ammo * 100), 360, 25 + (ammo * 100), y) | app.draw_rectangle("myCanvas", 15 + (ammo * 100), 360, 25 + (ammo * 100), y) | ||
− | |||
else: | else: | ||
app.change_label_text('ammo', "Out of ammo!!!") | app.change_label_text('ammo', "Out of ammo!!!") | ||
Line 120: | Line 117: | ||
# Vertical scale lines and numbers | # Vertical scale lines and numbers | ||
− | vertical_steps = [310, 260, 210, 160, 110, 60] | + | vertical_steps = [310, 260, 210, 160, 110, 60] |
for i, y in enumerate(vertical_steps, start=1): | for i, y in enumerate(vertical_steps, start=1): | ||
− | app.draw_line("myCanvas", 35, y, 45, y) | + | app.draw_line("myCanvas", 35, y, 45, y) |
− | app.add_text("myCanvas", 10, y + 5, str(i * 10)) | + | app.add_text("myCanvas", 10, y + 5, str(i * 10)) |
− | |||
− | |||
Line 131: | Line 126: | ||
app.add_css_file('static/cannon.css') | app.add_css_file('static/cannon.css') | ||
modified_img_src = app.set_img_src_to_camera('/video_feed', 0) | modified_img_src = app.set_img_src_to_camera('/video_feed', 0) | ||
− | app.run_app("templates/ | + | app.run_app("templates/cannon.html") |
− | |||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 18:18, 9 June 2024
Return back to project page: Avalanche Cannon - Jakub Vojtek
Python code for the Avalanche Cannon:
import cv2
import numpy as np
import pytesseract
from buildhat import Motor, ForceSensor
import time
import re
import serial
import app
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 ser.in_waiting > 0:
latest_pitch = ser.readline().decode('utf-8').rstrip()
print(latest_pitch)
@app.button_click_signal.connect
def handle_button_click(sender, button_id):
global setup_done
if not setup_done:
setup()
setup_done = True
read_serial()
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]
for i, y in enumerate(vertical_steps, start=1):
app.draw_line("myCanvas", 35, y, 45, y)
app.add_text("myCanvas", 10, y + 5, str(i * 10))
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/cannon.html")