The VisAO Camera
FocusMotorCtrl.h
Go to the documentation of this file.
1 /************************************************************
2  * FocusMotorCtrl.h
3  *
4  * Author: Jared R. Males (jrmales@email.arizona.edu)
5  *
6  * Declarations for the VisAO focus stage stepper motor controller.
7  *
8  * Developed as part of the Magellan Adaptive Optics system.
9  ************************************************************/
10 
11 /** \file FocusMotorCtrl.h
12  * \author Jared R. Males
13  * \brief Declarations for the focus stage stepper motor controller.
14  *
15  */
16 
17 #ifndef __VisAOFocusMotorCtrl_h__
18 #define __VisAOFocusMotorCtrl_h__
19 
20 #include "VisAOApp_standalone.h"
21 #include "libvisao.h"
22 
23 #include <fstream>
24 #include <cmath>
25 
26 ///No pending move
27 #define MOVE_NONE 0
28 ///Pending offset move
29 #define MOVE_OFFSET 1
30 ///Pending move to absolute position
31 #define MOVE_ABS 2
32 
33 #define MOVE_HOME 3
34 #define MOVE_NEGHOME 4
35 #define MOVE_POSHOME 5
36 
37 ///The fifo_list fifo channel for enable
38 #define FIFOCH_ENABLE 0
39 ///The fifo_list fifo channel for direction
40 #define FIFOCH_DIR 1
41 ///The fifo_list fifo channel for step
42 #define FIFOCH_STEP 2
43 
44 ///The fifo_list fifo channel for power
45 #define FIFOCH_PWR 3
46 
47 ///The fifo_list fifo channel for the front limit
48 #define FIFOCH_NEGL 4
49 
50 ///The fifo_list fifo channel for the home switch
51 #define FIFOCH_HOMESW 5
52 
53 ///The fifo_list fifo channel for the back limit
54 #define FIFOCH_POSL 6
55 
56 namespace VisAO
57 {
58 
59 
60 /// The focus stage stepper motor controller class.
61 /** Manges the digital inputs to the BSD-02 stepper motor controller.
62  * Tracks position relative to the home position in microns, as an integer number
63  * of steps of size \ref step_ratio. Is a standalone VisAOApp, and has remote, local
64  * and script fifos. No auto control is provided. The config file parameters are:
65  * - MyName string (required)
66  * - ID int (required)
67  * - LogLevel string (required)
68  * - com_path string (optional)
69  * - diofifo_path string (optional)
70  * - dioch_enable int (required)
71  * - dioch_dir int (required)
72  * - dioch_step int (required)
73  * - step_ratio double (required)
74  * - min_step_time double (required)
75  * - hw_dir int (optional)
76  */
78 {
79 public:
80  /// Standard constructor with a config file.
81  FocusMotorCtrl(std::string name, const std::string& conffile) throw (AOException);
82 
83  /// Standard constructor with a command line.
84  FocusMotorCtrl( int argc, char**argv) throw (AOException);
85 
86  virtual ~FocusMotorCtrl();
87 
88 
89  /// Initialization common to both constructors.
90  /** Reads the app specific config detals, and sets up the fifo_list and connects it.
91  * Upon exit, SIGIO is blocked.
92  */
93  void initapp();
94 
95 protected:
96  std::string diofifo_path; ///< The path of the dioserver fifos
97  int dioch_enable; ///<The dioserver software channel connected to the enable pin
98  int dioch_dir; ///<The dioserver software channel connected to the direction pin
99  int dioch_step; ///<The dioserver software channel connected to the step pin
100 
101  int dioch_pwr; ///<The dioserver software channel connected to +5V terminal
102  int dioch_limpos; ///<The dioserver software channel connected to the positive limit switch output
103  int dioch_limhome; ///<The dioserver software channel connected to the middle limit switch output
104  int dioch_limneg; ///<The dioserver software channel connected to the negative limit switch output
105 
106  pthread_mutex_t dio_mutex;
107 
108  int power_state; ///Power state of the controller.
109 
110  int cur_enabled; ///<Tracks the current setting of the enable pin TTL level
111  int DO_ENABLE;///<Flag for main loop. +1 calls enable, -1 calls disable
112  int cur_dir; ///<Tracks the current setting of the direction pin TTL level
113 
114  double min_step_time; ///<Minimum time between steps, in seconds. Can't be < 1e-6.
115 
116  double step_ratio; ///<Microns per step. For E35H4N-12-900 with BSD-02H in 1/8 step resolution this is 0.375
117 
118  int hw_dir; ///<Sets the polarity of the direction pin relative to the software direction, that is so forward is forward as wired.
119 
120  double cur_pos; ///<The position, relative to home, in microns
121 
122  int pending_move; ///<If non zero, a move is pending. Can be \ref MOVE_OFFSET or \ref MOVE_ABS.
123  double next_pos; ///<Position of next move. Interpreted as either an offset or absolute position depending on \ref pending_move.
124 
125  bool is_moving; ///<True if currently processing a position change.
126  bool stop_moving; ///<If true, the currently processing position change is terminated.
127 
128  timeval last_step_time; ///<Time of the last step.
129 
130  bool neg_limit; ///<True if negative limit switch is active
131  bool pos_limit; ///<True if positive limit switch is active
132  bool home_switch;///<True if home limit switch is active
133 
134  bool pos_limit_disabled; ///<True if back limit is disabled for dismounting
135 
136  int sw_limits_only;
137 
138  double sw_neg_limit;
139  double sw_pos_limit;
140 
141  double home_pos; ///<The position to set at the after homing to the home switch
142 
143  int homing; //0 = not homing
144  //1 = initial homing, first stage of homing to make sure we aren't on the center switch to start
145  //2 = main homing, moving to find the limit switch
146  //3 = secondary homing, occurs after finding the limit switch moving backwards, lasts until switch clears
147  //4 = negative homing, moving negative until negative switch trips
148  //5 = positive homing, moving positive until back switch trips
149  //Center home is defined as having tripped the center switch from the back while moving forward.
150 
151  int check_limits(); ///<Gets the limit switch status from dioserver, and performs homing logic checks.
152 
157 
158 public:
159  ///Get the current position in microns.
160  double get_cur_pos(){return cur_pos;}
161  ///Set the current position. This does not move the motor.
162  /** \param cp the new value of the current position.
163  * \retval 0 on succes (always)
164  */
165  int set_cur_pos(double);
166 
167  ///Set the current position as the home position.
168  /** Equivalent to set_cur_pos(0).
169  */
170  int set_home();
171 
172  //status functions:
173  /// Get the power state of the controller
174  int get_power_state();
175 
176  //control functions:
177  /// Set the enable state of the controller.
178  /** The software state is true=enabled, false=disabled. The
179  * hardware state is low=enabled, high=disabled. To enable
180  * call with en=true.
181  * \param en the desired enable state.
182  * \retval 0 on success
183  * \retval -1 on failure
184  */
185  int set_enable(bool en);
186  ///Call set_enable(true);
187  int enable();
188  ///Call set_enable(false);
189  int disable();
190 
191  /// Set the direction of the controller.
192  /** The software direction determines whether cur_pos increases or decreases.
193  * This also changes the hardware direction by setting the direction pin, but the
194  * actual direction of motion is set by the wiring and hw_dir.
195  * \param dir 1 for forward, 0 for backward
196  * \retval 0 on success
197  * \retval -1 on failure
198  */
199  int set_direction(bool dir);
200  ///Call set_direction(true);
201  int set_forward();
202  ///Call set_direction(false);
203  int set_backward();
204 
205  /// The routine to control motion of the stepper motor.
206  /** The BSD-02 steps on a low-high transition. There is a minimum
207  * dwell time for each of 1 microsecond. This loop also waits at least
208  * min_step_time between steps, as part of the low dwell time.
209  * Enables the controller prior to first step, and updates cur_pos at each step.
210  * Stops moving and exits normally if stop_moving becomes true.
211  * On exit, is_moving, pending_move, and stop_moving are all false
212  * and the controller is disabled.
213  * \param nsteps is the number of steps to take.
214  * \retval 0 on success
215  * \retval -1 on failure.
216  */
217  int step(int nsteps);
218 
219  /// Move by 1 step in current direction.
220  /** Calls step(1)
221  * \retval 0 on success
222  * \retval -1 on failure.
223  */
224  int step();
225 
226  /// Move the motor forward by nsteps.
227  /** First sets the direction, then calls step(nsteps).
228  * \param nsteps is the number of steps to take.
229  * \retval 0 on success
230  * \retval -1 on failure.
231  */
232  int step_forward(int nsteps);
233  /// Move by 1 step in forward direction.
234  /** Calls step(1)
235  * \retval 0 on success
236  * \retval -1 on failure.
237  */
238  int step_forward();
239 
240  /// Move the motor backward by nsteps.
241  /** First sets the direction, then calls step(nsteps).
242  * \param nsteps is the number of steps to take.
243  * \retval 0 on success
244  * \retval -1 on failure.
245  */
246  int step_backward(int nsteps);
247  /// Move by 1 step in backward direction.
248  /** Calls step(1)
249  * \retval 0 on success
250  * \retval -1 on failure.
251  */
252  int step_backward();
253 
254  /// Offset current position (in microns).
255  /** Calculates the number of steps to move, and direction, then calls
256  * either step_forward(nsteps) or step_backward(nsteps) as appropriate.
257  * \param dpos the size of the offset desired, in microns
258  * \retval 0 on success.
259  * \retval -1 on failure.
260  */
261  int offset_pos(double dpos);
262 
263  /// Move to an absolute position (in microns).
264  /** Calculates the number of steps to move, and direction, then calls
265  * either step_forward(nsteps) or step_backward(nsteps) as appropriate.
266  * \param pos the position to move to, in microns
267  * \retval 0 on success.
268  * \retval -1 on failure.
269  */
270  int goto_pos(double pos);
271 
272  /// Calls either offset_pos(next_pos) or goto_pos(next_pos) when the main loop detects a pending move.
273  /** The main loop pause() is interrupted by a SIGIO signal, and once control returns it checks
274  * pending_move, and if ture calls this routine. The move will continue until complete or stopped.
275  * \retval 0 on success
276  * \retval -1 on failure.
277  */
278  int start_pending_move();
279 
280  ///Reads the preset file for the current setup as determined from the shared memory status boards.
281  /** If a preset file exists for current conditions it is read and the arguments are populated.
282  */
283  int get_preset(double &fcal, std::vector<double> & preset, std::string & presetf);
284 
285  ///Check if the focus stage is currently at the preset (focused) position (within 2 microns)
286  int check_preset();
287 
288  ///Move the focus stage to the preset position for the current VisAO setup.
289  /** Gets the current preset from get_preset. If a preset exists, the stage is moved.
290  */
291  int goto_preset();
292 
293  /// The main loop.
294  /** Sets the signal handling for SIGIO then
295  * starts pause()-ing.
296  */
297  virtual int Run();
298 
299  /// Overridden from VisAOApp_base::remote_command, here just calls common_command.
300  virtual std::string remote_command(std::string com);
301  /// Overridden from VisAOApp_base::local_command, here just calls common_command.
302  virtual std::string local_command(std::string com);
303  /// Overridden from VisAOApp_base::script_command, here just calls common_command.
304  virtual std::string script_command(std::string com);
305 
306  /// The common command processor for commands received by fifo.
307  /** The return value depends on the command received. Recognized commands are:
308  * - POS? the return value is the current position in microns as "x.XXXX\n"
309  * - ISMOVING? the return value is "1\n" if moving, "0\n" if not moving.
310  * - STATE? returns the result of get_state_str()
311  * - ABORT if control_mode allows it, sets stop_moving = true and returns "0\n". Otherwise returns the control_mode in 1 letter.
312  * - POS x.x if control_mode allows it and not already moving, sets pending_move = \ref MOVE_ABS and next_pos = x.x, and returns "1\n".
313  * if control_mode would allow it but already moving does nothing and returns "0\n". Othewrise, returns the control mode in 1 letter.
314  * - DPOS x.x if control_mode allows it and not already moving, sets pending_move = \ref MOVE_OFFSET and next_pos = x.x, and returns "1\n".
315  * if control_mode would allow it but already moving does nothing and returns "0\n". Othewrise, returns the control mode in 1 letter.
316  * - For any other inputs returns "UNKNOWN COMMAND: (str)\n"
317  */
318  std::string common_command(std::string com, int cmode);
319 
320  /// Get the state string.
321  /** The state string encodes the current state of the controller as:
322  * C PPPPPPP.PPPP M RRRRRRR.RRRR
323  * Where C is the current control_mode, PPPPPPP.PPPP is the current position
324  * M is 1 if moving, 0 if not, and RRRRRRR.RRRR is the remaining distance to travel.
325  * \returns the state string
326  */
327  std::string get_state_str();
328 
329 protected:
330  ///Save the initialization data to disk
331  int save_init();
332 
333  ///Delete the initialization file
334  int delete_init();
335 
336 public:
337  virtual int update_statusboard();
338 
339  ///Write focus positions to the data log
340  virtual void dataLogger(timeval tv);
341 };
342 
343 } //namespace VisAO
344 
345 #endif //__VisAOFocusMotorCtrl_h__
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.
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);.
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.
std::string get_state_str()
Get the state string.
int disable()
Call set_enable(false);.
The focus stage stepper motor controller class.
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.
void initapp()
Initialization common to both constructors.
Declarations for the standalone VisAO application.
int set_forward()
Call set_direction(true);.
int step()
Move by 1 step in current direction.
int dioch_dir
The dioserver software channel connected to the direction pin.
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.
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.
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.
VisAO software utilitites, declarations.
int goto_preset()
Move the focus stage to the preset position for the current VisAO setup.
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 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.
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...
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) ...
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.
timeval last_step_time
Time of the last step.
int dioch_step
The dioserver software channel connected to the step pin.
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.
double next_pos
Position of next move. Interpreted as either an offset or absolute position depending on pending_move...
int step_backward()
Move by 1 step in backward direction.