|
| 1 | +#------------------------------------------------------------------------------- |
| 2 | +# SPDX-License-Identifier: MIT |
| 3 | +# |
| 4 | +# Copyright (c) 2025 SparkFun Electronics |
| 5 | +#------------------------------------------------------------------------------- |
| 6 | +# ex01_touch_drive.py |
| 7 | +# |
| 8 | +# This example creates a simple touch screen interface to drive the XRP robot. |
| 9 | +# It creates arrow buttons to drive around, and a stop button to exit the |
| 10 | +# example. The XRP is available from SparkFun: |
| 11 | +# https://www.sparkfun.com/experiential-robotics-platform-xrp-kit.html |
| 12 | +#------------------------------------------------------------------------------- |
| 13 | + |
| 14 | +# Import XRPLib defaults |
| 15 | +from XRPLib.defaults import * |
| 16 | + |
| 17 | +# Import OpenCV and hardware initialization module |
| 18 | +import cv2 as cv |
| 19 | +from cv2_hardware_init import * |
| 20 | + |
| 21 | +# Import NumPy |
| 22 | +from ulab import numpy as np |
| 23 | + |
| 24 | +# Initialize arrow button image |
| 25 | +btn_arrow_shape = (50, 50, 3) |
| 26 | +btn_arrow_cx = btn_arrow_shape[1] // 2 |
| 27 | +btn_arrow_cy = btn_arrow_shape[0] // 2 |
| 28 | +btn_arrow_length = 30 |
| 29 | +btn_arrow_thickness = 5 |
| 30 | +btn_arrow_tip_length = 0.5 |
| 31 | +btn_arrow_offset = 75 |
| 32 | +img_btn_arrow_vertical = np.zeros(btn_arrow_shape, dtype=np.uint8) |
| 33 | +img_btn_arrow_vertical[:, :] = (255, 0, 0) |
| 34 | +img_btn_arrow_horizontal = img_btn_arrow_vertical.copy() |
| 35 | +img_btn_arrow_vertical = cv.arrowedLine( |
| 36 | + img_btn_arrow_vertical, |
| 37 | + (btn_arrow_cx, btn_arrow_cy + btn_arrow_length // 2), |
| 38 | + (btn_arrow_cx, btn_arrow_cy - btn_arrow_length // 2), |
| 39 | + (255, 255, 255), |
| 40 | + btn_arrow_thickness, |
| 41 | + cv.FILLED, |
| 42 | + 0, |
| 43 | + btn_arrow_tip_length |
| 44 | +) |
| 45 | +img_btn_arrow_horizontal = cv.arrowedLine( |
| 46 | + img_btn_arrow_horizontal, |
| 47 | + (btn_arrow_cx - btn_arrow_length // 2, btn_arrow_cy), |
| 48 | + (btn_arrow_cx + btn_arrow_length // 2, btn_arrow_cy), |
| 49 | + (255, 255, 255), |
| 50 | + btn_arrow_thickness, |
| 51 | + cv.FILLED, |
| 52 | + 0, |
| 53 | + btn_arrow_tip_length |
| 54 | +) |
| 55 | + |
| 56 | +# Initialize stop button image |
| 57 | +btn_stop_shape = (50, 50, 3) |
| 58 | +btn_stop_cx = btn_stop_shape[1] // 2 |
| 59 | +btn_stop_cy = btn_stop_shape[0] // 2 |
| 60 | +btn_stop_size = 25 |
| 61 | +img_btn_stop = np.zeros(btn_stop_shape, dtype=np.uint8) |
| 62 | +img_btn_stop[:, :] = (0, 0, 255) # Red color |
| 63 | +img_btn_stop = cv.rectangle( |
| 64 | + img_btn_stop, |
| 65 | + (btn_stop_cx - btn_stop_size // 2, btn_stop_cy - btn_stop_size // 2), |
| 66 | + (btn_stop_cx + btn_stop_size // 2, btn_stop_cy + btn_stop_size // 2), |
| 67 | + (255, 255, 255), # White border |
| 68 | + -1 # Fill the rectangle |
| 69 | +) |
| 70 | + |
| 71 | +# Initialize UI image |
| 72 | +ui_img = np.zeros((240, 320, 3), dtype=np.uint8) |
| 73 | +# Draw the stop button in the center |
| 74 | +center_x = ui_img.shape[1] // 2 |
| 75 | +center_y = ui_img.shape[0] // 2 |
| 76 | +ui_img[ |
| 77 | + center_y-btn_stop_cy:center_y+btn_stop_cy, |
| 78 | + center_x-btn_stop_cx:center_x+btn_stop_cx |
| 79 | +] = img_btn_stop |
| 80 | +# Draw the forward arrow above the stop button |
| 81 | +ui_img[ |
| 82 | + center_y-btn_arrow_offset-btn_arrow_cy:center_y-btn_arrow_offset+btn_arrow_cy, |
| 83 | + center_x-btn_arrow_cx:center_x+btn_arrow_cx |
| 84 | +] = img_btn_arrow_vertical |
| 85 | +# Draw the backward arrow below the stop button |
| 86 | +ui_img[ |
| 87 | + center_y+btn_arrow_offset-btn_arrow_cy:center_y+btn_arrow_offset+btn_arrow_cy, |
| 88 | + center_x-btn_arrow_cx:center_x+btn_arrow_cx |
| 89 | +] = img_btn_arrow_vertical[::-1, :, :] # Flip the arrow image vertically |
| 90 | +# Draw the right arrow to the right of the stop button |
| 91 | +ui_img[ |
| 92 | + center_y-btn_arrow_cy:center_y+btn_arrow_cy, |
| 93 | + center_x+btn_arrow_offset-btn_arrow_cx:center_x+btn_arrow_offset+btn_arrow_cx |
| 94 | +] = img_btn_arrow_horizontal |
| 95 | +# Draw the left arrow to the left of the stop button |
| 96 | +ui_img[ |
| 97 | + center_y-btn_arrow_cy:center_y+btn_arrow_cy, |
| 98 | + center_x-btn_arrow_offset-btn_arrow_cx:center_x-btn_arrow_offset+btn_arrow_cx |
| 99 | +] = img_btn_arrow_horizontal[:, ::-1, :] # Flip the arrow image horizontally |
| 100 | + |
| 101 | +# Show the UI image on the display |
| 102 | +cv.imshow(display, ui_img) |
| 103 | + |
| 104 | +# Prompt the user to touch the screen to drive around |
| 105 | +print("Touch the screen to drive around. Press any key to exit.") |
| 106 | + |
| 107 | +# Loop to continuously read touch input and drive around |
| 108 | +while True: |
| 109 | + # Read touch input |
| 110 | + x, y, touch_num = touch_screen.get_touch() |
| 111 | + |
| 112 | + if touch_num > 0: |
| 113 | + # Check if the stop button was pressed |
| 114 | + if (center_x - btn_stop_cx <= x <= center_x + btn_stop_cx and |
| 115 | + center_y - btn_stop_cy <= y <= center_y + btn_stop_cy): |
| 116 | + print("Stop") |
| 117 | + break |
| 118 | + # Check if the forward arrow was pressed |
| 119 | + elif (center_x - btn_arrow_cx <= x <= center_x + btn_arrow_cx and |
| 120 | + center_y - btn_arrow_offset - btn_arrow_cy <= y <= center_y - btn_arrow_offset + btn_arrow_cy): |
| 121 | + print("Forward") |
| 122 | + drivetrain.straight(20, 0.5) |
| 123 | + # Check if the backward arrow was pressed |
| 124 | + elif (center_x - btn_arrow_cx <= x <= center_x + btn_arrow_cx and |
| 125 | + center_y + btn_arrow_offset - btn_arrow_cy <= y <= center_y + btn_arrow_offset + btn_arrow_cy): |
| 126 | + print("Backward") |
| 127 | + drivetrain.straight(-20, 0.5) |
| 128 | + # Check if the right arrow was pressed |
| 129 | + elif (center_y - btn_arrow_cy <= y <= center_y + btn_arrow_cy and |
| 130 | + center_x + btn_arrow_offset - btn_arrow_cx <= x <= center_x + btn_arrow_offset + btn_arrow_cx): |
| 131 | + print("Right") |
| 132 | + drivetrain.turn(-90, 0.5) |
| 133 | + # Check if the left arrow was pressed |
| 134 | + elif (center_y - btn_arrow_cy <= y <= center_y + btn_arrow_cy and |
| 135 | + center_x - btn_arrow_offset - btn_arrow_cx <= x <= center_x - btn_arrow_offset + btn_arrow_cx): |
| 136 | + print("Left") |
| 137 | + drivetrain.turn(90, 0.5) |
| 138 | + |
| 139 | + if cv.waitKey(1) != -1: |
| 140 | + # Exit the loop if any key is pressed |
| 141 | + break |
| 142 | + |
| 143 | +# Clear the display |
| 144 | +display.clear() |
0 commit comments