CiscoTheProot/rpi/antRender.py

177 lines
5.7 KiB
Python
Raw Normal View History

from rgbmatrix import RGBMatrix, RGBMatrixOptions
from Point2D import interpolate_point_pairs, mirror_points, generate_image_from_point_array, generate_point_array_from_image, pair_points
2023-05-29 20:26:00 +02:00
from ProotState import ProotState
2023-05-29 20:23:33 +02:00
import time
import random
from PIL import Image
import paho.mqtt.client as mqtt
import time
import threading
print("start configuring matrix")
startT = curr_time = round(time.time()*1000)
# Configuration for the matrix screens
options = RGBMatrixOptions()
options.rows = 32
options.cols = 64
options.chain_length = 2
options.parallel = 1
options.hardware_mapping = 'regular' # If you have an Adafruit HAT: 'adafruit-hat'
matrix = RGBMatrix(options=options)
endT = curr_time = round(time.time()*1000)
print("configuring matrix took: " + str(endT - startT) + " ms")
# array to hold the blink animation frames
blinkFrameCanvases = []
2023-05-29 20:23:33 +02:00
def interrupt_timer():
global blinkFrameCanvases, matrix
proot_state = ProotState()
while True:
proot_state.update_screen(blinkFrameCanvases, matrix)
time.sleep(0.01)
def random_blinks():
while True:
time.sleep(random.randint(3, 5))
proot_state = ProotState()
if proot_state.get_blinks_frames_ready():
proot_state.blink()
# Create and start screen update interrupts
2023-05-29 20:24:34 +02:00
screen_update_thread = threading.Thread(target=interrupt_timer)
screen_update_thread.start()
# Create and start random blinks interrupts
2023-05-29 20:24:34 +02:00
screen_update_thread = threading.Thread(target=random_blinks)
screen_update_thread.start()
print("start loading images")
2023-05-23 19:51:52 +02:00
startT = curr_time = round(time.time()*1000)
# Loading all images
# TODO looking into storing and loading lists of points
image_left_eye_open = Image.open("faces/eyeLeftOpen.png")
image_left_eye_closed = Image.open("faces/eyeLeftClosed.png")
image_left_nose = Image.open("faces/noseLeft.png")
image_left_mouth = Image.open("faces/mouthLeft.png")
2023-05-23 19:51:52 +02:00
endT = curr_time = round(time.time()*1000)
print("loading images took: " + str(endT - startT) + " ms")
print("start generating pixel array")
2023-05-23 19:51:52 +02:00
startT = curr_time = round(time.time()*1000)
# generate pixel arrays from each image
# TODO ^ storing and loading lists of points will take away this step. (it will require a dedicated script to precompute these)
points_left_eye_open = generate_point_array_from_image(image_left_eye_open)
points_left_eye_closed = generate_point_array_from_image(image_left_eye_closed)
points_left_nose = generate_point_array_from_image(image_left_nose)
points_left_mouth = generate_point_array_from_image(image_left_mouth)
2023-05-23 19:51:52 +02:00
endT = curr_time = round(time.time()*1000)
print("generating pixel array took: " + str(endT - startT) + " ms")
print("start pairing points for one eye")
2023-05-23 19:51:52 +02:00
startT = curr_time = round(time.time()*1000)
#calculate the point pairs between the open and closed left eye
# TODO look into precomputing and storing these animations before runtime
left_eye_blink_pairs = pair_points(points_left_eye_open, points_left_eye_closed)
2023-05-23 19:51:52 +02:00
endT = curr_time = round(time.time()*1000)
print("pairing points for one eye took: " + str(endT - startT) + " ms")
print("start populating matrices for each blink frame")
2023-05-23 19:51:52 +02:00
startT = curr_time = round(time.time()*1000)
# TODO look into the possibility of precomputing and more importantly storing the matrix objects
for alpha in range(0,11):
offscreen_interpolated_canvas = matrix.CreateFrameCanvas()
left_eye = interpolate_point_pairs(left_eye_blink_pairs, alpha/10)
right_eye = mirror_points(left_eye)
nose = points_left_nose + mirror_points(points_left_nose)
mouth = points_left_mouth + mirror_points(points_left_mouth)
face = left_eye + right_eye + nose + mouth
print("start gen image")
startTa = curr_time = round(time.time()*1000)
interpolated_face_image = generate_image_from_point_array(face, 128, 32)
endTa = curr_time = round(time.time()*1000)
print("gen image took: " + str(endTa - startTa) + " ms")
blinkFrameCanvases.append(offscreen_interpolated_canvas)
print("start populating matrices for each blink frame")
startTa = curr_time = round(time.time()*1000)
offscreen_interpolated_canvas.SetImage(interpolated_face_image, unsafe=False)
endTa = curr_time = round(time.time()*1000)
print("populating matrices for each blink frame took: " + str(endTa - startTa) + " ms")
blinkFrameCanvases.append(offscreen_interpolated_canvas)
2023-05-23 19:51:52 +02:00
endT = curr_time = round(time.time()*1000)
print("populating matrices for each blink frame took: " + str(endT - startT) + " ms")
2023-05-29 20:26:00 +02:00
proot_state = ProotState()
2023-05-29 20:23:33 +02:00
proot_state.set_matrix(matrix)
proot_state.set_blinks_frames_ready(True)
proot_state.blink()
# functions called by the MQTT listener
def on_connect(client, userdata, flags, response_code):
print("Connected to MQTT broker with result code " + str(response_code))
client.subscribe("test")
def on_message(client, userdata, message):
print("Received message '" + str(message.payload) + "' on topic '"
+ message.topic + "' with QoS " + str(message.qos))
bean_number = str(message.payload)[12:13]
bean_state = str(message.payload)[6:10]
print("pin number: " + bean_number + " pin state: " + bean_state)
2023-05-29 20:26:00 +02:00
proot_state = ProotState()
proot_state.blink()
proot_state.set_bean(bean_number, bean_state)
# MQTT broker configuration
broker_address = "10.1.13.173" # Replace with your MQTT broker's address
broker_port = 1883
broker_keepalive = 60
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(broker_address, broker_port, broker_keepalive)
client.loop_start()
while True:
2023-05-23 20:58:43 +02:00
# this sleep sets the time between finishing one screen update and the next starting
pass
2023-05-23 20:58:43 +02:00