Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ground track improvements #194

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/config-keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
#define MOD_CFG_MAP_SHADOW_ALPHA "SHADOW_ALPHA"
#define MOD_CFG_MAP_SHOWTRACKS "SHOWTRACKS"
#define MOD_CFG_MAP_HIDECOVS "HIDECOVS"
#define MOD_CFG_MAP_AUTO_GROUND_TRACK "AUTO_GROUND_TRACK"

/* polar view specific */
#define MOD_CFG_POLAR_SECTION "POLAR"
Expand Down
203 changes: 143 additions & 60 deletions src/gtk-sat-map-ground-track.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ void ground_track_create(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
double t0; /* time when this_orbit starts */
double t;
ssp_t *this_ssp;
double track_num;
double target_phase;
double prev_phase;
double total_phase;
gboolean wrap;

sat_log_log(SAT_LOG_LEVEL_DEBUG,
_("%s: Creating ground track for %s"),
Expand All @@ -83,76 +88,133 @@ void ground_track_create(GtkSatMap * satmap, sat_t * sat, qth_t * qth,

/* get configuration parameters */
this_orbit = sat->orbit;
max_orbit = sat->orbit - 1 + mod_cfg_get_int(satmap->cfgdata,
MOD_CFG_MAP_SECTION,
MOD_CFG_MAP_TRACK_NUM,
SAT_CFG_INT_MAP_TRACK_NUM);

sat_log_log(SAT_LOG_LEVEL_DEBUG,
_("%s: Start orbit: %d"), __func__, this_orbit);
sat_log_log(SAT_LOG_LEVEL_DEBUG,
_("%s: End orbit %d"), __func__, max_orbit);

/* find the time when the current orbit started */

/* Iterate backwards in time until we reach sat->orbit < this_orbit.
Use predict_calc from predict-tools.c as SGP/SDP driver.
As a built-in safety, we stop iteration if the orbit crossing is
more than 24 hours back in time.
*/
t0 = satmap->tstamp; //get_current_daynum ();
/* use == instead of >= as it is more robust */
for (t = t0; (sat->orbit == this_orbit) && ((t + 1.0) > t0); t -= 0.0007)
predict_calc(sat, qth, t);

/* set it so that we are in the same orbit as this_orbit
and not a different one */
t += 2 * 0.0007;
t0 = t;
predict_calc(sat, qth, t0);
track_num = mod_cfg_get_double(satmap->cfgdata, MOD_CFG_MAP_SECTION,
MOD_CFG_MAP_TRACK_NUM,
SAT_CFG_DOUBLE_MAP_TRACK_NUM);

/* If number of orbits to draw is less than 2, we start the track 25% or an
* orbit behind the satellites current position. Otherwise it starts at the
* start of the orbit. */
if (track_num < 2.0)
{
/* Start a quarter of an orbit ago */
if (sat->phase <= 90.0)
{
target_phase = sat->phase + 360.0 - 90.0;
wrap = TRUE;
}
else
{
target_phase = sat->phase - 90.0;
wrap = FALSE;
}
for (t = satmap->tstamp; (wrap && (sat->phase <= 90.0)) || (sat->phase > target_phase); t -= 0.0007)
predict_calc(sat, qth, t);
t += 0.0007;

/* Move ahead user-defined number of orbits (or parts of) */
prev_phase = sat->phase;
total_phase = 0.0;
while ((total_phase < 360.0 * track_num) && (!decayed(sat)))
{
/* We use 30 sec time steps. If resolution is too fine, the
line drawing routine will filter out unnecessary points
*/
t += 0.00035;
predict_calc(sat, qth, t);
if (sat->phase < prev_phase) // have we wrapped?
total_phase += sat->phase + 360.0 - prev_phase;
else
total_phase += sat->phase - prev_phase;
prev_phase = sat->phase;

sat_log_log(SAT_LOG_LEVEL_DEBUG,
_("%s: T0: %f (%d)"), __func__, t0, sat->orbit);
/* store this SSP */
this_ssp = g_try_new(ssp_t, 1);
if (this_ssp == NULL)
{
sat_log_log(SAT_LOG_LEVEL_ERROR,
_("%s: MAYDAY: Insufficient memory for ground track!"),
__func__);
return;
}

/* calculate (lat,lon) for the required orbits */
while ((sat->orbit <= max_orbit) &&
(sat->orbit >= this_orbit) && (!decayed(sat)))
this_ssp->lat = sat->ssplat;
this_ssp->lon = sat->ssplon;
obj->track_data.latlon =
g_slist_prepend(obj->track_data.latlon, this_ssp);
}
}
else
{
/* We use 30 sec time steps. If resolution is too fine, the
line drawing routine will filter out unnecessary points
*/
t += 0.00035;
predict_calc(sat, qth, t);
max_orbit = sat->orbit - 1 + (long)track_num;

sat_log_log(SAT_LOG_LEVEL_DEBUG,
_("%s: Start orbit: %d"), __func__, this_orbit);
sat_log_log(SAT_LOG_LEVEL_DEBUG,
_("%s: End orbit %d"), __func__, max_orbit);

/* store this SSP */
/* find the time when the current orbit started */

/* Note: g_slist_append() has to traverse the entire list to find the end, which
is inefficient when adding multiple elements. Therefore, we use g_slist_prepend()
and reverse the entire list when we are done.
/* Iterate backwards in time until we reach sat->orbit < this_orbit.
Use predict_calc from predict-tools.c as SGP/SDP driver.
As a built-in safety, we stop iteration if the orbit crossing is
more than 24 hours back in time.
*/
this_ssp = g_try_new(ssp_t, 1);
t0 = satmap->tstamp; //get_current_daynum ();
/* use == instead of >= as it is more robust */
for (t = t0; (sat->orbit == this_orbit) && ((t + 1.0) > t0); t -= 0.0007)
predict_calc(sat, qth, t);

/* set it so that we are in the same orbit as this_orbit
and not a different one */
t += 2 * 0.0007;
t0 = t;
predict_calc(sat, qth, t0);

sat_log_log(SAT_LOG_LEVEL_DEBUG,
_("%s: T0: %f (%d)"), __func__, t0, sat->orbit);

/* calculate (lat,lon) for the required orbits */
while ((sat->orbit <= max_orbit) &&
(sat->orbit >= this_orbit) && (!decayed(sat)))
{
/* We use 30 sec time steps. If resolution is too fine, the
line drawing routine will filter out unnecessary points
*/
t += 0.00035;
predict_calc(sat, qth, t);

/* store this SSP */

/* Note: g_slist_append() has to traverse the entire list to find the end, which
is inefficient when adding multiple elements. Therefore, we use g_slist_prepend()
and reverse the entire list when we are done.
*/
this_ssp = g_try_new(ssp_t, 1);

if (this_ssp == NULL)
{
sat_log_log(SAT_LOG_LEVEL_ERROR,
_("%s: MAYDAY: Insufficient memory for ground track!"),
__func__);
return;
}

if (this_ssp == NULL)
this_ssp->lat = sat->ssplat;
this_ssp->lon = sat->ssplon;
obj->track_data.latlon =
g_slist_prepend(obj->track_data.latlon, this_ssp);

}

/* log if there is a problem with the orbit calculation */
if (sat->orbit != (max_orbit + 1))
{
sat_log_log(SAT_LOG_LEVEL_ERROR,
_("%s: MAYDAY: Insufficient memory for ground track!"),
__func__);
_("%s: Problem computing ground track for %s"),
__func__, sat->nickname);
return;
}

this_ssp->lat = sat->ssplat;
this_ssp->lon = sat->ssplon;
obj->track_data.latlon =
g_slist_prepend(obj->track_data.latlon, this_ssp);

}
/* log if there is a problem with the orbit calculation */
if (sat->orbit != (max_orbit + 1))
{
sat_log_log(SAT_LOG_LEVEL_ERROR,
_("%s: Problem computing ground track for %s"),
__func__, sat->nickname);
return;
}

/* Reset satellite structure to eliminate glitches in single sat
Expand Down Expand Up @@ -313,6 +375,7 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
guint start;
guint i, j, n, num_points;
guint32 col;
gboolean start_not_end;

(void)sat;
(void)qth;
Expand All @@ -327,6 +390,10 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
MOD_CFG_MAP_SECTION,
MOD_CFG_MAP_TRACK_COL, SAT_CFG_INT_MAP_TRACK_COL);

/* Determine which end arrow heads should be drawn, depending on direction
satellite is moving in, which is determined by its inclination. */
start_not_end = sat->tle.xincl > 90.0;

/* loop over each SSP */
for (i = 0; i < n; i++)
{
Expand Down Expand Up @@ -375,6 +442,16 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
CAIRO_LINE_CAP_SQUARE,
"line-join",
CAIRO_LINE_JOIN_MITER,
"end-arrow",
!start_not_end,
"start-arrow",
start_not_end,
"arrow-length",
10.0,
"arrow-tip-length",
8.0,
"arrow-width",
8.0,
NULL);
goo_canvas_points_unref(gpoints);
goo_canvas_item_model_lower(line, obj->marker);
Expand Down Expand Up @@ -438,7 +515,13 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
"stroke-color-rgba", col,
"line-cap", CAIRO_LINE_CAP_SQUARE,
"line-join",
CAIRO_LINE_JOIN_MITER, NULL);
CAIRO_LINE_JOIN_MITER,
"end-arrow", !start_not_end,
"start-arrow", start_not_end,
"arrow-length", 10.0,
"arrow-tip-length", 8.0,
"arrow-width", 8.0,
NULL);
goo_canvas_points_unref(gpoints);
goo_canvas_item_model_lower(line, obj->marker);

