Skip to content

Commit

Permalink
Merge PR #194
Browse files Browse the repository at this point in the history
  • Loading branch information
nonoo committed Apr 28, 2021
1 parent 1482feb commit 2903be6
Show file tree
Hide file tree
Showing 8 changed files with 465 additions and 81 deletions.
1 change: 1 addition & 0 deletions src/config-keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,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 @@ -439,7 +516,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 @@ -77,6 +77,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 @@ -929,6 +931,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 @@ -949,6 +953,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 @@ -980,6 +996,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 @@ -993,6 +1026,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

0 comments on commit 2903be6

Please sign in to comment.