40 std::string visao_root = getenv(
"VISAO_ROOT");
49 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for setting enable (dioch_enable) set to %i.",
dioch_enable);
51 catch(Config_File_Exception)
53 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for setting enable (dioch_enable) not set in config file.");
59 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for setting direction (dioch_dir) set to %i.",
dioch_dir);
61 catch(Config_File_Exception)
63 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for setting direction (dioch_dir) not set in config file.");
69 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for stepping (dioch_step) set to %i.",
dioch_step);
71 catch(Config_File_Exception)
73 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for stepping (dioch_step) not set in config file.");
80 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for controller power (dioch_pwr) set to %i.",
dioch_pwr);
82 catch(Config_File_Exception)
84 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for controller power (dioch_pwr) not set in config file.");
91 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for positive limit switch (dioch_limpos) set to %i.",
dioch_limpos);
93 catch(Config_File_Exception)
95 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for positive limit switch (dioch_limpos) not set in config file.");
102 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for home limit switch (dioch_limhome) set to %i.",
dioch_limhome);
104 catch(Config_File_Exception)
106 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for home limit switch (dioch_limhome) not set in config file.");
113 _logger->log(Logger::LOG_LEV_INFO,
"dioserver channel for negative limit switch (dioch_limneg) set to %i.",
dioch_limneg);
115 catch(Config_File_Exception)
117 _logger->log(Logger::LOG_LEV_FATAL,
"dioserver channel for negative limit switch (dioch_limneg) not set in config file.");
126 pathtmp = (std::string)(ConfigDictionary())[
"diofifo_path"];
128 catch(Config_File_Exception)
133 _logger->log(Logger::LOG_LEV_INFO,
"Set diofifo_path: %s",
diofifo_path.c_str());
159 signal(SIGIO, SIG_IGN);
163 step_ratio = (double)(ConfigDictionary())[
"step_ratio"];
164 _logger->log(Logger::LOG_LEV_INFO,
"step ratio (step_ratio) set to %0.4f microns per step.",
step_ratio);
166 catch(Config_File_Exception)
168 _logger->log(Logger::LOG_LEV_FATAL,
"step ratio (step_ratio) not set in config file.");
174 min_step_time = (double)(ConfigDictionary())[
"min_step_time"];
176 _logger->log(Logger::LOG_LEV_INFO,
"minimum step time (min_step_time) set to %0.3g seconds.",
min_step_time);
178 catch(Config_File_Exception)
180 _logger->log(Logger::LOG_LEV_FATAL,
"minimum step time (min_step_time) not set in config file.");
185 hw_dir = (
int)(ConfigDictionary())[
"hw_dir"];
188 _logger->log(Logger::LOG_LEV_INFO,
"hardware direction (hw_dir) set to %i.",
hw_dir);
190 catch(Config_File_Exception)
193 _logger->log(Logger::LOG_LEV_INFO,
"hardware direction (hw_dir) set to default %i.",
hw_dir);
198 sw_limits_only = (ConfigDictionary())[
"sw_limits_only"];
200 catch(Config_File_Exception)
204 _logger->log(Logger::LOG_LEV_INFO,
"software limits only (sw_limits_only) set to %i.", sw_limits_only);
212 sw_neg_limit = (ConfigDictionary())[
"sw_neg_limit"];
213 _logger->log(Logger::LOG_LEV_INFO,
"software negative limit (sw_neg_limit) set to %f.", sw_neg_limit);
215 catch(Config_File_Exception)
217 _logger->log(Logger::LOG_LEV_FATAL,
"Missing software negative limit (sw_neg_limit) in config file .");
223 sw_pos_limit = (ConfigDictionary())[
"sw_pos_limit"];
224 _logger->log(Logger::LOG_LEV_INFO,
"software positive limit (sw_pos_limit) set to %f.", sw_pos_limit);
226 catch(Config_File_Exception)
228 _logger->log(Logger::LOG_LEV_FATAL,
"Missing software positive limit (sw_pos_limit) in config file .");
238 _logger->log(Logger::LOG_LEV_ERROR,
"Could not create status board.");
243 strncpy(bsb->appname, MyFullName().c_str(), 25);
257 pthread_mutex_init(&dio_mutex, 0);
273 cur_pos = (*init_vars)[
"cur_pos"];
275 catch(Config_File_Exception)
287 home_pos = (double)(ConfigDictionary())[
"home_pos"];
289 _logger->log(Logger::LOG_LEV_INFO,
"home position (home_pos) set to %f.",
home_pos);
291 catch(Config_File_Exception)
294 _logger->log(Logger::LOG_LEV_INFO,
"home position (home_pos) set to %f.",
home_pos);
300 FocusMotorCtrl::~FocusMotorCtrl()
314 pthread_mutex_lock(&dio_mutex);
319 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error getting front limit ");
320 pthread_mutex_unlock(&dio_mutex);
330 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error getting home switch");
331 pthread_mutex_unlock(&dio_mutex);
341 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in getting back limit");
342 pthread_mutex_unlock(&dio_mutex);
346 pthread_mutex_unlock(&dio_mutex);
379 if(homing && homing !=4 )
392 if(homing && homing!=5)
411 if(!homing)
return 0;
460 of.open((std::string(getenv(
"VISAO_ROOT")) +
"/" + init_file).c_str());
463 of <<
"cur_pos float32 " <<
cur_pos <<
"\n";
471 remove((std::string(getenv(
"VISAO_ROOT")) +
"/" + init_file).c_str());
486 pthread_mutex_lock(&dio_mutex);
489 _logger->log(Logger::LOG_LEV_ERROR,
"dioserver response error in get_power_state");
491 pthread_mutex_unlock(&dio_mutex);
494 pthread_mutex_unlock(&dio_mutex);
501 power_state = (resp[0] ==
'1');
518 pthread_mutex_lock(&dio_mutex);
524 logss <<
"Error writing to fifo channel " <<
FIFOCH_ENABLE <<
". Attempting to set enable.";
526 std::cerr <<
logss.str() <<
" (logged) \n";
534 logss <<
"Error writing to fifo channel " <<
FIFOCH_ENABLE <<
". Attempting to set disable.";
536 std::cerr <<
logss.str() <<
" (logged) \n";
539 pthread_mutex_unlock(&dio_mutex);
557 pthread_mutex_lock(&dio_mutex);
565 logss <<
"Error writing to fifo channel " <<
FIFOCH_DIR <<
". Attempting to set direction high.";
567 std::cerr <<
logss.str() <<
" (logged) \n";
575 logss <<
"Error writing to fifo channel " <<
FIFOCH_DIR <<
". Attempting to set direction low.";
577 std::cerr <<
logss.str() <<
" (logged) \n";
588 logss <<
"Error writing to fifo channel " <<
FIFOCH_DIR <<
". Attempting to set direction low.";
590 std::cerr <<
logss.str() <<
" (logged) \n";
598 logss <<
"Error writing to fifo channel " <<
FIFOCH_DIR <<
". Attempting to set direction high.";
600 std::cerr <<
logss.str() <<
" (logged) \n";
604 pthread_mutex_unlock(&dio_mutex);
628 std::cout <<
"In Step\nnsteps = " << nsteps <<
"\nhoming = " << homing <<
"\n";
629 std::cout <<
"stop_moving = " <<
stop_moving <<
"\n" <<
"cur_dir = " <<
cur_dir <<
"\n\n";
632 if(!homing) _logger->log(Logger::LOG_LEV_TRACE,
"Starting move of %i steps.", nsteps);
633 else _logger->log(Logger::LOG_LEV_TRACE,
"Starting homing of type %i.", homing);
650 logss <<
"Error checking limit switch status. Stopping move.";
659 logss <<
"Error checking power status. Stopping move.";
666 std::cout <<
"Beginning loop\nnsteps = " << nsteps <<
"\nhoming = " << homing <<
"\n";
667 std::cout <<
"stop_moving = " <<
stop_moving <<
"\n" <<
"cur_dir = " << cur_dir <<
"\n\n";
672 gettimeofday(&currtime,0);
673 stepdt = ((double)currtime.tv_sec+((
double)currtime.tv_usec)/1e6) - ((double)
last_step_time.tv_sec+((
double)
last_step_time.tv_usec)/1e6);
677 gettimeofday(&currtime,0);
678 stepdt = ((double)currtime.tv_sec+((
double)currtime.tv_usec)/1e6) - ((double)
last_step_time.tv_sec+((
double)
last_step_time.tv_usec)/1e6);
682 pthread_mutex_lock(&dio_mutex);
686 logss <<
"Error writing to fifo channel " <<
FIFOCH_STEP <<
". Attempting to set step high.";
690 pthread_mutex_unlock(&dio_mutex);
695 logss <<
"Step failed on setting step to high. Response from dioserver: " << resp <<
" Position not updated. Stopping move.";
700 if(i > 0) avstepdt += stepdt;
704 pthread_mutex_lock(&dio_mutex);
708 logss <<
"Error writing to fifo channel " <<
FIFOCH_STEP <<
". Attempting to set step low.";
712 pthread_mutex_unlock(&dio_mutex);
718 logss <<
"Step failed (bad return from dioserver) on setting step to low. Stopping move.";
727 logss <<
"Error checking limit switch status. Stopping move.";
736 logss <<
"Error checking power status. Stopping move.";
754 logss <<
"Completed move. " << i <<
" steps, ave time: " << avstepdt/itmp <<
" secs/step";
760 pthread_mutex_lock(&dio_mutex);
764 logss <<
"Error writing to fifo channel " <<
FIFOCH_STEP <<
". Attempting to set direction low during move cleanup.";
768 pthread_mutex_unlock(&dio_mutex);
778 std::cout <<
"Leaving by the back\nnsteps = " << nsteps <<
"\nhoming = " << homing <<
"\n";
779 std::cout <<
"stop_moving = " <<
stop_moving <<
"\n" <<
"cur_dir = " << cur_dir <<
"\n\n";
781 _logger->log(Logger::LOG_LEV_TRACE,
"Completed %i steps.", i);
877 if(!aosb || !wsb || !fw2sb || !fw3sb)
880 logss <<
"Not connected to status boards for preset.";
886 if( get_focuscal(&fcal) < 0)
889 logss <<
"Could not get focus cal.";
897 if(::
get_preset(
"focus", aosb->filter1_reqpos, (
int) wsb->cur_pos, fw2sb->req_pos, fw3sb->req_pos, &preset, presetf) < 0)
900 logss <<
"Could not get preset: " << presetf <<
".";
912 std::vector<double> preset(1);
920 if(fabs(fcal+preset[0] -
cur_pos) < 2.)
return 1;
929 std::vector<double> preset(1);
938 logss <<
"Found focus cal: " << fcal;
939 LOG_INFO(
logss.str().c_str());
943 logss <<
"Found preset: " << presetf <<
" -> " << preset[0] <<
".";
944 LOG_INFO(
logss.str().c_str());
947 logss <<
"Presetting to: " << fcal + preset[0];
948 LOG_INFO(
logss.str().c_str());
960 std::cout.precision(20);
964 ERROR_REPORT(
"Error installing main thread catcher.");
971 ERROR_REPORT(
"Error starting signal catching thread.");
978 ERROR_REPORT(
"Error blocking SIGIO in main thread.");
982 LOG_INFO(
"starting up . . .");
986 pthread_mutex_lock(&dio_mutex);
990 logss <<
"Error writing to fifo channel " <<
FIFOCH_STEP <<
". Attempting to set step to low.";
994 pthread_mutex_unlock(&dio_mutex);
1036 _logger->log(Logger::LOG_LEV_TRACE,
"Received remote command: %s.", com.c_str());
1038 _logger->log(Logger::LOG_LEV_TRACE,
"Response to remote command: %s.", resp.c_str());
1045 _logger->log(Logger::LOG_LEV_TRACE,
"Received local command: %s.", com.c_str());
1047 _logger->log(Logger::LOG_LEV_TRACE,
"Response to local command: %s.", resp.c_str());
1054 _logger->log(Logger::LOG_LEV_TRACE,
"Received script command: %s.", com.c_str());
1056 _logger->log(Logger::LOG_LEV_TRACE,
"Response to script command: %s.", resp.c_str());
1072 if(com ==
"ismoving?")
1083 if(com ==
"enable?")
1091 if(power_state)
return "1\n";
1117 if(com.substr(0,3) ==
"pos")
1123 npos = strtod(com.substr(3,com.length()-3).c_str(),0);
1131 if(com.substr(0,4) ==
"dpos")
1137 npos = strtod(com.substr(4,com.length()-4).c_str(),0);
1154 if(com ==
"homeneg")
1166 if(com ==
"homepos")
1190 if(com ==
"disable")
1202 if(com ==
"disable_pos_limit")
1220 return (std::string(
"UNKOWN COMMAND: ") + com +
"\n");
1228 snprintf(statestr, 100,
"%c %012.4f %i %i %i %i %i %i %i %012.4f %i\n", str[0],
cur_pos,
cur_enabled, power_state,
is_moving, homing,
neg_limit,
home_switch,
pos_limit,
next_pos-
cur_pos,
pos_limit_disabled);
1244 fsb->homing = homing;
1248 fsb->power_state = power_state;
1256 checkDataFileOpen();
1258 dataof << tv.tv_sec <<
" " << tv.tv_usec <<
" " <<
cur_pos << std::endl;
1262 Logger::get()->log(Logger::LOG_LEV_ERROR,
"Error in Focus motor data file. Focus data may not be logged correctly");
#define MOVE_OFFSET
Pending offset move.
void log_msg(int LogLevel, std::string lmsg)
Report an error. Also calls log_msg. Overloaded from VisAOApp_base.
#define FIFOCH_NEGL
The fifo_list fifo channel for the front limit.
double min_step_time
Minimum time between steps, in seconds. Can't be < 1e-6.
int check_limits()
Gets the limit switch status from dioserver, and performs homing logic checks.
double get_curr_time(void)
Gets the current CLOCK_REALTIME time, returns it in seconds to double precision.
int set_cur_pos(double)
Set the current position. This does not move the motor.
double home_pos
The position to set at the after homing to the home switch.
int start_pending_move()
Calls either offset_pos(next_pos) or goto_pos(next_pos) when the main loop detects a pending move...
int enable()
Call set_enable(true);.
virtual int start_signal_catcher(bool inherit_sched=true)
Starts the signal catching loop.
int delete_init()
Delete the initialization file.
virtual std::string script_command(std::string com)
Overridden from VisAOApp_base::script_command, here just calls common_command.
int dioch_pwr
The dioserver software channel connected to +5V terminal.
virtual std::string remote_command(std::string com)
Overridden from VisAOApp_base::remote_command, here just calls common_command.
int offset_pos(double dpos)
Offset current position (in microns).
int dioch_limhome
The dioserver software channel connected to the middle limit switch output.
pthread_mutex_t signal_mutex
Mutex for the condition signaling.
std::string get_state_str()
Get the state string.
int disable()
Call set_enable(false);.
The standalone VisAO application, does not interface with the AO Supervisor.
int hw_dir
Sets the polarity of the direction pin relative to the software direction, that is so forward is forw...
double step_ratio
Microns per step. For E35H4N-12-900 with BSD-02H in 1/8 step resolution this is 0.375.
std::ostringstream logss
Conveninence string stream for building log messages.
void initapp()
Initialization common to both constructors.
void * statusboard_shmemptr
The pointer to the shared memory block for the statusboard.
#define FIFOCH_HOMESW
The fifo_list fifo channel for the home switch.
#define MOVE_ABS
Pending move to absolute position.
int set_forward()
Call set_direction(true);.
virtual int update_statusboard()
Update the status board.
virtual int setup_baseApp(bool usethreads=false)
Install fifo channels.
int step()
Move by 1 step in current direction.
Declarations for the focus stage stepper motor controller.
#define FIFOCH_POSL
The fifo_list fifo channel for the back limit.
int dioch_dir
The dioserver software channel connected to the direction pin.
#define FIFOCH_DIR
The fifo_list fifo channel for direction.
int set_backward()
Call set_direction(false);.
virtual int Run()
The main loop.
virtual void dataLogger(timeval tv)
Write focus positions to the data log.
FocusMotorCtrl(std::string name, const std::string &conffile)
Standard constructor with a config file.
int set_home()
Set the current position as the home position.
int setup_fifo_list(int nfifos)
Allocate the fifo_list.
bool neg_limit
True if negative limit switch is active.
bool is_moving
True if currently processing a position change.
bool stop_moving
If true, the currently processing position change is terminated.
#define MOVE_NONE
No pending move.
pthread_cond_t signal_cond
Condition for telling main thread that something changed.
int goto_pos(double pos)
Move to an absolute position (in microns).
int DO_ENABLE
Flag for main loop. +1 calls enable, -1 calls disable.
int pending_move
If non zero, a move is pending. Can be MOVE_OFFSET or MOVE_ABS.
bool pos_limit
True if positive limit switch is active.
int save_init()
Save the initialization data to disk.
double cur_pos
The position, relative to home, in microns.
pthread_t signal_thread
Identifier for the separate signal handling thread.
int goto_preset()
Move the focus stage to the preset position for the current VisAO setup.
key_t statusboard_shmemkey
The key used to lookup the shared memory.
#define FIFOCH_PWR
The fifo_list fifo channel for power.
int dioch_limneg
The dioserver software channel connected to the negative limit switch output.
int set_enable(bool en)
Set the enable state of the controller.
virtual int block_sigio()
Sets the signal mask to block SIGIO and RTSIGIO.
int TimeToDie
Global set by SIGTERM.
virtual std::string local_command(std::string com)
Overridden from VisAOApp_base::local_command, here just calls common_command.
int step_forward()
Move by 1 step in forward direction.
double get_cur_pos()
Get the current position in microns.
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.
int get_preset(double &fcal, std::vector< double > &preset, std::string &presetf)
Reads the preset file for the current setup as determined from the shared memory status boards...
fifo_list fl
The list of named-pipe fifos used for inter-process comms.
int cur_enabled
Power state of the controller.
int get_power_state()
Get the power state of the controller.
bool home_switch
True if home limit switch is active.
int check_preset()
Check if the focus stage is currently at the preset (focused) position (within 2 microns) ...
double pause_time
Time to pause during application main loop.
#define FIFOCH_ENABLE
The fifo_list fifo channel for enable.
int cur_dir
Tracks the current setting of the direction pin TTL level.
bool pos_limit_disabled
True if back limit is disabled for dismounting.
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
#define FIFOCH_STEP
The fifo_list fifo channel for step.
timeval last_step_time
Time of the last step.
int dioch_step
The dioserver software channel connected to the step pin.
#define MAX_FNAME_SZ
The maximum allowed filename length.
static int control_mode
The current control mode.
virtual int install_sig_mainthread_catcher()
Install the SIG_MAINTHREAD signal catcher.
virtual int update_statusboard()
Update the status board.
int set_direction(bool dir)
Set the direction of the controller.
int dioch_enable
The dioserver software channel connected to the enable pin.
std::string common_command(std::string com, int cmode)
The common command processor for commands received by fifo.
The namespace of VisAO software.
std::string diofifo_path
The path of the dioserver fifos.
int dioch_limpos
The dioserver software channel connected to the positive limit switch output.
pthread_t main_thread
Identifier for the main thread.
double next_pos
Position of next move. Interpreted as either an offset or absolute position depending on pending_move...
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.
int step_backward()
Move by 1 step in backward direction.
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.