44 aoapp_name = MyFullName();
46 int spos = aoapp_name.find(
"Local", 0);
47 int epos = aoapp_name.find(
".L", 0);
49 if(spos < 0 || epos < 0)
51 std::cerr <<
"Can't create aoapp_name.\n";
52 Logger::get()->log( Logger::LOG_LEV_ERROR,
"Can't create aoapp_name.");
53 throw AOException(
"Fatal: cannot create name of filterwheel AOApp.");
56 aoapp_name.erase(spos, epos-spos);
58 std::cerr <<
"aoapp_name set to: " << aoapp_name <<
"\n";
64 pathtmp = (std::string)((ConfigDictionary()))[
"com_path"];
66 catch(Config_File_Exception)
70 com_path = std::string(getenv(
"VISAO_ROOT")) +
"/" + pathtmp +
"/" + MyName();
79 catch(Config_File_Exception)
89 _logger->log(Logger::LOG_LEV_ERROR,
"Could not create status board.");
94 strncpy(bsb->appname, MyFullName().c_str(), 25);
99 strncpy(fwsb->filter_name,
"unknown", 50);
106 signal(SIGIO, SIG_IGN);
114 Config_File* adopt_cfg;
115 int dotpos = aoapp_name.find(
".L", 0);
119 throw AOException(
"Fatal: cannot create name of filterwheel config file.");
121 std::cerr << aoapp_name.substr(0, dotpos) <<
"\n";
124 adopt_cfg =
new Config_File(Utils::getConffile(aoapp_name.substr(0, dotpos)));
126 catch (Config_File_Exception &e)
128 Logger::get()->log( Logger::LOG_LEV_FATAL,
"%s", e.what().c_str());
129 throw AOException(
"Fatal: cannot find adopt filter wheel configuration.");
134 _abortPos = (double)(*adopt_cfg)[
"AbortPosition"];
135 std::cout <<
"_abortPos " << _abortPos <<
"\n";
136 _homingPos = (double)(*adopt_cfg)[
"HomingPosition"];
137 std::cout <<
"_homingPos " << _homingPos <<
"\n";
138 _startingPos = (double)(*adopt_cfg)[
"StartingPos"];
139 std::cout <<
"_startingPos " << _startingPos <<
"\n";
142 catch(Config_File_Exception &e)
144 Logger::get()->log( Logger::LOG_LEV_FATAL,
"%s", e.what().c_str());
145 throw AOException(
"Fatal: cannot find required config values.");
153 numCustomPos = (*adopt_cfg)[
"customPositionNum"];
155 catch (Config_File_Exception &e)
157 _logger->log( Logger::LOG_LEV_INFO,
"No custom positions defined in cfg file.");
162 for (
int i=0; i<numCustomPos; i++)
164 ostringstream namekey, poskey;
165 namekey <<
"pos" << i <<
"_name";
166 poskey <<
"pos" << i <<
"_pos";
171 name = (std::string) (*adopt_cfg)[namekey.str()];
172 pos = (float)(*adopt_cfg)[poskey.str()];
173 _customPos[name] = pos;
175 catch (Config_File_Exception &e)
177 _logger->log( Logger::LOG_LEV_ERROR,
"Custom position %d not found in cfg file.", i);
184 int numCustomTypes=0;
187 numCustomTypes = (*adopt_cfg)[
"customPositionNum"];
189 catch (Config_File_Exception &e)
191 Logger::get()->log( Logger::LOG_LEV_INFO,
"No custom positions defined in cfg file.");
194 if (numCustomTypes >0)
196 std::cout <<
"Loading " << numCustomTypes <<
" custom types.\n";
198 for (
int i=0; i<numCustomTypes; i++)
200 ostringstream typekey, poskey;
201 typekey <<
"pos" << i <<
"_type";
202 poskey <<
"pos" << i <<
"_pos";
207 type = (
int) (*adopt_cfg)[typekey.str()];
208 pos = (float) (*adopt_cfg)[poskey.str()];
211 catch (Config_File_Exception &e)
213 Logger::get()->log( Logger::LOG_LEV_ERROR,
"Custom type for %d not found in cfg file.", i);
227 var_status = RTDBvar ( aoapp_name,
"STATUS", NO_DIR, INT_VARIABLE, 1, 1);
228 var_cmode_cur = RTDBvar( aoapp_name,
"ConMode", CUR_VAR, INT_VARIABLE, 1,1);
230 var_cmode_req = RTDBvar( aoapp_name,
"ConMode", REQ_VAR, INT_VARIABLE, 1,1);
231 var_pos_cur = RTDBvar( aoapp_name,
"POS", CUR_VAR, REAL_VARIABLE, 1,1);
232 var_pos_req = RTDBvar( aoapp_name,
"POS", REQ_VAR, REAL_VARIABLE, 1);
233 var_pos_local_req = RTDBvar( aoapp_name,
"POS_LOCAL", REQ_VAR, REAL_VARIABLE, 1,1);
261 catch (AOVarException &e)
263 Logger::get()->log(Logger::LOG_LEV_FATAL,
"%s:%s: %s", __FILE__, __LINE__, e.what().c_str());
264 throw AOException(
"Error creating RTDB variables");
281 pos = fmod(pos, _customPos.size());
282 if(pos < 0) pos += _customPos.size();
285 while(
cpos_it != _customPos.end())
287 name = (*cpos_it).first;
288 np = (*cpos_it).second;
289 ll = fmod(np-.25, _customPos.size());
290 if(ll < 0) ll += _customPos.size();
291 ul = fmod(np+.25, _customPos.size());
292 if(ul < 0) ul += _customPos.size();
293 if((pos > ll && pos < ul) || (ul-ll < 0 && (pos < ul || pos > ll)))
302 return "intermediate";
317 type = (*ctype_it).first;
318 np = (*ctype_it).second;
323 if((pos > ll && pos < ul) || (ul-ll < 0 && (pos < ul || pos > ll)))
343 _logger->log( Logger::LOG_LEV_FATAL,
"Error starting signal thread.");
351 sigaddset(&set, SIGIO);
352 sigaddset(&set, RTSIGIO);
354 if(pthread_sigmask(SIG_BLOCK, &set, 0) != 0)
356 _logger->log( Logger::LOG_LEV_FATAL,
"Error blocking SIGIO in main thread.");
367 std::cerr <<
"Main thread: exception caught." << std::endl;
370 std::cerr <<
"Main thread exiting." << std::endl;
397 void FilterWheelLocal::set_control_mode(
int cmode)
402 void FilterWheelLocal::set_status(
int stat)
414 logss <<
"fifo_list connected.";
419 error_report(Logger::LOG_LEV_FATAL,
"Error connecting the fifo list.");
443 catch(AOVarException e)
447 std::cerr <<
"Fifo thread: exception caught. " << __LINE__ <<
" " << e.what() << std::endl;
451 std::cerr <<
"Fifo thread: exception caught. " << __LINE__ << std::endl;
454 std::cerr <<
"Fifo thread exiting." << std::endl;
457 void * __fwstart_signal_catcher(
void * ptr)
465 struct sched_param schedpar;
468 pthread_attr_init(&attr);
474 schedpar.sched_priority = 0;
476 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
477 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
478 pthread_attr_setschedparam(&attr, &schedpar);
483 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
487 if(pthread_create(&
signal_thread, &attr, &__fwstart_signal_catcher, (
void *)
this) == 0)
return 0;
499 std::cout <<
"Requesting control\n";
503 if(
override) cmode *= 10;
507 catch(AOVarException e)
509 std::cerr <<
"request_control: exception caught " << __LINE__ <<
" " << e.what() << std::endl;
522 vmc->set_control_mode(msgb->Value.Lv[0]);
539 int FilterWheelLocal::PosReqChanged(
void *pt, Variable *var)
552 int FilterWheelLocal::StatusChanged(
void *pt, Variable *var)
559 vmc->set_status(var->Value.Lv[0]);
567 std::cout <<
"Changing Pos\n";
591 catch(AOVarException e)
593 std::cerr <<
"ChangePos: exception caught " <<
" " << __LINE__ <<
" " << e.what() << std::endl;
609 _logger->log(Logger::LOG_LEV_TRACE,
"Received remote command: %s.", com.c_str());
613 if(rstr ==
"") rstr =
"UNKOWN COMMAND: " + com +
"\n";
615 _logger->log(Logger::LOG_LEV_TRACE,
"Response to remote command: %s.", rstr.c_str());
624 _logger->log(Logger::LOG_LEV_TRACE,
"Received local command: %s.", com.c_str());
628 if(rstr ==
"") rstr =
"UNKOWN COMMAND: " + com +
"\n";
630 _logger->log(Logger::LOG_LEV_TRACE,
"Response to local command: %s.", rstr.c_str());
639 _logger->log(Logger::LOG_LEV_TRACE,
"Received script command: %s.", com.c_str());
643 if(rstr ==
"") rstr =
"UNKOWN COMMAND: " + com +
"\n";
645 _logger->log(Logger::LOG_LEV_TRACE,
"Response to script command: %s.", rstr.c_str());
654 int ismov = 0, ishom = 0;
678 snprintf(statestr, 100,
"%c %2i %i %i %09.4f %s\n", str[0], status, ismov, ishom, cur_pos, filt.c_str());
688 int pos = com.find_first_of(
"\n\r", 0);
689 if(pos > -1) com.erase(pos, com.length()-pos);
699 snprintf(rvstr, 5,
"%i\n", rv);
707 snprintf(rvstr, 5,
"%i\n", rv);
717 snprintf(rvstr, 50,
"%0.3f\n", cur_pos );
724 if(cur_state == STATE_OPERATING || cur_state == STATE_HOMING)
730 snprintf(rvstr, 50,
"%i\n", ismov);
737 if(cur_state == STATE_HOMING)
742 snprintf(rvstr, 50,
"%i\n", ishom);
751 if(com.substr(0,3) ==
"pos")
754 if(control_mode == calling_ctype)
756 double pos = strtod(com.substr(3, com.size()-3).c_str(), 0);
757 std::cout <<
"Here we go\n";
759 snprintf(rvstr, 5,
"%i\n", rv);
768 if(com.substr(0,6) ==
"filter")
772 int idx = com.find_first_not_of(
' ', 6);
773 std::string filt = com.substr(idx, com.size()-idx);
774 double pos = _customPos[filt];
777 snprintf(rvstr, 5,
"%i\n", rv);
798 int status = cur_state;
800 fwsb->state = status;
801 if(status == STATE_READY || status == STATE_OPERATING || status == STATE_HOMING)
809 if(cur_state == STATE_HOMING)
811 std::cout <<
"STATE_HOMING\n";
814 fwsb->req_pos = _startingPos;
816 else if(cur_state == STATE_OPERATING)
818 std::cout <<
"STATE_OPERATING\n";
819 fwsb->req_pos = req_pos;
823 std::cout <<
"NOT MOVING\n";
824 fwsb->req_pos = cur_pos;
836 strncpy(fwsb->filter_name,
GetPosName(fwsb->pos).c_str(), 50);
837 fwsb->type =
GetType(fwsb->pos);
838 fwsb->req_type =
GetType(fwsb->req_pos);
RTDBvar var_status
The current status of the controller, STATE_CONNECTED, STATE_OPERATING,STATE_HOMING, etc.
A class to provide Filter Wheel functionality for the VisAO Camera.
virtual void updatePos(double pos)
Update position variables in RTDB.
virtual std::string local_command(std::string com)
VisAO local command fifo handler.
RTDBvar var_pos_cur
The current position.
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.
RTDBvar var_cmode_cur
The current control mode in the RTDB.
void readFilterConfig()
Read the corresponding filter wheel controller configuration file.
void SetupVars()
Virtual function to setup variables in RTDB.
std::string common_command(std::string com, int)
Where the command logic actually happens, since it is common.
int GetType(double pos)
Get the position type from the wheel position.
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.
std::string GetPosName(double pos)
Get the position name from wheel position.
Declarations for the FilterWheelLocal class, which interfaces with the VisAOSimpleMotorCtrl class via...
double getAbortPos()
Exposes the abort Position (_abortPos) for use in PosReqChanged (which is static) ...
std::string com_path
The control fifo path base name.
virtual int start_signal_catcher(bool inherit_sched=true)
Starts the signal catching loop.
virtual int update_statusboard()
Update the status board.
multimap< int, float >::iterator ctype_it
An iterator for accessing the custom pos list.
virtual int setup_baseApp(bool usethreads=false)
Install fifo channels.
int check_fifo_list_RTpending()
Check for pending reads for the fifo list while using the RT signals.
multimap< int, float > _customTypes
Custom filter types list.
int setup_fifo_list(int nfifos)
Allocate the fifo_list.
pthread_t signal_thread
The thread where fifo async signals are caught.
FilterWheelLocal(std::string name, const std::string &conffile)
Standard adopt style config file constructor.
static int PosCurChanged(void *pt, Variable *msgb)
RTDB handler for a position change by the AO Supervisor.
key_t statusboard_shmemkey
The key used to lookup the shared memory.
RTDBvar var_pos_local_req
Position requester for local control.
int TimeToDie
Global set by SIGTERM.
std::string control_mode_response()
Convenience function to return the control type response string, e.g. "A\n".
std::string get_state_str()
Produce the state string for response to state?
fifo_list fl
The list of named-pipe fifos used for inter-process comms.
virtual std::string remote_command(std::string com)
VisAO remote command fifo handler.
void setupVisAOApp()
Basic setup of the class, called by both constructors.
double pause_time
Time to pause during application main loop.
virtual int request_control(int cmode)
Calls request_control(cmode, 0).
int set_app_name(std::string an)
Set the application name.
RTDBvar var_pos_script_req
Position requester for script control.
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
RTDBvar var_cmode_req
The requested control mode in the RTDB.
void signal_catcher()
Signal loop, normally won't need to be overridden.
virtual std::string script_command(std::string com)
VisAO script command fifo handler.
int connect_fifo_list()
Connect the fifo_list with exclusive locking.
static int control_mode
The current control mode.
int setup_RTsigio()
Setup SIGIO signal handling using realtime signals.
The namespace of VisAO software.
RTDBvar var_pos_req
The requested position.
int ChangePos(double pos)
An interface to SimpleMotorCtrl::PosReqChanged for the fifo command processors.
virtual void log_msg(int LogLevel, std::string lmsg)
Log a message.
virtual void updateReq(double pos)
Update req position variables in RTDB.
virtual int update_statusboard()
Update the status board.
static int CModeCurChanged(void *pt, Variable *msgb)
RTDB handler for a control mode change request from the AO Supervisor.
map< std::string, float >::iterator cpos_it
An iterator for accessing the custom pos list.