32 GimbalMotorCtrl::~GimbalMotorCtrl()
48 ip_addr = (std::string)(ConfigDictionary())[
"ip_addr"];
50 catch(Config_File_Exception)
52 ERROR_REPORT(
"ip_addr is required in configuration.");
55 _logger->log(Logger::LOG_LEV_INFO,
"ip_addr set to %s.",
ip_addr.c_str());
60 ip_port = (
int)(ConfigDictionary())[
"ip_port"];
62 catch(Config_File_Exception)
64 ERROR_REPORT(
"ip_port is required in configuration.");
67 _logger->log(Logger::LOG_LEV_INFO,
"ip_port set to %i.",
ip_port);
72 x_addr = (
int)(ConfigDictionary())[
"x_addr"];
74 catch(Config_File_Exception)
76 ERROR_REPORT(
"x_addr is required in configuration.");
79 _logger->log(Logger::LOG_LEV_INFO,
"x_addr set to %i.",
x_addr);
84 y_addr = (
int)(ConfigDictionary())[
"y_addr"];
86 catch(Config_File_Exception)
88 ERROR_REPORT(
"y_addr is required in configuration.");
91 _logger->log(Logger::LOG_LEV_INFO,
"y_addr set to %i.",
y_addr);
99 scale = (double)(ConfigDictionary())[
"scale"];
101 catch(Config_File_Exception)
105 _logger->log(Logger::LOG_LEV_INFO,
"Gimbal scale set to %f arcsec/mm.",
scale);
110 x_center = (double)(ConfigDictionary())[
"x_center"];
112 catch(Config_File_Exception)
114 ERROR_REPORT(
"Gimbal x_center is required in configuration.");
116 _logger->log(Logger::LOG_LEV_INFO,
"Gimbal x_center set to %f.",
x_center);
121 y_center = (double)(ConfigDictionary())[
"y_center"];
123 catch(Config_File_Exception)
125 ERROR_REPORT(
"Gimbal y_center is required in configuration.");
127 _logger->log(Logger::LOG_LEV_INFO,
"Gimbal y_center set to %f.",
y_center);
133 x_dark = (double)(ConfigDictionary())[
"x_dark"];
135 catch(Config_File_Exception)
139 _logger->log(Logger::LOG_LEV_INFO,
"Gimbal x_dark set to %f.",
x_dark);
144 y_dark = (double)(ConfigDictionary())[
"y_dark"];
146 catch(Config_File_Exception)
150 _logger->log(Logger::LOG_LEV_INFO,
"Gimbal y_dark set to %f.",
y_dark);
158 _logger->log(Logger::LOG_LEV_ERROR,
"Could not create status board.");
163 strncpy(bsb->appname, MyFullName().c_str(), 25);
172 catch(Config_File_Exception)
174 _logger->log(Logger::LOG_LEV_ERROR,
"Gimbal power_outlet is required in configuration.");
176 _logger->log(Logger::LOG_LEV_INFO,
"Gimbal power_outlet set to %i.",
power_outlet);
227 if (stat != NO_ERROR)
230 logss <<
"Error attempting to connect to " <<
ip_addr <<
":" <<
ip_port <<
". Connect result: ";
231 logss << stat <<
" - errno says: " << strerror(errno);
232 ERROR_REPORT(
logss.str().c_str());
241 LOG_INFO(
logss.str().c_str());
259 if(getCtrlState(
xAxisNo, axstate) < 0)
265 ERROR_REPORT(errStr.str().c_str());
266 ERROR_REPORT(
"error getting x axis state");
271 if(axstate[0] ==
'0') newState = STATE_CONNECTED;
272 else if (axstate[0] ==
'1' && (axstate[1] ==
'E' || axstate[1] ==
'F'))
274 newState = STATE_HOMING;
277 else if (axstate[0] ==
'2') newState = STATE_OPERATING;
278 else if (axstate[0] ==
'3' && isdigit(axstate[1])) newState = STATE_READY;
282 logss <<
"Invalid x axis state:" << axstate <<
".";
283 ERROR_REPORT(
logss.str().c_str());
284 newState = STATE_INVALID;
287 if(getCtrlState(
yAxisNo, axstate)<0)
291 ERROR_REPORT(errStr.str().c_str());
292 ERROR_REPORT(
"error getting y axis state");
296 if(axstate[0] ==
'0')
298 newState = STATE_CONNECTED;
300 else if ((axstate[0] ==
'1' && (axstate[1] ==
'E' || axstate[1] ==
'F')))
302 if(newState != STATE_INVALID)
304 newState = STATE_HOMING;
308 else if (axstate[0] ==
'2')
310 if(newState != STATE_HOMING && newState != STATE_INVALID)
312 newState = STATE_OPERATING;
315 else if (axstate[0] ==
'3' && isdigit(axstate[1]))
317 if(newState != STATE_HOMING && newState != STATE_INVALID && newState != STATE_OPERATING)
319 newState = STATE_READY;
324 ERROR_REPORT(
"Invalid y axis state");
325 newState = STATE_INVALID;
328 if(newState == STATE_READY)
336 std::vector<double> preset(2);
338 if( get_preset(
"gimbal", 0, -1, 0, 0, &preset, presetf) < 0)
341 logss <<
"Found preset: " << presetf <<
" -> " << preset[0] <<
" " << preset[1] <<
". Centering.";
342 LOG_INFO(
logss.str().c_str());
344 ERROR_REPORT(
"Could not get center preset for post homing.");
351 rv = gotoAbsPos(
xAxisNo, preset[0]);
354 ERROR_REPORT(errStr.str().c_str());
356 rv += gotoAbsPos(
yAxisNo, preset[1]);
359 ERROR_REPORT(errStr.str().c_str());
381 if(resp.length() != 2)
return -1;
384 if(resp[0] ==
'2' && resp[1] ==
'8')
389 if(resp[0] ==
'1' && (resp[1] ==
'E' || resp[1] ==
'F'))
407 if(resp.length() != 2)
return -1;
409 if(resp[0] ==
'2' && resp[1] ==
'8')
414 if(resp[0] ==
'1' && (resp[1] ==
'E' || resp[1] ==
'F'))
458 else powerState = -1;
466 std::vector<double> preset(2);
477 ERROR_REPORT(
"Not connected to status boards for center preset.");
482 if( get_preset(
"gimbal",
aosb->filter1_reqpos, (
int)
wsb->cur_pos,
fw2sb->req_pos,
fw3sb->req_pos, &preset, presetf) < 0)
484 if( get_preset(
"gimbal",
aosb->filter1_reqpos, (
int)
wsb->cur_pos, 0, 0, &preset, presetf) < 0)
486 ERROR_REPORT(
"Could not get exact center preset.");
492 logss <<
"Found preset: " << presetf <<
" -> " << preset[0] <<
" " << preset[1] <<
". Centering.";
493 LOG_INFO(
logss.str().c_str());
497 ERROR_REPORT(errStr.str().c_str());
502 ERROR_REPORT(errStr.str().c_str());
516 ERROR_REPORT(errStr.str().c_str());
521 ERROR_REPORT(errStr.str().c_str());
527 LOG_INFO(
logss.str().c_str());
534 std::vector<double> preset(2);
545 ERROR_REPORT(
"Not connected to status boards for saving preset.");
568 if( save_preset(
"gimbal",
aosb->filter1_pos, (
int)
wsb->cur_pos, 0., fw3pos, &preset) < 0)
571 logss <<
"Could not save center preset: " << (
int)
aosb->filter1_pos <<
" " << (
int)
wsb->cur_pos <<
" " << 0 <<
" " <<
fw3sb <<
" " << preset[0] <<
" " << preset[1] <<
"\n";
572 ERROR_REPORT(
logss.str().c_str());
580 logss <<
"Saved preset " << preset[0] <<
" " << preset[1] <<
".";
581 LOG_INFO(
logss.str().c_str());
594 std::cout <<
"Sending " << com <<
"\n";
597 std::string termcom = com +
"\r\n";
599 if(SerialOut(termcom.c_str(), termcom.length()) != 0)
601 ERROR_REPORT(
"Communication send error in sendCommand");
608 std::cout <<
"Sent. Getting response.\n";
611 if(SerialInString(answer, 256, timeout,
'\n') < 0)
614 ERROR_REPORT(
"Communication receive error in sendCommand");
621 std::cout <<
"Response got.\n";
628 int cr = resp.find(
"\r", 0);
631 std::cout <<
"CR pos = " << cr <<
".\n";
634 if(cr > 0) resp.erase(cr, resp.length()-cr);
638 std::cout <<
"Received " << resp <<
"\n";
648 std::cout <<
"Sending " << com <<
"\n";
651 std::string termcom = com +
"\r\n";
653 if(SerialOut(termcom.c_str(), termcom.length()) != 0)
655 ERROR_REPORT(
"Communication send error in sendCommand");
668 signal(SIGIO, SIG_IGN);
669 signal(RTSIGIO, SIG_IGN);
674 ERROR_REPORT(
"Error installing main thread catcher.");
681 ERROR_REPORT(
"Error starting signal catching thread.");
688 ERROR_REPORT(
"Error blicking SIGIO.");
692 LOG_INFO(
"starting up . . .");
716 case STATE_CONNECTED:
718 std::cout <<
"STATE_CONNECTED\n";
722 ERROR_REPORT(
"Error in power on init:");
723 ERROR_REPORT(errStr.str().c_str());
729 std::cout <<
"STATE_HOMING\n";
732 case STATE_OPERATING:
734 std::cout <<
"STATE_OPERATING\n";
739 std::cout <<
"STATE_READY\n";
742 case STATE_NOCONNECTION:
744 std::cout <<
"STATE_NOCONNECTION\n";
749 std::cout <<
"STATE_OFF\n";
754 std::cout <<
"STATE_?\n";
758 ERROR_REPORT(
logss.str().c_str());
794 std::cout <<
"Common Command " << com <<
"\n";
800 snprintf(str, 256,
"%i\n", rv);
807 snprintf(str, 256,
"%i\n", rv);
814 snprintf(str, 256,
"%i\n", rv);
825 snprintf(str, 256,
"%f\n",
scale);
832 snprintf(str, 256,
"%f\n", val);
836 if(com ==
"xmoving?")
845 snprintf(str, 256,
"%f\n", val);
849 if(com ==
"ymoving?")
857 if(com.substr(0,4) ==
"xrel" && com.length() > 4)
859 val = strtod(com.substr(5, com.length()-5).c_str(), 0);
863 ERROR_REPORT(errStr.str().c_str());
865 snprintf(str, 256,
"%i\n", rv);
869 if(com.substr(0,4) ==
"xabs" && com.length() > 4)
871 val = strtod(com.substr(5, com.length()-5).c_str(), 0);
875 ERROR_REPORT(errStr.str().c_str());
877 snprintf(str, 256,
"%i\n", rv);
881 if(com.substr(0,4) ==
"yrel" && com.length() > 4)
883 val = strtod(com.substr(5, com.length()-5).c_str(), 0);
887 ERROR_REPORT(errStr.str().c_str());
889 snprintf(str, 256,
"%i\n", rv);
893 if(com.substr(0,4) ==
"yabs" && com.length() > 4)
895 val = strtod(com.substr(5, com.length()-5).c_str(), 0);
899 ERROR_REPORT(errStr.str().c_str());
901 snprintf(str, 256,
"%i\n", rv);
909 if(rv < 0)
return "-1\n";
917 if(rv < 0)
return "-1\n";
921 if(com ==
"savepreset")
924 if(rv < 0)
return "-1\n";
937 return "UNKOWN COMMAND";
954 snprintf(tmp, 100,
"%c,%i,%i,%i,%f,%i,%f,%f\n",
control_mode_response()[0],
curState,
getPowerStatus(),xm, xp, ym, yp,
scale);
962 gettimeofday(&tv, 0);
970 gettimeofday(&tv, 0);
1004 checkDataFileOpen();
1006 dataof << tv.tv_sec <<
" " << tv.tv_usec <<
" " <<
get_x_pos() <<
" " <<
get_y_pos() << std::endl;
1010 Logger::get()->log(Logger::LOG_LEV_ERROR,
"Error in Gimbal data file. Gimbal data may not be logged correctly");
int center()
Read the preset center position for current board conditions, and gimbal to it.
int x_addr
The controller address of the x axis.
int y_addr
The controller address of the y axis.
double get_curr_time(void)
Gets the current CLOCK_REALTIME time, returns it in seconds to double precision.
virtual std::string script_command(std::string com)
Overridden from VisAOApp_base::script_command, here just calls common_command.
int * powerOutletState
The power strip outlet controlling shutter power.
virtual int start_signal_catcher(bool inherit_sched=true)
Starts the signal catching loop.
int getXMoving()
Get the moving status of the x axis.
double x_dark
The configurable location of the x dark location.
int xAxisNo
The axis number of x, e.g. 0.
int postHoming
When 1, the gimbal will center after homing.
pthread_mutex_t comMutex
Mutex for communicating with the controllers.
The standalone VisAO application, does not interface with the AO Supervisor.
std::string common_command(std::string com, int cmode)
The common command processor for commands received by fifo.
std::ostringstream logss
Conveninence string stream for building log messages.
void * statusboard_shmemptr
The pointer to the shared memory block for the statusboard.
double get_x_pos()
Get the x position.
virtual int update_statusboard()
Update the status board.
virtual int setup_baseApp(bool usethreads=false)
Install fifo channels.
VisAO::filterwheel_status_board * fw2sb
pointer to status board of F/W 2 (for presets)
virtual int sendCommand(std::string &com, std::string &resp, int timeout)
Implementation of ESPMotorCtrl sendCommand.
int setup_fifo_list(int nfifos)
Allocate the fifo_list.
bool isMoving
True if moving - set when move starts and updating data logger.
int savepreset()
Save the current position as the preset for this board setup.
The ESP motor controller class.
int powerOnInit()
Checks the controllers for current errors, and populates the stageName vector.
pthread_t signal_thread
Identifier for the separate signal handling thread.
key_t statusboard_shmemkey
The key used to lookup the shared memory.
double scale
The conversion scale from encoder mm to arcsec on the CCD47, i.e. arcsec/mm.
Definitions for the gimbal motor controller.
virtual int block_sigio()
Sets the signal mask to block SIGIO and RTSIGIO.
int ip_port
ip port on which the motor controllers are connected
virtual int update_statusboard()
Update the gimbal status board.
int TimeToDie
Global set by SIGTERM.
std::string control_mode_response()
Convenience function to return the control type response string, e.g. "A\n".
int getYMoving()
Get the moving status of the y axis.
void * attach_shm(size_t *sz, key_t mkey, int shmemid)
Attach to a shared memory buffer and get its size.
int setupNetwork()
Establish the serial-over-ip connection.
virtual void dataLogger(timeval tv)
Write gimbal positions to the data log.
int getPowerStatus()
Get the status of the power outlet.
double get_y_pos()
Get the y position.
void moveStop()
Called when a move stops, for data logging.
double pause_time
Time to pause during application main loop.
#define STATUS_gimbal
Shared memory key for the Gimbal mirror status board.
double y_center
The configurable location of the default x-center.
int power_outlet
Configuration variable, setting which power outlet to monitor.
VisAO::wollaston_status_board * wsb
pointer to status board of wollaston (for presets)
VisAO::aosystem_status_board * aosb
pointer to status board of VisAOI (for presets)
virtual void moveStart()
Called when a move starts, for data logging. Overriden from ESPMotorCtrl.
virtual std::string remote_command(std::string com)
Overridden from VisAOApp_base::remote_command, here just calls common_command.
power_status_board * psb
This is for monitoring power outlet state.
int checkConnStat()
Check connection status by querying the status of each controller. Changes curState.
int curState
The current controller state (READY, etc.)
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
virtual int Run()
The main loop.
double x_center
The configurable location of the default x-center.
double y_dark
The configurable location of the y dark location.
double ts_to_curr_time(struct timespec *tsp)
Convert a timespec structure to double seconds.
static int control_mode
The current control mode.
int yAxisNo
The axis number of y, e.g. 1.
virtual int install_sig_mainthread_catcher()
Install the SIG_MAINTHREAD signal catcher.
virtual std::string local_command(std::string com)
Overridden from VisAOApp_base::local_command, here just calls common_command.
VisAO::filterwheel_status_board * fw3sb
pointer to status board of F/W 3 (for presets)
void Create()
Initialization common to both constructors.
std::string ip_addr
ip address of the serial converter
The namespace of VisAO software.
int dark()
Gimbal to the dark position.
GimbalMotorCtrl(std::string name, const std::string &conffile)
Standard constructor with a config file.
std::string get_state_str()
Get the state string.