import ast import math import struct import sys import time import numpy as np import redis from libs3 import gstt, log def pack_point(laser, intensity, x, y, r, g, b, i=-1, u1=0, u2=0, flags=0): """Pack some color values into a struct dac_point.""" # print("Tracer", laser,":", r,g,b,"intensity", intensity, "i", i) if r > intensity: r = intensity if g > intensity: g = intensity if b > intensity: b = intensity if max(r, g, b) == 0: i = 0 else: i = intensity x = int(x) y = int(y) # print("Tracer ", laser, ": packing", x, y, r, g, b, "intensity", intensity, "i", i) if x < -32767: if gstt.debug > 1: log.err("Tracer " + str(laser) + " : x coordinates " + str(x) + " was below -32767") x = -32000 if x > 32767: if gstt.debug > 1: log.err("Tracer " + str(laser) + " : x coordinates " + str(x) + " was bigger than 32767") x = 32000 if y < -32767: if gstt.debug > 1: log.err("Tracer " + str(laser) + " : y coordinates " + str(y) + " was below -32767") y = -32000 if y > 32767: if gstt.debug > 1: log.err("Tracer " + str(laser) + " : y coordinates " + str(y) + " was bigger than 32767") y = 32000 return struct.pack(" by default prev_x = 0 prev_y = 0 black_points = [(278.0, 225.0, 0), (562.0, 279.0, 0), (401.0, 375.0, 0), (296.0, 454.0, 0), (298.0, 165.0, 0)] grid_points = [(300.0, 200.0, 0), (500.0, 200.0, 65280), (500.0, 400.0, 65280), (300.0, 400.0, 65280), (300.0, 200.0, 65280), (300.0, 200.0, 0), (200.0, 100.0, 0), (600.0, 100.0, 65280), (600.0, 500.0, 65280), (200.0, 500.0, 65280), (200.0, 100.0, 65280)] ackstate = {'61': 'ACK', '46': 'FULL', '49': "INVALID", '21': 'STOP', '64': "NO CONNECTION ?", '35': "NO CONNECTION ?", '97': 'ACK', '70': 'FULL', '73': "INVALID", '33': 'STOP', '100': "NOCONNECTION", '48': "NOCONNECTION", 'a': 'ACK', 'F': 'FULL', 'I': "INVALID", '!': 'STOP', 'd': "NO CONNECTION ?", '0': "NO CONNECTION ?"} lstate = {'0': 'IDLE', '1': 'PREPARE', '2': "PLAYING", '3': 'STOP', '64': "NOCONNECTION ?"} """ status : the general status of the DAC, is it working or not? ack_status : DAC specific, sent continuously by the DAC to track activity """ def int_to_rgb(self, c): return ((c >> 16) & 0xFF) << 8, ((c >> 8) & 0xFF) << 8, (c & 0xFF) << 8 def get_status(self): raise Exception("Please override the method") def set_status(self, status: int): raise Exception("Please override the method") def get_warped_point(self, x, y): """ A DAC specific point model, ex EtherPoint or HeliosPoint :param xyc: x,y,color :return: """ raise Exception("Please override the method") # def get_ack_status(self): # raise Exception("Please override the method") # # def set_ack_status(self, ack_status: int): # raise Exception("Please override the method") def prepare(self): raise Exception("Please override the method") def begin(self, n, kpps): raise Exception("Please override the method") def before_loop(self): """ Hook for DAC specific actions on each loop :return: """ raise Exception("Please override the method") def get_points_capacity(self): """ How much points can we send next to the DAC :return: int """ raise Exception("Please override the method") def convert_color(self, c): """ DAC specific color conversion :param c: :return: """ raise Exception("Please override the method") def write(self, points): """ Actual sending to the DAC :param points: a list of points "corrected" with geometry, color, intensity settings :return: """ raise Exception("Please override the method") def play_stream(self): """ Main loop common for every dac driver :return: """ self.before_loop() started = 0 while True: self.redis.set('/lstate/' + str(self.laser_id), self.get_status()) # print("laser", self.laser_id, "Pb : ",self.last_status.playback_state) order = int(self.redis.get('/order/' + str(self.laser_id)).decode('ascii')) # print("tracer", str(self.laser_id),"order", order, type(order) if order == 0: """ 0 : The actual points sending to laser """ # USER point list / # @todo si la clef est vide utiliser les points noirs ? -> syntax error -> black points. try: self.pl = ast.literal_eval(self.redis.get(self.clientkey + str(self.laser_id)).decode('ascii')) # print(self.clientkey + str(self.laser_id)) # print(self.pl) except SyntaxError: print("BAD POINTLIST on Tracer : laser", self.laser_id, " order 0 : pl : ", self.pl) self.pl = self.black_points # print("Tracer : laser", self.laser_id, " order 0 : pl : ",len(self.pl)) else: if order == 1: """ 1 : Get the new EDH / The zoom || trapezoidal / homography settings for the laser """ print("Tracer", self.laser_id, "new EDH ORDER in redis") gstt.EDH[self.laser_id] = np.array( ast.literal_eval(self.redis.get('/EDH/' + str(self.laser_id)).decode('ascii'))) # Back to user point list self.redis.set('/order/' + str(self.laser_id), 0) # if order == 2: """ 2 : Send a BLACK point list """ print("Tracer", self.laser_id, "BLACK ORDER in redis") self.pl = self.black_points if order == 3: """ 3: Send a GRID point list""" print("Tracer", self.laser_id, "GRID ORDER in redis") self.pl = self.grid_points if order == 4: """ 4: Resampler Change, modify the automatic intermediary points settings """ self.resampler = ast.literal_eval( self.redis.get('/resampler/' + str(self.laser_id)).decode('ascii')) print("Tracer", self.laser_id, " : resetting lsteps for", self.resampler) gstt.stepshortline = self.resampler[0] gstt.stepslongline[0] = self.resampler[1] gstt.stepslongline[1] = self.resampler[2] gstt.stepslongline[2] = self.resampler[3] # Back to user point list order self.redis.set('/order/' + str(self.laser_id), 0) if order == 5: """ 5: Client Key change, change the address to read points from in redis ex: /pl/0 => /pl/3""" print("Tracer", self.laser_id, "new clientkey") self.clientkey = self.redis.get('/clientkey') # Back to user point list order self.redis.set('/order/' + str(self.laser_id), 0) if order == 6: """ 6: change intensity """ # @todo check for helios vs etherdream self.intensity = int(self.redis.get('/intensity/' + str(self.laser_id)).decode('ascii')) << 8 print("Tracer", self.laser_id, "new Intensity", self.intensity) gstt.intensity[self.laser_id] = self.intensity self.redis.set('/order/' + str(self.laser_id), "0") if order == 7: """ 7: kpps change""" gstt.kpps[self.laser_id] = int(self.redis.get('/kpps/' + str(self.laser_id)).decode('ascii')) print("Tracer", self.laser_id, "new kpps", gstt.kpps[self.laser_id]) self.update(0, gstt.kpps[self.laser_id]) self.redis.set('/order/' + str(self.laser_id), "0") if order == 8: """ 8: color balance change""" self.intred = int(self.redis.get('/red/' + str(self.laser_id)).decode('ascii')) self.intgreen = int(self.redis.get('/green/' + str(self.laser_id)).decode('ascii')) self.intblue = int(self.redis.get('/blue/' + str(self.laser_id)).decode('ascii')) print("Tracer", self.laser_id, "new color balance", self.intred, "% ", self.intgreen, "% ", self.intblue, "% ") self.redis.set('/order/' + str(self.laser_id), "0") # if getattr(self, "last_status") : # self.redis.set('/lstt/' + str(self.laser_id), self.last_status.playback_state) # pdb.set_trace() # How much room? capacity = self.get_points_capacity() iterator = iter(OnePointIterator(self)) self.redis.set('/cap/' + str(self.laser_id), capacity) points = [next(iterator) for i in range(capacity)] self.write(points) if not started: print("Tracer", self.laser_id, "starting with", gstt.kpps[self.laser_id], "kpps") self.begin(0, gstt.kpps[self.laser_id]) started = 1