Commit cb9f29e9 authored by Ansgar Schmidt's avatar Ansgar Schmidt 🚀
Browse files

Add parameter for max duration of an observation


Signed-off-by: Ansgar Schmidt's avatarAnsgar Schmidt <ansgar.schmidt@gmx.net>
parent da31bffe
Pipeline #229135239 failed with stage
in 1 minute and 9 seconds
......@@ -103,6 +103,7 @@ def find_passes(satellite, observer, tmin, tmax, minimum_altitude, min_pass_dura
'tt': tt.datetime(), # Max altitude time
'altt': elevation, # Max altitude
'ts': ts.datetime(), # Set time
'td': pass_duration, # Set duration
'azs': azimuth_s, # Set azimuth
'transmitter': {
'uuid': satellite.transmitter,
......@@ -193,6 +194,8 @@ def constrain_pass_to_az_window(satellite, observer, satpass, start_azimuth, sto
if pass_duration < timedelta(minutes=min_pass_duration):
return None
satpass['td'] = pass_duration
return satpass
......@@ -224,3 +227,36 @@ def check_az_in_window(azimuth, start_azimuth, stop_azimuth):
# Azimuth is outside the window (normal or complementary)
return complementary_window
def constrain_pass_to_max_observation_duration(satpass, max_pass_duration, tmin, tmax):
"""
Determines wheather a given observation duration time exceeds the time to record an
observation. In case the calculated recording time is longer then the max_pass_duration
the start and end values are shortened to have the optimal recording time above the horizon
for the given satellite.
:param satpass: Satpass to be adjusted to fit within the recording duration. Modified
in-place.
:param max_pass_duration: Maximum pass duration in minutes. Passes longer than this are
shortned.
:param tmin: Earliest time for a schedule
:param tmax: Latest time for a schedule
:return: The modified satpass object that satisfies the record duration constraint.
"""
max_duration = timedelta(minutes=max_pass_duration)
if satpass['td'] > max_duration:
half = (satpass['td'] - max_duration) / 2
# Max elevation fits within time frame
if satpass['tr'] + half >= tmin and satpass['ts'] - half <= tmax:
satpass['tr'] += half
satpass['ts'] -= half
else:
satpass['ts'] = min(satpass['ts'], tmax)
satpass['tr'] = satpass['ts'] - max_duration
satpass['td'] = satpass['ts'] - satpass['tr']
return satpass
......@@ -96,9 +96,12 @@ def get_scheduled_passes_from_network(ground_station, tmin, tmax):
# r.json() is a list of dicts/observations
for o in r.json():
start = datetime.strptime(o['start'].replace("Z", ""), "%Y-%m-%dT%H:%M:%S")
end = datetime.strptime(o['end'].replace("Z", ""), "%Y-%m-%dT%H:%M:%S")
satpass = {
"tr": datetime.strptime(o['start'].replace("Z", ""), "%Y-%m-%dT%H:%M:%S"),
"ts": datetime.strptime(o['end'].replace("Z", ""), "%Y-%m-%dT%H:%M:%S"),
"tr": start,
"ts": end,
"td": end - start,
"scheduled": True,
"altt": o['max_altitude'],
"priority": 1,
......
......@@ -52,14 +52,14 @@ def satellites_from_transmitters(transmitters, tles):
def print_scheduledpass_summary(scheduledpasses, ground_station_id, printer=print):
printer("GS | Sch | NORAD | Start time | End time | El | " +
printer("GS | Sch | NORAD | Start time | End time | Duration | El | " +
"Priority | Transmitter UUID | Mode | Satellite name ")
for satpass in sorted(scheduledpasses, key=lambda satpass: satpass['tr']):
printer(
"%3d | %3s | %05d | %s | %s | %3.0f | %4.6f | %s | %-10s | %s" %
"%4d | %3s | %05d | %s | %s | %s | %3.0f | %4.6f | %s | %-10s | %s" %
(ground_station_id, 'Y' if satpass['scheduled'] else 'N', int(
satpass['satellite']['id']), satpass['tr'].strftime("%Y-%m-%dT%H:%M:%S"),
satpass['ts'].strftime("%Y-%m-%dT%H:%M:%S"), float(satpass['altt']) if satpass['altt']
satpass['satellite']['id']), satpass['tr'].strftime("%Y-%m-%dT%H:%M:%S"),
satpass['ts'].strftime("%Y-%m-%dT%H:%M:%S"), str(satpass['td']).split(".")[0], float(satpass['altt']) if satpass['altt']
else 0., satpass.get('priority', 0.0), satpass['transmitter'].get('uuid', ''),
satpass['transmitter'].get('mode', ''), satpass['satellite']['name'].rstrip()))
......@@ -11,7 +11,7 @@ from auto_scheduler import __version__ as auto_scheduler_version
from auto_scheduler.io import read_priorities_transmitters, read_tles, \
read_transmitters
from auto_scheduler.pass_predictor import constrain_pass_to_az_window, \
create_observer, find_passes
create_observer, find_passes, constrain_pass_to_max_observation_duration
from auto_scheduler.satnogs_client import get_groundstation_info, \
get_scheduled_passes_from_network, schedule_observations_batch
from auto_scheduler.schedulers import ordered_scheduler, report_efficiency
......@@ -51,6 +51,11 @@ def main():
help="Duration to schedule [hours; default: 1.0]",
type=float,
default=1.0)
parser.add_argument("-o",
"--max-observation-duration",
help="Max time for a single observation [minutes; default: 30]",
type=float,
default=30.0)
parser.add_argument("-m",
"--min-culmination",
help="Minimum culmination elevation [degrees; " +
......@@ -167,6 +172,9 @@ def main():
tmin = tnow
tmax = tnow + timedelta(hours=length_hours)
# Set max record duration
max_observation_duration = args.max_observation_duration
# Get ground station information
ground_station = get_groundstation_info(ground_station_id, args.allow_testing)
if not ground_station:
......@@ -261,6 +269,12 @@ def main():
logging.debug("Adjusted pass inside azimuth window is azr %f and azs %f",
float(p['azr']), float(p['azs']))
logging.debug("Original pass for %s is start %s and end %s", str(satellite.name),
p['tr'], p['ts'])
p = constrain_pass_to_max_observation_duration(p, max_observation_duration, tmin, tmax)
logging.debug("Adjusted max observation duration for %s to start %s and end %s",
str(satellite.name), p['tr'], p['ts'])
p.update({
'satellite': {
'name': str(satellite.name),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment