diff --git a/LJ.conf b/LJ.conf index 73181d1..5b2ebba 100644 --- a/LJ.conf +++ b/LJ.conf @@ -1,8 +1,8 @@ [General] -lasernumber = 1 +lasernumber = 4 debug = 0 ljayserverip = 0.0.0.0 -wwwip = 127.0.0.1 +wwwip = 192.168.2.44 nozoscip = 127.0.0.1 bhoroscip = 127.0.0.1 autostart = artnet @@ -12,7 +12,7 @@ wsport = 9001 [laser0] color = -1 type = DS1000 -ip = 127.0.0.1 +ip = 192.168.2.3 kpps = 25000 centerx = 0 centery = 0 @@ -21,7 +21,7 @@ zoomy = 50.0 sizex = 32000 sizey = 32000 finangle = 0.0 -swapx = 1 +swapx = -1 swapy = -1 lsteps = [ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] warpdest = [[-1500., 1500.], @@ -36,8 +36,8 @@ ip = 192.168.2.5 kpps = 25000 centerx = 0 centery = 0 -zoomx = 50.0 -zoomy = 50.0 +zoomx = 80.0 +zoomy = 80.0 sizex = 32000 sizey = 32000 finangle = 0.0 @@ -45,9 +45,9 @@ swapx = -1 swapy = -1 lsteps = [ (1.0, 2),(0.25, 1), (0.75, 1), (1.0, 5)] warpdest = [[-1500., 1500.], - [ 1500., 1500.], - [ 1500.,-1500.], - [-1500.,-1500.]] + [ 1500., 1500.], + [ 1500.,-1500.], + [-1500.,-1500.]] [laser2] color = -1 @@ -65,14 +65,14 @@ swapx = -1 swapy = -1 lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] warpdest = [[-1500., 1500.], - [ 1500., 1500.], - [ 1500.,-1500.], - [-1500.,-1500.]] + [ 1500., 1500.], + [ 1500.,-1500.], + [-1500.,-1500.]] [laser3] color = -1 type = LUKE400 -ip = 192.168.1.5 +ip = 192.168.2.4 kpps = 25000 centerx = 0 centery = 0 @@ -81,19 +81,34 @@ zoomy = 50.0 sizex = 32000 sizey = 32000 finangle = 0.0 -swapx = -1 -swapy = -1 +swapx = 1 +swapy = 1 lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] warpdest = [[-1500., 1500.], - [ 1500., 1500.], - [ 1500.,-1500.], - [-1500.,-1500.]] + [ 1500., 1500.], + [ 1500.,-1500.], + [-1500.,-1500.]] [plugins] plugins = { "aurora": {"OSC": 8090, "command": "python3 plugins/aurora/aurora.py", "display": True}, + "nozoid": {"OSC": 8003, "command": "python3 plugins/audio/nozoids3.py", "display": True}, + "glyph": {"OSC": 8004, "command": "python3 plugins/laserglyph.py", "display": True}, + "planet": {"OSC": 8005, "command": "python3 plugins/planetarium/main.py", "display": True}, + "words": {"OSC": 8006, "command": "python3 plugins/livewords3.py", "display": True}, + "cycl": {"OSC": 8007, "command": "python3 plugins/textcycl.py", "display": True}, + "simu": {"OSC": 8008, "command": "python plugins/pysimu.py", "display": False}, "artnet": {"OSC": 8009, "command": "python3 libs3/artnet.py", "display": False}, + "trckr": {"OSC": 8017, "command": "python3 plugins/trckr.py", "display": False}, + "maxw": {"OSC": 8012, "command": "python3 plugins/maxwell.py", "display": True}, "square": {"OSC": 8013, "command": "python3 plugins/square.py", "display": True}, - "custom1": {"OSC": 8014, "command": "python3 plugins/custom1.py", "display": True} + "custom1": {"OSC": 8014, "command": "python3 plugins/custom1.py", "display": True}, + "mitraille": {"OSC": 8015, "command": "python3 plugins/audio/mitraille.py", "display": True}, + "livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True}, + "ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py", "display": True}, + "ljwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py", "display": True}, + "audiogen": {"OSC": 8030, "command": "python3 plugins/audio/audiogen.py", "display": False}, + "midigen": {"OSC": 8031, "command": "python3 plugins/audio/midigen.py", "display": False}, + "viewgen": {"OSC": 8032, "command": "python3 plugins/audio/viewgen.py", "display": True} } diff --git a/LJ_template.conf b/LJ_template.conf new file mode 100644 index 0000000..002fe4c --- /dev/null +++ b/LJ_template.conf @@ -0,0 +1,114 @@ +[General] +lasernumber = 1 +debug = 0 +ljayserverip = 0.0.0.0 +wwwip = 192.168.2.43 +nozoscip = 127.0.0.1 +bhoroscip = 127.0.0.1 +autostart = artnet +wstype = ws +wsport = 9001 + +[laser0] +color = -1 +type = DS1000 +ip = 192.168.2.3 +kpps = 25000 +centerx = 0 +centery = 0 +zoomx = 50.0 +zoomy = 50.0 +sizex = 32000 +sizey = 32000 +finangle = 0.0 +swapx = 1 +swapy = -1 +lsteps = [ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] +warpdest = [[-1500., 1500.], + [ 1500., 1500.], + [ 1500.,-1500.], + [-1500.,-1500.]] + +[laser1] +color = -1 +type = LOCAL +ip = 192.168.2.5 +kpps = 25000 +centerx = 0 +centery = 0 +zoomx = 50.0 +zoomy = 50.0 +sizex = 32000 +sizey = 32000 +finangle = 0.0 +swapx = -1 +swapy = -1 +lsteps = [ (1.0, 2),(0.25, 1), (0.75, 1), (1.0, 5)] +warpdest = [[-1500., 1500.], + [ 1500., 1500.], + [ 1500.,-1500.], + [-1500.,-1500.]] + +[laser2] +color = -1 +type = LUKE400 +ip = 192.168.2.6 +kpps = 25000 +centerx = 0 +centery = 0 +zoomx = 50.0 +zoomy = 50.0 +sizex = 32000 +sizey = 32000 +finangle = 0.0 +swapx = -1 +swapy = -1 +lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] +warpdest = [[-1500., 1500.], + [ 1500., 1500.], + [ 1500.,-1500.], + [-1500.,-1500.]] + +[laser3] +color = -1 +type = LUKE400 +ip = 192.168.1.5 +kpps = 25000 +centerx = 0 +centery = 0 +zoomx = 50.0 +zoomy = 50.0 +sizex = 32000 +sizey = 32000 +finangle = 0.0 +swapx = -1 +swapy = -1 +lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] +warpdest = [[-1500., 1500.], + [ 1500., 1500.], + [ 1500.,-1500.], + [-1500.,-1500.]] + +[plugins] +plugins = { + "aurora": {"OSC": 8090, "command": "python3 plugins/aurora/aurora.py", "display": True}, + "nozoid": {"OSC": 8003, "command": "python3 plugins/audio/nozoids3.py", "display": True}, + "glyph": {"OSC": 8004, "command": "python3 plugins/laserglyph.py", "display": True}, + "planet": {"OSC": 8005, "command": "python3 plugins/planetarium/main.py", "display": True}, + "words": {"OSC": 8006, "command": "python3 plugins/livewords3.py", "display": True}, + "cycl": {"OSC": 8007, "command": "python3 plugins/textcycl.py", "display": True}, + "simu": {"OSC": 8008, "command": "python plugins/pysimu.py", "display": False}, + "artnet": {"OSC": 8009, "command": "python3 libs3/artnet.py", "display": False}, + "trckr": {"OSC": 8017, "command": "python3 plugins/trckr.py", "display": False}, + "maxw": {"OSC": 8012, "command": "python3 plugins/maxwell.py", "display": True}, + "square": {"OSC": 8013, "command": "python3 plugins/square.py", "display": True}, + "custom1": {"OSC": 8014, "command": "python3 plugins/custom1.py", "display": True}, + "mitraille": {"OSC": 8015, "command": "python3 plugins/audio/mitraille.py", "display": True}, + "livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True}, + "ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py", "display": True}, + "ljwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py", "display": True}, + "audiogen": {"OSC": 8030, "command": "python3 plugins/audio/audiogen.py", "display": False}, + "midigen": {"OSC": 8031, "command": "python3 plugins/audio/midigen.py", "display": False}, + "viewgen": {"OSC": 8032, "command": "python3 plugins/audio/viewgen.py", "display": True} + } + diff --git a/Pd/.DS_Store b/Pd/.DS_Store deleted file mode 100644 index 31a0d67..0000000 Binary files a/Pd/.DS_Store and /dev/null differ diff --git a/Pd/LJsender.pd b/Pd/LJsender.pd deleted file mode 100644 index 82c3bd3..0000000 --- a/Pd/LJsender.pd +++ /dev/null @@ -1,23 +0,0 @@ -#N canvas 468 143 709 527 10; -#X msg 60 237 disconnect; -#X floatatom 27 294 0 0 0 0 - - -; -#X text 22 315 Outlet is nonzero if connection is open \, zero otherwise. -; -#X msg 37 60 send mytext trololo; -#X obj 28 267 netsend 1; -#X msg 51 125 send /pl/0/0 (150 2300 65280) (170 170 65280) (230 170 -65280) (210 230 65280) (150 230 65280); -#X text 258 29 LJ Sender; -#X msg 46 84 send /pl/0/0 150 2300 65280 170 170 65280 230 170 65280 -210 230 65280 150 230 65280; -#X msg 26 39 connect 127.0.0.1 8083; -#X msg 58 165 send /pl/0/0 [(150.0:230.0:65280) (170.0:170.0:65280) -(230.0:170.0:65280) (210.0:230.0:65280) (150.0:230.0:65280)]; -#X text 444 174 <- le mieux; -#X connect 0 0 4 0; -#X connect 3 0 4 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 7 0 4 0; -#X connect 8 0 4 0; -#X connect 9 0 4 0; diff --git a/Pd/ljpd.py b/Pd/ljpd.py deleted file mode 100644 index 67c97d1..0000000 --- a/Pd/ljpd.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# -*- mode: Python -*- - -''' - -LJPD - -Udp server to redis -v0.1b - -''' -import traceback, time -import argparse -import socket -import _thread -import redis - - -print() -print ("LJPD") -print ("Arguments parsing if needed...") -argsparser = argparse.ArgumentParser(description="dumpUDP v0.1b help mode") -argsparser.add_argument("-i","--IP",help="IP to bind to (0.0.0.0 by default)", type=str) -argsparser.add_argument("-p","--port",help="UDP port to bind to (9000 by default)", type=str) -argsparser.add_argument("-l","--lj",help="LJ IP address (127.0.0.1 by default)", type=str) - - -args = argsparser.parse_args() - -# LJ server IP name -if args.IP: - ljIP = lj.IP -else: - ljIP = "127.0.0.1" - -# Server -if args.IP: - serverIP = args.IP -else: - serverIP = "0.0.0.0" - -# ORCA destination device -if args.port: - UDPORT = int(args.port) -else: - UDPORT = 8083 - -print("Connecting to Redis...") - -r = redis.StrictRedis(host= ljIP, port=6379, db=0) - -def GetTime(): - return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()) - - -def udp_thread(): - - while True: - - payload, client_address = sock.recvfrom(1024) - udpath = payload.decode('utf_8') - print(GetTime(),"From", str(client_address),"got", udpath ) - #r.set('/pl/0/0', "/pl/"+str(clientnumber)+"/") - #print(udpath[0:1], " ",udpath[1:2], " ",udpath[2:3], " ",udpath[3:4], " " ) - - - # Reply to client - bytesToSend = str.encode("ACK :"+str(payload)) - serverAddressPort = (client_address, UDPORT) - bufferSize = 1024 - #sock.sendto(bytesToSend, serverAddressPort) - sock.sendto(bytesToSend, client_address) - - - time.sleep(0.005) - - - -def Start(serverIP, UDPORT): - global sock - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - server = ( serverIP,UDPORT) - sock.bind(server) - _thread.start_new_thread(udp_thread, ()) - - - -# Launch server in another thread. -print("Launching UDP Server", serverIP,':', UDPORT) -Start(serverIP, UDPORT) - - -# Do something else -try: - - while True: - time.sleep(0.005) - -except Exception: - traceback.print_exc() - -finally: - print("") - print("ljpd stopped.") \ No newline at end of file diff --git a/README.md b/README.md index 3618c65..e43eebb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -LJ v0.8.2 'fireandforget' +LJ v0.8.2 By Sam Neurohack, Loloster, Cocoa @@ -7,26 +7,17 @@ LICENCE : CC BY ![LJ](https://www.teamlaser.fr/lj/images/lj2.png) -LJ is like a video projector where you fire images and forget. Lasers are dangerous : you can really fire real world objects. - -A software laser framework with webGUI, for up to 4 lasers live actions with ethedreams DACs. Think creative like Laser "battles", planetarium, sharing available lasers in demoparties for competition,... +A software laser framework with GUI, for up to 4 lasers live actions with ethedreams DACs. Think creative like Laser "battles", planetarium, sharing available lasers in demoparties for competition, ... + LJ has 5 main components : -- "Plugins" are "frames" generators to one or more lasers. Frames goes to different possible frames inputs of the "manager". With laser one frame = one polyline, like in LOGO. Lot examples comes with LJ : planetarium, 3D anaglyph animations,... See plugins directory. +- "Plugins" are points generators (to one or more lasers). Lot examples comes with LJ : planetarium, 3D anaglyph animations,... See plugins directory. - A "tracer" per etherdream/laser that take its given point list, correct geometry, recompute in laser controller coordinates, send it to its controller and report its status to the "manager". -- A "manager" that talk to all tracers (which point lists to draw, new geometry correction,...), handle IOs (webui functions, OSC commands,...) and plugins. +- A "manager" that talk to all tracers (which client number point lists to draw, new geometry correction,...), handle IOs (webui functions, OSC commands,...) and plugins. - A web GUI in html, css, and vanilla js. This UI can be used in a tablet, computer, whatever. LJ does not come with an html server but absolutely can . This GUI has a (currently slow) simulator, but one can also use an etherdream/laser emulator (see nannou simulator below) to work without physical lasers !! - A network available database (redis). "Plugins" can send directly their pointlists to redis. Each "tracer" is instructed to get one of the avalaible pointlist in redis. -"Frames" (actually polylines) inputs are : - -- OSC (port 8002) -- Websocket (port 9001) -- Cli pipe (see clitools) -- Redis keys - - Important : for best performance LJ is meant to run in a dedicated computer especially with multiple lasers and highly multitasked load : if you watch video, use live webcam face recognition, webui simulator,... and run LJ on the same computer, well you need a bunch of cores. If you don't, spread the load : you can use webui on a tablet, the livecam on a phone, run pointlists generators on another computer,... # @@ -393,8 +384,6 @@ python3 talk3.py -i etherdreamIP - Switch to simu page. If you don't see anything : check redis server or your points in redis doesn't respect pointlist formatting (see command reference). -- Check Leds : for each IRL lasers the two sets of must be green at startup and laser should display their number or the pointlist you want. - - If talk3 works but you don't see your points : click on the Grid icon in Align page. This will override your pointlist and display squares. If Grid works : recomputed points by tracers are "bad" with given values in LJ.conf. "Bad points" ? @@ -455,6 +444,8 @@ lsteps is a string like "[ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]" /scene/scenenumber/start 0 or 1 : tell all tracers to use given scene +/regen : regen webui index html page. + /scim : change webui simulated laser. diff --git a/clitools/exports/toUDP.py b/clitools/exports/toUDP.py deleted file mode 100644 index 64787db..0000000 --- a/clitools/exports/toUDP.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# -*- mode: Python -*- - - -''' - -toUDP -v0.1.0 - -A basic exporter - -LICENCE : CC - -by cocoa - - -''' -from __future__ import print_function -import sys -import os -import argparse -import time -import socket -import ast - -argsparser = argparse.ArgumentParser(description="toUDP v0.1b help mode") -argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output") -argsparser.add_argument("-i","--ip",help="IP to bind to (0.0.0.0 by default)",default="0.0.0.0",type=str) -argsparser.add_argument("-p","--port",help="UDP port to bind to (9000 by default)",default="9003",type=str) -args = argsparser.parse_args() - -verbose = args.verbose -ip = args.ip -port = int(args.port) -verbose = args.verbose - - -name = "exports::toUDP" - -def debug(*args, **kwargs): - if( verbose == False ): - return - print(*args, file=sys.stderr, **kwargs) - -def ClientStart(ip, port): - global sockclient - - sockclient = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) - -def ClientSend(msgFromClient): - - bytesToSend = str.encode(str(msgFromClient)) - serverAddressPort = (ip, port) - bufferSize = 1024 - - # Send to server using created UDP socket - sockclient.sendto(bytesToSend, serverAddressPort) - - ''' - # If reply : - msgFromServer = sockclient.recvfrom(bufferSize) - - msg = "Message from Server {}".format(msgFromServer[0]) - print(msg) - ''' - -try: - - ClientStart(ip, port) - while True: - - line = sys.stdin.readline() - if line == "": - time.sleep(0.01) - line = line.rstrip('\n') - #pointsList = ast.literal_eval(line) - debug(name,": "+line) - ClientSend(line) - - -except EOFError: - debug("break")# no more information - diff --git a/clitools/filters/kaleidoscope.py b/clitools/filters/kaleidoscope.py index 5ca4396..0495f23 100755 --- a/clitools/filters/kaleidoscope.py +++ b/clitools/filters/kaleidoscope.py @@ -163,7 +163,6 @@ try: # Do the filter result = kaleidoscope( pointsList ) print( result, flush=True ) - looptime = time.time() - start # debug(name+" looptime:"+str(looptime)) if( looptime < optimal_looptime ): diff --git a/clitools/generators/fromOSC.py b/clitools/generators/fromOSC.py deleted file mode 100644 index d8005c5..0000000 --- a/clitools/generators/fromOSC.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# -*- mode: Python -*- - -''' -Forward /pl pointlist to cli - -input OSC in END points format : (x,y,color) -output CLI in CLI points format : [x,y,color] - -/pl "[(150.0, 230.0, 255), (170.0, 170.0, 255), (230.0, 170.0, 255), (210.0, 230.0, 255), (150.0, 230.0, 255)]" - -v0.1.0 - -LICENCE : CC - -by Cocoa, Sam Neurohack - -''' -from __future__ import print_function -from OSC3 import OSCServer, OSCClient, OSCMessage -import sys -from time import sleep -import argparse -import ast - -argsparser = argparse.ArgumentParser(description="fromOSC generator") -argsparser.add_argument("-i","--ip",help="IP to bind to (0.0.0.0 by default)",default="0.0.0.0",type=str) -argsparser.add_argument("-p","--port",help="OSC port to bind to (9002 by default)",default=9002,type=str) -argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output") -args = argsparser.parse_args() - -verbose = args.verbose -ip = args.ip -port = int(args.port) - -def debug(*args, **kwargs): - if( verbose == False ): - return - print(*args, file=sys.stderr, **kwargs) - -oscserver = OSCServer( (ip, port) ) -oscserver.timeout = 0 -run = True - -# this method of reporting timeouts only works by convention -# that before calling handle_request() field .timed_out is -# set to False -def handle_timeout(self): - self.timed_out = True - -# funny python's way to add a method to an instance of a class -import types -oscserver.handle_timeout = types.MethodType(handle_timeout, oscserver) - -# RAW OSC Frame available ? -def OSC_frame(): - # clear timed_out flag - oscserver.timed_out = False - # handle all pending requests then return - while not oscserver.timed_out: - oscserver.handle_request() - - -# default handler -def OSChandler(oscpath, tags, args, source): - - oscaddress = ''.join(oscpath.split("/")) - debug("fromOSC Default OSC Handler got oscpath", oscpath, "from" + str(source[0]), ":", args) - #print("OSC address", path) - #print("find.. /bhoreal ?", path.find('/bhoreal')) - - if oscpath == "/pl" and len(args)==1: - - debug("correct OSC type :'/pl") - - if validate(args[0]) == True: - - debug("new pl : ", args[0]) - line = args[0].replace("(",'[') - line = line.replace(")",']') - line = "[{}]".format(line) - print(line, flush=True); - - else: - debug("Bad pointlist -> msg trapped.") - - else: - debug("BAD OSC Message : " + oscpath +" " +args[0]) - - -oscserver.addMsgHandler( "default", OSChandler ) - - -def validate(pointlist): - - state = True - - if len(pointlist)<9: - debug("Not enough characters :", pointlist) - state = False - - if pointlist.find("(") == -1: - debug("Bad format : use () not [] for points", pointlist) - state = False - - try: - pl = bytes(pointlist, 'ascii') - check = ast.literal_eval(pl.decode('ascii')) - - except: - debug("BAD POINTLIST :", pointlist) - state = False - - return state - - -# simulate a "game engine" -while run: - # do the game stuff: - sleep(0.01) - # call user script - OSC_frame() - -oscserver.close() - diff --git a/clitools/generators/fromUDP.py b/clitools/generators/fromUDP.py deleted file mode 100644 index 5f6e5e9..0000000 --- a/clitools/generators/fromUDP.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# -*- mode: Python -*- - -''' - -fromUDP - -Udp server to cli -v0.1b - -''' -from __future__ import print_function -import traceback, time -import argparse -import socket -import _thread -import sys - -name="generator::fromUDP" - - -def debug(*args, **kwargs): - if( verbose == False ): - return - print(*args, file=sys.stderr, **kwargs) - - -argsparser = argparse.ArgumentParser(description="fromUDP v0.1b help mode") -argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output") -argsparser.add_argument("-i","--ip",help="IP to bind to (0.0.0.0 by default)",default="0.0.0.0",type=str) -argsparser.add_argument("-p","--port",help="UDP port to bind to (9000 by default)",default=9000,type=str) -args = argsparser.parse_args() - -verbose = args.verbose -ip = args.ip -port = int(args.port) -verbose = args.verbose - - - -def udp_thread(): - - while True: - - payload, client_address = sock.recvfrom(1024) - udpath = payload.decode('utf_8') - debug(udpath[0:]) - print(udpath[0:], flush=True); - - ''' - # Reply to client - bytesToSend = str.encode("ACK :"+str(payload)) - serverAddressPort = (client_address, port) - bufferSize = 1024 - #sock.sendto(bytesToSend, serverAddressPort) - sock.sendto(bytesToSend, client_address) - ''' - -def StartUDP(serverIP, UDPORT): - global sock - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - server = ( serverIP,UDPORT) - sock.bind(server) - _thread.start_new_thread(udp_thread, ()) - - -StartUDP(ip, port) - - -# Do something else -try: - - while True: - time.sleep(0.005) - -except Exception: - traceback.print_exc() - - - - - diff --git a/ethertools/receivebroadcast.py b/ethertools/receivebroadcast.py deleted file mode 100644 index ec73293..0000000 --- a/ethertools/receivebroadcast.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# -*- mode: Python -*- - -# or tcpdump -i eth1 port 54545 -XX - -import socket - - -def find_LJ(): - """Listen for broadcast packets.""" - - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.bind(("0.0.0.0", 54545)) - - while True: - data, addr = s.recvfrom(1024) - print(" %s " % (data, )) - print("Packet from %s: " % (addr, )) - - -find_LJ() \ No newline at end of file diff --git a/libs3/OSCom.py b/libs3/OSCom.py index a297f4b..4bf607b 100644 --- a/libs3/OSCom.py +++ b/libs3/OSCom.py @@ -70,9 +70,12 @@ def OSCframe(): oscserver.handle_request() + + # OSC server Thread : handler, dacs reports and simulator points sender to UI. def osc_thread(): + #print("osc Thread launched") try: while True: @@ -89,6 +92,8 @@ def osc_thread(): print("\n") + + # Properly close the system. Todo def Stop(): oscserver.close() diff --git a/libs3/commands.py b/libs3/commands.py index e80363b..abbfd98 100644 --- a/libs3/commands.py +++ b/libs3/commands.py @@ -398,16 +398,6 @@ def handler(oscpath, args): print() DAChecks() print("Done.") - - - if oscpath[2] == "reset": - import shutil - print() - shutil.copyfile(gstt.ljpath+'/templates/LJ_template.conf', gstt.ljpath+'/LJ.conf') - print("templates/LJ_template.conf copied to LJ.conf.") - print("** RESTART LJ **") - #LJautokill() - if oscpath[2] == "restart": print() @@ -607,7 +597,7 @@ def UpdateAllwww(): Updatepage(gstt.ljpath+"/www/LJ.js") Updatepage(gstt.ljpath+"/www/trckr/trckrcam1.html") Updatepage(gstt.ljpath+"/www/simu.html") - Updatepage(gstt.ljpath+"/www/settings.html") + Updatepage(gstt.ljpath+"/www/align.html") Updatepage(gstt.ljpath+"/www/auralls.html") Updatepage(gstt.ljpath+"/www/index.html") diff --git a/libs3/lj23layers.py b/libs3/lj23layers.py index a6488f3..f766121 100644 --- a/libs3/lj23layers.py +++ b/libs3/lj23layers.py @@ -1012,4 +1012,8 @@ def TextRGB(message, zpos, c, layer, xpos, ypos, resize, rotx, roty, rotz): Text(message, zpos, int('0x%02x%02x%02x' % (red,green,blue),0), layer, xpos, ypos, resize, rotx, roty, rotz) + + + + \ No newline at end of file diff --git a/libs3/plugins.py b/libs3/plugins.py index 392bd1c..bfa4eb1 100644 --- a/libs3/plugins.py +++ b/libs3/plugins.py @@ -15,7 +15,7 @@ from libs3 import gstt import os import subprocess import sys -from socket import * + def Init(wserver): global WSserver @@ -177,14 +177,6 @@ def OSCsend(name, oscaddress, oscargs =''): #PluginStart(name) return False -def sendbroadcast(): - - if gstt.debug > 0: - print("Sending broadcast") - cs = socket(AF_INET, SOCK_DGRAM) - cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) - cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) - cs.sendto("LJ 0.8".encode(), ("255.255.255.255", 54545)) # for each plugin will automatically add /pluginame before oscpath to send like /aurora/scim 1, if oscpath = "/scim 1" diff --git a/libs3/tracer3.py b/libs3/tracer3.py index 85400c2..02ffa1e 100644 --- a/libs3/tracer3.py +++ b/libs3/tracer3.py @@ -23,44 +23,44 @@ This tracer include an enhanced version (support for several lasers) of the ethe - Drawing things : -/pl/Scene/lasernumber [(x,y,color),(x1,y1,color),...] The live list of drawn pygame points. Tracer continously ask redis for key /clientkey+lasernumber +/pl/Scene/lasernumber [(x,y,color),(x1,y1,color),...] The live list of drawn pygame points. Tracer continously ask redis for key /clientkey+lasernumber /resampler/lasernumber [(1.0,8), (0.25,3),(0.75,3),(1.0,10)] : a string for resampling rules. the first tuple (1.0,8) is for short line < 4000 in etherdream space (0.25,3),(0.75,3),(1.0,10) for long line > 4000 i.e (0.25,3) means go at 25% position on the line, send 3 times this position to etherdream -/clientkey "/pl/SceneNumber/" What Scene to retrieve from redis +/clientkey "/pl/SceneNumber/" What Scene to retrieve from redis /EDH/lasernumber - Tracer control : -/order 0-8 Set redis key with new value then issue the order number +/order 0-8 Set redis key with new value then issue the order number 0 : Draw Normal point list - 1 : Get the new EDH = reread redis key /EDH/lasernumber + 1 : Get the new EDH = reread redis key /EDH/lasernumber 2 : Draw BLACK point list 3 : Draw GRID point list 4 : Resampler Change (longs and shorts lsteps) - 5 : Client Key Change = reread redis key /clientkey - 6 : Max Intensity Change = reread redis key /intensity - 7 : kpps change = reread redis key /kpps - 8 : color balance change = reread redis keys /red /green /blue + 5 : Client Key Change = reread redis key /clientkey + 6 : Max Intensity Change = reread redis key /intensity + 7 : kpps change = reread redis key /kpps + 8 : color balance change = reread redis keys /red /green /blue - Managing Etherdream DACs : Discrete drawing values -/kpps 0- DAC output speed to laser, then order 7. Depends of actual angle -/intensity 0-255 Laser output power, then order 6 (for alignement,...) -/red 0-100 % of full red, then order 8 -/green 0-100 % of full green, then order 8 -/blue 0-100 % of full blue, then order 8 +/kpps 0- DAC output speed to laser, then order 7. Depends of actual angle +/intensity 0-255 Laser output power, then order 6 (for alignement,...) +/red 0-100 % of full red, then order 8 +/green 0-100 % of full green, then order 8 +/blue 0-100 % of full blue, then order 8 DAC status report -/lstt/lasernumber etherdream last_status.playback_state (0: idle 1: prepare 2: playing) -/cap/lasernumber number of empty points sent to fill etherdream buffer (up to 1799) -/lack/lasernumber "a": ACK "F": Full "I": invalid. 64 or 35 for no connection. +/lstt/lasernumber etherdream last_status.playback_state (0: idle 1: prepare 2: playing) +/cap/lasernumber number of empty points sent to fill etherdream buffer (up to 1799) +/lack/lasernumber "a": ACK "F": Full "I": invalid. 64 or 35 for no connection. Geometric corrections @@ -223,7 +223,7 @@ class DAC(object): while True: - #pdb.set_trace() + #pdb.set_trace() for indexpoint,currentpoint in enumerate(self.pl): #print indexpoint, currentpoint xyc = [currentpoint[0],currentpoint[1],currentpoint[2]] @@ -335,7 +335,7 @@ class DAC(object): # ipconn state is -1 at startup (see gstt) and modified here r.set('/lack/'+str(self.mylaser), self.connstatus) - gstt.lstt_ipconn[self.mylaser] = self.connstatus + gstt.lstt_ipconn[self.mylaser] = self.connstatus self.buf = b'' # Upper case PL is the Point List number @@ -349,7 +349,7 @@ class DAC(object): if r.get('/EDH/'+str(self.mylaser)) == None: #print("Laser",self.mylaser,"NO EDH !! Computing one...") homographyp.newEDH(self.mylaser) - else: + else: gstt.EDH[self.mylaser] = np.array(ast.literal_eval(r.get('/EDH/'+str(self.mylaser)).decode('ascii'))) #print("Laser",self.mylaser,"found its EDH in redis") @@ -447,17 +447,9 @@ class DAC(object): if order == 0: # USER point list - - #self.pl = ast.literal_eval(r.get(self.clientkey+str(self.mylaser)).decode('ascii')) + self.pl = ast.literal_eval(r.get(self.clientkey+str(self.mylaser)).decode('ascii')) #print("Tracer : laser", self.mylaser, " order 0 : pl : ",len(self.pl)) - try: - self.pl = ast.literal_eval(r.get(self.clientkey+str(self.mylaser)).decode('ascii')) - - except SyntaxError: - print("BAD POINTLIST on Tracer : laser", self.mylaser, " order 0 : pl :",self.pl) - self.pl = grid_points - else: # Get the new EDH @@ -532,13 +524,13 @@ class DAC(object): time.sleep(0.001) cap += 150 - #print("Writing %d points" % (cap, )) +# print("Writing %d points" % (cap, )) #t0 = time.time() #if self.mylaser == 2: - # print(points) + # print(points) self.write(points) #t1 = time.time() - #print("Took %f" % (t1 - t0, ) +# print("Took %f" % (t1 - t0, ) if not started: print("Tracer", self.mylaser, "starting with", gstt.kpps[self.mylaser],"kpps") @@ -579,7 +571,7 @@ def find_dac(): order = r.get('/order') neworder = order & ~(1<< self.mylaser*2) neworder = neworder & ~(1<< 1+ self.mylaser*2) - r.set('/order', str(neworder)) + r.set('/order', str(neworder)) else: # Laser bit 0 = 1 diff --git a/main.py b/main.py index 08dbd47..acaefe9 100755 --- a/main.py +++ b/main.py @@ -36,32 +36,35 @@ print("") import redis import os ljpath = r'%s' % os.getcwd().replace('\\','/') + + import sys #sys.path.append('libs3/') + from libs3 import gstt, settings -gstt.ljpath = ljpath +gstt.ljpath= ljpath log.info("Reading " + gstt.ConfigName + " setup file...") settings.Read() # Arguments may alter .conf file so import settings first then cli from libs3 import cli + settings.Write() from multiprocessing import Process, set_start_method import random, ast + from libs3 import plugins - - -#from libs3 import lasytracer as tracer from libs3 import tracer3 as tracer - - from libs3 import homographyp, commands, font1 + #import subprocess + import os #import midi + from libs3 import OSC3 from websocket_server import WebsocketServer #import socket @@ -261,16 +264,14 @@ def osc_thread(): #print("Sending simu frame from",'/pl/'+str(gstt.SceneNumber)+'/'+str(gstt.Laser)) #print(r.get('/pl/'+str(gstt.SceneNumber)+'/'+str(gstt.Laser))) - sendWSall("/simul" +" "+ str(r.get('/po/'+str(gstt.SceneNumber)+'/'+str(gstt.Laser)).decode('ascii'))) - if random.randint(0,100)>95: - plugins.sendbroadcast() + sendWSall("/simul" +" "+ str(r.get('/pl/'+str(gstt.SceneNumber)+'/'+str(gstt.Laser)).decode('ascii'))) except Exception as e: import sys, traceback - print('\n--------------------------') - print('OSC Thread Exception: %s' % e) - print('- - - - - - - - - - - - - - ') + print('\n---------------------') + print('Exception: %s' % e) + print('- - - - - - - - - - -') traceback.print_tb(sys.exc_info()[2]) print("\n") diff --git a/plugins/aurora/aurora.py b/plugins/aurora/aurora.py index 5bdbe60..303baa0 100644 --- a/plugins/aurora/aurora.py +++ b/plugins/aurora/aurora.py @@ -181,7 +181,7 @@ log.infog("Aurora v0.1b") OSCinPort = 8090 ljscene = 0 -StartFXs = ["anim.Starfield","anim.Starfield","anim.Starfield", "anim.Word"] +StartFXs = ["anim.Maxwell","anim.Starfield","anim.Starfield", "anim.Word"] # Useful variables init. white = lj.rgb2int(255,255,255) @@ -1125,9 +1125,9 @@ def AllFX(): dots = eval(LAY['FX']+"(LAY)") if LAY['FX'] != "Zero" or lent(dots) != 0: #print(dots, LAY['color']) - #for cc in range(15): - # ccmidi[cc] = int(lj.fromKey("/midi/cc/1/"+str(cc))) - # #print(ccmidi) + for cc in range(15): + ccmidi[cc] = int(lj.fromKey("/midi/cc/1/"+str(cc))) + #print(ccmidi) lj.rPolyLineOneColor(dots, c = LAY['color'], layer = l, closed = LAY['closed'], xpos = LAY['Xcoord'] + LAY['stepvals'][LAY['step']] - (LAY['lineSize']/2), ypos = Layer[l]['Ycoord'], resize = LAY['scale'] * audioR, rotx = LAY['Xrotdirec'], roty = LAY['Yrotdirec'], rotz = LAY['Zrotdirec']) #lj.rPolyLineOneColor(dots, c = LAY['color'], layer = l, closed = LAY['closed'], xpos = LAY['Xcoord'] - (ccmidi[0]-64)*4 - (LAY['lineSize']/2), ypos = Layer[l]['Ycoord'] + (ccmidi[1]-64)*4, resize = LAY['scale'] * audioR * (ccmidi[2])/50, rotx = LAY['Xrotdirec']+(ccmidi[3]*3), roty = LAY['Yrotdirec']+(ccmidi[3]*3), rotz = LAY['Zrotdirec']+(ccmidi[3]*3)) else: diff --git a/www/align.html b/www/align.html new file mode 100644 index 0000000..6a6d427 --- /dev/null +++ b/www/align.html @@ -0,0 +1,937 @@ + + + + Align Rack + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ + + + + +
+
+
+

