Stellarium / stellarium

Stellarium is a free GPL software which renders realistic skies in real time with OpenGL. It is available for Linux/Unix, Windows and macOS. With Stellarium, you really see what you can see with your eyes, binoculars or a small telescope.
https://stellarium.org
GNU General Public License v2.0
7.54k stars 813 forks source link

New Stellarium script example request to update Stellarium view based on telescope Line of sight #3362

Open vpicouet opened 1 year ago

vpicouet commented 1 year ago

Telescope control is a very interesting feature but I could not find a way to do the reverse action: Use some updating line of sight position from a telescope (+ possibly GPS positions for a balloon or satellite project for instance) and update Stellarium view accordingly.

Is there already a .ssc script that does a similar thing (like read the last line of a catalog every second and update the Stellarium sky position)? Thanks a lot for the help!

github-actions[bot] commented 1 year ago

Thanks for adding your first issue to Stellarium. If you have questions, please do not hesitate to contact us.

gzotti commented 1 year ago

TelescopeControl sends GOTO commands to connected telescopes and displays a marker at the position which these telescopes transmits. There is no known scripting application with the TelescopeControl plugin I am aware of.

Can you explain more clearly a scenario of what you want to achieve?

vpicouet commented 1 year ago

Thanks for your quick reply! Sure! I work on a balloon borne telescope project (~40km altitude). We have guidance capabilities so we always know what is the line of sight of the instrument. We receive this information quasi in real time (added in a standard .csv table).

During the balloon flight, we would like to have the capability to display on Stellarium the evolution of the line of sight / FOV of the telescope.

I guess that in order to do that we should use the scripting capabilities of Stellarium and write a .ssc script that:

We already have an estimation of the RA,DEC so a simpler alternative would just be to ask Stellarium to stay on the last RA,DEC,rotation values.

I feel it's a pretty interesting & useful feature, so I guess this kind of scripts must have been already developed several times by space agencies or universities in the past. Do you see more what I was refering to?

gzotti commented 1 year ago

Not sure if you can read a CSV file. It may be far simpler to use the RemoteControl API. Just reset view direction and location via HTTP whenever you write out a line to CSV.

vpicouet commented 1 year ago

Ok thanks: You are suggesting to just use curl -d "j2000=[3, 2, 2]" http://localhost:8090/api/main/view each time the table is updated.

I did not find the Stellarium documentation to convert J2000(ra,dec) into Vec3d used for setViewDirectionJ2000. Let's say I want to move on RAD/DEC J2000: 279.24°/38.78°, what x,y,z should I give to curl -d "j2000=[x,y,z]" http://localhost:8090/api/main/view ?

Thanks for the help!

gzotti commented 1 year ago

/api/main/view is documented at https://stellarium.org/doc/head/remoteControlApi.html#rcMainService

vpicouet commented 1 year ago

Ok thanks, indeed I developed a short python script to do so:

def follow_FB_LOS_on_Stellarium(path="/tmp/test.csv",ftype="replay",n_ra="DV Asc D",n_dec="DV Dec",gtype="radec",n_alt="DV EL",n_az="DV Az",lat="Latitude",lon="Longi",alt="Altitude",date="Datation GPS",dformat="%d/%m/%y %H:%M:%S",sleep=0.1):

    i=0
    cat = Table.read(path,format="csv",delimiter=";")
    loc = EarthLocation(lat = cat[lat][-1]*u.deg, lon = cat[lon][-1]*u.deg, height = cat[alt][-1]*u.m)
    obj = SkyCoord(ra = cat[n_ra]*u.deg, dec = cat[n_dec]*u.deg)
    delay=1*u.min
    altaz = obj.transform_to(AltAz(obstime=Time([datetime.datetime.strptime(cat[date][i], dformat) for i in range(len(cat))])+delay, location = loc))
    cat["alt_from_ra"] =  np.array((altaz.alt)*u.deg)
    cat["az_from_ra"] =  np.array((altaz.az)*u.deg)

    n_az_b = n_az+"_b"
    cat[n_az_b] = 180 - cat[n_az]
    os.system('curl -d "latitude=%0.3f" http://localhost:8090/api/location/setlocationfields > /dev/null 2>&1'%(cat[lat][0]))
    os.system('curl -d "longitude=%0.3f" http://localhost:8090/api/location/setlocationfields  > /dev/null 2>&1'%(cat[lon][0]))
    os.system('curl -d "altitude=%0.3f" http://localhost:8090/api/location/setlocationfields  > /dev/null 2>&1'%(cat[alt][0]))

    while 1>0:
        cat = Table.read(path,format="csv",delimiter=";")
        cat[n_az_b] =  180-cat[n_az]
        if gtype=="radec":
            a,b = n_ra, n_dec
        elif gtype=="altaz":
            b,a = n_alt, n_az_b

        if ftype=="real-time":
            i=-1
        elif ftype=="replay":
            cat["x"] = np.cos(cat[b] * np.pi / 180) * np.cos(cat[a] * np.pi / 180)
            cat["y"] = np.cos(cat[b] * np.pi / 180) * np.sin(cat[a] * np.pi / 180)
            cat["z"] = np.sin(cat[b] * np.pi / 180)
            i+=1

        alpha, delta = cat[a][int(i)], cat[b][int(i)]
        x = np.cos(delta * np.pi / 180) * np.cos(alpha * np.pi / 180)
        y = np.cos(delta * np.pi / 180) * np.sin(alpha * np.pi / 180)
        z = np.sin(delta * np.pi / 180)

        if gtype=="radec":
            command = ['curl -d "j2000=[%0.10f,%0.10f,%0.10f]" http://localhost:8090/api/main/view  > /dev/null 2>&1'%(x,y,z)]
            command.append('curl -d "time=%0.10f" http://localhost:8090/api/main/time  > /dev/null 2>&1'%(convert_to_julian(cat[date][i], dformat)))
            os.system(";".join(command))
        elif gtype=="altaz":
            command = ['curl -d "altAz=[%0.10f,%0.10f,%0.10f]" http://localhost:8090/api/main/view  > /dev/null 2>&1'%(x,y,z)]
            command.append('curl -d "time=%0.10f" http://localhost:8090/api/main/time  > /dev/null 2>&1'%(convert_to_julian(cat[date][i], dformat)))
            # os.system('curl -d "latitude=%0.3f" http://localhost:8090/api/location/setlocationfields  > /dev/null 2>&1'%(cat[lat][i]))
            # os.system('curl -d "longitude=%0.3f" http://localhost:8090/api/location/setlocationfields  > /dev/null 2>&1'%(cat[lon][i]))
            # os.system('curl -d "altitude=%0.3f" http://localhost:8090/api/location/setlocationfields  > /dev/null 2>&1'%(cat[alt][i]))
            os.system(";".join(command))

        time.sleep(sleep)

