diff --git a/detect.h b/detect.h index 53a5d77..b2fc5ba 100644 --- a/detect.h +++ b/detect.h @@ -50,8 +50,8 @@ enum { POSCTL_MODE_OFF = 0, POSCTL_MODE_CALIB, POSCTL_MODE_CONTROL, - POSCTL_MODE_2STEPINIT, - POSCTL_MODE_2STEP + POSCTL_MODE_2STEPWAIT, + POSCTL_MODE_2STEPRUN }; enum { @@ -73,6 +73,7 @@ enum { struct PosCtl_2Step_Data { + int mode; double pv[2]; double op[2]; double npv[2]; @@ -150,8 +151,7 @@ class PosCtl { void Stop (); void StartCalibration (); void StartControl (); - void Start2Step (); - void Stop2Step (); + void Run2Step (); void Reset2Step (); int GetMode () { return mode; }; void SetAxisParam (int axis, double min, double max, double k, double i, double d); diff --git a/gui.h b/gui.h index 4bb1116..5690921 100644 --- a/gui.h +++ b/gui.h @@ -202,7 +202,7 @@ G_MODULE_EXPORT void cb_posctl_btnsimreset (GtkWidget *widget, gpointer data); G_MODULE_EXPORT void cb_posctl_angles_draw (GtkWidget *area, cairo_t *cr, int w, int h, gpointer data); G_MODULE_EXPORT void cb_posctl_axis_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data); G_MODULE_EXPORT void cb_posctl_track_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data); -G_MODULE_EXPORT void cb_posctl_btn2stepstartstop (GtkWidget *widget, gpointer data); +G_MODULE_EXPORT void cb_posctl_btn2steprun (GtkWidget *widget, gpointer data); G_MODULE_EXPORT void cb_posctl_btn2stepreset (GtkWidget *widget, gpointer data); diff --git a/posctl.cc b/posctl.cc index 180966a..0389e58 100644 --- a/posctl.cc +++ b/posctl.cc @@ -130,17 +130,9 @@ void cb_posctl_btnsetdest (GtkWidget *widget, gpointer data) { /* * calibrate adjust control output.. */ -void cb_posctl_btn2stepstartstop (GtkWidget *widget, gpointer data) { +void cb_posctl_btn2steprun (GtkWidget *widget, gpointer data) { printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); - GtkWidget *btn = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_btn_2stepctl")); - if (posctl.GetMode() == POSCTL_MODE_2STEP || posctl.GetMode() == POSCTL_MODE_2STEPINIT) { - posctl.Stop2Step(); - gtk_button_set_label(GTK_BUTTON(btn), "Start"); - } - else { - posctl.Start2Step(); - gtk_button_set_label(GTK_BUTTON(btn), "Stop"); - } + posctl.Run2Step(); }; @@ -492,8 +484,7 @@ void cb_posctl_axis_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da /* * add result to the table */ -void posctl_2step_gui_update( double axis_pv[2], double axis_op[2], - double npv[2], double nop[2], double ppv[2], double pop[2]) { +void posctl_2step_gui_update(struct PosCtl_2Step_Data *d) { GtkWidget *lramin = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_2s_ramin")); GtkWidget *lramax = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_2s_ramax")); @@ -501,25 +492,28 @@ void posctl_2step_gui_update( double axis_pv[2], double axis_op[2], GtkWidget *ldecmax = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_2s_decmax")); GtkWidget *lraout = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_2s_raout")); GtkWidget *ldecout = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_2s_decout")); + GtkWidget *btn = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_btn_2steprun")); - char txt[255]; + if (d->mode == POSCTL_MODE_2STEPWAIT) gtk_widget_set_sensitive(btn, FALSE); + else gtk_widget_set_sensitive(btn, TRUE); + char txt[255]; // min - snprintf (txt, 255, "%2.5f [%2.5f]", npv[AXIS_RA], nop[AXIS_RA]); + snprintf (txt, 255, "%2.5f [%2.5f]", d->npv[AXIS_RA], d->nop[AXIS_RA]); gtk_label_set_text(GTK_LABEL(lramin), txt); - snprintf (txt, 255, "%2.5f [%2.5f]", npv[AXIS_DEC], nop[AXIS_DEC]); + snprintf (txt, 255, "%2.5f [%2.5f]", d->npv[AXIS_DEC], d->nop[AXIS_DEC]); gtk_label_set_text(GTK_LABEL(ldecmin), txt); // max - snprintf (txt, 255, "%2.5f [%2.5f]", ppv[AXIS_RA], pop[AXIS_RA]); + snprintf (txt, 255, "%2.5f [%2.5f]", d->ppv[AXIS_RA], d->pop[AXIS_RA]); gtk_label_set_text(GTK_LABEL(lramax), txt); - snprintf (txt, 255, "%2.5f [%2.5f]", ppv[AXIS_DEC], pop[AXIS_DEC]); + snprintf (txt, 255, "%2.5f [%2.5f]", d->ppv[AXIS_DEC], d->pop[AXIS_DEC]); gtk_label_set_text(GTK_LABEL(ldecmax), txt); // output - snprintf (txt, 255, "%2.5f [%2.5f]", axis_pv[AXIS_RA], axis_op[AXIS_RA]); + snprintf (txt, 255, "%2.5f [%2.5f]", d->pv[AXIS_RA], d->op[AXIS_RA]); gtk_label_set_text(GTK_LABEL(lraout), txt); - snprintf (txt, 255, "%2.5f [%2.5f]", axis_pv[AXIS_DEC], axis_op[AXIS_DEC]); + snprintf (txt, 255, "%2.5f [%2.5f]", d->pv[AXIS_DEC], d->op[AXIS_DEC]); gtk_label_set_text(GTK_LABEL(ldecout), txt); cb_posctl_entryanglelen(NULL, NULL); @@ -576,10 +570,14 @@ void posctl_gui_update() { GtkWidget *dec_pv = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_lb_d_dec")); GtkWidget *pos_filter = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_entry_inputfilter")); + GtkWidget *btn = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "posctl_btn_2steprun")); posctl.LockMutex(); int m = posctl.GetMode(); + if (m == POSCTL_MODE_2STEPWAIT) gtk_widget_set_sensitive(btn, FALSE); + else gtk_widget_set_sensitive(btn, TRUE); + if (m == POSCTL_MODE_OFF) { gtk_widget_set_sensitive(btnclib, true); gtk_widget_set_sensitive(btncontrol, true); @@ -682,7 +680,7 @@ gboolean cb_thread_posctl_2step (gpointer data) { posctl_gui_update(); if (data) { - posctl_2step_gui_update(d->pv, d->op, d->npv, d->nop, d->ppv, d->pop); + posctl_2step_gui_update(d); free (data); } @@ -792,6 +790,7 @@ void PosCtl::Stop() { void PosCtl::NotifyGtk2Step() { struct PosCtl_2Step_Data *data = (struct PosCtl_2Step_Data*) malloc (sizeof(struct PosCtl_2Step_Data)); + data->mode = mode; for (int i = 0; i < 2; i++) { data->pv[i] = axis_pv[i]; data->op[i] = axis_op[i]; @@ -1125,11 +1124,30 @@ void PosCtl::Loop (int pos_x, int pos_y, double dt) { NotifyGtk(); } - else if (mode == POSCTL_MODE_2STEP || mode == POSCTL_MODE_2STEPINIT) { - LockMutex(); + else if (mode == POSCTL_MODE_2STEPWAIT) { + // + // wait time CALIB_STARTSTOP_DELAY sec over? + struct timeval tv; + float timediff; + gettimeofday (&tv, NULL); + timediff = (float)(tv.tv_sec - calib_timestamp.tv_sec) + ((tv.tv_usec - calib_timestamp.tv_usec) / 1000000.0); + + if (timediff > CALIB_STARTSTOP_DELAY) { + mode = POSCTL_MODE_2STEPRUN; + target_pos.x = pos.x; + target_pos.y = pos.y; + calib_timestamp = tv; + } + + LockMutex(); NotifyGtk2Step(); + UnLockMutex(); + } + else if (mode == POSCTL_MODE_2STEPRUN) { + LockMutex(); + NotifyGtk2Step(); UnLockMutex(); } @@ -1163,8 +1181,7 @@ void PosCtl::Reset2Step() { nop[i] = NAN; pop[i] = NAN; } - posctl_2step_gui_update(axis_pv, axis_op, npv, nop, ppv, pop); - + NotifyGtk2Step(); UnLockMutex(); NotifyGtk(); }; @@ -1175,82 +1192,66 @@ void PosCtl::Reset2Step() { * if npv and ppv == NAN set min pos for both axes * min and max values will be read from the PID objects */ -void PosCtl::Start2Step() { - int found1 = 0, found2 = 0, i; +void PosCtl::Run2Step() { + int allset = 0, i; LockMutex(); - for (i = 0, found2 = 0, found1 = 0; i < 2; i++) { - if (isnan(npv[i]) && isnan(ppv[i])) found1 = 1; - if (isnan(npv[i]) || isnan(ppv[i])) found2 = 1; - } - if (found1) { - mode = POSCTL_MODE_2STEPINIT; - for (i = 0; i < 2; i++) { - axis_op[i] = pid_axis[1-i].GetMin(); - OutputWriteValue(i, axis_op[i]); - } - } - else if (found2) { - for (i = 0; i < 2; i++) { - axis_op[i] = pid_axis[1-i].GetMax(); - OutputWriteValue(i, axis_op[i]); - } - mode = POSCTL_MODE_2STEPINIT; + for (i = 0, allset = 1; i < 2; i++) { + if (isnan(npv[i]) || isnan(ppv[i])) allset = 0; } - else mode = POSCTL_MODE_2STEP; - - target_pos = pos; - printf ("%s:%d %s axis_op: (%f %f)\n", __FILE__, __LINE__, __FUNCTION__, axis_op[0], axis_op[1]); - posctl_2step_gui_update(axis_pv, axis_op, npv, nop, ppv, pop); - - UnLockMutex(); -}; + if (mode != POSCTL_MODE_2STEPRUN && mode != POSCTL_MODE_2STEPWAIT) { + // + // just start from the beginning + for (int i = 0; i < 2; i++) { + npv[i] = NAN; + ppv[i] = NAN; + nop[i] = NAN; + pop[i] = NAN; + } + target_pos = pos; + mode = POSCTL_MODE_2STEPWAIT; + OutputWriteStart(); + OutputWriteValue(AXIS_DEC, pid_axis[AXIS_DEC].GetMin()); + OutputWriteValue(AXIS_RA, pid_axis[AXIS_RA].GetMin()); -/* - * with each cycle, caclulate an output between p and n values. - */ -void PosCtl::Stop2Step() { - double axisnew_op[2] = { NAN, NAN }; - int i; - LockMutex(); - - // - // check if we got better values - for (int i = 0; i < 2; i++) { - if (axis_pv[i] < 0.0 && (isnan(npv[i]) || axis_pv[i] > npv[i])) { - npv[i] = axis_pv[i]; - nop[i] = axis_op[i]; + gettimeofday (&calib_timestamp, NULL); + } + else if (mode == POSCTL_MODE_2STEPRUN) { + if (allset) { + // + // check if we got better values + // FIXME: need to finish what to do next } - if (axis_pv[i] > 0.0 && (isnan(ppv[i]) || axis_pv[i] < ppv[i])) { - ppv[i] = axis_pv[i]; - pop[i] = axis_op[i]; + else { + // + // one value still missing: set nXX and pXX and go to maximum output + for (int i = 0; i < 2; i++) { + ppv[i] = npv[i] = axis_pv[i]; + pop[i] = nop[i] = axis_op[i]; + } + OutputWriteStart(); + OutputWriteValue(AXIS_DEC, pid_axis[AXIS_DEC].GetMax()); + OutputWriteValue(AXIS_RA, pid_axis[AXIS_RA].GetMax()); } - } - // need to calculate new step - if (mode == POSCTL_MODE_2STEP) { - for (i = 0; i < 2; i++) { - axisnew_op[i] = (nop[i] + pop[i]) / 2.0; - OutputWriteValue(i, axisnew_op[i]); - } + target_pos = pos; + mode = POSCTL_MODE_2STEPWAIT; + gettimeofday (&calib_timestamp, NULL); + } + else { + printf ("%s:%d %s ERROR: something went wrong. Mode not correct.\n", __FILE__, __LINE__, __FUNCTION__); } - printf ("%s:%d %s axis \t_op:\t%f\t%f \t_pv:\t%f\t%f \t new:\t%f\t%f\n", __FILE__, __LINE__, __FUNCTION__, - axis_op[0], axis_op[1], axis_pv[0], axis_pv[1], axisnew_op[0], axisnew_op[1]); - - mode = POSCTL_MODE_OFF; - - posctl_2step_gui_update(axis_pv, axis_op, npv, nop, ppv, pop); - for (i = 0; i < 2; i++) axis_op[i] = axisnew_op[i]; + printf ("%s:%d %s axis_op: (%f %f)\n", __FILE__, __LINE__, __FUNCTION__, axis_op[0], axis_op[1]); + NotifyGtk2Step(); UnLockMutex(); }; - void PosCtl::SetDevice (std::string d) { printf ("%s:%d %s new device:%s\n", __FILE__, __LINE__, __FUNCTION__, d.c_str()); @@ -1392,6 +1393,10 @@ int PosCtl::ReadTTY (char * inbuf, int length) { return 0; } + +/* + * write output, and save last set value in axis_op + */ int PosCtl::OutputWriteValue (int axis, double value) { char outbuf[255]; @@ -1419,6 +1424,8 @@ int PosCtl::OutputWriteValue (int axis, double value) { WriteTTY(outbuf); ReadTTY(outbuf, sizeof(outbuf) - 1); + axis_op[axis] = value; + return 0; }; diff --git a/simpleskycam.ui b/simpleskycam.ui index 5bf5859..5bb8d53 100644 --- a/simpleskycam.ui +++ b/simpleskycam.ui @@ -487,6 +487,11 @@ False gtk-close + + True + False + gtk-refresh + True False @@ -502,6 +507,11 @@ False gtk-refresh + + True + False + gtk-cancel + False 4 @@ -1992,6 +2002,8 @@ True True True + image_reset + True @@ -2002,13 +2014,15 @@ - - Start + + Run True True True - - + image_calc + True + + False