poliastro / poliastro

poliastro - :rocket: Astrodynamics in Python
https://docs.poliastro.space
MIT License
886 stars 284 forks source link

Ground Track Plotter #497

Closed jorgepiloto closed 4 years ago

jorgepiloto commented 5 years ago

🎯 Objective Hi everyone,

I thought it would be interesting to include a "Ground Track Plotter" in the module of poliastro.plotting. It works in the same way as the other functions of this module: you just have to call a function called groundTrackthat takes as arguments an orbit, labelwith the possibility of using the dark mode.

πŸ–₯ Previous figure tries to plot the following orbit:

#PLOTING GROUND TRACK
from poliastro.plotting import groundTrack 

r = [-6045, -3490, 2500] * u.km
v = [-3.457, 6.618, 2.533] * u.km / u.s
ss = Orbit.from_vectors(Earth, r, v)

groundTrack(ss, dark=True)
plt.show()

Till here everything works as it should. However, once I pass the function an Orbitobject, I obtain really strange ground tracks:

pic

Notice that horizontal dashed lines are just for plotting Cancer and Capricorn Tropics.

πŸ’‘ Possible solutions

If the idea is interesting for poliastro community, I will make a pull request but probably will need some help with the conversions between reference systems. I think the problem may be here, since if you try to plot just a latitude and longitude it works perfectly, showing that exact point on map.

Cape Canaveral Coordinates lat = 28.396837 lon = -80.605659

plot

astrojuanlu commented 5 years ago

Hi @IngenieroDeAviones, thanks a lot for the suggestion! I recommend you to check out this notebook of mine:

http://nbviewer.jupyter.org/github/Juanlu001/catching-asteroids-tracking-satellites/blob/master/Talk.ipynb#Plot-groundtrack

In particular, Cartopy will help you a lot projecting lat/lon data in the right way, avoiding all sorts of singularities.

Also, avoid basemap because it's abandoned: https://matplotlib.org/basemap/users/intro.html#cartopy-new-management-and-eol-announcement

And finally, to create a really cool 3D version:

https://plot.ly/python/lines-on-maps/#contour-lines-on-globe

jorgepiloto commented 5 years ago

Wow! That was exactly the idea I had on my mind! Hope to finish this night the #491 API Docs :notebook: and start reading in detail all the information in previous links to complete this plotting enhancement :smile:

jorgepiloto commented 5 years ago

Finally I was able to get a beautiful plot based on cartopy as @Juanlu001 suggested :+1: Next plot is a 24 hours track for the orbit satellite that I have simulated: :artificial_satellite:

plot

However, it should be shifting towards West due to Earth's rotation. May this be a good starting point for trying to improve the frames module by adding a body-fixed frame? :earth_africa:

astrojuanlu commented 5 years ago

That's right @IngenieroDeAviones, we will need proper frame support for this. To clarify, there is already an Earth-rotating frame: ITRF. However, what we need in poliastro is two things (which can be done separately):

  1. Allow the user to define an orbit in any reference frame #434. There are some notes in the wiki about that, but the most important thing is that we must ensure Orbit.propagate does not give garbage results when the frame is rotating.
  2. Define the rest of body-centered reference frames #109 and #451. There are already some formulas in poliastro, but in the ideal case they would need some validation and also they would have to be turned into a proper Reference Frame object from Astropy.

With 1) we should be able to leverage ITRF already and produce correct groundtrack plots, but it has to be general enough to allow for 2). Are you up to the challenge? :wink:

astrojuanlu commented 5 years ago

See also #429.

jorgepiloto commented 5 years ago

Are you up to the challenge? I am up for it, Sir! :smile: I will try to work on #434 from now on, but before, I did the following:

To transform a GCRS frame orbit (after being propagated) into ITRF frame orbit:


from astropy.coordinates import ITRS

r = [-6045, -3490, 2500] * u.km
v = [-3.457, 6.618, 2.533] * u.km / u.s
ss_gcrs = Orbit.from_vectors(Earth, r, v) #Orbit in GCRS