+ /TL Align +   +

+ + +
+
+
+ Align Rack +
+
+ /team/laser +
+
+
+ Stt + + + + +
+
+ Ack + + + + +
+ +
+
+ + +
+
+ +
+

Scene

+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+
+
+
+
+
+ + + + + + +
+ +
+ +
+ + +
+ +
+
+ +
+
+ + + +
+ +
+ + + + + + + + +
+ + +
+ + +
+ + + +
+ +
+
+
+ +
+
kPPS
+
Buffer
+
+
+
+ + +
+
+
+
Angle
+
Offset X
+
Offset Y
+
+
+
+
+
+
+ + +
+
+
+
Intens
+
Scale X
+
Scale X
+
+
+
+
+
+
+ + +
+
+
+
Red
+
Green
+
Blue
+
+
+ + + +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + +
+
+ + +
+ + + + +
+ + +
+
+
+
+
kPPS
+
Buffer
+
+
+
+ + +
+
+
+
Angle
+
Offset X
+
Offset Y
+
+
+
+
+
+
+ + +
+
+
+
Intens
+
Scale X
+
Scale X
+
+
+
+
+
+
+ + +
+
+
+
Red
+
Green
+
Blue
+
+
+ + + +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + +
+
+ + +
+ + +
+ + +
+
+
+
+
kPPS
+
Buffer
+
+
+
+ + +
+
+
+
Angle
+
Offset X
+
Offset Y
+
+
+
+
+
+
+ + +
+
+
+
Intens
+
Scale X
+
Scale X
+
+
+
+
+
+
+ + +
+
+
+
Red
+
Green
+
Blue
+
+
+ + + +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + +
+
+ + +
+ + + +
+ + +
+
+
+
+
kPPS
+
Buffer
+
+
+
+ + +
+
+
+
Angle
+
Offset X
+
Offset Y
+
+
+
+
+
+
+ + +
+
+
+
Intens
+
Scale X
+
Scale X
+
+
+
+
+
+
+ + +
+
+
+
Red
+
Green
+
Blue
+
+
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + diff --git a/www/auralls.html b/www/auralls.html index daf2a20..866ed23 100644 --- a/www/auralls.html +++ b/www/auralls.html @@ -59,10 +59,10 @@
- +
@@ -93,8 +93,8 @@
-
diff --git a/www/index.html b/www/index.html index e843eae..ddde89a 100644 --- a/www/index.html +++ b/www/index.html @@ -101,15 +101,15 @@ - +

