Planetarium alpha

This commit is contained in:
nrhck 2019-02-10 16:53:51 +01:00
parent 4e37cdaa46
commit 6ae38061a5
12 changed files with 706 additions and 257 deletions

20
LJ.conf
View File

@ -1,5 +1,5 @@
[General] [General]
lasernumber = 1 lasernumber = 4
debug = 0 debug = 0
ljayserverip = 127.0.0.1 ljayserverip = 127.0.0.1
nozoscip = 127.0.0.1 nozoscip = 127.0.0.1
@ -39,9 +39,9 @@ swapx = -1
swapy = -1 swapy = -1
lsteps = [ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] lsteps = [ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]
warpdest = [[-1500., 1500.], warpdest = [[-1500., 1500.],
[ 1500., 1500.], [ 1500., 1500.],
[ 1500.,-1500.], [ 1500.,-1500.],
[-1500.,-1500.]] [-1500.,-1500.]]
[laser2] [laser2]
color = -1 color = -1
@ -58,9 +58,9 @@ swapx = 1
swapy = 1 swapy = 1
lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]
warpdest = [[-1500., 1500.], warpdest = [[-1500., 1500.],
[ 1500., 1500.], [ 1500., 1500.],
[ 1500.,-1500.], [ 1500.,-1500.],
[-1500.,-1500.]] [-1500.,-1500.]]
[laser3] [laser3]
color = -1 color = -1
@ -77,7 +77,7 @@ swapx = -1
swapy = -1 swapy = -1
lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]
warpdest = [[-1500., 1500.], warpdest = [[-1500., 1500.],
[ 1500., 1500.], [ 1500., 1500.],
[ 1500.,-1500.], [ 1500.,-1500.],
[-1500.,-1500.]] [-1500.,-1500.]]

View File

@ -59,6 +59,8 @@ In webui/index.html change the ws ip adress to the server IP if needed.
Using the same idea check all ip address in LJ.conf. Using the same idea check all ip address in LJ.conf.
There is a nice ws debug tool websocat.
# #

View File