t_span = np.linspace(0, 24, 24*60) * u.h #Time span for each minute within 24 hours

pos_gcrs = ss_gcrs.sample(t_span) #astropy.coordinates.builtin_frames.gcrs.GCRS
pos_itrs = pos_gcrs.transform_to(ITRS) #astropy.coordinates.builtin_frames.itrs.ITRS

coord_itrs = pos_itrs.spherical #Convert to spherical
lon, lat = coord_itrs.lon, coord_itrs.lat #Just calling atributes

However, I got this plot:

plot_1

A closer look:

plot_2

Not sure what is going on here, because propagation is done with GCRS. I am missing something.

astrojuanlu commented 5 years ago

That orbit is a bit low, isn't it? The position vector suggests that you didn't take the Earth radius into account πŸ˜‰

On Fri, 23 Nov 2018, 20:53 Jorge Martinez <notifications@github.com wrote:

Are you up to the challenge? I am up for it, Sir! πŸ˜„ I will try to work on #434 https://github.com/poliastro/poliastro/issues/434 from now on, but before, I did the following:

To transform a GCRS frame orbit (after being propagated) into ITRF frame orbit:

from astropy.coordinates import ITRS

r = [-6045, -3490, 2500] u.km v = [-3.457, 6.618, 2.533] u.km / u.s ss_gcrs = Orbit.from_vectors(Earth, r, v) #Orbit in GCRS

t_span = np.linspace(0, 24, 2460) u.h #Time span for each minute within 24 hours

pos_gcrs = ss_gcrs.sample(t_span) #astropy.coordinates.builtin_frames.gcrs.GCRS pos_itrs = pos_gcrs.transform_to(ITRS) #astropy.coordinates.builtin_frames.itrs.ITRS

coord_itrs = pos_itrs.spherical #Convert to spherical lon, lat = coord_itrs.lon, coord_itrs.lat #Just calling atributes

However, I got this plot:

[image: plot_1] https://user-images.githubusercontent.com/28702884/48958694-2667c080-ef61-11e8-932b-194c4ff1796a.png

A closer look:

[image: plot_2] https://user-images.githubusercontent.com/28702884/48958701-2ebffb80-ef61-11e8-8741-ad03e83534df.png

Not sure what is going on here, because propagation is done with GCRS. I am missing something.

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/poliastro/poliastro/issues/497#issuecomment-441310290, or mute the thread https://github.com/notifications/unsubscribe-auth/AATUZSShEHCjdR2YCIkyMJFJk4qwZ4E0ks5uyFJQgaJpZM4YsAuC .

astrojuanlu commented 5 years ago

I updated the status of this issue because a past comment of mine contained a mistake.

In particular, the two blockers are #109 and #451, which are kind of the same problem. At the moment, we could of course perform groundtrack plotting using ITRF as defined in Astropy, but in poliastro we try not to include features that apply only to the Earth, so we should take the planetary frames and properly define them using the astropy.coordinates machinery.

Also, @jorgepiloto already tried to build a prototype but something was not quite working, as can be seen in the plots above. For anyone willing to work on this issue, showing a proper groundtrack would be a good starting point.

sakethramanujam commented 5 years ago

@Juanlu001 As discussed in the email, I'm willing to work on this issue. Will update the comment upon reception of a positive result. Currently understanding the math and what @jorgepiloto has done.

astrojuanlu commented 5 years ago

I adjusted @jorgepiloto code and I seem to get a proper groundtrack:

Figure_1

Perhaps the key is using the right projection:

https://scitools.org.uk/cartopy/docs/latest/matplotlib/intro.html#adding-data-to-the-map

While working with Cartopy, please note that it can be challenging to install.

jorgepiloto commented 5 years ago

Now that I feel more comfortable working with astropy.coordinates I decided to go back to this. I was able to make the ground-track in GCRS and ITRS. However the plot is not showing the shift in ITRS curve and it should appear...

track

astrojuanlu commented 5 years ago

However the plot is not showing the shift in ITRS curve and it should appear...

