19 #define SHUTTER_AUTO_FIFO_CH 2
27 ShutterControlDioclient::ShutterControlDioclient(
int argc,
char **argv)
throw (AOException) :
VisAOApp_standalone(argc, argv)
29 initialize_ShutterControl();
33 ShutterControlDioclient::ShutterControlDioclient(std::string name,
const std::string &conffile)
throw (AOException) : VisAOApp_standalone(name, conffile)
35 initialize_ShutterControl();
39 ShutterControlDioclient::~ShutterControlDioclient()
45 int ShutterControlDioclient::initialize_ShutterControl() throw (AOException)
52 std::string visao_root = getenv(
"VISAO_ROOT");
58 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for setting state (dio_ch_set) set to %i.",
dio_ch_set);
60 catch(Config_File_Exception)
62 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for setting state (dio_ch_set) not set in config file.");
68 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for getting state (dio_ch_get) set to %i.",
dio_ch_get);
70 catch(Config_File_Exception)
72 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for getting state (dio_ch_get) not set in config file.");
79 pathtmp = (std::string)(ConfigDictionary())[
"diofifo_path"];
81 catch(Config_File_Exception)
83 _logger->log(Logger::LOG_LEV_INFO,
"Setting diofifo_path to default");
87 _logger->log(Logger::LOG_LEV_INFO,
"Set diofifo_path: %s",
diofifo_path.c_str());
106 dead_time = (float32)(ConfigDictionary())[
"dead_time"];
107 _logger->log(Logger::LOG_LEV_INFO,
"Shutter dead time (dead_time) set to %f sec.", (
float)
dead_time);
109 catch(Config_File_Exception)
111 _logger->log(Logger::LOG_LEV_FATAL,
"Shutter dead time (dead_time) not set in config file.");
120 if(
ignore_hw_state) _logger->log(Logger::LOG_LEV_INFO,
"Shutter set to ignore hardware state (ignore_hw_state)");
121 else _logger->log(Logger::LOG_LEV_INFO,
"Shutter set to use hardware state (ignore_hw_state)");
123 catch(Config_File_Exception)
125 _logger->log(Logger::LOG_LEV_INFO,
"Shutter set to use hardware state (ignore_hw_state)");
134 _logger->log(Logger::LOG_LEV_INFO,
"Shutter powerOutlet set to %i.",
power_outlet);
136 catch(Config_File_Exception)
139 _logger->log(Logger::LOG_LEV_INFO,
"Shutter powerOutlet set to default %i.",
power_outlet);
147 catch(Config_File_Exception)
151 _logger->log(Logger::LOG_LEV_INFO,
"Set the shared memory key (shmem_key): %i",
shmem_key);
158 catch(Config_File_Exception)
162 _logger->log(Logger::LOG_LEV_INFO,
"Set number of images in the shared image buffer (num_timestamps): %i",
num_timestamps);
167 initSaveInterval = (
int)(ConfigDictionary())[
"initSaveInterval"];
169 catch(Config_File_Exception)
171 initSaveInterval = 200;
173 _logger->log(Logger::LOG_LEV_INFO,
"Set interval to save init info to disk (initSaveInterval): %i", initSaveInterval);
180 cycleNo = (uint64) (*init_vars)[
"cycleNo"];
182 catch(Config_File_Exception)
191 logger_pause = (double)(ConfigDictionary())[
"logger_pause"];
193 catch(Config_File_Exception)
197 _logger->log(Logger::LOG_LEV_INFO,
"Set logger pause time to (logger_pause): %f secs",
logger_pause);
203 catch(Config_File_Exception)
207 _logger->log(Logger::LOG_LEV_INFO,
"Set logger file length to (data_log_time_length): %f secs",
data_log_time_length);
212 save_path = (std::string)(ConfigDictionary())[
"save_path"];
214 catch(Config_File_Exception)
218 _logger->log(Logger::LOG_LEV_INFO,
"Set logger save path to (save_path): %s",
save_path.c_str());
221 std::string com =
"mkdir -p ";
222 com += getenv(
"VISAO_ROOT");
252 _logger->log(Logger::LOG_LEV_ERROR,
"Could not create status board.");
257 strncpy(bsb->appname, MyFullName().c_str(), 25);
267 int ShutterControlDioclient::getPowerStatus()
304 return start_ShutterControl();
307 int ShutterControlDioclient::start_ShutterControl()
311 ERROR_REPORT(
"Error attaching to shared memory for sharedim_stack.");
320 ERROR_REPORT(
"Error starting data logging thread.");
324 signal(SIGIO, SIG_IGN);
325 signal(RTSIGIO, SIG_IGN);
330 ERROR_REPORT(
"Error installing main thread catcher.");
339 ERROR_REPORT(
"Error starting signal catching thread.");
348 ERROR_REPORT(
"Error blicking SIGIO.");
352 LOG_INFO(
"starting up . . .");
356 global_shutter =
this;
358 fcntl(
fl.
fifo_ch[SHUTTER_AUTO_FIFO_CH].fd_in, F_SETOWN, getpid());
360 int rv = fcntl(
fl.
fifo_ch[SHUTTER_AUTO_FIFO_CH].fd_in, F_SETSIG, RTSIGPING);
363 std::cerr <<
"Error changing signal.\n";
364 perror(
"shuttercontrol");
367 struct sigaction act;
370 act.sa_sigaction = &shutter_auto_handler;
371 act.sa_flags = SA_SIGINFO;
377 if(sigaction(RTSIGPING, &act, 0) < 0)
380 logss <<
"Error setting signal handler for RTSIGPING. Errno says: " << strerror(errno) <<
".";
397 if(DO_OPENSHUT == 1) open_shutter();
398 if(DO_OPENSHUT == -1) close_shutter();
401 pthread_cond_broadcast(&profile->thcond);
411 int ShutterControlDioclient::shutdown_ShutterControl()
424 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in init_shutter_open");
428 if(resp[0] !=
'1')
return -1;
433 int ShutterControlDioclient::do_shutter_open(
void *adata)
437 struct timespec ts, ts1;
443 clock_gettime(CLOCK_REALTIME, &ts);
444 profile->logseqmsg((
char *) adata,
"dso1", &ts);
450 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in do_shutter_open");
453 clock_gettime(CLOCK_REALTIME, &ts1);
454 profile->logseqmsg((
char *) adata,
"dso2", &ts);
458 clock_gettime(CLOCK_REALTIME, &ts);
463 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in do_shutter_open");
469 sim->frameNo = ++cycleNo;
470 sim->frame_time.tv_sec = ts.tv_sec;
471 sim->frame_time.tv_usec = ts.tv_nsec/1000;
477 if(resp[0] !=
'1')
return -1;
482 int ShutterControlDioclient::do_shutter_close(
void *adata)
489 clock_gettime(CLOCK_REALTIME, &ts);
490 profile->logseqmsg((
char *) adata,
"dsc1", &ts);
496 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in do_shutter_close");
499 clock_gettime(CLOCK_REALTIME, &ts);
500 profile->logseqmsg((
char *) adata,
"dsc2", &ts1);
504 clock_gettime(CLOCK_REALTIME, &ts);
509 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in do_shutter_close");
515 sim->frameNo = ++cycleNo;
516 sim->frame_time.tv_sec = ts.tv_sec;
517 sim->frame_time.tv_usec = ts.tv_nsec/1000;
523 if(resp[0] !=
'0')
return -1;
532 of.open((std::string(getenv(
"VISAO_ROOT")) +
"/" + init_file).c_str());
534 of <<
"cycleNo uint64 " << cycleNo <<
"\n";
547 gettimeofday(&tv, 0);
550 fname = getenv(
"VISAO_ROOT");
562 struct sched_param schedpar;
563 schedpar.sched_priority = 0;
566 pthread_attr_init(&attr);
568 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
569 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
570 pthread_attr_setschedparam(&attr, &schedpar);
581 static int last_image_abs = -1, last_image = 0;
583 bool fileOpen =
false;
584 double fileOpenTime = 0;
593 ERROR_REPORT(
"Error blocking SIGIO in data logger thread.");
597 std::cout <<
"Data logger started.\n";
619 while(last_image_abs <
sis.get_last_image_abs())
628 of.open(fname.c_str());
631 ERROR_REPORT(
"Error opening shutter data file. Shutter data may not be logged correctly");
638 of <<
"#Cycle # of first entry: " << currData.frameNo <<
"\n";
642 _sst = currData.imdata[0];
643 if(_sst < 0) sst =
"-1";
644 else if(_sst > 0) sst =
"1";
647 of << currData.frame_time.tv_sec <<
" " << currData.frame_time.tv_usec <<
" " << sst <<
"\n";
651 ERROR_REPORT(
"Error in shutter data file. Shutter data may not be logged correctly");
689 if(fileOpen) of.close();
690 std::cout <<
"Data logging stopped." << std::endl;
695 ERROR_REPORT(
"Exception thrown in data logging thread. Shutter data no longer being logged");
700 int ShutterControlDioclient::get_hw_state()
709 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in get_hw_state");
714 hws = (resp[0] ==
'1');
745 std::string ShutterControlDioclient::get_state_str()
774 snprintf(schr, 50,
"%c %i %i %i %i", sstr[0], get_state(), get_sw_state(), get_hw_state(), getPowerStatus());
780 std::string ShutterControlDioclient::remote_command(std::string com,
char *seqmsg __attribute__((unused)))
784 rstr = common_command(com, CMODE_REMOTE);
786 if(rstr ==
"")
return "UNKOWN COMMAND: " + com +
"\n";
792 std::string ShutterControlDioclient::local_command(std::string com,
char *seqmsg __attribute__((unused)))
798 rstr = common_command(com, CMODE_LOCAL);
800 if(rstr ==
"")
return "UNKOWN COMMAND: " + com +
"\n";
805 std::string ShutterControlDioclient::script_command(std::string com,
char *seqmsg __attribute__((unused)))
809 rstr = common_command(com, CMODE_SCRIPT);
811 if(rstr ==
"")
return "UNKOWN COMMAND: " + com +
"\n";
823 close_shutter(seqmsg);
844 open_shutter(seqmsg);
864 rstr = common_command(com, CMODE_AUTO);
866 if(rstr !=
"")
return rstr;
872 std::string ShutterControlDioclient::common_command(std::string com,
int calling_cmode)
877 int pos = com.find_first_of(
"\n\r", 0);
878 if(pos > -1) com.erase(pos, com.length()-pos);
880 if(com ==
"open" || com ==
"1")
884 if(!getPowerStatus())
893 snprintf(rvstr, 5,
"%i\n", rv);
902 if(com ==
"close" || com ==
"-1")
906 if(!getPowerStatus())
915 snprintf(rvstr, 5,
"%i\n", rv);
927 snprintf(rvstr, 50,
"%s\n", get_state_str().c_str());
936 static int lastInitSave = 0;
953 ssb->sw_state = get_sw_state();
954 ssb->hw_state = get_hw_state();
959 ssb->power_state = getPowerStatus();
965 if(lastInitSave > initSaveInterval)
983 void shutter_auto_handler(
int signum, siginfo_t *siginf,
void *ucont)
990 if(siginf->si_code == POLL_IN)
996 resp = global_shutter->
auto_command(fc->server_response, fc->seqmsg);
int launchDataLogger()
Launches the data logger thread.
int dio_ch_set
The dioserver channel used for setting shutter state (open or shut)
double data_log_time_length
Time duration of a shutter log file, seconds.
double dead_time
Time to wait between commanded changes in state.
std::string diofifo_path
The base path of the dioserver fifos.
int write_fifo_channel(fifo_channel *fc, const char *com, int comlen)
Write data to the output channel.
int enable_next_image()
Increments last_image.
int power_outlet
Configuration variable, setting which power outlet to monitor.
fifo_list * global_fifo_list
The global fifo_list, for signal handling.
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.
int num_timestamps
The number of shared "images" available in the ring buffer.
pthread_mutex_t signal_mutex
Mutex for the condition signaling.
int read_fifo_channel(fifo_channel *fc)
Read data from the input fifo channel.
int shmem_key
The key for the ring buffer shared memory.
The standalone VisAO application, does not interface with the AO Supervisor.
int dio_ch_get
The dioserver channel used for getting shutter state (open or shut)
std::ostringstream logss
Conveninence string stream for building log messages.
void * statusboard_shmemptr
The pointer to the shared memory block for the statusboard.
virtual void error_report(int LogLevel, std::string emsg)
Report an error. Also calls log_msg.
virtual int update_statusboard()
Update the status board.
sharedim_stack_header * header
Convenient pointer to the stack header, has same value as shmemptr.
std::string com_path
The control fifo path base name.
virtual int update_statusboard()
Update the status board.
virtual int setup_baseApp(bool usethreads=false)
Install fifo channels.
int init_shutter_open()
Send shutter open signal for initialization, but do not log or profile this.
fifo_channel * fifo_ch
An array of fifo_channels.
int setup_fifo_list(int nfifos)
Allocate the fifo_list.
int * powerOutlet
The power strip outlet controlling shutter power.
pthread_cond_t signal_cond
Condition for telling main thread that something changed.
sharedim< IMDATA_TYPE > * set_next_image(int nx, int ny)
Sets the next image, and returns a pointer to it, but does not increment last_image.
sharedim_stack< char > sis
The shared memory ring buffer for timestamp storage.
int hw_state
1 is open, -1 is shut, 0 is unknown
int sw_state
1 is open, -1 is shut, 0 is unknown
virtual int block_signal(int signum)
Sets the signal mask to block signal signum.
pthread_t signal_thread
Identifier for the separate signal handling thread.
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.
pthread_t logger_th
Thread which periodically logs data in the sharedim_stack data buffer.
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.
sharedim< char > * sim
Pointer to a shared memory "image".
fifo_list fl
The list of named-pipe fifos used for inter-process comms.
virtual int Run()
The application main loop, to be re-implemented in derived classes.
std::string com_path_auto
The path for the auto control fifos.
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...
std::string auto_command(std::string com, char *seqmsg)
Processing for auto commands - to be overriden.
std::string getDataFileName()
Generate a unique data file name, using the standard VisAO timestamp.
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
void * __launch_data_logger(void *Sctrl)
Launches the data logger.
ShutterControlDioclient * global_shutter
For the auto command handler, which live in the main thread.
#define MAX_FNAME_SZ
The maximum allowed filename length.
std::string save_path
Path, relative to VISAO_ROOT, where to save data.
double ts_to_curr_time(struct timespec *tsp)
Convert a timespec structure to double seconds.
static int control_mode
The current control mode.
int get_visao_filename(char *buffer, struct timeval *tv)
Writes the standard visao unique filename for a timeval to the buffer.
virtual int install_sig_mainthread_catcher()
Install the SIG_MAINTHREAD signal catcher.
int create_shm(key_t mkey, size_t sz)
For the writer process, creates then attaches the shared memory.
void dataLogger()
Log data at intervals.
The namespace of VisAO software.
Declarations for the shutter controller as a client of the dioserver.
virtual std::string post_auto_command(std::string com, char *seqmsg=0)
Processing for auto commands - not normally overriden.
double logger_pause
Pause time of the logger thread, seconds.
int saveInit()
Save the initialization data to disk.
#define RWBUFF_SZ
The size of the i/o buffer.
int get_dio_fnames(char *fout, char *fin, char *fbase, int ch)
Fills in the properly formatted dioserver channel fifo names.
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.
bool ignore_hw_state
For when hw_state is unavailable.
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.
int get_max_n_images()
Returns the value of max_n_images currently in the header.