Difference between revisions of "Cannon - Code"

From RoboWiki
Jump to: navigation, search
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
import serial
 
import threading
 
  
 
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
+
# Serial connection to Arduino
 
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
 
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
time.sleep(5)  # allow time for serial connection to stabilize
+
time.sleep(5)  # Allow time for serial connection to stabilize
ser.reset_input_buffer()  # clear 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 True:
+
     while ser.in_waiting > 0:
        if ser.in_waiting > 0:
+
        latest_pitch = ser.readline().decode('utf-8').rstrip()
            print(latest_pitch)
+
        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()
 
  
  
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] # Y positions for 10, 20, 30, 40, 50
+
     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) # Small horizontal lines
+
         app.draw_line("myCanvas", 35, y, 45, y)
         app.add_text("myCanvas", 10, y + 5, str(i * 10)) # Text for 10, 20, 30, 40, 50
+
         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/index.html")
+
     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")