True! I got it in https://github.com/poliastro/poliastro/issues/497#issuecomment-471910884, can you share a https://gist.github.com?

jorgepiloto commented 5 years ago

Sure! There it goes:

https://gist.github.com/jorgepiloto/acb36f0b995bf7f9619ca605bef1581d

astrojuanlu commented 5 years ago

I can reproduce this plot, but not exactly sure what changed. Investigating.

astrojuanlu commented 5 years ago

Aha! You are missing the obstime :) The ITRS evolves with time! You have to do this:

    # Transform GCRS to ITRS
    ss_gcrs = ss.sample()
    ss_itrs = ss_gcrs.transform_to(coord.ITRS(obstime=ss_gcrs.obstime))
jorgepiloto commented 5 years ago

Oh! I thought the conversion between GCRS and ITRS did not need any extra parameters, that everything has done by itself :thinking: Thank you so much!

Still working on this... :rocket:

jorgepiloto commented 5 years ago

Finally working! I also added the option for the user to plot the ground track for a given time of flight. Before making the corresponding pull request I would like to add more features related to plotting options. For example:

gndtrack = Groundtrack()
gndtrack.plot(iss, 12 * u.h, label='ISS')
gndtrack.plot(molniya, 24 * u.h, label='Molniya-1')

And it would show the ground-track with beautiful labels as other plotting utilities available in poliastro. What do you think about it?

Some images for the iss being tracked for the next 5 hours (directly taken from poliastro.examples): iss_track

astrojuanlu commented 5 years ago

I would call it GroundtrackPlotter for consistency :)

Some questions:

jorgepiloto commented 5 years ago

Sure, GroundtrackPlotter sounds better!

Related with different attractors, it is something I still have to deal with. I thought about imposing for the moment that the only valid attractor was Earth till I found a better solution.

When talking about plot only coordinates, you mean that user should do the propagation for sampling the orbit positions and then pass them to the GroundtrackPlotter?

astrojuanlu commented 5 years ago

Regarding the attractors: sounds fair!

Regarding the API: yes, that was my thinking!

astrojuanlu commented 5 years ago

@Sedictious is working on a complementary approach using Cesium in https://github.com/poliastro/poliastro/pull/739

astrojuanlu commented 4 years ago

Going back to this, I think Plotly would be a compelling alternative to Cartopy in terms of ease of installation: https://plotly.com/python/lines-on-maps/

priyanshurohilla commented 4 years ago

Hi @astrojuanlu , I am done with my exams now i can start working again on #953. Also this is based on plotly only ;).

jorgepiloto commented 4 years ago

As discussed in official poliastro-earth chat, this feature might be placed under poliastro.earth.plotting sub-package since it is clearly focused on Earth capabilities.

jorgepiloto commented 4 years ago

After two years, this feature has been implemented. I think this was one of my first issues at poliastro. Please, if you find any king of bug or would like to extend its functionalities, open an issue or contact developers through official channels :rocket:

priyanshurohilla commented 4 years ago

I am soo glad this has been implemented. πŸ˜ƒ

FrancescoColombi commented 4 years ago

Sure, GroundtrackPlotter sounds better!

Related with different attractors, it is something I still have to deal with. I thought about imposing for the moment that the only valid attractor was Earth till I found a better solution.

When talking about plot only coordinates, you mean that user should do the propagation for sampling the orbit positions and then pass them to the GroundtrackPlotter?

Hi everyone, First of all I would say that I love these plots of ground track.

I have an idea to generalize the reference attractor: Giving as input the orientation of the Prime Meridian (e.g. the Prime Meridian Sidereal Time, PMST) at a desired reference epoch (e.g. reference JD) and the rotation rate of the attractor (e.g. omega_attractor), you can get the ground track of a given set of position in time.

astrojuanlu commented 4 years ago

Hi @FrancescoColombi, glad you like this new feature! Using the orientation of the prime meridian and the rotation rate of the attractor sounds like a good idea for generalizing this, I'll open a new issue.