23 coronguide::coronguide(
int argc,
char **argv)
throw (AOException) : VisAOApp_standalone(argc, argv)
28 coronguide::coronguide(std::string name,
const std::string &conffile)
throw (AOException) : VisAOApp_standalone(name, conffile)
33 int coronguide::Create()
36 std::string visao_root = getenv(
"VISAO_ROOT");
43 signal(SIGIO, SIG_IGN);
47 gimbscale = (
int)(ConfigDictionary())[
"gimbscale"];
49 catch(Config_File_Exception)
51 _logger->log(Logger::LOG_LEV_FATAL,
"Gimbal scale (gimbscale) is a required config parameter.");
57 ap_recov_time = (double)(ConfigDictionary())[
"ap_recov_time"];
59 catch(Config_File_Exception)
62 _logger->log(Logger::LOG_LEV_INFO,
"Auto pause recover time set to default %f secs.", ap_recov_time);
69 catch(Config_File_Exception)
71 _logger->log(Logger::LOG_LEV_FATAL,
"shmem_key is a required config parameter.");
74 attached_to_shmem =
false;
77 std::string gimbal_fifopath;
81 gimbal_fifopath = (std::string)(ConfigDictionary())[
"gimbal_fifopath"];
85 gimbal_fifopath =
"fifos";
88 std::string fpathin = visao_root +
"/" + gimbal_fifopath +
"/gimbal_com_script_in";
89 std::string fpathout = visao_root +
"/" + gimbal_fifopath +
"/gimbal_com_script_out";
95 if(MyFullName() ==
"coronguide.L")
101 if(statusboard_shmemkey)
106 _logger->log(Logger::LOG_LEV_ERROR,
"Could not create status board.");
111 strncpy(bsb->appname, MyFullName().c_str(), 25);
137 bgAlgorithm = MEDSUB;
151 pthread_mutex_init(&memmutex, NULL);
156 int coronguide::open_loop()
170 int coronguide::close_loop()
173 if(useAvg && (xcen_avg == NOAVG || ycen_avg == NOAVG))
return -1;
189 _logger->log(Logger::LOG_LEV_INFO,
"Loop closed on target x: %f y: %f",
tgtx, tgty);
201 int coronguide::pause_loop()
203 if(loopState == 0)
return -1;
214 int coronguide::set_loop_gain(
double lg)
218 _logger->log(Logger::LOG_LEV_INFO,
"Crazy loop gain requested: %f", lg);
226 _logger->log(Logger::LOG_LEV_INFO,
"Loop gain set to: %f", loop_gain);
235 int coronguide::set_bgalgo(
int bga)
237 pthread_mutex_lock(&memmutex);
242 bgAlgorithm = MEDSUB;
245 bgAlgorithm = UNSHARP;
248 bgAlgorithm = MEDSUB;
257 pthread_mutex_unlock(&memmutex);
262 int coronguide::set_kfwhm(
double kfw)
264 pthread_mutex_lock(&memmutex);
272 pthread_mutex_unlock(&memmutex);
277 int coronguide::set_ksize(
int ks)
279 pthread_mutex_lock(&memmutex);
289 pthread_mutex_unlock(&memmutex);
293 int coronguide::setUseAvg(
bool ua)
299 int coronguide::setMinMaxReject(
bool mmr)
306 int coronguide::setAvgLen(
int na)
308 if(na != avgLen && na > 0)
310 pthread_mutex_lock(&memmutex);
323 pthread_mutex_unlock(&memmutex);
327 int coronguide::set_shmem_key(
int sk)
333 int coronguide::connect_shmem()
338 ERROR_REPORT(
"Error attaching to shared memory.");
339 attached_to_shmem =
false;
349 ERROR_REPORT(
"Error attaching to shared memory for darks.");
350 attached_to_shmem =
false;
359 attached_to_shmem =
true;
372 ERROR_REPORT(
"Error installing main thread catcher.");
379 ERROR_REPORT(
"Error starting signal catching thread.");
386 ERROR_REPORT(
"Error blocking SIGIO in main thread.");
390 attach_status_boards();
391 LOG_INFO(
"starting up . . .");
393 while((!sbconn || !attached_to_shmem) && !
TimeToDie)
397 if(!isb || !aosb) attach_status_boards();
399 if(attached_to_shmem ==
false)
416 int coronguide::write_frame()
420 static int last_image = -1;
422 static double autopause_time = 0;
424 double background = 0.;
433 if(curr_image == last_image || curr_image < 0)
return -1;
436 last_image = curr_image;
439 dark_sim = dark_sis->
get_image(darkcurrim);
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;
452 pthread_mutex_lock(&memmutex);
455 if(x0 != last_x0 || x1 != last_x1 || y0 != last_y0 || y1 != last_y1)
457 if(tempIm)
delete tempIm;
458 if(backgroundIm)
delete backgroundIm;
490 if(x0 >= nx or y0 >= nx or x1 >= nx or y1 >= nx or x0 == x1 or y0 == y1)
492 pthread_mutex_unlock(&memmutex);
500 if(!tempIm) tempIm =
new double[xdim*ydim];
505 backgroundIm =
new double[xdim*ydim];
507 for(
size_t i=0;i<xdim; i++)
509 for(
size_t j=0;j< ydim; j++)
511 backgroundIm[j*xdim + i] = 0.;
520 for(
size_t i=x0;i<x1;i++)
522 for(
size_t j=y0;j<y1;j++)
525 tempIm[(j-y0)*xdim+(i-x0)] =
sim.imdata[idx];
533 if(bgAlgorithm == MEDSUB)
536 std::vector<double> medvect((y1-y0)*(x1-x0));
538 for(
size_t i=0;i<xdim;i++)
540 for(
size_t j=0;j<ydim;j++)
542 imv = tempIm[j*xdim + i];
544 if(isnan(imv) || imv < 0 || imv > 16383)
continue;
551 std::sort(medvect.begin(), medvect.end());
553 background = medvect[meddx];
559 if(bgAlgorithm == UNSHARP)
564 kernel =
new double[kdim*kdim];
565 gaussKernel(kernel, kdim, kdim, kfwhm/GSIG2FW);
569 applyKernel(backgroundIm, tempIm, xdim, ydim, kernel, kdim, kdim);
575 for(
size_t i=0;i<xdim;i++)
577 for(
size_t j=0;j<ydim;j++)
580 imv = tempIm[idx] - backgroundIm[idx] - background;
582 if(bgAlgorithm == UNSHARP)
587 if(isnan(imv))
continue;
597 pthread_mutex_unlock(&memmutex);
599 xcen = tmp_xcen/totl;
600 ycen = tmp_ycen/totl;
604 if(loopState==0 or loopState==1)
606 xcens[avgidx] = tmp_xcen/totl;
607 ycens[avgidx] = tmp_ycen/totl;
612 if(avgidx >= avgLen) avgidx = 0;
613 if(inAvg > avgLen) inAvg = avgLen;
617 double totx = 0, minx = xcens[0], maxx = xcens[0];
618 double toty = 0, miny = ycens[0], inAvg = ycens[0];
620 for(
int q=0; q < avgLen; q++)
623 if(xcens[q] < minx) minx = xcens[q];
624 if(xcens[q] > maxx) maxx = xcens[q];
627 if(ycens[q] < miny) miny = ycens[q];
628 if(ycens[q] > inAvg) inAvg = ycens[q];
631 if(minMaxReject && avgLen > 2)
633 xcen_avg = (totx - minx - maxx)/(avgLen-2);
634 ycen_avg = (toty - miny - inAvg)/(avgLen-2);
638 xcen_avg = totx/avgLen;
639 ycen_avg = toty/avgLen;
649 std::cout << xcen <<
" " << ycen <<
" " << xcen_avg <<
" " << ycen_avg << std::endl;
670 if(aosb->loop_on != 1 || aosb->nodInProgress || ssb->sw_state != 1)
678 else if(loopState == 3)
680 if(!aosb->nodInProgress && ssb->sw_state == 1 && aosb->loop_on == 1)
687 else if(loopState == 4)
689 if(
get_curr_time() - autopause_time > 1.5 + 1./ccdsb->framerate)
695 else if(loopState == 1)
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);
707 gx = -1.*(xcen-
tgtx)/gimbscale*loop_gain;
708 gy = (ycen-tgty)/gimbscale*loop_gain;
720 int coronguide::move_gimbal(
double gx,
double gy)
729 std::cout <<
"moving gimbal: " << gx <<
" " << gy << std::endl;
734 snprintf(str, 256,
"xrel %f", gx);
739 snprintf(str, 256,
"yrel %f", gy);
748 int coronguide::attach_status_boards()
772 if(isb && aosb && ssb && ccdsb) sbconn = 1;
780 _logger->log(Logger::LOG_LEV_TRACE,
"Received remote command: %s.", com.c_str());
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());
790 _logger->log(Logger::LOG_LEV_TRACE,
"Received local command: %s.", com.c_str());
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());
800 _logger->log(Logger::LOG_LEV_TRACE,
"Received script command: %s.", com.c_str());
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());
810 _logger->log(Logger::LOG_LEV_TRACE,
"Received auto command: %s.", com.c_str());
814 _logger->log(Logger::LOG_LEV_TRACE,
"Response to auto command: %s.", resp.c_str());
824 return get_state_str();
827 if(com ==
"loopstate?")
829 snprintf(tmpstr, 256,
"%i\n", loopState);
833 if(com ==
"loopgain?")
835 snprintf(tmpstr, 256,
"%0.4f\n", loop_gain);
841 snprintf(tmpstr, 256,
"%0.4f\n",
tgtx);
847 snprintf(tmpstr, 256,
"%0.4f\n", tgty);
853 snprintf(tmpstr, 256,
"%0.4f\n", xcen);
859 snprintf(tmpstr, 256,
"%0.4f\n", ycen);
907 if(com.substr(0, 4)==
"gain")
911 std::string newgain = com.substr(5, com.length()-5);
912 set_loop_gain(strtod(newgain.c_str(),0));
924 if(com.substr(0, 6)==
"bgalgo")
928 std::string newalgo = com.substr(7, com.length()-7);
929 set_bgalgo(atoi(newalgo.c_str()));
941 if(com.substr(0, 5)==
"kfwhm")
945 std::string newkfwhm = com.substr(6, com.length()-6);
946 set_kfwhm(strtod(newkfwhm.c_str(), 0));
958 if(com.substr(0, 5)==
"ksize")
962 std::string newksize = com.substr(6, com.length()-6);
963 set_ksize(atoi(newksize.c_str()));
975 if(com.substr(0, 6)==
"useavg")
979 std::string newua = com.substr(7, com.length()-7);
980 setUseAvg(atoi(newua.c_str()));
992 if(com.substr(0, 5)==
"mmrej")
996 std::string mmrej = com.substr(6, com.length()-6);
997 setMinMaxReject(atoi(mmrej.c_str()));
1007 if(com.length() > 6)
1009 if(com.substr(0, 6)==
"avglen")
1013 std::string avglen = com.substr(7, com.length()-7);
1014 setAvgLen(atoi(avglen.c_str()));
1027 std::string coronguide::get_state_str()
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);
1049 cgsb->loopState = loopState;
1050 cgsb->loop_gain = loop_gain;
1064 checkDataFileOpen();
1067 dataof << tv.tv_sec <<
" " << tv.tv_usec <<
" " << loopState <<
" " << loop_gain <<
" " <<
tgtx <<
" " << tgty <<
" " << xcen <<
" " << ycen << std::endl;
1071 Logger::get()->log(Logger::LOG_LEV_ERROR,
"Error in coronguide data file. Data may not be logged correctly");
virtual std::string script_command(std::string com)
Overridden from VisAOApp_base::script_command, here just calls common_command.
sharedim< short > sim
The sharedim structure retreived from the stack.
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.
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.
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.
sharedim_stack< short > * sis
Manages a VisAO shared memory image stack.
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.
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.
fifo_list fl
The list of named-pipe fifos used for inter-process comms.
double pause_time
Time to pause during application main loop.
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.
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.
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.
virtual int Run()
The application main loop, to be re-implemented in derived classes.
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.
int shmem_key
shared memory key for
#define STATUS_ccd47
Shared memory key for the ccd47 controller status board.
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.
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.