brandon-rhodes / pyephem

Scientific-grade astronomy routines for Python
Other
766 stars 121 forks source link

next_pass returns mixed results when satellite overhead #105

Closed cshields closed 5 years ago

cshields commented 8 years ago

From the docs, we assume next_pass to return "when it will next cross above the horizon". However, if you call on an object when it is currently overhead the return will be a mix of fields that are calculated against the current pass and fields that are calculated for the next pass:

In the following example the object was overhead for the first observer.date, with a rise time of 19:09:21 (per another app, which matched the set time closely). The expectation is that the overhead pass is ignored completely and the results from the second observer.date should all be the same.

This is with pyephem 3.7.6.0, linux. Underlying bug behind satnogs/satnogs-network#199

import ephem
import math

observer = ephem.Observer()
observer.lat = "39.236"
observer.lon = "-86.3053"
observer.elevation = 286

observer.date = "2016/3/19 19:17:19"

sat_ephem = ephem.readtle("ITAMSAT (IO-26)",
                          "1 22826U 93061D   16078.88578765  .00000055  00000-0  38689-4 0  9993",
                          "2 22826  98.7432  34.7612 0008331 207.2611 152.8135 14.30268351172493")

print "observer date: " + str(observer.date)
tr, azr, tt, altt, ts, azs = observer.next_pass(sat_ephem)
print "altitude: " + format(math.degrees(altt), '.0f') + " rising from: " + format(math.degrees(azr), '.0f')
print "rise time: " + str(tr)

observer.date = "2016/3/19 19:30:00"
print "\n\nobserver date: " + str(observer.date)
tr, azr, tt, altt, ts, azs = observer.next_pass(sat_ephem)
print "altitude: " + format(math.degrees(altt), '.0f') + " rising from: " + format(math.degrees(azr), '.0f')
print "rise time: " + str(tr)

Gives us:

observer date: 2016/3/19 19:17:19
altitude: 46 rising from: 202
rise time: 2016/3/19 20:49:28

observer date: 2016/3/19 19:30:00
altitude: 21 rising from: 202
rise time: 2016/3/19 20:49:28

cheers!

brandon-rhodes commented 8 years ago

Unfortunately, PyEphem is simply a thin wrapper around a C-language astronomy library, and next_pass() is merely a conversion routine that calls the real libastro routine riset_cir(), wraps its return values in PyEphem date and angle data types, and then returns the results to the user.

It looks like the version of libastro included with PyEphem is the most recent one, 3.7.7, since the parent project itself is at that version number:

http://www.clearskyinstitute.com/xephem/

I have been working on a new library, Skyfield, which will be pure Python and not tied to a specific C library. I will keep this issue open until I have a good satellite rise / set solution written for Skyfield, and then will let you know that there is a replacement. In the meantime — yes, the libastro idea of what it should report for satellite circumstances is, unfortunately, a bit surprising sometimes.

baddev89 commented 7 years ago

I saw skyfield is at 1.0. I was just curious if it had a replacement for next_pass in it? I have an old utility that used pyephem that I was going to update to switch over to skyfield but wanted to get on this issue first.

brandon-rhodes commented 7 years ago

I have done experiments with solvers for finding rising and setting, but nothing official yet. I will update this issue when I have something for Skyfield that I'm confident about!

me-at-git-hub commented 5 years ago

I do not know if cshields has switched entirely to skyfield at this point, years later. However, regarding this issue in pyephem, I have been using a 'duct tape' solution for any satellite next_pass issues I encountered. I set my searchdatetime to one day before (expecting several passes, or at least one pass before my target searchdatetime). After finding at least one pass before my target searchdatetime, I then set my new searchdatetime to the set_time of the currently found pass data, plus one minute. This all occurs within a while loop which also tests that none of the next_pass values are None. I then, in this loop, add 15 minutes per loop until the rise_time of the next_pass is greater than 1 minute later than the previously found pass's rise_time. Why? I was getting duplicates that had rise_times differing by a second or two, so testing for rt_prev == rt_current was not good enough. The rt_current - rt_previous >= timedelta(minutes=1) condition, after being properly setup, did the job. Reasoning: No sat pass was going to be less than a minute from the previous one. timedelta(seconds=3) probably would have worked as well, but I opted for a bigger piece of duct tape. The ISS passes are ~90 minutes apart. Of course, adjust according to what is generally known about the satellite being calculated.

There are also intermittent odd results if the first searchdatetime occurs during a current pass. Sometimes I only encountered these after 100 or more calculations, some of them only after tens of thousands of loops. Rather than trying to narrow down every precise cause, I adopted usage practices to test and avoid those scenarios. It is only after taking all these measures that any strange, None or mixed next_pass data was eliminated. At the time that I resolved issues with this duct tape, I was unaware of skyfield. I am still using pyephem for some projects, noting to stick to these usage practices for satellite calculations.

I had mentioned the while loop conditions in a stackexchange reply, and if you want, you may see them there. I may now add to it concerning eliminating the duplicate passes.

https://space.stackexchange.com/questions/4339/calculating-which-satellite-passes-are-visible/4347#4347

I also added code to calculate the maxAltAz and determine whether a particular pass is progressing CW or CCW in its azimuth, showing this in a simple next_pass table of results. This made it much easier to check that all the odd results had been eliminated. They are gone.

adamkalis commented 5 years ago

The issue seems to be solved/tackled in the latest release (3.7.7.0). Here is an example using a similar code with the one in the first post showing the use of the new parameter in next_pass method: https://repl.it/repls/UnsightlyConsiderateDistributedcomputing

@brandon-rhodes I guess you can close this issue.

brandon-rhodes commented 5 years ago

@adamkalis Thanks, I’ll try closing this, and one of the other folks can re-open it if they run into the same problem again.