Expand Down
61 changes: 61 additions & 0 deletions src/gtk-sat-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ static gboolean on_button_press(GooCanvasItem * item,
static gboolean on_button_release(GooCanvasItem * item,
GooCanvasItem * target,
GdkEventButton * event, gpointer data);
static void clear_auto_ground_tracks(gpointer key, gpointer val,
gpointer data);
static void clear_selection(gpointer key, gpointer val, gpointer data);
static void load_map_file(GtkSatMap * satmap, float clon);
static GooCanvasItemModel *create_canvas_model(GtkSatMap * satmap);
Expand Down Expand Up @@ -823,6 +825,8 @@ static gboolean on_button_release(GooCanvasItem * item,
gint *catpoint = NULL;
sat_map_obj_t *obj = NULL;
guint32 col;
sat_t *sat = NULL;
gboolean auto_ground_track;

(void)target;

Expand All @@ -843,6 +847,18 @@ static gboolean on_button_release(GooCanvasItem * item,
}
else
{
auto_ground_track = mod_cfg_get_bool(satmap->cfgdata,
MOD_CFG_MAP_SECTION,
MOD_CFG_MAP_AUTO_GROUND_TRACK,
SAT_CFG_BOOL_MAP_AUTO_GROUND_TRACK);

if (auto_ground_track)
{
/* Clear auto-enabled ground trackss. */
g_hash_table_foreach(satmap->obj, clear_auto_ground_tracks,
satmap);
}

obj->selected = !obj->selected;

if (obj->selected)
Expand Down Expand Up @@ -874,6 +890,23 @@ static gboolean on_button_release(GooCanvasItem * item,
if (obj->oldrcnum == 2)
g_object_set(obj->range2, "stroke-color-rgba", col, NULL);

if (auto_ground_track)
{
/* Create ground track for newly selected satellite. */
sat = SAT(g_hash_table_lookup(satmap->sats, catpoint));
if (sat != NULL)
{
if (!obj->showtrack)
{
obj->showtrack = TRUE;
/* create ground track */
ground_track_create(satmap, sat, satmap->qth, obj);
/* do not add to satmap->showtracks, that's just for
* sats where it has manually been enabled. */
}
}
}

/* clear other selections */
g_hash_table_foreach(satmap->obj, clear_selection, catpoint);
}
Expand All @@ -887,6 +920,34 @@ static gboolean on_button_release(GooCanvasItem * item,
return TRUE;
}

/* Delete ground tracks that were automatically enabled for the selected
* satellite. */

static void clear_auto_ground_tracks(gpointer key, gpointer val, gpointer data)
{
GtkSatMap *satmap = GTK_SAT_MAP(data);
sat_map_obj_t *obj = SAT_MAP_OBJ(val);
sat_t *sat = NULL;
gint *catpoint = key;

if (obj->selected)
{
sat = SAT(g_hash_table_lookup(satmap->sats, catpoint));
if (sat != NULL)
{
/* If ground track was auto enabled, this sat will not be in
* showtracks hash table. Don't use value in hash table,
* just whether it exists */
if (!g_hash_table_lookup_extended(satmap->showtracks,
&(sat->tle.catnr), NULL, NULL))
{
obj->showtrack = FALSE;
ground_track_delete(satmap, sat, satmap->qth, obj, TRUE);
}
}
}
}

static void clear_selection(gpointer key, gpointer val, gpointer data)
{
gint *old = key;
Expand Down
32 changes: 32 additions & 0 deletions src/mod-cfg-get-param.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,38 @@ gchar *mod_cfg_get_str(GKeyFile * f, const gchar * sec,
return param;
}

gdouble mod_cfg_get_double(GKeyFile * f, const gchar * sec, const gchar * key,
sat_cfg_double_e p)
{
GError *error = NULL;
gdouble param;

/* check whether parameter is present in GKeyFile */
if (g_key_file_has_key(f, sec, key, NULL))
{
param = g_key_file_get_double(f, sec, key, &error);

if (error != NULL)
{
sat_log_log(SAT_LOG_LEVEL_WARN,
_("%s: Failed to read double (%s)"),
__func__, error->message);

g_clear_error(&error);

/* get a timeout from global config */
param = sat_cfg_get_double(p);
}
}
/* get value from sat-cfg */
else
{
param = sat_cfg_get_double(p);
}

return param;
}

/**
* \brief Load an integer list into a hash table that uses the
* existinence of datain the hash as a boolean.
Expand Down
Loading