Unfortunately, because it takes some time for stellarium to interpret each command (~0.1sec), if I want to both change LOS(alt/az) and time, we see 2 moves in stellarium while there should be continuity (as we are guiding).

Is there a way with the API to send two commands at once so that Stellarium change the display only once (when both command have been interpreted). Thanks for the help

10110111 commented 1 year ago

Is there a way with the API to send two commands at once so that Stellarium change the display only once

Have you tried passing multiple -d parameters to curl? This way you could use a single setlocationfields request for latitude, longitude and altitude. Maybe this is what gives you two movements, rather than the separation of time setting.

vpicouet commented 1 year ago

Thanks for the answer, but for now the issue is when I use

            command = ['curl -d "j2000=[%0.10f,%0.10f,%0.10f]" http://localhost:8090/api/main/view  > /dev/null 2>&1'%(x,y,z)]
            command.append('curl -d "time=%0.10f" http://localhost:8090/api/main/time  > /dev/null 2>&1'%(convert_to_julian(cat[date][i], dformat)))
            os.system(";".join(command))

or

            command = ['curl -d "altAz=[%0.10f,%0.10f,%0.10f]" http://localhost:8090/api/main/view  > /dev/null 2>&1'%(x,y,z)]
            command.append('curl -d "time=%0.10f" http://localhost:8090/api/main/time  > /dev/null 2>&1'%(convert_to_julian(cat[date][i], dformat)))
            os.system(";".join(command))

Is there a command to both set LOS and time at the same time?

10110111 commented 1 year ago

There's no such command, but you can try using the same connection, so that curl doesn't have to connect, send first command, disconnect, then again connect, and send second command. This should reduce time gap. See this discussion.

vpicouet commented 1 year ago

Thanks! indeed using command = ['curl -d "j2000=[%0.10f,%0.10f,%0.10f]" http://localhost:8090/api/main/view > /dev/null 2>&1'%(x,y,z)] command.append(' -d "time=%0.10f" http://localhost:8090/api/main/time > /dev/null 2>&1'%(convert_to_julian(cat[date][i], dformat))) os.system(" --next ".join(command)) helps to go from 0.1s lag to ~0.03s lag, though it still impacts the visual rendering. For now I can live with this small issue.

I was wondering if there is also a way to change the angle of the oculars captors via the API. This could be very helpful for lost in sky / field recognition. Capture d’écran, le 2023-08-11 à 15 52 51

10110111 commented 1 year ago

I was wondering if there is also a way to change the angle of the oculars captors via the API.

I don't think there is (at least there's no mention of "ocular" in RemoteControl plugin sources). But if your aim is to have orientation of the stars always the same relative to the sensor frame, maybe you just need to enable equatorial mount in the Telescopes tab?

gzotti commented 1 year ago

There is no dedicated RemoteControl API for the Oculars plugin, and Oculars was not in focus of this RC development. If Oculars settings are StelProperties (I have not checked), it should work, though.

vpicouet commented 1 year ago

Thanks for your answers, it helped a lot