- Settings + Align  

@@ -117,7 +117,7 @@
- Settings + Align
  diff --git a/www/simu.html b/www/simu.html index 68885af..e3b1320 100644 --- a/www/simu.html +++ b/www/simu.html @@ -56,10 +56,10 @@
- +
@@ -90,8 +90,8 @@
-
diff --git a/www/trckr/trckr.html b/www/trckr/trckr.html new file mode 100644 index 0000000..1cc933c --- /dev/null +++ b/www/trckr/trckr.html @@ -0,0 +1,680 @@ + + + + LASERCam 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+ + + + +
+
+
+

+ /TL RGY 1 +   +

+ + +
+
+
+ LASERcam 1 : Allow to use your webcam + start +
+
+ /team/laser +
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+

+ Colors + +

+
+ +
+
+
+
+
+
+
+
+
+ +
+
+ + + +
+ + + +
+ + + +
+
+
+

To try it out: +

    +
  1. Allow the page to use your webcamera
  2. +
  3. Make sure that your face is clearly visible in the video, and click start
  4. +
  5. See the model fitted to your face
  6. +
      +

      +
+
+
+
+
+
+ + + + + + + + + + + + + + + + diff --git a/www/trckr/trckrcam1.html b/www/trckr/trckrcam1.html index 4e2056e..f94f0b5 100644 --- a/www/trckr/trckrcam1.html +++ b/www/trckr/trckrcam1.html @@ -93,10 +93,10 @@
- +
@@ -127,8 +127,8 @@
-