The VisAO Camera
coronguide.cpp
1 /************************************************************
2 * coronguide.cpp
3 *
4 * Author: Jared R. Males (jrmales@email.arizona.edu)
5 *
6 * Definitions for a class to auto guide for the coronagraph
7 *
8 * Developed as part of the Magellan Adaptive Optics system.
9 ************************************************************/
10 
11 /** \file coronguide.h
12  * \author Jared R. Males
13  * \brief Definitions for a class to auto guide for the coronagraph
14  *
15  *
16 */
17 
18 #include "coronguide.h"
19 
20 namespace VisAO
21 {
22 
23 coronguide::coronguide(int argc, char **argv) throw (AOException) : VisAOApp_standalone(argc, argv)
24 {
25  Create();
26 }
27 
28 coronguide::coronguide(std::string name, const std::string &conffile) throw (AOException) : VisAOApp_standalone(name, conffile)
29 {
30  Create();
31 }
32 
33 int coronguide::Create()
34 {
35 
36  std::string visao_root = getenv("VISAO_ROOT");
37 
38 
39  setup_fifo_list(4);
40  setup_baseApp(0, 1, 1, 1, false);
41  //setup_baseApp();
42 
43  signal(SIGIO, SIG_IGN);
44 
45  try
46  {
47  gimbscale = (int)(ConfigDictionary())["gimbscale"];
48  }
49  catch(Config_File_Exception)
50  {
51  _logger->log(Logger::LOG_LEV_FATAL, "Gimbal scale (gimbscale) is a required config parameter.");
52  throw;
53  }
54 
55  try
56  {
57  ap_recov_time = (double)(ConfigDictionary())["ap_recov_time"];
58  }
59  catch(Config_File_Exception)
60  {
61  ap_recov_time = 1.5;
62  _logger->log(Logger::LOG_LEV_INFO, "Auto pause recover time set to default %f secs.", ap_recov_time);
63  }
64 
65  try
66  {
67  shmem_key = (int)(ConfigDictionary())["shmem_key"];
68  }
69  catch(Config_File_Exception)
70  {
71  _logger->log(Logger::LOG_LEV_FATAL, "shmem_key is a required config parameter.");
72  throw;
73  }
74  attached_to_shmem = false;
75 
76 
77  std::string gimbal_fifopath;
78 
79  try
80  {
81  gimbal_fifopath = (std::string)(ConfigDictionary())["gimbal_fifopath"];
82  }
83  catch(...)
84  {
85  gimbal_fifopath = "fifos";
86  }
87 
88  std::string fpathin = visao_root + "/" + gimbal_fifopath + "/gimbal_com_script_in";
89  std::string fpathout = visao_root + "/" + gimbal_fifopath + "/gimbal_com_script_out";
90  set_fifo_list_channel(&fl, 0, 100, fpathout.c_str(), fpathin.c_str(), 0, 0);
91 
92 
93  //Init the status board for known process names
95  if(MyFullName() == "coronguide.L")
96  {
97  //std::cout << "Initing for coronguide.L\n";
98  statusboard_shmemkey = STATUS_coronguide;
99  }
100 
101  if(statusboard_shmemkey)
102  {
103  if(create_statusboard(sizeof(basic_status_board)) != 0)
104  {
106  _logger->log(Logger::LOG_LEV_ERROR, "Could not create status board.");
107  }
108  else
109  {
111  strncpy(bsb->appname, MyFullName().c_str(), 25);
112  bsb->max_update_interval = pause_time;
113  }
114  }
115 
116  isb = 0;
117  aosb = 0;
118  sis = 0;
119  dark_sis = 0;
120  ssb = 0;
121  ccdsb = 0;
122  sbconn = 0;
123 
124  loop_gain = 0.01;
125 
126  wait_to = .5;
127 
128  last_x0 = 0;
129  last_x1 = 0;
130  last_y0 = 0;
131  last_y1 = 0;
132 
133  tempIm = 0;
134  backgroundIm = 0;
135  kernel = 0;
136 
137  bgAlgorithm = MEDSUB;
138  kfwhm = 10.;
139  ksize = 4.;
140 
141  avgLen = 10;
142  xcens.resize(10);
143  ycens.resize(10);
144  inAvg = 0;
145  avgidx = 0;
146 
147  useAvg = false;
148  minMaxReject = true;
149 
150  gimbCounter = 0;
151  pthread_mutex_init(&memmutex, NULL);
152 
153  return 0;
154 }
155 
156 int coronguide::open_loop()
157 {
158  loopState = 0;
159 
160  struct timeval tv;
161  gettimeofday(&tv,0);
162  dataLogger(tv);
163 
164 
165 
166 
167  return 0;
168 }
169 
170 int coronguide::close_loop()
171 {
172 
173  if(useAvg && (xcen_avg == NOAVG || ycen_avg == NOAVG)) return -1;
174 
175  if(loopState == 0)
176  {
177 
178  if(useAvg)
179  {
180  tgtx = xcen_avg;
181  tgty = ycen_avg;
182  }
183  else
184  {
185  tgtx = xcen;
186  tgty = ycen;
187  }
188 
189  _logger->log(Logger::LOG_LEV_INFO, "Loop closed on target x: %f y: %f", tgtx, tgty);
190  }
191 
192  loopState = 1;
193 
194  struct timeval tv;
195  gettimeofday(&tv,0);
196  dataLogger(tv);
197 
198  return 0;
199 }
200 
201 int coronguide::pause_loop()
202 {
203  if(loopState == 0) return -1;
204 
205  loopState = 2;
206 
207  struct timeval tv;
208  gettimeofday(&tv,0);
209  dataLogger(tv);
210 
211  return 0;
212 }
213 
214 int coronguide::set_loop_gain(double lg)
215 {
216  if(lg < 0 || lg >=1)
217  {
218  _logger->log(Logger::LOG_LEV_INFO, "Crazy loop gain requested: %f", lg);
219 
220  lg = .01;
221 
222  }
223 
224  loop_gain = lg;
225 
226  _logger->log(Logger::LOG_LEV_INFO, "Loop gain set to: %f", loop_gain);
227 
228  struct timeval tv;
229  gettimeofday(&tv,0);
230  dataLogger(tv);
231 
232  return 0;
233 }
234 
235 int coronguide::set_bgalgo(int bga)
236 {
237  pthread_mutex_lock(&memmutex);
238 
239  switch(bga)
240  {
241  case MEDSUB:
242  bgAlgorithm = MEDSUB;
243  break;
244  case UNSHARP:
245  bgAlgorithm = UNSHARP;
246  break;
247  default:
248  bgAlgorithm = MEDSUB;
249  }
250 
251  if(backgroundIm)
252  {
253  delete backgroundIm;
254  backgroundIm = 0;
255  }
256 
257  pthread_mutex_unlock(&memmutex);
258  return 0;
259 }
260 
261 
262 int coronguide::set_kfwhm(double kfw)
263 {
264  pthread_mutex_lock(&memmutex);
265  kfwhm = kfw;
266 
267  if(kernel)
268  {
269  delete kernel;
270  kernel = 0;
271  }
272  pthread_mutex_unlock(&memmutex);
273  return 0;
274 
275 }
276 
277 int coronguide::set_ksize(int ks)
278 {
279  pthread_mutex_lock(&memmutex);
280 
281  ksize = ks;
282 
283  if(kernel)
284  {
285  delete kernel;
286  kernel = 0;
287  }
288 
289  pthread_mutex_unlock(&memmutex);
290  return 0;
291 }
292 
293 int coronguide::setUseAvg(bool ua)
294 {
295  useAvg = ua;
296  //std::cerr << "useAvg = " << useAvg << "\n";
297 }
298 
299 int coronguide::setMinMaxReject(bool mmr)
300 {
301  minMaxReject = mmr;
302  //std::cerr << "minMaxReject = " << minMaxReject << "\n";
303 
304 }
305 
306 int coronguide::setAvgLen(int na)
307 {
308  if(na != avgLen && na > 0)
309  {
310  pthread_mutex_lock(&memmutex);
311 
312  avgLen = na;
313  xcens.resize(na);
314  ycens.resize(na);
315  inAvg = 0;
316  avgidx = 0;
317 
318  xcen_avg = NOAVG;
319  ycen_avg = NOAVG;
320 
321  //std::cerr << "avgLen = " << avgLen << "\n";
322 
323  pthread_mutex_unlock(&memmutex);
324  }
325 }
326 
327 int coronguide::set_shmem_key(int sk)
328 {
329  shmem_key = sk;
330  return 0;
331 }
332 
333 int coronguide::connect_shmem()
334 {
336  if(sis->attach_shm(shmem_key) != 0)
337  {
338  ERROR_REPORT("Error attaching to shared memory.");
339  attached_to_shmem = false;
340  delete sis;
341  sis = 0;
342  dark_sis = 0;
343  return -1;
344  }
345 
346  dark_sis = new sharedim_stackS;
347  if(dark_sis->attach_shm(5002) != 0)
348  {
349  ERROR_REPORT("Error attaching to shared memory for darks.");
350  attached_to_shmem = false;
351  delete sis;
352  delete dark_sis;
353  sis = 0;
354  dark_sis = 0;
355  return -1;
356  }
357 
358 
359  attached_to_shmem = true;
360  return 0;
361 }
362 
363 
364 
366 {
367  connect_shmem();
368 
369  //Install the main thread handler
371  {
372  ERROR_REPORT("Error installing main thread catcher.");
373  return -1;
374  }
375 
376  //Startup the I/O signal handling thread
377  if(start_signal_catcher(true) != 0)
378  {
379  ERROR_REPORT("Error starting signal catching thread.");
380  return -1;
381  }
382 
383  //Now Block all I/O signals in this thread.
384  if(block_sigio() != 0)
385  {
386  ERROR_REPORT("Error blocking SIGIO in main thread.");
387  return -1;
388  }
389 
390  attach_status_boards();
391  LOG_INFO("starting up . . .");
392 
393  while((!sbconn || !attached_to_shmem) && !TimeToDie)
394  {
395  sleep(1);
396 
397  if(!isb || !aosb) attach_status_boards();
398 
399  if(attached_to_shmem == false)
400  {
401  connect_shmem();
402  }
403  }
404 
405  while(!TimeToDie)
406  {
407  //usleep(50000);
408  sleep(1);
409  write_frame();
410 
411  }
412 
413  return 0;
414 }
415 
416 int coronguide::write_frame()
417 {
418  int curr_image;
419 
420  static int last_image = -1;
421 
422  static double autopause_time = 0;
423 
424  double background = 0.;
425  double imv;
426 
427 
428  size_t xdim;
429  size_t ydim;
430 
431  curr_image = sis->get_last_image();
432 
433  if(curr_image == last_image || curr_image < 0) return -1;
434 
435  sim = sis->get_image(curr_image);
436  last_image = curr_image;
437 
438  int darkcurrim = dark_sis->get_last_image();
439  dark_sim = dark_sis->get_image(darkcurrim);
440 
441  double totl = 0;
442  double tmp_xcen = 0;
443  double tmp_ycen = 0;
444 
445  size_t x0 = isb->guidebox_x0;
446  size_t x1 = isb->guidebox_x1;
447  size_t y0 = isb->guidebox_y0;
448  size_t y1 = isb->guidebox_y1;
449  size_t idx;
450  size_t nx = sim.nx;
451 
452  pthread_mutex_lock(&memmutex);
453 
454  //If different, need to reallocate
455  if(x0 != last_x0 || x1 != last_x1 || y0 != last_y0 || y1 != last_y1)
456  {
457  if(tempIm) delete tempIm;
458  if(backgroundIm) delete backgroundIm;
459 
460  tempIm = 0;
461  backgroundIm = 0;
462 
463  open_loop();
464 
465  inAvg = 0;
466  avgidx = 0;
467  }
468 
469  last_x0 = x0;
470  last_x1 = x1;
471  last_y0 = y0;
472  last_y1 = y1;
473 
474 
475  //If box inverted, fix.
476  if(x1 < x0)
477  {
478  double dtmp = x1;
479  x1 = x0;
480  x0 = dtmp;
481  }
482 
483  if(y1 < y0)
484  {
485  double dtmp = y1;
486  y1 = y0;
487  y0 = dtmp;
488  }
489 
490  if(x0 >= nx or y0 >= nx or x1 >= nx or y1 >= nx or x0 == x1 or y0 == y1)
491  {
492  pthread_mutex_unlock(&memmutex);
493  return 0;
494  }
495 
496  xdim = x1 - x0;
497  ydim = y1 - y0;
498 
499  //If necessary, allocate tempIm
500  if(!tempIm) tempIm = new double[xdim*ydim];
501 
502  //If necessary, allocate and initialize backgroundIm
503  if(!backgroundIm)
504  {
505  backgroundIm = new double[xdim*ydim];
506 
507  for(size_t i=0;i<xdim; i++)
508  {
509  for(size_t j=0;j< ydim; j++)
510  {
511  backgroundIm[j*xdim + i] = 0.;
512  }
513  }
514  }
515 
516 
517  /******************/
518  //copy to tempIm
519  /*****************/
520  for(size_t i=x0;i<x1;i++)
521  {
522  for(size_t j=y0;j<y1;j++)
523  {
524  idx = j*nx + i;
525  tempIm[(j-y0)*xdim+(i-x0)] = sim.imdata[idx];
526  }
527  }
528 
529 
530  /******************/
531  //Median subtraction
532  /*****************/
533  if(bgAlgorithm == MEDSUB)
534  {
535  size_t cnt = 0;
536  std::vector<double> medvect((y1-y0)*(x1-x0));
537 
538  for(size_t i=0;i<xdim;i++)
539  {
540  for(size_t j=0;j<ydim;j++)
541  {
542  imv = tempIm[j*xdim + i]; //sim.imdata[idx]; //-dark_sim.imdata[idx];
543 
544  if(isnan(imv) || imv < 0 || imv > 16383) continue;
545  medvect[cnt] = imv;
546 
547  cnt++;
548  }
549  }
550 
551  std::sort(medvect.begin(), medvect.end());
552  int meddx = 0.5*cnt;
553  background = medvect[meddx];
554  }
555 
556  /******************/
557  //Unsharp mask
558  /*****************/
559  if(bgAlgorithm == UNSHARP)
560  {
561  if(!kernel)
562  {
563  kdim = ksize*kfwhm;
564  kernel = new double[kdim*kdim];
565  gaussKernel(kernel, kdim, kdim, kfwhm/GSIG2FW);
566  }
567 
568  //std::cerr << "usm-ing\n";
569  applyKernel(backgroundIm, tempIm, xdim, ydim, kernel, kdim, kdim);
570  background = 0;
571  }
572 
573 
574  totl = 0;
575  for(size_t i=0;i<xdim;i++)
576  {
577  for(size_t j=0;j<ydim;j++)
578  {
579  idx = j*xdim+i;
580  imv = tempIm[idx] - backgroundIm[idx] - background; //dark_sim.imdata[idx] - med;
581 
582  if(bgAlgorithm == UNSHARP)
583  {
584  if(imv < 0) imv = 0;
585  }
586  //if(isnan(imv) || imv < 0 || imv > 16383) continue;
587  if(isnan(imv)) continue;
588 
589  totl += imv;
590 
591  tmp_xcen += imv*i;
592  tmp_ycen += imv*j;
593 
594  }
595  }
596 
597  pthread_mutex_unlock(&memmutex);
598 
599  xcen = tmp_xcen/totl;
600  ycen = tmp_ycen/totl;
601 
602  //oooh, don't add to avg if paused, autopause, etc., only closed or open.
603 
604  if(loopState==0 or loopState==1)
605  {
606  xcens[avgidx] = tmp_xcen/totl;
607  ycens[avgidx] = tmp_ycen/totl;
608  avgidx++;
609  inAvg++;
610  gimbCounter++;
611 
612  if(avgidx >= avgLen) avgidx = 0;
613  if(inAvg > avgLen) inAvg = avgLen;
614 
615  if(inAvg >= avgLen)
616  {
617  double totx = 0, minx = xcens[0], maxx = xcens[0];
618  double toty = 0, miny = ycens[0], inAvg = ycens[0];
619 
620  for(int q=0; q < avgLen; q++)
621  {
622  totx += xcens[q];
623  if(xcens[q] < minx) minx = xcens[q];
624  if(xcens[q] > maxx) maxx = xcens[q];
625 
626  toty += ycens[q];
627  if(ycens[q] < miny) miny = ycens[q];
628  if(ycens[q] > inAvg) inAvg = ycens[q];
629  }
630 
631  if(minMaxReject && avgLen > 2)
632  {
633  xcen_avg = (totx - minx - maxx)/(avgLen-2);
634  ycen_avg = (toty - miny - inAvg)/(avgLen-2);
635  }
636  else
637  {
638  xcen_avg = totx/avgLen;
639  ycen_avg = toty/avgLen;
640  }
641  }
642  else
643  {
644  xcen_avg = NOAVG;
645  ycen_avg = NOAVG;
646  }
647  }
648 
649  std::cout << xcen << " " << ycen << " " << xcen_avg << " " << ycen_avg << std::endl;
650 
651  /*if(bgAlgorithm == UNSHARP)
652  {
653  for(size_t i=0;i<xdim;i++)
654  {
655  for(size_t j=0;j<ydim;j++)
656  {
657  idx = j*xdim+i;
658  std::cout << tempIm[idx] << " " << backgroundIm[idx] << "\n";
659  }
660  }
661 }*/
662 
663  struct timeval tv;
664 
665  gettimeofday(&tv,0);
666 
667  if(loopState > 0)
668  {
669 
670  if(aosb->loop_on != 1 || aosb->nodInProgress || ssb->sw_state != 1)
671  {
672  if(loopState == 1)
673  {
674  loopState = 3;
675  dataLogger(tv);
676  }
677  }
678  else if(loopState == 3)
679  {
680  if(!aosb->nodInProgress && ssb->sw_state == 1 && aosb->loop_on == 1)
681  {
682  autopause_time = get_curr_time();
683  loopState = 4;
684  dataLogger(tv);
685  }
686  }
687  else if(loopState == 4)
688  {
689  if(get_curr_time() - autopause_time > 1.5 + 1./ccdsb->framerate)
690  {
691  dataLogger(tv);
692  loopState = 1;
693  }
694  }
695  else if(loopState == 1)
696  {
697  double gx, gy;
698 
699  if(useAvg)
700  {
701  gx = -1.*(xcen_avg-tgtx)/gimbscale*loop_gain;
702  gy = (ycen_avg-tgty)/gimbscale*loop_gain;
703  if(gimbCounter > avgLen) move_gimbal(gx, gy);
704  }
705  else
706  {
707  gx = -1.*(xcen-tgtx)/gimbscale*loop_gain;
708  gy = (ycen-tgty)/gimbscale*loop_gain;
709  move_gimbal(gx, gy);
710  }
711 
712 
713  dataLogger(tv);
714  }
715  }
716 
717  return 0;
718 }
719 
720 int coronguide::move_gimbal(double gx, double gy)
721 {
722  char str[256];
723  std::string resp;
724 
725  //std::cout << "Gimb dx: " << gx << " Gimb dy: " << gy << "\n";
726 
727  //std::cout << "Taking Script control" << std::endl;
728 
729  std::cout << "moving gimbal: " << gx << " " << gy << std::endl;
730  write_fifo_channel(0, "SCRIPT", 7, &resp);
731 
732  //std::cout << "Applying x diff" << std::endl;
733 
734  snprintf(str, 256, "xrel %f", gx);
735  write_fifo_channel(0, str, strlen(str)+1, &resp);
736 
737  //std::cout << "Applying y diff" << std::endl;
738 
739  snprintf(str, 256, "yrel %f", gy);
740  write_fifo_channel(0, str, strlen(str)+1, &resp);
741 
742  gimbCounter = 0;
743 
744  return 0;
745 }
746 
747 
748 int coronguide::attach_status_boards()
749 {
750  size_t sz;
751 
752  if(!isb)
753  {
755  }
756 
757  if(!aosb)
758  {
759  aosb = (VisAO::aosystem_status_board*) attach_shm(&sz, STATUS_aosystem, 0);
760  }
761 
762  if(!ssb)
763  {
764  ssb = (VisAO::shutter_status_board*) attach_shm(&sz, STATUS_shutterctrl, 0);
765  }
766 
767  if(!ccdsb)
768  {
770  }
771 
772  if(isb && aosb && ssb && ccdsb) sbconn = 1;
773 
774  return 0;
775 }
776 
777 std::string coronguide::remote_command(std::string com)
778 {
779  std::string resp;
780  _logger->log(Logger::LOG_LEV_TRACE, "Received remote command: %s.", com.c_str());
781  resp = common_command(com, CMODE_REMOTE);
782  if(resp == "") resp = (std::string("UNKOWN COMMAND: ") + com + "\n");
783  _logger->log(Logger::LOG_LEV_TRACE, "Response to remote command: %s.", resp.c_str());
784  return resp;
785 }
786 
787 std::string coronguide::local_command(std::string com)
788 {
789  std::string resp;
790  _logger->log(Logger::LOG_LEV_TRACE, "Received local command: %s.", com.c_str());
791  resp = common_command(com, CMODE_LOCAL);
792  if(resp == "") resp = (std::string("UNKOWN COMMAND: ") + com + "\n");
793  _logger->log(Logger::LOG_LEV_TRACE, "Response to local command: %s.", resp.c_str());
794  return resp;
795 }
796 
797 std::string coronguide::script_command(std::string com)
798 {
799  std::string resp;
800  _logger->log(Logger::LOG_LEV_TRACE, "Received script command: %s.", com.c_str());
801  resp = common_command(com, CMODE_SCRIPT);
802  if(resp == "") resp = (std::string("UNKOWN COMMAND: ") + com + "\n");
803  _logger->log(Logger::LOG_LEV_TRACE, "Response to script command: %s.", resp.c_str());
804  return resp;
805 }
806 
807 std::string coronguide::auto_command(std::string com, char *seqmsg)
808 {
809  std::string resp;
810  _logger->log(Logger::LOG_LEV_TRACE, "Received auto command: %s.", com.c_str());
811  resp = common_command(com, CMODE_AUTO);
812  seqmsg = 0; //just to avoid the warning
813  if(resp == "") resp = post_auto_command(com);
814  _logger->log(Logger::LOG_LEV_TRACE, "Response to auto command: %s.", resp.c_str());
815  return resp;
816 }
817 
818 std::string coronguide::common_command(std::string com, int cmode)
819 {
820  char tmpstr[256];
821 
822  if(com == "state?")
823  {
824  return get_state_str();
825  }
826 
827  if(com == "loopstate?")
828  {
829  snprintf(tmpstr, 256, "%i\n", loopState);
830  return tmpstr;
831  }
832 
833  if(com == "loopgain?")
834  {
835  snprintf(tmpstr, 256, "%0.4f\n", loop_gain);
836  return tmpstr;
837  }
838 
839  if(com == "tgtx?")
840  {
841  snprintf(tmpstr, 256, "%0.4f\n", tgtx);
842  return tmpstr;
843  }
844 
845  if(com == "tgty?")
846  {
847  snprintf(tmpstr, 256, "%0.4f\n", tgty);
848  return tmpstr;
849  }
850 
851  if(com == "xcen?")
852  {
853  snprintf(tmpstr, 256, "%0.4f\n", xcen);
854  return tmpstr;
855  }
856 
857  if(com == "ycen?")
858  {
859  snprintf(tmpstr, 256, "%0.4f\n", ycen);
860  return tmpstr;
861  }
862 
863  if(com == "open")
864  {
865  if(cmode == control_mode)
866  {
867  //std::cout << "Opening the loop\n";
868  open_loop();
869  return "0\n";
870  }
871  else
872  {
873  return control_mode_response();
874  }
875  }
876 
877  if(com == "close" && cmode == control_mode)
878  {
879  if(cmode == control_mode)
880  {
881  //std::cout << "Closing the loop\n";
882  close_loop();
883  return "0\n";
884  }
885  else
886  {
887  return control_mode_response();
888  }
889  }
890 
891  if(com == "pause" && cmode == control_mode)
892  {
893  if(cmode == control_mode)
894  {
895  //std::cout << "Pausing the loop\n";
896  pause_loop();
897  return "0\n";
898  }
899  else
900  {
901  return control_mode_response();
902  }
903  }
904 
905  if(com.length() > 4)
906  {
907  if(com.substr(0, 4)== "gain")
908  {
909  if(cmode == control_mode)
910  {
911  std::string newgain = com.substr(5, com.length()-5);
912  set_loop_gain(strtod(newgain.c_str(),0));
913  return "0\n";
914  }
915  else
916  {
917  return control_mode_response();
918  }
919  }
920  }
921 
922  if(com.length() > 6)
923  {
924  if(com.substr(0, 6)== "bgalgo")
925  {
926  if(cmode == control_mode)
927  {
928  std::string newalgo = com.substr(7, com.length()-7);
929  set_bgalgo(atoi(newalgo.c_str()));
930  return "0\n";
931  }
932  else
933  {
934  return control_mode_response();
935  }
936  }
937  }
938 
939  if(com.length() > 5)
940  {
941  if(com.substr(0, 5)== "kfwhm")
942  {
943  if(cmode == control_mode)
944  {
945  std::string newkfwhm = com.substr(6, com.length()-6);
946  set_kfwhm(strtod(newkfwhm.c_str(), 0));
947  return "0\n";
948  }
949  else
950  {
951  return control_mode_response();
952  }
953  }
954  }
955 
956  if(com.length() > 5)
957  {
958  if(com.substr(0, 5)== "ksize")
959  {
960  if(cmode == control_mode)
961  {
962  std::string newksize = com.substr(6, com.length()-6);
963  set_ksize(atoi(newksize.c_str()));
964  return "0\n";
965  }
966  else
967  {
968  return control_mode_response();
969  }
970  }
971  }
972 
973  if(com.length() > 6)
974  {
975  if(com.substr(0, 6)== "useavg")
976  {
977  if(cmode == control_mode)
978  {
979  std::string newua = com.substr(7, com.length()-7);
980  setUseAvg(atoi(newua.c_str()));
981  return "0\n";
982  }
983  else
984  {
985  return control_mode_response();
986  }
987  }
988  }
989 
990  if(com.length() > 5)
991  {
992  if(com.substr(0, 5)== "mmrej")
993  {
994  if(cmode == control_mode)
995  {
996  std::string mmrej = com.substr(6, com.length()-6);
997  setMinMaxReject(atoi(mmrej.c_str()));
998  return "0\n";
999  }
1000  else
1001  {
1002  return control_mode_response();
1003  }
1004  }
1005  }
1006 
1007  if(com.length() > 6)
1008  {
1009  if(com.substr(0, 6)== "avglen")
1010  {
1011  if(cmode == control_mode)
1012  {
1013  std::string avglen = com.substr(7, com.length()-7);
1014  setAvgLen(atoi(avglen.c_str()));
1015  return "0\n";
1016  }
1017  else
1018  {
1019  return control_mode_response();
1020  }
1021  }
1022  }
1023 
1024  return "";
1025 }
1026 
1027 std::string coronguide::get_state_str()
1028 {
1029  std::string cmstr;
1030  char str[256];
1031 
1032  cmstr= control_mode_response();
1033 
1034  snprintf(str, 256, "%c %i %0.4f %0.4f %0.4f %0.4f %0.4f %i %0.4f %i %i %i %i\n", cmstr[0], loopState, loop_gain, tgtx, tgty, xcen, ycen, bgAlgorithm, kfwhm, ksize, useAvg, minMaxReject, avgLen);
1035 
1036  return str;
1037 }
1038 
1039 
1040 
1042 {
1044  {
1046 
1048 
1049  cgsb->loopState = loopState;
1050  cgsb->loop_gain = loop_gain;
1051  cgsb->tgtx = tgtx;
1052  cgsb->tgty = tgty;
1053  cgsb->xcen = xcen;
1054  cgsb->ycen = ycen;
1055 
1056  }
1057 
1058  return 0;
1059 
1060 }
1061 
1063 {
1064  checkDataFileOpen();
1065 
1066 
1067  dataof << tv.tv_sec << " " << tv.tv_usec << " " << loopState << " " << loop_gain << " " << tgtx << " " << tgty << " " << xcen << " " << ycen << std::endl;
1068 
1069  if(!dataof.good())
1070  {
1071  Logger::get()->log(Logger::LOG_LEV_ERROR, "Error in coronguide data file. Data may not be logged correctly");
1072  }
1073 
1074 }
1075 
1076 } //namespace VisAO
1077 
virtual std::string script_command(std::string com)
Overridden from VisAOApp_base::script_command, here just calls common_command.
Definition: coronguide.cpp:797
sharedim< short > sim
The sharedim structure retreived from the stack.
Definition: coronguide.h:58
virtual void dataLogger(timeval tv)
Write coronguide status to the data log.
double get_curr_time(void)
Gets the current CLOCK_REALTIME time, returns it in seconds to double precision.
Definition: libvisaoc.c:40
virtual int start_signal_catcher(bool inherit_sched=true)
Starts the signal catching loop.
double wait_to
The timeout for waiting on responses from FIFOs in seconds.
Definitions for a class to auto guide for the coronagraph.
std::string common_command(std::string com, int cmode)
The common command processor for commands received by fifo.
Definition: coronguide.cpp:818
void * statusboard_shmemptr
The pointer to the shared memory block for the statusboard.
virtual int update_statusboard()
Update the status board.
virtual int setup_baseApp(bool usethreads=false)
Install fifo channels.
virtual std::string local_command(std::string com)
Overridden from VisAOApp_base::local_command, here just calls common_command.
Definition: coronguide.cpp:787
sharedim_stack< short > * sis
Manages a VisAO shared memory image stack.
Definition: coronguide.h:51
int setup_fifo_list(int nfifos)
Allocate the fifo_list.
virtual std::string remote_command(std::string com)
Overridden from VisAOApp_base::remote_command, here just calls common_command.
Definition: coronguide.cpp:777
key_t statusboard_shmemkey
The key used to lookup the shared memory.
virtual int block_sigio()
Sets the signal mask to block SIGIO and RTSIGIO.
int TimeToDie
Global set by SIGTERM.
int attach_shm(key_t mkey)
Attachess the shared memory. A Reader process should start here.
std::string control_mode_response()
Convenience function to return the control type response string, e.g. "A\n".
void * attach_shm(size_t *sz, key_t mkey, int shmemid)
Attach to a shared memory buffer and get its size.
Definition: libvisaoc.c:90
fifo_list fl
The list of named-pipe fifos used for inter-process comms.
double pause_time
Time to pause during application main loop.
Definition: VisAOApp_base.h:84
sharedim< IMDATA_TYPE > get_image(int imno)
Gets an image, as a sharedim structure, with the imdata pointer properly set for the calling process...
double tgtx
Size of the kernel, in units of kfwhm.
Definition: coronguide.h:97
int update_statusboard()
Update the status board.
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
#define STATUS_imviewer
Shared memory key for imviewer status board.
Definition: statusboard.h:77
static int control_mode
The current control mode.
virtual int install_sig_mainthread_catcher()
Install the SIG_MAINTHREAD signal catcher.
std::string auto_command(std::string com, char *seqmsg)
Overridden from VisAOApp_base::auto_command, here just calls common_command.
Definition: coronguide.cpp:807
virtual int Run()
The application main loop, to be re-implemented in derived classes.
Definition: coronguide.cpp:365
The namespace of VisAO software.
virtual std::string post_auto_command(std::string com, char *seqmsg=0)
Processing for auto commands - not normally overriden.
int get_last_image()
Returns the value of last_image currently in the header.
#define STATUS_coronguide
Shared memory key for the Coronagraph Guider status board.
Definition: statusboard.h:68
int shmem_key
shared memory key for
Definition: coronguide.h:54
#define STATUS_ccd47
Shared memory key for the ccd47 controller status board.
Definition: statusboard.h:41
int set_fifo_list_channel(fifo_list *fl, int nch, int buffsz, const char *fin, const char *fout, int(*inp_hand)(fifo_channel *), void *adata)
Set the details of one channel in the list.
Definition: fifoutils.c:373
int write_fifo_channel(int ch, const char *com, int comlen, std::string *resp)
Write data to a fifo_channel, and get a response if desired.