[Gpredict-svn] SF.net SVN: gpredict:[726] trunk
Real time satellite tracking and orbit prediction
Status: Beta
Brought to you by:
csete
From: <aa...@us...> - 2010-12-26 17:49:14
|
Revision: 726 http://gpredict.svn.sourceforge.net/gpredict/?rev=726&view=rev Author: aa1vs Date: 2010-12-26 17:49:08 +0000 (Sun, 26 Dec 2010) Log Message: ----------- Lead satellite when pointing rotator. Modified Paths: -------------- trunk/ChangeLog trunk/src/gtk-rot-ctrl.c Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-12-26 16:17:56 UTC (rev 725) +++ trunk/ChangeLog 2010-12-26 17:49:08 UTC (rev 726) @@ -1,3 +1,9 @@ +2010-12-26 Charles Suprin <hamaa1vs at gmail.com> + + * src/gtk-rot-ctrl.c + Make rotator lead satellite on update. + Restructure error handling for cleaner code. + 2010-12-26 Alexandru Csete <oz9aec at gmail.com> * src/gtk-sat-map.c: Modified: trunk/src/gtk-rot-ctrl.c =================================================================== --- trunk/src/gtk-rot-ctrl.c 2010-12-26 16:17:56 UTC (rev 725) +++ trunk/src/gtk-rot-ctrl.c 2010-12-26 17:49:08 UTC (rev 726) @@ -867,11 +867,14 @@ { GtkRotCtrl *ctrl = GTK_ROT_CTRL (data); gdouble rotaz=0.0, rotel=0.0; - gdouble setaz,setel; + gdouble setaz=0.0, setel=0.0; gchar *text; gboolean error = FALSE; gboolean update_flag=FALSE; sat_t sat_working, *sat; + /*parameters for path predictions*/ + gdouble time_delta; + gdouble step_size; if (g_static_mutex_trylock(&(ctrl->busy))==FALSE) { @@ -904,24 +907,21 @@ setel=ctrl->target->el; update_flag=TRUE; } - if (update_flag){ - /* if this is a flipped pass and the rotor supports it*/ - if ((ctrl->flipped)&&(ctrl->conf->maxel>=180.0)){ - setel=180-setel; - if (setaz>180) - setaz-=180; - else - setaz+=180; - } - - if ((ctrl->conf->aztype == ROT_AZ_TYPE_180) && (setaz > 180.0)) { - gtk_rot_knob_set_value (GTK_ROT_KNOB (ctrl->AzSet), setaz- 360.0); - } - else { - gtk_rot_knob_set_value (GTK_ROT_KNOB (ctrl->AzSet), setaz); - } - gtk_rot_knob_set_value (GTK_ROT_KNOB (ctrl->ElSet), setel); + /* if this is a flipped pass and the rotor supports it*/ + if ((ctrl->flipped)&&(ctrl->conf->maxel>=180.0)){ + setel=180-setel; + if (setaz>180) + setaz-=180; + else + setaz+=180; } + if ((ctrl->conf->aztype == ROT_AZ_TYPE_180) && (setaz > 180.0)) { + setaz = setaz- 360.0; + } + + } else { + setaz = gtk_rot_knob_get_value (GTK_ROT_KNOB (ctrl->AzSet)); + setel = gtk_rot_knob_get_value (GTK_ROT_KNOB (ctrl->ElSet)); } if ((ctrl->engaged) && (ctrl->conf != NULL)) { @@ -953,14 +953,83 @@ } /* if tolerance exceeded */ - setaz = gtk_rot_knob_get_value (GTK_ROT_KNOB (ctrl->AzSet)); - setel = gtk_rot_knob_get_value (GTK_ROT_KNOB (ctrl->ElSet)); if ((fabs(setaz-rotaz) > ctrl->tolerance) || (fabs(setel-rotel) > ctrl->tolerance)) { - + + if (ctrl->tracking){ + /*if we are in a pass try to lead the satellite + some so we are not always chasing it*/ + if (ctrl->target->el>0.0) { + /*starting the rotator moving while we do some computation can lead to errors later*/ + /* + compute a time in the future when the position is + within tolerance so and send the rotor there. + */ + + /*use a working copy so data does not get corrupted*/ + sat=memcpy(&(sat_working),ctrl->target,sizeof(sat_t)); + + /* + compute az/el in the future that is past end of pass + or exceeds tolerance + */ + if (ctrl->pass) { + /* the next point is before the end of the pass + if there is one.*/ + time_delta=ctrl->pass->los-ctrl->t; + } else { + /* otherwise look 20 minutes into the future*/ + time_delta=1.0/72.0; + } + + step_size = time_delta / 2.0; + + /* + find a time when satellite is above horizon and at the + edge of tolerance. the final step size needs to be smaller + than delay. otherwise the az/el could be further away than + tolerance the next time we enter the loop and we end up + pushing ourselves away from the satellite. + */ + while (step_size > (ctrl->delay/1000.0/4.0/(secday))) { + predict_calc (sat,ctrl->qth,ctrl->t+time_delta); + /*update sat->az and sat->el to account for flips and az range*/ + if ((ctrl->flipped) && (ctrl->conf->maxel >= 180.0)){ + sat->el = 180.0-sat->el; + if (sat->az > 180.0) + sat->az -= 180.0; + else + sat->az += 180.0; + } + if ((ctrl->conf->aztype == ROT_AZ_TYPE_180) && (setaz > 180.0)) { + sat->az = sat->az - 360.0; + } + if ((sat->el < 0.0)||(sat->el > 180.0)|| + (fabs(setaz - sat->az) > (ctrl->tolerance)) || + (fabs(setel - sat->el) > (ctrl->tolerance))) { + time_delta -= step_size; + } else { + time_delta += step_size; + } + step_size /= 2.0; + } + setel = sat->el; + if (setel < 0.0) { + setel = 0.0; + } + if (setel > 180.0) { + setel = 180.0; + } + setaz = sat->az; + } + } /* send controller values to rotator device */ + /* this is the newly computed value which should be ahead of the current position */ if (!set_pos (ctrl, setaz, setel)) { error = TRUE; + } else { + gtk_rot_knob_set_value (GTK_ROT_KNOB (ctrl->AzSet), setaz); + gtk_rot_knob_set_value (GTK_ROT_KNOB (ctrl->ElSet), setel); } } @@ -999,7 +1068,7 @@ /* update controller circle on polar plot */ if (ctrl->conf !=NULL){ - if ((ctrl->conf->aztype == ROT_AZ_TYPE_180) && (rotaz < 0.0)) { + if ((ctrl->conf->aztype == ROT_AZ_TYPE_180) && (setaz < 0.0)) { gtk_polar_plot_set_ctrl_pos (GTK_POLAR_PLOT (ctrl->plot), gtk_rot_knob_get_value (GTK_ROT_KNOB (ctrl->AzSet))+360.0, gtk_rot_knob_get_value (GTK_ROT_KNOB (ctrl->ElSet))); @@ -1100,12 +1169,57 @@ if (retcode==TRUE){ retval=(gint)g_strtod(buffback+4,NULL); + /*treat errors as soft errors unless there is good reason*/ + /*good reasons come from operator experience or documentation*/ switch(retval) { case 0: /*no error case*/ break; + case -1: + /*RIG_EINVAL error*/ + /* + Returned by gs232 (-m 601) driver when value sent to + rotator outside configured range. + Based on author's experiment. + */ + sat_log_log (SAT_LOG_LEVEL_ERROR, + _("%s:%d: rotctld returned error %d (%s). Check the limits in your configuration."), + __FILE__, __LINE__, retval, buffback); + + retcode=FALSE; + break; + + case -5: + /*RIG_ETIMEOUT error*/ + /* + Returned by ea4tx interface when stuck + Based on comments on hamlib-discussion list. + */ + sat_log_log (SAT_LOG_LEVEL_ERROR, + _("%s:%d: rotctld returned error %d (%s)."), + __FILE__, __LINE__, retval, buffback); + + + retcode=FALSE; + break; + + + case -8: + /*RIG_EPROTO error*/ + /* + Returned by gs232 (-m 601) driver when interface is turned off + Based on author's experiment. + */ + sat_log_log (SAT_LOG_LEVEL_ERROR, + _("%s:%d: rotctld returned error %d (%s). Check that interface power on."), + __FILE__, __LINE__, retval, buffback); + + + retcode=FALSE; + break; + default: /*any other case*/ /*not sure what is a hard error or soft error*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |