[Gpredict-svn] SF.net SVN: gpredict:[93] trunk/src
Real time satellite tracking and orbit prediction
Status: Beta
Brought to you by:
csete
|
From: <cs...@us...> - 2008-09-06 21:38:04
|
Revision: 93
http://gpredict.svn.sourceforge.net/gpredict/?rev=93&view=rev
Author: csete
Date: 2008-09-06 21:38:14 +0000 (Sat, 06 Sep 2008)
Log Message:
-----------
Finished implementation of doppler tuning.
Modified Paths:
--------------
trunk/src/gtk-rig-ctrl.c
trunk/src/gtk-rig-ctrl.h
Modified: trunk/src/gtk-rig-ctrl.c
===================================================================
--- trunk/src/gtk-rig-ctrl.c 2008-09-06 18:42:03 UTC (rev 92)
+++ trunk/src/gtk-rig-ctrl.c 2008-09-06 21:38:14 UTC (rev 93)
@@ -41,14 +41,24 @@
#include "compat.h"
#include "sat-log.h"
#include "predict-tools.h"
+#include "gpredict-utils.h"
+#include "sat-cfg.h"
#include "gtk-freq-knob.h"
#include "gtk-rig-ctrl.h"
+#include "radio-conf.h"
#ifdef HAVE_CONFIG_H
# include <build-config.h>
#endif
+/* NETWORK */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+/* END */
-#define FMTSTR "%7.2f\302\260"
+#define AZEL_FMTSTR "%7.2f\302\260"
static void gtk_rig_ctrl_class_init (GtkRigCtrlClass *class);
@@ -136,7 +146,8 @@
ctrl->target = NULL;
ctrl->pass = NULL;
ctrl->qth = NULL;
-
+ ctrl->conf = NULL;
+ ctrl->sock = -10;
ctrl->tracking = FALSE;
ctrl->busy = FALSE;
ctrl->engaged = FALSE;
@@ -149,12 +160,23 @@
{
GtkRigCtrl *ctrl = GTK_RIG_CTRL (object);
-
/* stop timer */
if (ctrl->timerid > 0)
g_source_remove (ctrl->timerid);
+ /* close network socket */
+ if (ctrl->sock >= 0) {
+ close (ctrl->sock);
+ }
+ /* free configuration */
+ if (ctrl->conf != NULL) {
+ g_free (ctrl->conf->name);
+ g_free (ctrl->conf->host);
+ g_free (ctrl->conf);
+ ctrl->conf = NULL;
+ }
+
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
@@ -225,23 +247,57 @@
void
gtk_rig_ctrl_update (GtkRigCtrl *ctrl, gdouble t)
{
+ gdouble satfreq, doppler;
gchar *buff;
if (ctrl->target) {
+ /* update Az/El */
+ buff = g_strdup_printf (AZEL_FMTSTR, ctrl->target->az);
+ gtk_label_set_text (GTK_LABEL (ctrl->SatAz), buff);
+ g_free (buff);
+ buff = g_strdup_printf (AZEL_FMTSTR, ctrl->target->el);
+ gtk_label_set_text (GTK_LABEL (ctrl->SatEl), buff);
+ g_free (buff);
+
+ /* update range */
+ if (sat_cfg_get_bool (SAT_CFG_BOOL_USE_IMPERIAL)) {
+ buff = g_strdup_printf ("%.0f mi", KM_TO_MI (ctrl->target->range));
+ }
+ else {
+ buff = g_strdup_printf ("%.0f km", ctrl->target->range);
+ }
+ gtk_label_set_text (GTK_LABEL (ctrl->SatRng), buff);
+ g_free (buff);
+
+ /* update range rate */
+ if (sat_cfg_get_bool (SAT_CFG_BOOL_USE_IMPERIAL)) {
+ buff = g_strdup_printf ("%.3f mi/s", KM_TO_MI (ctrl->target->range_rate));
+ }
+ else {
+ buff = g_strdup_printf ("%.3f km/s", ctrl->target->range_rate);
+ }
+ gtk_label_set_text (GTK_LABEL (ctrl->SatRngRate), buff);
+ g_free (buff);
+
+ /* doppler shift */
+ satfreq = gtk_freq_knob_get_value (GTK_FREQ_KNOB (ctrl->SatFreq));
+ doppler = -satfreq * (ctrl->target->range_rate / 299792.4580); // Hz
+ buff = g_strdup_printf ("%.0f Hz", doppler);
+ gtk_label_set_text (GTK_LABEL (ctrl->SatDop), buff);
+ g_free (buff);
+
/* update next pass if necessary */
if (ctrl->pass != NULL) {
if (ctrl->target->aos > ctrl->pass->aos) {
/* update pass */
free_pass (ctrl->pass);
ctrl->pass = get_next_pass (ctrl->target, ctrl->qth, 3.0);
- /* TODO: update polar plot */
}
}
else {
/* we don't have any current pass; store the current one */
ctrl->pass = get_next_pass (ctrl->target, ctrl->qth, 3.0);
- /* TODO: update polar plot */
}
}
}
@@ -258,15 +314,17 @@
GtkWidget *create_sat_widgets (GtkRigCtrl *ctrl)
{
GtkWidget *frame;
+ GtkWidget *label;
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), _("<b>Satellite</b>"));
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
+ gtk_frame_set_label_widget (GTK_FRAME (frame), label);
- frame = gtk_frame_new (_("Satellite"));
-
-
- ctrl->SatFreq = gtk_freq_knob_new (145890000.0);
+ ctrl->SatFreq = gtk_freq_knob_new (145890000.0, TRUE);
gtk_container_add (GTK_CONTAINER (frame), ctrl->SatFreq);
-
return frame;
}
@@ -281,18 +339,16 @@
GtkWidget *create_rig_widgets (GtkRigCtrl *ctrl)
{
GtkWidget *frame;
- GtkWidget *table;
GtkWidget *label;
-
- frame = gtk_frame_new (_("Radio"));
-
- table = gtk_table_new (2, 2, FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (table), 5);
- gtk_table_set_col_spacings (GTK_TABLE (table), 5);
- gtk_table_set_row_spacings (GTK_TABLE (table), 5);
- gtk_container_add (GTK_CONTAINER (frame), table);
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), _("<b>Radio</b>"));
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
+ gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+ ctrl->RigFreq = gtk_freq_knob_new (145890000.0, FALSE);
+ gtk_container_add (GTK_CONTAINER (frame), ctrl->RigFreq);
return frame;
}
@@ -309,9 +365,9 @@
sat_t *sat = NULL;
- buff = g_strdup_printf (FMTSTR, 0.0);
+ buff = g_strdup_printf (AZEL_FMTSTR, 0.0);
- table = gtk_table_new (4, 3, FALSE);
+ table = gtk_table_new (4, 4, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 5);
gtk_table_set_col_spacings (GTK_TABLE (table), 5);
gtk_table_set_row_spacings (GTK_TABLE (table), 5);
@@ -328,33 +384,64 @@
gtk_combo_box_set_active (GTK_COMBO_BOX (satsel), 0);
gtk_widget_set_tooltip_text (satsel, _("Select target object"));
g_signal_connect (satsel, "changed", G_CALLBACK (sat_selected_cb), ctrl);
- gtk_table_attach_defaults (GTK_TABLE (table), satsel, 0, 2, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (table), satsel, 0, 3, 0, 1);
/* tracking button */
track = gtk_toggle_button_new_with_label (_("Track"));
gtk_widget_set_tooltip_text (track, _("Track the satellite when it is within range"));
- gtk_table_attach_defaults (GTK_TABLE (table), track, 2, 3, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (table), track, 3, 4, 0, 1);
g_signal_connect (track, "toggled", G_CALLBACK (track_toggle_cb), ctrl);
/* Azimuth */
label = gtk_label_new (_("Az:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+ ctrl->SatAz = gtk_label_new (buff);
+ gtk_misc_set_alignment (GTK_MISC (ctrl->SatAz), 1.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), ctrl->SatAz, 1, 2, 1, 2);
-
/* Elevation */
label = gtk_label_new (_("El:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
+ ctrl->SatEl = gtk_label_new (buff);
+ gtk_misc_set_alignment (GTK_MISC (ctrl->SatEl), 1.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), ctrl->SatEl, 1, 2, 2, 3);
-
/* count down */
label = gtk_label_new (_("Time:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4);
+ ctrl->SatCnt = gtk_label_new ("00:00:00");
+ gtk_misc_set_alignment (GTK_MISC (ctrl->SatCnt), 0.5, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), ctrl->SatCnt, 1, 2, 3, 4);
+ /* Range */
+ label = gtk_label_new (_(" Range:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 1, 2);
+ ctrl->SatRng = gtk_label_new ("0 km");
+ gtk_misc_set_alignment (GTK_MISC (ctrl->SatRng), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), ctrl->SatRng, 3, 4, 1, 2);
+
+ /* Range rate */
+ label = gtk_label_new (_(" Rate:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 2, 3);
+ ctrl->SatRngRate = gtk_label_new ("0.0 km/s");
+ gtk_misc_set_alignment (GTK_MISC (ctrl->SatRngRate), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), ctrl->SatRngRate, 3, 4, 2, 3);
+
+ /* Doppler shift */
+ label = gtk_label_new (_(" Doppler:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 3, 4);
+ ctrl->SatDop = gtk_label_new ("0 Hz");
+ gtk_misc_set_alignment (GTK_MISC (ctrl->SatDop), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), ctrl->SatDop, 3, 4, 3, 4);
+
frame = gtk_frame_new (_("Target"));
-;
+
gtk_container_add (GTK_CONTAINER (frame), table);
g_free (buff);
@@ -366,7 +453,7 @@
static GtkWidget *
create_conf_widgets (GtkRigCtrl *ctrl)
{
- GtkWidget *frame,*table,*label,*timer,*toler;
+ GtkWidget *frame,*table,*label,*timer;
GtkWidget *lock;
GDir *dir = NULL; /* directory handle */
GError *error = NULL; /* error flag and info */
@@ -422,6 +509,7 @@
gtk_combo_box_set_active (GTK_COMBO_BOX (ctrl->DevSel), 0);
g_signal_connect (ctrl->DevSel, "changed", G_CALLBACK (rig_selected_cb), ctrl);
gtk_table_attach_defaults (GTK_TABLE (table), ctrl->DevSel, 1, 2, 0, 1);
+ /* config will be force-loaded after LO spin is created */
/* Engage button */
lock = gtk_toggle_button_new_with_label (_("Engage"));
@@ -429,10 +517,29 @@
g_signal_connect (lock, "toggled", G_CALLBACK (rig_locked_cb), ctrl);
gtk_table_attach_defaults (GTK_TABLE (table), lock, 2, 3, 0, 1);
+ /* Local oscillator value */
+ label = gtk_label_new (_("Local Osc:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+
+ ctrl->LO = gtk_spin_button_new_with_range (-10000, 10000, 1);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (ctrl->LO), 0);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (ctrl->LO), 0);
+ gtk_widget_set_tooltip_text (ctrl->LO,
+ _("Enter the frequency of the local oscillator, if any."));
+ gtk_table_attach_defaults (GTK_TABLE (table), ctrl->LO, 1, 2, 1, 2);
+
+ label = gtk_label_new (_("MHz"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 1, 2);
+
+ /* Now, load config*/
+ rig_selected_cb (GTK_COMBO_BOX (ctrl->DevSel), ctrl);
+
/* Timeout */
label = gtk_label_new (_("Cycle:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
- gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
timer = gtk_spin_button_new_with_range (100, 5000, 10);
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (timer), 0);
@@ -441,12 +548,12 @@
"commands sent to the rigator."));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (timer), ctrl->delay);
g_signal_connect (timer, "value-changed", G_CALLBACK (delay_changed_cb), ctrl);
- gtk_table_attach (GTK_TABLE (table), timer, 1, 2, 1, 2,
+ gtk_table_attach (GTK_TABLE (table), timer, 1, 2, 2, 3,
GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new (_("msec"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 2, 3);
frame = gtk_frame_new (_("Settings"));
@@ -555,9 +662,43 @@
{
GtkRigCtrl *ctrl = GTK_RIG_CTRL (data);
- /* TODO: update device */
+ /* free previous configuration */
+ if (ctrl->conf != NULL) {
+ g_free (ctrl->conf->name);
+ g_free (ctrl->conf->host);
+ g_free (ctrl->conf);
+ }
+
+ ctrl->conf = g_try_new (radio_conf_t, 1);
+ if (ctrl->conf == NULL) {
+ sat_log_log (SAT_LOG_LEVEL_ERROR,
+ _("%s:%d: Failed to allocate memory for radio config"),
+ __FILE__, __LINE__);
+ return;
+ }
+
+ /* load new configuration */
+ ctrl->conf->name = gtk_combo_box_get_active_text (box);
+ if (radio_conf_read (ctrl->conf)) {
+ sat_log_log (SAT_LOG_LEVEL_MSG,
+ _("Loaded new radio configuration %s"),
+ ctrl->conf->name);
+ /* update LO widget */
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (ctrl->LO), ctrl->conf->lo/1.0e6);
+ }
+ else {
+ sat_log_log (SAT_LOG_LEVEL_ERROR,
+ _("%s:%d: Failed to load radio configuration %s"),
+ __FILE__, __LINE__, ctrl->conf->name);
+ g_free (ctrl->conf->name);
+ if (ctrl->conf->host)
+ g_free (ctrl->conf->host);
+ g_free (ctrl->conf);
+ ctrl->conf = NULL;
+ }
+
}
@@ -571,14 +712,62 @@
rig_locked_cb (GtkToggleButton *button, gpointer data)
{
GtkRigCtrl *ctrl = GTK_RIG_CTRL (data);
+
- if (gtk_toggle_button_get_active (button)) {
- gtk_widget_set_sensitive (ctrl->DevSel, FALSE);
+ if (!gtk_toggle_button_get_active (button)) {
+ /* close socket */
+ gtk_widget_set_sensitive (ctrl->DevSel, TRUE);
ctrl->engaged = FALSE;
+
+ if (ctrl->sock >= 0) {
+ close (ctrl->sock);
+ ctrl->sock = -10;
+ }
}
else {
- gtk_widget_set_sensitive (ctrl->DevSel, TRUE);
+ if (ctrl->conf == NULL) {
+ /* we don't have a working configuration */
+ return;
+ }
+
+ gtk_widget_set_sensitive (ctrl->DevSel, FALSE);
ctrl->engaged = TRUE;
+
+ gint status;
+ struct sockaddr_in ServAddr;
+ struct hostent *h;
+
+ ctrl->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (ctrl->sock < 0) {
+ sat_log_log (SAT_LOG_LEVEL_ERROR,
+ _("%s: Failed to create socket"),
+ __FUNCTION__);
+ return;
+ }
+ else {
+ sat_log_log (SAT_LOG_LEVEL_DEBUG,
+ _("%s: Network socket created successfully"),
+ __FUNCTION__);
+ }
+
+ memset(&ServAddr, 0, sizeof(ServAddr)); /* Zero out structure */
+ ServAddr.sin_family = AF_INET; /* Internet address family */
+ h = gethostbyname(ctrl->conf->host);
+ memcpy((char *) &ServAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
+ ServAddr.sin_port = htons(ctrl->conf->port); /* Server port */
+
+ status = connect(ctrl->sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr));
+ if (status < 0) {
+ sat_log_log (SAT_LOG_LEVEL_ERROR,
+ _("%s: Failed to connect to %s:%d"),
+ __FUNCTION__, ctrl->conf->host, ctrl->conf->port);
+ return;
+ }
+ else {
+ sat_log_log (SAT_LOG_LEVEL_DEBUG,
+ _("%s: Connection opened to %s:%d"),
+ __FUNCTION__, ctrl->conf->host, ctrl->conf->port);
+ }
}
}
@@ -591,7 +780,9 @@
rig_ctrl_timeout_cb (gpointer data)
{
GtkRigCtrl *ctrl = GTK_RIG_CTRL (data);
+ gdouble satfreq,doppler,lof;
+
if (ctrl->busy) {
sat_log_log (SAT_LOG_LEVEL_ERROR,_("%s missed the deadline"),__FUNCTION__);
return TRUE;
@@ -599,27 +790,41 @@
ctrl->busy = TRUE;
- /* If we are tracking and the target satellite is within
- range, set the rig controller knob value to the target
- frequency value. If the target satellite is out of range
- set the rig controller to the frequency which we expect
- when the target sat comes up.
- In either case, update the range, delay, loss, rate, and
- doppler values.
+ /* If we are tracking, calculate the radio freq by applying both dopper shift
+ and tranverter LO frequency.
+ If we are not tracking, apply only LO frequency.
*/
if (ctrl->tracking) {
- if (ctrl->target->el < 0.0) {
- gdouble aosshift = 0.0;
-
- }
- else {
- }
-
-
+ satfreq = gtk_freq_knob_get_value (GTK_FREQ_KNOB (ctrl->SatFreq));
+ doppler = -satfreq * (ctrl->target->range_rate / 299792.4580);
+ lof = 1.0e6*gtk_spin_button_get_value (GTK_SPIN_BUTTON (ctrl->LO));
+ gtk_freq_knob_set_value (GTK_FREQ_KNOB (ctrl->RigFreq), satfreq+doppler+lof);
}
+ else {
+ satfreq = gtk_freq_knob_get_value (GTK_FREQ_KNOB (ctrl->SatFreq));
+ lof = 1.0e6*gtk_spin_button_get_value (GTK_SPIN_BUTTON (ctrl->LO));
+ gtk_freq_knob_set_value (GTK_FREQ_KNOB (ctrl->RigFreq), satfreq+lof);
+ }
- if (ctrl->engaged) {
- /* TODO: send controller values to radio device */
+ /* if device is engaged, send freq command to radio */
+ if ((ctrl->engaged) && (ctrl->sock >= 0)) {
+ gchar *buff;
+ gint written,size;
+
+ buff = g_strdup_printf ("F %10.0f\n",
+ gtk_freq_knob_get_value (GTK_FREQ_KNOB (ctrl->RigFreq)));
+
+ /* number of bytes to write depends on platform (EOL) */
+#ifdef G_OS_WIN32
+ size = 14;
+#else
+ size = 13;
+#endif
+ written = send(ctrl->sock, buff, size, 0);
+ if (written != size) {
+ g_print ("SIZE ERR: %d\n", written);
+ }
+ g_free (buff);
}
Modified: trunk/src/gtk-rig-ctrl.h
===================================================================
--- trunk/src/gtk-rig-ctrl.h 2008-09-06 18:42:03 UTC (rev 92)
+++ trunk/src/gtk-rig-ctrl.h 2008-09-06 21:38:14 UTC (rev 93)
@@ -33,6 +33,7 @@
#include <gtk/gtk.h>
#include "sgpsdp/sgp4sdp4.h"
#include "gtk-sat-module.h"
+#include "radio-conf.h"
#ifdef __cplusplus
extern "C" {
@@ -63,11 +64,18 @@
GtkVBox vbox;
GtkWidget *SatFreq;
+ GtkWidget *RigFreq;
+
+ /* target status labels*/
+ GtkWidget *SatAz,*SatEl,*SatCnt;
+ GtkWidget *SatRng,*SatRngRate,*SatDop;
/* other widgets */
GtkWidget *DevSel; /*!< Device selector */
GtkWidget *LO; /*!< Local oscillator */
+ radio_conf_t *conf; /*!< Radio configuration */
+ gint sock; /*!< Network socket */
GSList *sats; /*!< List of sats in parent module */
sat_t *target; /*!< Target satellite */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|