@ -2,39 +2,41 @@ Multi Laser planetarium in python3 for LJ.
v0.01 v0.01
Sam Neurohack Sam Neurohack
User can define :
- Observer position using GPS coordinates or built in cities catalog on earth. Display all solar planets and hipparcos catalog objects below a given magnitude. Accuracy tested against apparent data and starchart at https://www.calsky.com/cs.cgi?cha=7&sec=3&sub=2
- Observer time. If you choose Now, the sky is updated live, so you can virtual sky photography :)
- Each laser starchart has a center direction like Azimuth : 63.86° & Altitude: 61.83° and a Field of view like 90°. For the all sky with 4 lasers, give 90° FOV per laser.
- What is displayed : Solar system objects, Stars, Compass letters.
-
Some future features : It's an alpha release so a little hardcoded :
- Constellations display - set observer position (find SkyCity, SkyCountryCode) in main.py like 'Paris' and 'FR'
- 3D with anaglyph - set observer date.time in InitObserver() arguments (default is now in UTC)
- Time Speed setting - set what sky part you want to display for each laser in 'LaserSkies' variable : Define alitude and azimuth for top left and bottom right
- What do you want ?
User must understand Right Ascension/Declinaison and Azimuth/Altitude coordinates system. Some needed astronomy concepts online : It needs more libraries than plan. Currently it relies on the awesome astropy, skyfield,...
https://rhodesmill.org/skyfield/stars.html
https://in-the-sky.org//staratlas.php?ra=15.358411414&dec=73.47660962&limitmag=2 Soon some pictures.
http://www.physics.csbsju.edu/astro/SF/SF.06.html
To Run :
Launch LJ first
python3 main.py
For debug options and more type : python3 --help
This project is on "OK" precision grade and definately not coding skills show off, I'm learning python coding it. To check accuracy, one can compare to : To install :
https://www.calsky.com/cs.cgi?cha=7&sec=3&sub=2
go3.sh
NB :
- if you get an year error out of range : install the last skyfield "python-skyfield" in github.
- Read main.py
The author barely understand astronomy so please report if you find newbie errors sam (at) neurohack cc
This project uses the awesome Skyfield by Brandon Rhodes and Astropy.
Kernels for Sky objects positions references :
Acton, C.H.; "Ancillary Data Services of NASA's Navigation and Ancillary Information Facility;" Planetary and Space Science, Vol. 44, No. 1, pp. 65-70, 1996.
Charles Acton, Nathaniel Bachman, Boris Semenov, Edward Wright; A look toward the future in the handling of space science mission geometry; Planetary and Space Science (2017);
DOI 10.1016/j.pss.2017.02.013
https://doi.org/10.1016/j.pss.2017.02.013
LICENCE : CC
Remember : LJ will automatically warp geometry according to alignement data before sending to lasers. See webUI.
'''

View File

@ -0,0 +1,9 @@
sudo apt install python3-pip
pip3 install jplephem
pip3 install pyephem
pip3 install astropy
pip3 install skyfield
pip3 install pandas
pip3 install redis
pip3 install osc4py3
pip3 install --pre astroquery

View File

@ -22,7 +22,11 @@ Sam Neurohack
import math import math
import redis import redis
#from OSC import OSCServer, OSCClient, OSCMessage
# Import needed modules from osc4py3
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
redisIP = '127.0.0.1' redisIP = '127.0.0.1'
r = redis.StrictRedis(host=redisIP, port=6379, db=0) r = redis.StrictRedis(host=redisIP, port=6379, db=0)
@ -32,16 +36,23 @@ ClientNumber = 0
point_list = [] point_list = []
pl = [[],[],[],[]] pl = [[],[],[],[]]
#
# OSC interaction with LJ
#
''' def OSCstart():
LJIP = "127.0.0.1" # Start the system.
osc_startup()
#osc_udp_client(redisIP, 8002, "LJ 8002")
def OSCframe():
osc_process()
# Properly close the system. Todo
def OSCstop():
osc_terminate()
osclientlj = OSCClient()
oscmsg = OSCMessage()
osclientlj.connect((redisIP, 8002))
'''
'''
def Send(oscaddress,oscargs=''): def Send(oscaddress,oscargs=''):
oscmsg = OSCMessage() oscmsg = OSCMessage()
@ -50,21 +61,35 @@ def Send(oscaddress,oscargs=''):
#print ("sending to bhorosc : ",oscmsg) #print ("sending to bhorosc : ",oscmsg)
try: try:
osclientlj.sendto(oscmsg, (redisIP, 8002)) msg = oscbuildparse.OSCMessage(oscaddress, None, [oscargs])
oscmsg.clearData() osc_send(msg, "LJ 8002")
except: except:
print ('Connection to LJ refused : died ?') print ('Connection to LJ refused : died ?')
pass pass
#time.sleep(0.001
def WebStatus(message):
Send("/status",message)
''' '''
def handlerfunction(s, x, y):
# Will receive message data unpacked in s, x, y
pass
def handlerfunction2(address, s, x, y):
# Will receive message address, and message data flattened in s, x, y
pass
# Make server channels to receive packets.
osc_udp_server("127.0.0.1", 3721, "localhost")
osc_udp_server("0.0.0.0", 3724, "anotherserver")
'''
ASCII_GRAPHICS = [ ASCII_GRAPHICS = [
#implementé # caracteres corrects
[(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)], #0 [(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)], #0
[(-20,30), (0,-30), (-20,30)], #1 [(-20,30), (0,-30), (-20,30)], #1
@ -77,7 +102,7 @@ ASCII_GRAPHICS = [
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #8 [(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #8
[(30,0), (-30,0), (-30,-10), (0,-30), (30,-30), (30,10), (0,30), (-30,30)], #9 [(30,0), (-30,0), (-30,-10), (0,-30), (30,-30), (30,10), (0,30), (-30,30)], #9
# A implementer # caracteres a implementer
[(-30,10), (30,-10), (30,10), (0,30), (-30,10), (-30,-10), (0,-30), (30,-10)], #: [(-30,10), (30,-10), (30,10), (0,30), (-30,10), (-30,-10), (0,-30), (30,-10)], #:
[(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #; [(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #;
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #< [(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #<
@ -86,7 +111,7 @@ ASCII_GRAPHICS = [
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #? [(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #?
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #@ [(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #@
# Implementé # Caracteres corrects
[(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A [(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A
@ -163,6 +188,7 @@ def Config(redisIP,client):
r = redis.StrictRedis(host=redisIP, port=6379, db=0) r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = client ClientNumber = client
osc_udp_client(redisIP, 8002, "LJ 8002")
def LineTo(xy, c, PL): def LineTo(xy, c, PL):
@ -296,10 +322,11 @@ def Text(message,c, PL, xpos, ypos, resize, rotx, roty, rotz):
# texte centre en x automatiquement selon le nombre de lettres l # texte centre en x automatiquement selon le nombre de lettres l
x_offset = 26 * (- (0.9*l) + 3*i) x_offset = 26 * (- (0.9*l) + 3*i)
#print i,x_offset #print i,x_offset
# if digit
if ord(ch)<58: if ord(ch)<58:
char_pl_list = ASCII_GRAPHICS[ord(ch) - 48] char_pl_list = ASCII_GRAPHICS[ord(ch) - 48]
else: else:
char_pl_list = ASCII_GRAPHICS[ord(ch) - 46] char_pl_list = ASCII_GRAPHICS[ord(ch) - 46 ]
char_draw = [] char_draw = []
#dots.append((char_pl_list[0][0] + x_offset,char_pl_list[0][1],0)) #dots.append((char_pl_list[0][0] + x_offset,char_pl_list[0][1],0))
@ -309,6 +336,7 @@ def Text(message,c, PL, xpos, ypos, resize, rotx, roty, rotz):
i +=1 i +=1
#print ch,char_pl_list,char_draw #print ch,char_pl_list,char_draw
rPolyLineOneColor(char_draw, c, PL , False, xpos, ypos, resize, rotx, roty, rotz) rPolyLineOneColor(char_draw, c, PL , False, xpos, ypos, resize, rotx, roty, rotz)
#print ("laser",PL,"message",message)
#dots.append(char_draw) #dots.append(char_draw)

301
clients/planetarium/main.py Normal file → Executable file
View File

@ -37,6 +37,11 @@ from astropy.time import Time
from skyfield.api import Star, load, Topos,Angle from skyfield.api import Star, load, Topos,Angle
from skyfield.data import hipparcos from skyfield.data import hipparcos
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
from osc4py3 import oscmethod as osm
import json import json
''' '''
@ -53,6 +58,8 @@ else:
import argparse import argparse
print ("") print ("")
print ("Arguments parsing if needed...") print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Planetarium for LJ") argsparser = argparse.ArgumentParser(description="Planetarium for LJ")
@ -60,6 +67,7 @@ argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int) argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int) argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int)
argsparser.add_argument("-d","--debug",help="Verbosity level (0 by default)",type=int) argsparser.add_argument("-d","--debug",help="Verbosity level (0 by default)",type=int)
argsparser.add_argument("-i","--input",help="inputs OSC Port (8005 by default)",type=int)
#argsparser.add_argument("-n","--name",help="City Name of the observer",type=str) #argsparser.add_argument("-n","--name",help="City Name of the observer",type=str)
#argsparser.add_argument("-r","--redisIP",help="Country code of the observer ",type=str) #argsparser.add_argument("-r","--redisIP",help="Country code of the observer ",type=str)
@ -81,6 +89,11 @@ if args.debug:
else: else:
debug = 0 debug = 0
if args.input:
OSCinPort = args.input
else:
OSCinPort = 8005
# Redis Computer IP # Redis Computer IP
if args.redisIP != None: if args.redisIP != None:
redisIP = args.redisIP redisIP = args.redisIP
@ -95,16 +108,12 @@ lj3.Config(redisIP,ljclient)
fov = 256 fov = 256
viewer_distance = 2.2 viewer_distance = 2.2
width = 450 width = 750
height = 450 height = 750
centerX = width / 2 centerX = width / 2
centerY = height / 2 centerY = height / 2
samparray = [0] * 100 samparray = [0] * 100
# (x,y,color in integer) 65280 is color #00FF00
# Green rectangular shape :
pl0 = [(100,300,65280),(200,300,65280),(200,200,65280),(100,200,65280),(100,300,65280)]
# If you want to use rgb for color : # If you want to use rgb for color :
@ -154,7 +163,7 @@ def Proj(x,y,z,angleX,angleY,angleZ):
''' '''
To minize number of sky objects coordinates conversion : Change planetarium FOV in Ra Dec to select objects To minize number of sky objects coordinates conversion : Change planetarium FOV in Ra Dec to select objects
(planets, hipparcos,..). Then get those objects in AltAz coordinates. (planets, hipparcos,..). Then get only those objects in AltAz coordinates.
aa2radec use Astropy to compute Equatorial Right Ascension and Declinaison coordinates from given observator Altitude and Azimuth. aa2radec use Astropy to compute Equatorial Right Ascension and Declinaison coordinates from given observator Altitude and Azimuth.
Example ra,dec = aa2radec( azimuth = 0, altitude = 90, lati = 48.85341, longi = 2.3488, elevation = 100, t =AstroPyNow ) Example ra,dec = aa2radec( azimuth = 0, altitude = 90, lati = 48.85341, longi = 2.3488, elevation = 100, t =AstroPyNow )
with AstroPyNow = Time.now() with AstroPyNow = Time.now()
@ -211,36 +220,60 @@ def RadecSkies(LaserSkies, AstroSkyTime):
print() print()
print("Converting", lasernumber, "LaserSkies limits in Right Ascension & Declination (radec) coordinates ") print("Converting", lasernumber, "LaserSkies limits in Right Ascension & Declination (radec) coordinates ")
for laser in range(lasernumber): for laser in range(lasernumber):
if debug > 0:
print("Laser",laser)
# Left top point # Left top point
LaserSkies[laser][4],LaserSkies[laser][6] = aa2radec(azimuth = LaserSkies[laser][0], altitude =LaserSkies[laser][2], t =AstroSkyTime) LaserSkies[laser][4],LaserSkies[laser][6] = aa2radec(azimuth = LaserSkies[laser][0], altitude =LaserSkies[laser][2], t =AstroSkyTime)
if debug > 0:
print(LaserSkies[laser][4],LaserSkies[laser][6])
# Right Bottom point # Right Bottom point
LaserSkies[laser][5],LaserSkies[laser][7] = aa2radec(azimuth = LaserSkies[laser][1], altitude =LaserSkies[laser][3], t =AstroSkyTime) LaserSkies[laser][5],LaserSkies[laser][7] = aa2radec(azimuth = LaserSkies[laser][1], altitude =LaserSkies[laser][3], t =AstroSkyTime)
if debug > 0:
print(LaserSkies[laser][5],LaserSkies[laser][7])
if debug > 0: if debug > 0:
print(LaserSkies) print(LaserSkies)
print ("Done.") print ("Done.")
def azimuth2scrX(leftAzi,rightAzi,s): def azimuth2scrX(leftAzi,rightAzi,s):
a1, a2 = leftAzi, rightAzi a1, a2 = leftAzi, rightAzi
b1, b2 = -width/2, width/2 b1, b2 = 0, width
#if debug > 0:
# print(leftAzi, rightAzi, s, b1 + ((s - a1) * (b2 - b1) / (a2 - a1)))
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1)) return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
def altitude2scrY(topAlti,botAlti,s): def altitude2scrY(topAlti,botAlti,s):
a1, a2 = botAlti, topAlti a1, a2 = topAlti, botAlti
b1, b2 = -height/2, height/2 b1, b2 = 0, height
#if debug > 0:
# print(topAlti,botAlti,s, b1 + ((s - a1) * (b2 - b1) / (a2 - a1)))
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1)) return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
# #
# Solar System # Solar System
# #
SolarObjectShape = [(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)] SolarObjectShape = [(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)]
# Planets Radius in km
SolarObjectradius = [
('Sun', 695500.0),
('Mercury', 2440.0),
('Venus', 6051.8),
('Earth', 6371.01),
('Mars', 3389.9),
('Jupiter', 69911.0),
('Saturn', 58232.0),
('Uranus', 25362.0),
('Neptune', 24624.0),
('134340 Pluto', 1195.0),
]
def LoadSolar(): def LoadSolar():
global planets, SolarObjects, earth global planets, SolarObjects, earth
@ -257,7 +290,6 @@ def LoadSolar():
def UpdateSolar(): def UpdateSolar():
global SolarObjects global SolarObjects
# Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver. # Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver.
for number,object in enumerate(SolarObjects): for number,object in enumerate(SolarObjects):
@ -300,56 +332,43 @@ def LoadHipparcos(ts):
hipparcosURL = 'data/hip_main.dat.gz' hipparcosURL = 'data/hip_main.dat.gz'
with load.open(hipparcosURL) as f: with load.open(hipparcosURL) as f:
hipdata = hipparcos.load_dataframe(f) hipdata = hipparcos.load_dataframe(f)
print("Loaded.") #print("Loaded.")
hipparcos_epoch = ts.tt(1991.25) hipparcos_epoch = ts.tt(1991.25)
# CODE IMPORTED HERE FROM TESTS. NEEDS TO ADAPT # CODE IMPORTED HERE FROM TESTS. NEEDS TO ADAPT
# Star selection # Star selection
def StarSelect(): def StarSelect():
global StarsObjects, hipdatafilt
hipparcos_epoch = ts.tt(1991.25) StarsObjects = [[]]
barnards_star = Star.from_dataframe(hipdata.loc[87937]) #hipparcos_epoch = ts.tt(1991.25)
polaris = Star.from_dataframe(hipdata.loc[11767]) #barnards_star = Star.from_dataframe(hipdata.loc[87937])
#polaris = Star.from_dataframe(hipdata.loc[11767])
print() print()
print ("Selecting sky portion") print ("Stars selection...")
hipdatafilt = hipdata[hipdata['magnitude'] <= 2.5] hipdatafilt = hipdata[hipdata['magnitude'] <= 3.5]
print(('After filtering, there are {} stars with magnitude <= 2.5'.format(len(hipdatafilt)))) print(('{} stars with magnitude <= 3.5'.format(len(hipdatafilt))))
bright_stars = Star.from_dataframe(hipdatafilt) Starnames = hipdatafilt.index
print (hipdatafilt)
#print (bright_stars)
t = ts.utc(2018, 9, 3) StarsObjects[0] = [Starnames[0],0,0]
for index in range(len(Starnames)-1):
''' StarsObjects.append([Starnames[index+1],0,0])
Observer = earth + Topos(gpslat, gpslong)
ApparentPosition = Observer.at(t).observe(bright_stars).apparent()
alt, az, distance = ApparentPosition.altaz('standard')
print(('Now there are {} azimuth'.format(len(az))))
print(('and {} altitute'.format(len(alt))))
'''
astrometric = earth.at(t).observe(bright_stars)
ra, dec, distance = astrometric.radec()
print(('Now there are {} right ascensions'.format(len(ra.hours))))
print(('and {} declinations'.format(len(dec.degrees))))
Observer = earth + Topos(gpslat, gpslong)
AP = Observer.at(t).observe(bright_stars)
print ("AP",AP.apparent())
def UpdateStars(): def UpdateStars(ts):
global StarsObjects global StarsObjects
hipparcos_epoch = ts.tt(1991.25)
# Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver. # Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver.
for number,object in enumerate(StarsObjects): for number,object in enumerate(StarsObjects):
#print(object[0],number) #print(object[0],number)
StarsObjects[number][1], StarsObjects[number][2], distance = EarthObjPosition(planets[object[0]],SkyfieldTime) StarsObjects[number][1], StarsObjects[number][2], distance = EarthObjPosition(Star.from_dataframe(hipdatafilt.loc[StarsObjects[number][0]]),SkyfieldTime)
if debug > 0: if debug > 0:
PrintSolar() PrintStars()
def PrintStars(): def PrintStars():
@ -360,10 +379,71 @@ def DrawStars(laser):
for number,object in enumerate(StarsObjects): for number,object in enumerate(StarsObjects):
# Solar object is in given laser sky azimuth and altitude range ? # Star object is in given lasersky altitude range ?
if LaserSkies[laser][0] < StarsObjects[number][2] < LaserSkies[laser][1] and LaserSkies[laser][3] < StarsObjects[number][1] < LaserSkies[laser][2]: if LaserSkies[laser][3] < StarsObjects[number][1] < LaserSkies[laser][2]:
#print ("drawing",StarsObjects[number][0],StarsObjects[number][1],StarsObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(StarsObjectshape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],StarsObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],StarsObjects[number][1]), resize = 2, rotx =0, roty =0 , rotz=0) # Star object is in given lasersky azimuth range ?
if LaserSkies[laser][0] < StarsObjects[number][2] < LaserSkies[laser][1] :
#print ("drawing",StarsObjects[number][0],StarsObjects[number][1],StarsObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(StarsObjectShape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],StarsObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],StarsObjects[number][1]), resize = 0.05, rotx =0, roty =0 , rotz=0)
# Star object is in given lasersky North azimuth ?
if LaserSkies[laser][0] > LaserSkies[laser][1] and StarsObjects[number][2] < LaserSkies[laser][1] :
#print ("drawing",StarsObjects[number][0],StarsObjects[number][1],StarsObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(StarsObjectShape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],StarsObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],StarsObjects[number][1]), resize = 0.05, rotx =0, roty =0 , rotz=0)
#
# Anything system. Say you want
#
AnythingObjectShape = [(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)]
def LoadAnything():
global planets, AnythingObjects, earth
print("Loading Anything System...")
# de421.bps https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/a_old_versions/de421.bsp
# planets = load('data/de421.bsp')
earth = planets['earth']
print('Loaded.')
# [Object name, object altitude, object azimuth]
AnythingObjects = [['MERCURY',0.0, 0.0], ['VENUS', 0.0, 0.0], ['JUPITER BARYCENTER', 0.0, 0.0], ['SATURN BARYCENTER', 0.0, 0.0], ['URANUS BARYCENTER', 0.0, 0.0], ['NEPTUNE BARYCENTER', 0.0, 0.0], ['PLUTO BARYCENTER', 0.0, 0.0], ['SUN', 0.0, 0.0], ['MOON', 0.0, 0.0], ['MARS', 0.0, 0.0]]
def UpdateAnything():
global AnythingObjects
# Compute Alt Az coordinates for all Anything objects for obsehttps://www.startpage.com/do/searchrver.
for number,object in enumerate(AnythingObjects):
#print(object[0],number)
AnythingObjects[number][1], AnythingObjects[number][2], distance = EarthObjPosition(planets[object[0]],SkyfieldTime)
if debug > 0:
PrintAnything()
def PrintAnything():
for number,object in enumerate(AnythingObjects):
print (AnythingObjects[number][0],"is at (alt,az)",AnythingObjects[number][1],AnythingObjects[number][2])
# Draw the AnythingShapeObject for any Anything object is in the laser Sky
def DrawAnything(laser):
for number,object in enumerate(AnythingObjects):
# Anything object is in given laser sky azimuth and altitude range ?
if LaserSkies[laser][0] < AnythingObjects[number][2] < LaserSkies[laser][1] and LaserSkies[laser][3] < AnythingObjects[number][1] < LaserSkies[laser][2]:
#print ("drawing",AnythingObjects[number][0],AnythingObjects[number][1],AnythingObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(AnythingObjectShape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],AnythingObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],AnythingObjects[number][1]), resize = 2, rotx =0, roty =0 , rotz=0)
@ -379,7 +459,7 @@ def LoadCities():
f=open("data/cities.json","r") f=open("data/cities.json","r")
s = f.read() s = f.read()
world = json.loads(s) world = json.loads(s)
print("Loaded.") #print("Loaded.")
# Get longitude and latitude of given City in given country. Need to better understand python dictionnaries. # Get longitude and latitude of given City in given country. Need to better understand python dictionnaries.
@ -398,24 +478,31 @@ def CityPositiion(cityname, countrycode):
# Add Kompass letter to given laser point list if it is in laser sky at Y axis 300 # Add Kompass orientation to given laser point list if it is in laser sky at Y axis 300
# point lasers to
def DrawOrientation(laser): def DrawOrientation(laser):
#print("LaserSkies 0",LaserSkies[laser][0],"LaserSkies 1",LaserSkies[laser][1])
# North direction is in given laser sky azimuth range? # North direction is in given laser sky azimuth range?
if LaserSkies[laser][0] < 0 < LaserSkies[laser][1]: if LaserSkies[laser][1] < LaserSkies[laser][0]:
lj3.Text("N",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0), 300) #print ("N az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("NORTH",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],359), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
# East direction is in given laser sky azimuth range ? # East direction is in given laser sky azimuth range ?
if LaserSkies[laser][0] < 90 < LaserSkies[laser][1]: if LaserSkies[laser][0] <= 90 < LaserSkies[laser][1]:
lj3.Text("E",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],90), 300) #print ("E az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("EAST",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],90), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
# South direction is in given laser sky azimuth range ? # South direction is in given laser sky azimuth range ?
if LaserSkies[laser][0] < 180 < LaserSkies[laser][1]: if LaserSkies[laser][0] <= 180 < LaserSkies[laser][1]:
lj3.Text("S",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],180), 300) #print ("S az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("SOUTH",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],180), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
# West direction is in given laser sky azimuth range ? # West direction is in given laser sky azimuth range ?
if LaserSkies[laser][0] < 270 < LaserSkies[laser][1]: if LaserSkies[laser][0] <= 270 < LaserSkies[laser][1]:
lj3.Text("W",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],270), 300) #print ("W az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("WEST",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],270), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
@ -427,7 +514,7 @@ def InitObserver(SkyCity, SkyCountryCode, time,ts):
# Observer position i.e : Paris FR # Observer position i.e : Paris FR
#Skylat = 48.85341 # decimal degree #Skylat = 48.85341 # decimal degree
#Skylong = 2.3488 # decimal degree #Skylong = 2.3488 # decimal degree
print() #print()
print("Observer GPS position and time...") print("Observer GPS position and time...")
Skylat, Skylong = CityPositiion(SkyCity,SkyCountryCode) Skylat, Skylong = CityPositiion(SkyCity,SkyCountryCode)
print ("GPS Position of",SkyCity, "in", SkyCountryCode, ":",Skylat,Skylong) print ("GPS Position of",SkyCity, "in", SkyCountryCode, ":",Skylat,Skylong)
@ -438,7 +525,7 @@ def InitObserver(SkyCity, SkyCountryCode, time,ts):
# Other time in Astropy style # Other time in Astropy style
# times = '1999-01-01T00:00:00.123456789' # times = '1999-01-01T00:00:00.123456789'
# t = Time(times, format='isot', scale='utc') # t = Time(times, format='isot', scale='utc')
print() #print()
AstroSkyTime = time AstroSkyTime = time
print ("AstroPy time", AstroSkyTime) print ("AstroPy time", AstroSkyTime)
SkyfieldTime = ts.from_astropy(AstroSkyTime) SkyfieldTime = ts.from_astropy(AstroSkyTime)
@ -450,53 +537,86 @@ def InitObserver(SkyCity, SkyCountryCode, time,ts):
# Computer for all Laser "skies" their Right Ascension/Declinaison coordinates from their Altitude/azimuth Coordinates. # Computer for all Laser "skies" their Right Ascension/Declinaison coordinates from their Altitude/azimuth Coordinates.
# to later select their visible objects in radec catalogs like hipparcos. # to later select their visible objects in radec catalogs like hipparcos.
# LaserSky definition for one laser (in decimal degrees) : [LeftAzi, RightAzi, TopAlt, BotAlt, LeftRa, RightRa, TopDec, BottomDec] # LaserSky definition for one laser (in decimal degrees) : [RightAzi, LeftAzi, TopAlt, BotAlt, LeftRa, RightRa, TopDec, BottomDec]
# With 4 lasers with each one a quarter of the 360 ° real sky, there is 4 LaserSky : # With 4 lasers with each one a quarter of the 360 ° real sky, there is 4 LaserSky :
LaserSkies = [[0.0,90.0,90.0,0.0,0.0,0.0,0.0,0.0],[90,180,90,0,0,0,0,0],[180,270,90,0,0,0,0,0],[270,360,90,0,0,0,0,0]] LaserSkies = [[45,135.0,90.0,0.0,0.0,0.0,0.0,0.0],[135,225,90,0,0,0,0,0],[225,315,90,0,0,0,0,0],[305,0,90,0,0,0,0,0]]
RadecSkies(LaserSkies, AstroSkyTime) RadecSkies(LaserSkies, AstroSkyTime)
def NewTime(timeshift): def NewTime(timeshift):
SkyfieldTime += timeshift SkyfieldTime += timeshift
UpdateSolar()
UpdateStars() if DisplaySolar:
UpdateSolar()
if DisplayStars:
UpdateStars()
if DisplayAnything:
UpdateAnything()
#def handlerfunction(s, x, y):
# Will receive message data unpacked in s, x, y
# pass
def OSChandler(address, s, x, y):
# Will receive message address, and message data flattened in s, x, y
print("Planetarium OSC server got address", address,"s",s,"x",x,"y",y)
pass
def WebStatus(message):
lj3.Send("/status",message)
# #
# Main functions # Main part
# #
try:
lj3.OSCstart()
def Planetarium(): # Make server channels to receive packets.
#osc_udp_server("127.0.0.1", 3721, "localhost")
osc_udp_server("0.0.0.0", OSCinPort, "InPort")
# Associate Python functions with message address patterns, using default
# argument scheme OSCARG_DATAUNPACK.
#osc_method("/planet/*", handlerfunction)
# Too, but request the message address pattern before in argscheme
osc_method("/planet/*", OSChandler, argscheme=osm.OSCARG_ADDRESS + osm.OSCARG_DATAUNPACK)
ts = load.timescale() ts = load.timescale()
LoadHipparcos(ts)
LoadSolar()
LoadCities() LoadCities()
SkyCity = 'Paris' SkyCity = 'Paris'
SkyCountryCode = 'FR' SkyCountryCode = 'FR'
LoadSolar()
InitObserver(SkyCity, SkyCountryCode, Time.now(),ts) InitObserver(SkyCity, SkyCountryCode, Time.now(),ts)
print()
print ("Updating Sky Objects for current observer...") LoadHipparcos(ts)
print()
StarSelect()
#print()
#print ("Updating Sky Objects for current observer...")
#print()
print("Updating solar system (de421) objects position for observer at", Skylat, Skylong, "time", SkyfieldTime.utc_iso()) print("Updating solar system (de421) objects position for observer at", Skylat, Skylong, "time", SkyfieldTime.utc_iso())
UpdateSolar() UpdateSolar()
print ("Done.") #print ("Done.")
print() #print()
print("Updating stars for observer at", Skylat, Skylong, "time", SkyfieldTime.utc_iso()) print("Updating stars for observer at", Skylat, Skylong, "time", SkyfieldTime.utc_iso())
#UpdateStars() UpdateStars(ts)
print ("Done.") print ("Done.")
# UpdateStars() Todo # UpdateStars() Todo
DisplayStars = False DisplayStars = True
DisplaySolar = True DisplaySolar = False
DisplayOrientation = True DisplayOrientation = True
DisplayAnything = False
while 1: while 1:
@ -507,14 +627,29 @@ def Planetarium():
if DisplaySolar: if DisplaySolar:
DrawSolar(laser) DrawSolar(laser)
if DisplayStars: if DisplayStars:
pass DrawStars(laser)
if DisplayAnything:
DrawAnything()
lj3.DrawPL(laser) lj3.DrawPL(laser)
time.sleep(0.01) lj3.OSCframe()
time.sleep(0.01)
except KeyboardInterrupt:
pass
# Gently stop on CTRL C
finally:
lj3.OSCstop()
print ("Fin du planetarium.")
Planetarium()

83
clients/textcycl.py Normal file
View File

@ -0,0 +1,83 @@
# coding=UTF-8
'''
Cycling text on one LJ laser.
LICENCE : CC
'''
import redis
import lj
import sys,time
import argparse
duration = 300
lasertext = ["TEAMLASER","FANFAN","LOLOSTER","SAM"]
'''
is_py2 = sys.version[0] == '2'
if is_py2:
from Queue import Queue
else:
from queue import Queue
'''
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Text Cycling for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int)
args = argsparser.parse_args()
if args.client:
ljclient = args.client
else:
ljclient = 0
if args.laser:
plnumber = args.laser
else:
plnumber = 0
# Redis Computer IP
if args.redisIP != None:
redisIP = args.redisIP
else:
redisIP = '127.0.0.1'
lj.Config(redisIP,ljclient)
#r = redis.StrictRedis(host=redisIP, port=6379, db=0)
# If you want to use rgb for color :
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
def Run():
counter =0
step = 0
timing = -1
color = rgb2int(255,255,255)
while 1:
if timing == duration or timing == -1:
message = lasertext[step]
lj.Text(message, color, PL = 0, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj.DrawPL(0)
timing = 0
else:
step += 1
if step >3:
step =0
timing += 1
time.sleep(0.01)
Run()

View File

@ -74,8 +74,11 @@ swapY = [1,1,1,-1]
# For glitch art : change position and number of points added by tracer.py # For glitch art : change position and number of points added by tracer.py
# shortline is for distance with next point, shorter than 4000 (in etherdream coordinates) # shortline is for distance with next point, shorter than 4000 (in etherdream coordinates)
# i.e (0.25,3) means add 3 points at 25% on the line. # i.e (0.25,3) means add 3 points at 25% on the line.
stepshortline = [(1.0, 8)] #stepshortline = [(1.0, 8)]
stepslongline = [(0.25, 3), (0.75, 3), (1.0, 10)] #stepslongline = [(0.25, 3), (0.75, 3), (1.0, 10)]
stepslongline = [(0.25,1), (0.75, 1), (1.0, 1)]
#stepshortline = [(1.0, 8)]
stepslongline = [(1.0, 1)]
point = [0,0,0] point = [0,0,0]

View File

@ -8,6 +8,7 @@ Laser server + webUI servers (ws + OSC)
- get point list to draw : /pl/lasernumber - get point list to draw : /pl/lasernumber
- for report /lstt/lasernumber /lack/lasernumber /cap/lasernumber - for report /lstt/lasernumber /lack/lasernumber /cap/lasernumber
- A nice ws debug tool : websocat
todo : todo :
@ -417,7 +418,7 @@ finally:
r.set('/lstt/'+str(laserid),64) r.set('/lstt/'+str(laserid),64)
r.set('/cap/'+str(laserid),0) r.set('/cap/'+str(laserid),0)
print "Fin des haricots" print "Fin de LJ."
''' '''

View File

@ -14,16 +14,26 @@
x.className = "button"; x.className = "button";
var x = document.getElementById("showlive"); var x = document.getElementById("showlive");
x.className = "button"; x.className = "button";
var x = document.getElementById("shownozoid");
x.className = "button";
var x = document.getElementById("showplanet");
x.className = "button";
// Hide all possible main central grids. // Hide all possible main central grids.
var x = document.getElementById("mgalign"); var x = document.getElementById("mgalign");
x.style.display = "none"; x.style.display = "none";
var x = document.getElementById("mgcanvas"); var x = document.getElementById("mgsimu");
x.style.display = "none";
var x = document.getElementById("mgrun");
x.style.display = "none";
var x = document.getElementById("mglive");
x.style.display = "none"; x.style.display = "none";
var x = document.getElementById("cnvbuttons");
x.style.display = "none";
var x = document.getElementById("mgrun");
x.style.display = "none";
var x = document.getElementById("mglive");
x.style.display = "none";
var x = document.getElementById("mgnozoid");
x.style.display = "none";
var x = document.getElementById("mgplanet");
x.style.display = "none";
} }
function showAlign() { function showAlign() {
@ -44,8 +54,10 @@
function showCanvas() { function showCanvas() {
noMenu(); noMenu();
var x = document.getElementById("mgcanvas"); var x = document.getElementById("mgsimu");
x.style.display = "block"; x.style.display = "grid";
var x = document.getElementById("cnvbuttons");
x.style.display = "grid";
var x = document.getElementById("showcanvas"); var x = document.getElementById("showcanvas");
x.className = "button:checked"; x.className = "button:checked";
} }
@ -57,7 +69,21 @@
var x = document.getElementById("showlive"); var x = document.getElementById("showlive");
x.className = "button:checked"; x.className = "button:checked";
} }
function showNozoid() {
noMenu();
var x = document.getElementById("mgnozoid");
x.style.display = "grid";
var x = document.getElementById("shownozoid");
x.className = "button:checked";
}
function showPlanet() {
noMenu();
var x = document.getElementById("mgplanet");
x.style.display = "grid";
var x = document.getElementById("showplanet");
x.className = "button:checked";
}
u
function buttonClicked(clicked_id) { function buttonClicked(clicked_id) {
_WS.send("/" + clicked_id); _WS.send("/" + clicked_id);
} }

View File

@ -21,7 +21,7 @@
} }
.mgstatus { .mgstatus {
display: grid; display: grid;
grid-template-columns: 250px 150px 1fr; grid-template-columns: 300px 150px 1fr;
grid-template-raw: 30px; grid-template-raw: 30px;
grid-column-gap: 1px; grid-column-gap: 1px;
grid-row-gap: 1px; grid-row-gap: 1px;
@ -46,15 +46,30 @@
border-style: groove; border-style: groove;
border-width: 1px; border-width: 1px;
} }
.mgcanvas { .mgsimu {
display: none; display: none;
height: 400px; height: 400px;
grid-template-columns: 1fr 1fr; width: 900px;
grid-template-rows: 1Fr; grid-template-columns: 500px 400px;
grid-template-rows: 400px;
background-color: #151515; background-color: #151515;
}
.cnvbuttons {
display: none;
height: 400px;
width: 400px;
grid-template-columns: 66px 66px 66px 66px;
grid-template-rows: 66px 17px 69px 17px;
background-color: #000;
justify-items: center;
align-items: center;
border-color: #445; border-color: #445;
border-style: groove; border-style: groove;
border-width: 1px; border-width: 1px;
grid-gap: 1px;
transition: all .3s ease;
background-color: #151515;
} }
.mglive { .mglive {
display: none; display: none;
@ -66,6 +81,24 @@
border-style: groove; border-style: groove;
border-width: 1px; border-width: 1px;
} }
.mgnozoid {
display: none;
height: 400px;
grid-template-columns: 1Fr;
grid-template-rows: 1Fr;
background-color: #151515;
border-color: #445;
border-style: groove;
border-width: 1px;
}
.mgplanet {
display: none;
height: 400px;
width: 900px;
grid-template-columns: 500px 400px;
grid-template-rows: 400px;
background-color: #151515;
}
.mgrun { .mgrun {
display: none; display: none;
height: 400px; height: 400px;

View File

@ -5,7 +5,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>LJ</title> <title>LJ</title>
<!-- Web audio defaults --> <!-- Web audio buttons defaults -->
<script src="webcomponents-lite.js"></script> <script src="webcomponents-lite.js"></script>
<script> <script>
WebAudioControlsOptions={ WebAudioControlsOptions={
@ -18,18 +18,26 @@
} }
</script> </script>
<script src="webaudio-controls.js"></script> <script src="webaudio-controls.js"></script>
<link rel="stylesheet" href="LJgrid.css" /> <link rel="stylesheet" href="LJgrid.css" />
<script src="LJ.js"></script> <!-- Javascript for this webapp is a the end of this html page and in LJ.js -->
<script src="LJ.js"></script>
</head> </head>
<body style="background-color:#222;"> <body style="background-color:#222;">
<!-- mg : MainGrid Webpage one column, different raws displayed or hidden by menu button --> <!--
MainGrid Webpage one column, different raws displayed or hidden by menu button
-->
<div class="maingrid"> <div class="maingrid">
<!-- mg : Title and laser state ()-->
<!--
Title and laser state
-->
<div class="mgtitle"> <div class="mgtitle">
<!-- LJ Logo --> <!-- LJ Logo -->
@ -73,7 +81,7 @@
</div> </div>
<div> <div>
<!-- <!--
<div class="topgrid"> <div class="topgrid">
<div class="lasertext">Laser</div> <div class="lasertext">Laser</div>
<div><webaudio-knob id="noteon" src="knobs/Prophetic5.png" diameter="70" min="16" max="20" value="0" sprites="5"></webaudio-knob></div> <div><webaudio-knob id="noteon" src="knobs/Prophetic5.png" diameter="70" min="16" max="20" value="0" sprites="5"></webaudio-knob></div>
@ -90,7 +98,11 @@
<div></div> <div></div>
</div> </div>
<!-- mg : Menu buttons and Status display -->
<!--
Menu buttons and Status display
-->
<div id="mgstatus" class="mgstatus"> <div id="mgstatus" class="mgstatus">
<div> <div>
<!-- <webaudio-switch id="align" height="10" width="99" value="0" src="knobs/align.png" type="toggle"></webaudio-switch> <!-- <webaudio-switch id="align" height="10" width="99" value="0" src="knobs/align.png" type="toggle"></webaudio-switch>
@ -101,18 +113,23 @@
<button class="button" id="showcanvas" onclick="showCanvas()">Simu</button> <button class="button" id="showcanvas" onclick="showCanvas()">Simu</button>
<button class="button" id="showrun" onclick="showRun()">Run</button> <button class="button" id="showrun" onclick="showRun()">Run</button>
<button class="button" id="showlive" onclick="showLive()">Live</button> <button class="button" id="showlive" onclick="showLive()">Live</button>
<button class="button" id="shownozoid" onclick="showNozoid()">Nozoid</button>
<button class="button" id="showplanet" onclick="showPlanet()">Planet</button>
</div> </div>
<div><button class="button" id="showstatus">DISCONNECTED</button></div> <div><button class="button" id="showstatus">DISCONNECTED</button></div>
<div></div> <div></div>
</div> </div>
<!-- mg : Align -->
<!--
Align
-->
<div id="mgalign" class="mgalign"> <div id="mgalign" class="mgalign">
<!-- Laserbox 0 --> <!-- Laser 0 -->
<div class="laserbox"> <div class="laserbox">
<!-- IP 0 --> <!-- IP laser 0 -->
<div> <div>
<form onsubmit="onSubmit(); return false;"> <form onsubmit="onSubmit(); return false;">
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/0"> <input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/0">
@ -160,24 +177,28 @@
</div> </div>
</div> </div>
<!-- Laserbox 1 --> <!-- Laser 1 -->
<div class="laserbox"> <div class="laserbox">
<!-- IP 1 --> <!-- IP laser 1 -->
<div> <div>
<form onsubmit="onSubmit(); return false;"> <form onsubmit="onSubmit(); return false;">
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/1"> <input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/1">
</form> </form>
</div> </div>
<div> <div>
<!-- Align Icons --> <!-- Align Icons -->
<webaudio-switch id="grid/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/grid.png"></webaudio-switch> <webaudio-switch id="grid/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/grid.png"></webaudio-switch>
<webaudio-switch id="mouse/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/mouse.png"></webaudio-switch> <webaudio-switch id="mouse/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/mouse.png"></webaudio-switch>
<!-- Blackout icon --> <!-- Blackout icon -->
<webaudio-switch id="black/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/blackout.png"></webaudio-switch> <webaudio-switch id="black/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/blackout.png"></webaudio-switch>
<!-- Swap Icons --> <!-- Swap Icons -->
<webaudio-switch id="swap/X/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapx.png"></webaudio-switch> <webaudio-switch id="swap/X/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapx.png"></webaudio-switch>
<webaudio-switch id="swap/Y/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapy.png"></webaudio-switch> <webaudio-switch id="swap/Y/1" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapy.png"></webaudio-switch>
</div> </div>
<!-- Lasergrid 1 --> <!-- Lasergrid 1 -->
<div class="lasergrid" style="background-image: url(lasergrid1.png);"> <div class="lasergrid" style="background-image: url(lasergrid1.png);">
<div><webaudio-param id="kpps/1" link="kpps/1"></webaudio-param></div> <div><webaudio-param id="kpps/1" link="kpps/1"></webaudio-param></div>
@ -209,24 +230,28 @@
</div> </div>
</div> </div>
<!-- Laserbox 2 --> <!-- Laser 2 -->
<div class="laserbox"> <div class="laserbox">
<!-- IP 2 --> <!-- IP laser 2 -->
<div> <div>
<form onsubmit="onSubmit(); return false;"> <form onsubmit="onSubmit(); return false;">
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/2"> <input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/2">
</form> </form>
</div> </div>
<div> <div>
<!-- Align Icons -->
<!-- Align Icons -->
<webaudio-switch id="grid/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/grid.png"></webaudio-switch> <webaudio-switch id="grid/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/grid.png"></webaudio-switch>
<webaudio-switch id="mouse/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/mouse.png"></webaudio-switch> <webaudio-switch id="mouse/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/mouse.png"></webaudio-switch>
<!-- Blackout icon --> <!-- Blackout icon -->
<webaudio-switch id="black/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/blackout.png"></webaudio-switch> <webaudio-switch id="black/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/blackout.png"></webaudio-switch>
<!-- Swap Icons --> <!-- Swap Icons -->
<webaudio-switch id="swap/X/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapx.png"></webaudio-switch> <webaudio-switch id="swap/X/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapx.png"></webaudio-switch>
<webaudio-switch id="swap/Y/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapy.png"></webaudio-switch> <webaudio-switch id="swap/Y/2" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapy.png"></webaudio-switch>
</div> </div>
<!-- Laser 2 grid --> <!-- Laser 2 grid -->
<div class="lasergrid" style="background-image: url(lasergrid2.png)"> <div class="lasergrid" style="background-image: url(lasergrid2.png)">
<div><webaudio-param id="kpps/2" link="kpps/2"></webaudio-param></div> <div><webaudio-param id="kpps/2" link="kpps/2"></webaudio-param></div>
@ -260,24 +285,28 @@
</div> </div>
</div> </div>
<!-- Laserbox 3 --> <!-- Laser 3 -->
<div class="laserbox"> <div class="laserbox">
<!-- IP 3 --> <!-- IP laser 3 -->
<div> <div>
<form onsubmit="onSubmit(); return false;"> <form onsubmit="onSubmit(); return false;">
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/3"> <input class = "submit" onchange = "onSubmit(this.id)" type="text" id="ip/3">
</form> </form>
</div> </div>
<div> <div>
<!-- Align Icons -->
<!-- Align Icons -->
<webaudio-switch id="grid/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/grid.png"></webaudio-switch> <webaudio-switch id="grid/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/grid.png"></webaudio-switch>
<webaudio-switch id="mouse/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/mouse.png"></webaudio-switch> <webaudio-switch id="mouse/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/mouse.png"></webaudio-switch>
<!-- Blackout icon --> <!-- Blackout icon -->
<webaudio-switch id="black/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/blackout.png"></webaudio-switch> <webaudio-switch id="black/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/blackout.png"></webaudio-switch>
<!-- Swap Icons --> <!-- Swap Icons -->
<webaudio-switch id="swap/X/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapx.png"></webaudio-switch> <webaudio-switch id="swap/X/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapx.png"></webaudio-switch>
<webaudio-switch id="swap/Y/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapy.png"></webaudio-switch> <webaudio-switch id="swap/Y/3" value="0" height="25" width="21" tooltip="Switch-B" src="knobs/swapy.png"></webaudio-switch>
</div> </div>
<!-- Laser 3 grid --> <!-- Laser 3 grid -->
<div class="lasergrid" style="background-image: url(lasergrid3.png)"> <div class="lasergrid" style="background-image: url(lasergrid3.png)">
<div><webaudio-param id="kpps/3" link="kpps/3" ></webaudio-param></div> <div><webaudio-param id="kpps/3" link="kpps/3" ></webaudio-param></div>
@ -312,11 +341,14 @@
</div> </div>
</div> </div>
<!-- mg : Live -->
<!--
Live
-->
<div id="mglive" class="mglive"> <div id="mglive" class="mglive">
<!-- with AI Interface -->
<!-- with AI box -->
<div class="withaibox"> <div class="withaibox">
<div class="lasertext" style="border-color:#334;border-style: groove;border-width:1px;">With AI <div class="lasertext" style="border-color:#334;border-style: groove;border-width:1px;">With AI
</div> </div>
@ -347,7 +379,7 @@
</div> </div>
<!-- Lissabox --> <!-- Lissa interface -->
<div class="lissabox"> <div class="lissabox">
<div class="lasertext" style="border-color:#334;border-style: groove;border-width:1px;">LISSA <div class="lasertext" style="border-color:#334;border-style: groove;border-width:1px;">LISSA
</div> </div>
@ -378,7 +410,7 @@
</div> </div>
</div> </div>
<!-- 3D proj grid --> <!-- 3D proj interface -->
<div class="projgrid"> <div class="projgrid">
<div></div> <div></div>
<div class="lasertext" style="border-color:#334;border-style: groove;border-width:1px;">3D ROT</div> <div class="lasertext" style="border-color:#334;border-style: groove;border-width:1px;">3D ROT</div>
@ -396,90 +428,181 @@
<div class="lasertext">Y</div> <div class="lasertext">Y</div>
<div class="lasertext">Z</div> <div class="lasertext">Z</div>
</div> </div>
</div> </div>
<!-- mg : canvas to display point list as laser simulator -->
<div id = "mgcanvas" class="mgcanvas"> <!--
<div> Simulator to display point list
<canvas id="canvas" width="500" height="500"></canvas> -->
</div>
<div></div> <div id = "mgsimu" class="mgsimu">
<div>
<canvas id="canvas" width="500" height="400" style="border-color: #445;border-style:groove;border-width:1px;"></canvas>
</div>
<!-- Selection buttons grid -->
<div id="cnvbuttons" class="cnvbuttons">
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 0" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 1" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 2" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 3" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 24" onclick ="buttonClicked(this.id)" class="button:checked">PL 0</button></div>
<div><button id ="noteon 25" onclick ="buttonClicked(this.id)" class="button">PL 1</button></div>
<div><button id ="noteon 26" onclick ="buttonClicked(this.id)" class="button">PL 2</button></div>
<div><button id ="noteon 27" onclick ="buttonClicked(this.id)" class="button">PL 3</button></div>
</div>
</div> </div>
<!-- mg run icons grid -->
<div id="mgrun"class="mgrun"> <!-- Laser Client selection grid -->
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 0" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 1" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 2" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 3" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div><button id ="noteon 4" onclick ="buttonClicked(this.id)" class="button">4</button></div>
<div><button id ="noteon 5" onclick ="buttonClicked(this.id)" class="button">5</button></div>
<div><button id ="noteon 6" onclick ="buttonClicked(this.id)" class="button">6</button></div>
<div><button id ="noteon 7" onclick ="buttonClicked(this.id)" class="button">7</button></div>
<!-- Simulator PL selection grid -->
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 24" onclick ="buttonClicked(this.id)" class="button:checked">PL 0</button></div>
<div><button id ="noteon 25" onclick ="buttonClicked(this.id)" class="button">PL 1</button></div>
<div><button id ="noteon 26" onclick ="buttonClicked(this.id)" class="button">PL 2</button></div>
<div><button id ="noteon 27" onclick ="buttonClicked(this.id)" class="button">PL 3</button></div>
<div></div>
<div></div>
<div></div>
<div></div>
<!-- Laser selection grid -->
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 16" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 17" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 18" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 19" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div></div>
<div></div>
<div></div>
<div></div>
<!-- Hidden grid -->
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<!-- mg : footer display events for debug --> <!--
Run
-->
<div id="mgrun" class="mgrun">
<!-- Laser Client selection grid -->
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 0" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 1" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 2" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 3" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div><button id ="noteon 4" onclick ="buttonClicked(this.id)" class="button">4</button></div>
<div><button id ="noteon 5" onclick ="buttonClicked(this.id)" class="button">5</button></div>
<div><button id ="noteon 6" onclick ="buttonClicked(this.id)" class="button">6</button></div>
<div><button id ="noteon 7" onclick ="buttonClicked(this.id)" class="button">7</button></div>
<!-- Simulator PL selection grid -->
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 24" onclick ="buttonClicked(this.id)" class="button:checked">PL 0</button></div>
<div><button id ="noteon 25" onclick ="buttonClicked(this.id)" class="button">PL 1</button></div>
<div><button id ="noteon 26" onclick ="buttonClicked(this.id)" class="button">PL 2</button></div>
<div><button id ="noteon 27" onclick ="buttonClicked(this.id)" class="button">PL 3</button></div>
<div></div>
<div></div>
<div></div>
<div></div>
<!-- Laser selection grid -->
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconlaser.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 16" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 17" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 18" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 19" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div></div>
<div></div>
<div></div>
<div></div>
<!-- Hidden grid -->
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconblack.png" alt=" " class="icongrid" /></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<!--
Nozoid
-->
<div id = "mgnozoid" class="mgnozoid">
<div>
<span class="lasertext">X</span>
<select>
<option value="LFO1">LFO1</option>
<option value="LFO2">LFO2</option>
<option value="LFO3">LFO3</option>
<option value="LFO4">LFO4</option>
</select>
<span class="lasertext">Y</span>
<select>
<option value="LFO1">LFO1</option>
<option value="LFO2">LFO2</option>
<option value="LFO3">LFO3</option>
<option value="LFO4">LFO4</option>
</select>
</div>
</div>
<!--
Planetarium
-->
<div id = "mgplanet" class="mgplanet">
<!-- Simuator canvas -->
<div>
<canvas id="canvas" width="500" height="400" style="border-color: #445;border-style:groove;border-width:1px;"></canvas>
</div>
<!-- Selection buttons grid -->
<div id="cnvbuttons" class="cnvbuttons">
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 0" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 1" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 2" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 3" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 24" onclick ="buttonClicked(this.id)" class="button:checked">PL 0</button></div>
<div><button id ="noteon 25" onclick ="buttonClicked(this.id)" class="button">PL 1</button></div>
<div><button id ="noteon 26" onclick ="buttonClicked(this.id)" class="button">PL 2</button></div>
<div><button id ="noteon 27" onclick ="buttonClicked(this.id)" class="button">PL 3</button></div>
</div>
</div>
<!--
Footer display events for debug
-->
<div class="mgfooter"> <div class="mgfooter">
<div id="showin"></div> <div id="showin"></div>
<div id="showout"></div> <div id="showout"></div>
@ -489,7 +612,9 @@
</div> </div>
<!-- web audio animations --> <!--
web audio buttons scripts
-->
<script type="text/javascript"> <script type="text/javascript">
var message=""; var message="";
var log=[]; var log=[];
@ -547,7 +672,9 @@
</script> </script>
<!-- Point list draw --> <!--
Simulator Point list drawing scripts
-->
<script type="text/javascript"> <script type="text/javascript">
// Store Reference To The Canvas & Set Context // Store Reference To The Canvas & Set Context
@ -655,7 +782,7 @@
</script> </script>
</body> </body>
<!-- non displayed items, for code reference <!-- non displayed items, for code reference mainly for other type of webaudio buttons
<div> <div>
<span class="lasertext">Swap X</span> <span class="lasertext">Swap X</span>
<span class="lasertext">Swap Y</span> <span class="lasertext">Swap Y</span>