diff --git a/LJ.conf b/LJ.conf index b71df3e..a842d13 100644 --- a/LJ.conf +++ b/LJ.conf @@ -1,5 +1,5 @@ [General] -lasernumber = 1 +lasernumber = 4 debug = 0 ljayserverip = 127.0.0.1 nozoscip = 127.0.0.1 @@ -39,9 +39,9 @@ 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.]] [laser2] color = -1 @@ -58,9 +58,9 @@ 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 @@ -77,7 +77,7 @@ 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.]] diff --git a/README.md b/README.md index ceef8b9..966dfc8 100644 --- a/README.md +++ b/README.md @@ -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. +There is a nice ws debug tool websocat. + # diff --git a/clients/planetarium/Readme.txt b/clients/planetarium/Readme.txt index a0bf4f1..c626757 100644 --- a/clients/planetarium/Readme.txt +++ b/clients/planetarium/Readme.txt @@ -2,39 +2,41 @@ Multi Laser planetarium in python3 for LJ. v0.01 Sam Neurohack -User can define : -- Observer position using GPS coordinates or built in cities catalog on earth. -- 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. -- +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 -Some future features : +It's an alpha release so a little hardcoded : -- Constellations display -- 3D with anaglyph -- Time Speed setting -- What do you want ? +- set observer position (find SkyCity, SkyCountryCode) in main.py like 'Paris' and 'FR' +- set observer date.time in InitObserver() arguments (default is now in UTC) +- set what sky part you want to display for each laser in 'LaserSkies' variable : Define alitude and azimuth for top left and bottom right -User must understand Right Ascension/Declinaison and Azimuth/Altitude coordinates system. Some needed astronomy concepts online : -https://rhodesmill.org/skyfield/stars.html -https://in-the-sky.org//staratlas.php?ra=15.358411414&dec=73.47660962&limitmag=2 -http://www.physics.csbsju.edu/astro/SF/SF.06.html +It needs more libraries than plan. Currently it relies on the awesome astropy, skyfield,... + +Soon some pictures. + +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 : -https://www.calsky.com/cs.cgi?cha=7&sec=3&sub=2 +To install : + +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. +''' \ No newline at end of file diff --git a/clients/planetarium/go3.sh b/clients/planetarium/go3.sh new file mode 100644 index 0000000..2760cb2 --- /dev/null +++ b/clients/planetarium/go3.sh @@ -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 \ No newline at end of file diff --git a/clients/planetarium/lj3.py b/clients/planetarium/lj3.py index 843ed35..7f47e5f 100644 --- a/clients/planetarium/lj3.py +++ b/clients/planetarium/lj3.py @@ -22,7 +22,11 @@ Sam Neurohack import math 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' r = redis.StrictRedis(host=redisIP, port=6379, db=0) @@ -32,16 +36,23 @@ ClientNumber = 0 point_list = [] pl = [[],[],[],[]] +# +# OSC interaction with LJ +# -''' -LJIP = "127.0.0.1" +def OSCstart(): + # 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=''): oscmsg = OSCMessage() @@ -50,21 +61,35 @@ def Send(oscaddress,oscargs=''): #print ("sending to bhorosc : ",oscmsg) try: - osclientlj.sendto(oscmsg, (redisIP, 8002)) - oscmsg.clearData() + msg = oscbuildparse.OSCMessage(oscaddress, None, [oscargs]) + osc_send(msg, "LJ 8002") except: print ('Connection to LJ refused : died ?') 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 = [ -#implementé +# caracteres corrects [(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)], #0 [(-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,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), (0,-30), (0,30)], [(-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), (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 @@ -163,6 +188,7 @@ def Config(redisIP,client): r = redis.StrictRedis(host=redisIP, port=6379, db=0) ClientNumber = client + osc_udp_client(redisIP, 8002, "LJ 8002") 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 x_offset = 26 * (- (0.9*l) + 3*i) #print i,x_offset + # if digit if ord(ch)<58: char_pl_list = ASCII_GRAPHICS[ord(ch) - 48] else: - char_pl_list = ASCII_GRAPHICS[ord(ch) - 46] + char_pl_list = ASCII_GRAPHICS[ord(ch) - 46 ] char_draw = [] #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 #print ch,char_pl_list,char_draw rPolyLineOneColor(char_draw, c, PL , False, xpos, ypos, resize, rotx, roty, rotz) + #print ("laser",PL,"message",message) #dots.append(char_draw) diff --git a/clients/planetarium/main.py b/clients/planetarium/main.py old mode 100644 new mode 100755 index 5e0b445..c6bfae6 --- a/clients/planetarium/main.py +++ b/clients/planetarium/main.py @@ -37,6 +37,11 @@ from astropy.time import Time from skyfield.api import Star, load, Topos,Angle from skyfield.data import hipparcos +from osc4py3.as_eventloop import * +from osc4py3 import oscbuildparse +from osc4py3 import oscmethod as osm + + import json ''' @@ -53,6 +58,8 @@ else: import argparse + + print ("") print ("Arguments parsing if needed...") 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("-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("-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("-r","--redisIP",help="Country code of the observer ",type=str) @@ -81,6 +89,11 @@ if args.debug: else: debug = 0 +if args.input: + OSCinPort = args.input +else: + OSCinPort = 8005 + # Redis Computer IP if args.redisIP != None: redisIP = args.redisIP @@ -95,16 +108,12 @@ lj3.Config(redisIP,ljclient) fov = 256 viewer_distance = 2.2 -width = 450 -height = 450 +width = 750 +height = 750 centerX = width / 2 centerY = height / 2 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 : @@ -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 - (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. Example ra,dec = aa2radec( azimuth = 0, altitude = 90, lati = 48.85341, longi = 2.3488, elevation = 100, t =AstroPyNow ) with AstroPyNow = Time.now() @@ -211,36 +220,60 @@ def RadecSkies(LaserSkies, AstroSkyTime): print() print("Converting", lasernumber, "LaserSkies limits in Right Ascension & Declination (radec) coordinates ") for laser in range(lasernumber): + if debug > 0: + print("Laser",laser) # Left top point 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 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: print(LaserSkies) print ("Done.") def azimuth2scrX(leftAzi,rightAzi,s): + 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)) def altitude2scrY(topAlti,botAlti,s): - a1, a2 = botAlti, topAlti - b1, b2 = -height/2, height/2 + a1, a2 = topAlti, botAlti + 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)) - - + # # Solar System # 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(): global planets, SolarObjects, earth @@ -257,7 +290,6 @@ def LoadSolar(): def UpdateSolar(): global SolarObjects - # Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver. for number,object in enumerate(SolarObjects): @@ -300,56 +332,43 @@ def LoadHipparcos(ts): hipparcosURL = 'data/hip_main.dat.gz' with load.open(hipparcosURL) as f: hipdata = hipparcos.load_dataframe(f) - print("Loaded.") + #print("Loaded.") hipparcos_epoch = ts.tt(1991.25) # CODE IMPORTED HERE FROM TESTS. NEEDS TO ADAPT # Star selection def StarSelect(): + global StarsObjects, hipdatafilt - hipparcos_epoch = ts.tt(1991.25) - barnards_star = Star.from_dataframe(hipdata.loc[87937]) - polaris = Star.from_dataframe(hipdata.loc[11767]) + StarsObjects = [[]] + #hipparcos_epoch = ts.tt(1991.25) + #barnards_star = Star.from_dataframe(hipdata.loc[87937]) + #polaris = Star.from_dataframe(hipdata.loc[11767]) print() - print ("Selecting sky portion") + print ("Stars selection...") - hipdatafilt = hipdata[hipdata['magnitude'] <= 2.5] - print(('After filtering, there are {} stars with magnitude <= 2.5'.format(len(hipdatafilt)))) - bright_stars = Star.from_dataframe(hipdatafilt) - print (hipdatafilt) - #print (bright_stars) + hipdatafilt = hipdata[hipdata['magnitude'] <= 3.5] + print(('{} stars with magnitude <= 3.5'.format(len(hipdatafilt)))) + Starnames = hipdatafilt.index - t = ts.utc(2018, 9, 3) - - ''' - 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()) + StarsObjects[0] = [Starnames[0],0,0] + for index in range(len(Starnames)-1): + StarsObjects.append([Starnames[index+1],0,0]) -def UpdateStars(): +def UpdateStars(ts): global StarsObjects + hipparcos_epoch = ts.tt(1991.25) # Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver. for number,object in enumerate(StarsObjects): #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: - PrintSolar() + PrintStars() def PrintStars(): @@ -360,10 +379,71 @@ def DrawStars(laser): for number,object in enumerate(StarsObjects): - # Solar object is in given laser sky azimuth and altitude range ? - if LaserSkies[laser][0] < StarsObjects[number][2] < LaserSkies[laser][1] and 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 altitude range ? + if LaserSkies[laser][3] < StarsObjects[number][1] < LaserSkies[laser][2]: + + # 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") s = f.read() world = json.loads(s) - print("Loaded.") + #print("Loaded.") # 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): + #print("LaserSkies 0",LaserSkies[laser][0],"LaserSkies 1",LaserSkies[laser][1]) # North direction is in given laser sky azimuth range? - if LaserSkies[laser][0] < 0 < LaserSkies[laser][1]: - lj3.Text("N",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0), 300) + if LaserSkies[laser][1] < LaserSkies[laser][0]: + #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 ? - if LaserSkies[laser][0] < 90 < LaserSkies[laser][1]: - lj3.Text("E",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],90), 300) + if LaserSkies[laser][0] <= 90 < LaserSkies[laser][1]: + #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 ? - if LaserSkies[laser][0] < 180 < LaserSkies[laser][1]: - lj3.Text("S",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],180), 300) + if LaserSkies[laser][0] <= 180 < LaserSkies[laser][1]: + #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 ? - if LaserSkies[laser][0] < 270 < LaserSkies[laser][1]: - lj3.Text("W",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],270), 300) + if LaserSkies[laser][0] <= 270 < LaserSkies[laser][1]: + #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 #Skylat = 48.85341 # decimal degree #Skylong = 2.3488 # decimal degree - print() + #print() print("Observer GPS position and time...") Skylat, Skylong = CityPositiion(SkyCity,SkyCountryCode) print ("GPS Position of",SkyCity, "in", SkyCountryCode, ":",Skylat,Skylong) @@ -438,7 +525,7 @@ def InitObserver(SkyCity, SkyCountryCode, time,ts): # Other time in Astropy style # times = '1999-01-01T00:00:00.123456789' # t = Time(times, format='isot', scale='utc') - print() + #print() AstroSkyTime = time print ("AstroPy time", 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. # 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 : - 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) def NewTime(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: - -def Planetarium(): - + lj3.OSCstart() + # 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() - LoadHipparcos(ts) - LoadSolar() LoadCities() - SkyCity = 'Paris' SkyCountryCode = 'FR' + LoadSolar() InitObserver(SkyCity, SkyCountryCode, Time.now(),ts) - print() - print ("Updating Sky Objects for current observer...") - print() + + LoadHipparcos(ts) + + + 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()) UpdateSolar() - print ("Done.") - print() + #print ("Done.") + #print() print("Updating stars for observer at", Skylat, Skylong, "time", SkyfieldTime.utc_iso()) - #UpdateStars() + UpdateStars(ts) print ("Done.") # UpdateStars() Todo - DisplayStars = False - DisplaySolar = True + DisplayStars = True + DisplaySolar = False DisplayOrientation = True - + DisplayAnything = False while 1: @@ -507,14 +627,29 @@ def Planetarium(): if DisplaySolar: DrawSolar(laser) if DisplayStars: - pass + DrawStars(laser) + if DisplayAnything: + DrawAnything() 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() diff --git a/clients/textcycl.py b/clients/textcycl.py new file mode 100644 index 0000000..40685a0 --- /dev/null +++ b/clients/textcycl.py @@ -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() + + diff --git a/gstt.py b/gstt.py index 52868dc..541b1c9 100644 --- a/gstt.py +++ b/gstt.py @@ -74,8 +74,11 @@ swapY = [1,1,1,-1] # 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) # i.e (0.25,3) means add 3 points at 25% on the line. -stepshortline = [(1.0, 8)] -stepslongline = [(0.25, 3), (0.75, 3), (1.0, 10)] +#stepshortline = [(1.0, 8)] +#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] diff --git a/main.py b/main.py index dcb1987..33eba79 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ Laser server + webUI servers (ws + OSC) - get point list to draw : /pl/lasernumber - for report /lstt/lasernumber /lack/lasernumber /cap/lasernumber +- A nice ws debug tool : websocat todo : @@ -417,7 +418,7 @@ finally: r.set('/lstt/'+str(laserid),64) r.set('/cap/'+str(laserid),0) -print "Fin des haricots" +print "Fin de LJ." ''' diff --git a/webui/LJ.js b/webui/LJ.js index 8394be9..9492431 100644 --- a/webui/LJ.js +++ b/webui/LJ.js @@ -14,16 +14,26 @@ x.className = "button"; var x = document.getElementById("showlive"); 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. var x = document.getElementById("mgalign"); x.style.display = "none"; - var x = document.getElementById("mgcanvas"); - x.style.display = "none"; - var x = document.getElementById("mgrun"); - x.style.display = "none"; - var x = document.getElementById("mglive"); + var x = document.getElementById("mgsimu"); 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() { @@ -44,8 +54,10 @@ function showCanvas() { noMenu(); - var x = document.getElementById("mgcanvas"); - x.style.display = "block"; + var x = document.getElementById("mgsimu"); + x.style.display = "grid"; + var x = document.getElementById("cnvbuttons"); + x.style.display = "grid"; var x = document.getElementById("showcanvas"); x.className = "button:checked"; } @@ -57,7 +69,21 @@ var x = document.getElementById("showlive"); 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) { _WS.send("/" + clicked_id); } diff --git a/webui/LJgrid.css b/webui/LJgrid.css index 2739fca..f905783 100644 --- a/webui/LJgrid.css +++ b/webui/LJgrid.css @@ -21,7 +21,7 @@ } .mgstatus { display: grid; - grid-template-columns: 250px 150px 1fr; + grid-template-columns: 300px 150px 1fr; grid-template-raw: 30px; grid-column-gap: 1px; grid-row-gap: 1px; @@ -46,15 +46,30 @@ border-style: groove; border-width: 1px; } -.mgcanvas { +.mgsimu { display: none; height: 400px; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1Fr; + width: 900px; + grid-template-columns: 500px 400px; + grid-template-rows: 400px; 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-style: groove; border-width: 1px; + grid-gap: 1px; + transition: all .3s ease; + background-color: #151515; } .mglive { display: none; @@ -66,6 +81,24 @@ border-style: groove; 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 { display: none; height: 400px; diff --git a/webui/index.html b/webui/index.html index 7a4bbaf..2978eaf 100644 --- a/webui/index.html +++ b/webui/index.html @@ -5,7 +5,7 @@ LJ - + - - + + + - + - + +
- + + +
@@ -73,7 +81,7 @@
- + + +
+ + +
- +
- +
@@ -160,24 +177,28 @@
- +
- +
+ + +
+
@@ -209,24 +230,28 @@
- +
- +
- + + + +
+
@@ -260,24 +285,28 @@
- +
- +
- + + + +
+
@@ -312,11 +341,14 @@
- + + +
- - +
With AI
@@ -347,7 +379,7 @@
- +
LISSA
@@ -378,7 +410,7 @@
- +
3D ROT
@@ -396,90 +428,181 @@
Y
Z
- -
- -
-
- -
-
+ + + +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- + + +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + +
+
+ X + + Y + +
+
+ + + + +
+ + +
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
@@ -489,7 +612,9 @@
- + - + -