13 #include "../../libMagAOX/libMagAOX.hpp"
27 template<
class parentT>
116 int name(
const std::string & n );
240 const std::string & repBuff
258 const std::string & command
313 template<
class parentT>
319 template<
class parentT>
326 template<
class parentT>
332 template<
class parentT>
339 template<
class parentT>
342 return m_deviceAddress;
345 template<
class parentT>
348 m_deviceAddress = da;
352 template<
class parentT>
358 template<
class parentT>
365 template<
class parentT>
368 return m_commandStatus;
371 template<
class parentT>
374 return m_deviceStatus;
377 template<
class parentT>
383 template<
class parentT>
389 template<
class parentT>
395 template<
class parentT>
401 template<
class parentT>
407 template<
class parentT>
413 template<
class parentT>
419 template<
class parentT>
425 template<
class parentT>
431 template<
class parentT>
437 template<
class parentT>
443 template<
class parentT>
449 template<
class parentT>
455 template<
class parentT>
461 template<
class parentT>
467 template<
class parentT>
473 template<
class parentT>
479 template<
class parentT>
485 template<
class parentT>
491 template<
class parentT>
497 template<
class parentT>
503 template<
class parentT>
509 template<
class parentT>
515 template<
class parentT>
521 template<
class parentT>
527 template<
class parentT>
533 template<
class parentT>
539 template<
class parentT>
541 const std::string & repBuff
545 int rv =
za_decode(&rep, repBuff.c_str(), repBuff.size());
550 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return rv;
553 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv,
"za_decode !=Z_SUCCESS"});
557 return getResponse(response, rep);
560 template<
class parentT>
567 if(rep.
reply_flags[0] ==
'O') m_commandStatus =
true;
568 else m_commandStatus =
false;
573 if(m_deviceStatus ==
'I' && m_homing)
588 MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0,
"wrong device"});
593 template<
class parentT>
596 const std::string & command
601 za_send(port, command.c_str(), command.size());
607 int rv =
za_receive(port, buff,
sizeof(buff));
612 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return rv;
615 MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0,
"Z_ERROR_TIMEOUT"});
622 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return rv;
625 MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0,
"za_receive !=Z_SUCCESS"});
633 rv =
za_decode(&rep, buff,
sizeof(buff));
638 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return rv;
641 MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0,
"za_decode !=Z_SUCCESS"});
645 if(rep.
device_address == m_deviceAddress)
return getResponse(response, rep);
653 template<
class parentT>
656 if(m_deviceAddress < 1)
658 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
661 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
662 com +=
"get limit.max";
664 std::string response;
666 int rv = sendCommand(response, port, com);
670 if( m_commandStatus )
672 m_maxPos = mx::ioutils::convertFromString<long>(response);
679 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
682 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv,
"get limit.max Command Rejected"});
688 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
691 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
698 template<
class parentT>
701 if(m_deviceAddress < 1)
703 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
706 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
709 std::string response;
711 int rv = sendCommand(response, port, com);
715 if( m_commandStatus )
717 m_rawPos = mx::ioutils::convertFromString<long>(response);
724 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
727 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv,
"get pos Command Rejected"});
735 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
738 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
743 template<
class parentT>
746 if(m_deviceAddress < 1)
748 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
751 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
752 com +=
"get driver.temperature";
754 std::string response;
756 int rv = sendCommand(response, port, com);
760 if( m_commandStatus )
762 m_temp = mx::ioutils::convertFromString<float>(response);
769 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
772 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv,
"get driver.temperature Command Rejected"});
780 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
783 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
788 template<
class parentT>
791 if(m_deviceAddress < 1)
793 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
796 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
799 std::string response;
801 int rv = sendCommand(response, port, com);
805 if( m_commandStatus )
813 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
816 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name +
" stop Command Rejected"});
824 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
827 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
832 template<
class parentT>
835 if(m_deviceAddress < 1)
837 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
840 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
843 std::string response;
845 int rv = sendCommand(response, port, com);
849 if( m_commandStatus )
857 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
860 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name +
" estop Command Rejected"});
868 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
871 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
876 template<
class parentT>
879 if(m_deviceAddress < 1)
881 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
884 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
887 std::string response;
889 int rv = sendCommand(response, port, com);
893 if( m_commandStatus )
902 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
905 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name +
"Home Command Rejected"});
913 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
916 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
921 template<
class parentT>
926 if(m_deviceAddress < 1)
928 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
931 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
932 com +=
"move abs " + std::to_string(rawPos);
936 std::string response;
938 int rv = sendCommand(response, port, com);
942 if( m_commandStatus )
950 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
953 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name +
"move abs Command Rejected"});
961 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
964 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
969 template<
class parentT>
998 template<
class parentT>
1003 if(!m_warnFDreported)
1005 MagAOXAppT::log<text_log>(m_name +
" Driver Disabled (FD): The driver has disabled itself due to overheating." ,
logPrio::LOG_EMERGENCY);
1006 m_warnFDreported =
true;
1012 else if(warn ==
"FQ")
1014 if(!m_warnFQreported)
1017 m_warnFQreported =
true;
1023 else if(warn ==
"FS")
1025 if(!m_warnFSreported)
1027 MagAOXAppT::log<text_log>(m_name +
" Stalled and Stopped (FS): Stalling was detected and the axis has stopped itself. " ,
logPrio::LOG_WARNING);
1028 m_warnFSreported =
true;
1033 else if(warn ==
"FT")
1035 if(!m_warnFTreported)
1037 MagAOXAppT::log<text_log>(m_name +
" Excessive Twist (FT): The lockstep group has exceeded allowable twist and has stopped. " ,
logPrio::LOG_WARNING);
1038 m_warnFTreported =
true;
1044 else if(warn ==
"FB")
1046 if(!m_warnFBreported)
1048 MagAOXAppT::log<text_log>(m_name +
" Stream Bounds Error (FB): A previous streamed motion could not be executed because it failed a precondition" ,
logPrio::LOG_WARNING);
1049 m_warnFBreported =
true;
1055 else if(warn ==
"FP")
1057 if(!m_warnFPreported)
1059 MagAOXAppT::log<text_log>(m_name +
" Interpolated Path Deviation (FP): Streamed or sinusoidal motion was terminated because an axis slipped and thus the device deviated from the requested path. " ,
logPrio::LOG_WARNING);
1060 m_warnFPreported =
true;
1066 else if(warn ==
"FE")
1068 if(!m_warnFEreported)
1070 MagAOXAppT::log<text_log>(m_name +
" Limit Error (FE): The target limit sensor cannot be reached or is faulty. " ,
logPrio::LOG_WARNING);
1071 m_warnFEreported =
true;
1077 else if(warn ==
"WH")
1079 if(m_warnWHreported ==
false)
1081 MagAOXAppT::log<text_log>(m_name +
" Device not homed (WH): The device has a position reference, but has not been homed." ,
logPrio::LOG_WARNING);
1082 m_warnWHreported =
true;
1088 else if(warn ==
"WL")
1090 if(!m_warnWLreported)
1092 MagAOXAppT::log<text_log>(m_name +
" Unexpected Limit Trigger warning (WL): A movement operation did not complete due to a triggered limit sensor." ,
logPrio::LOG_WARNING);
1093 m_warnWLreported =
true;
1099 else if(warn ==
"WP")
1101 if(!m_warnWPreported)
1103 MagAOXAppT::log<text_log>(m_name +
" Invalid calibration type (WP): The saved calibration data type is unsupported" ,
logPrio::LOG_WARNING);
1104 m_warnWPreported =
true;
1110 else if(warn ==
"WV")
1112 if(!m_warnWVreported)
1114 MagAOXAppT::log<text_log>(m_name +
" Voltage Out of Range (WV): The supply voltage is outside the recommended operating range of the device" ,
logPrio::LOG_WARNING);
1115 m_warnWVreported =
true;
1121 else if(warn ==
"WT")
1123 if(!m_warnWTreported)
1125 MagAOXAppT::log<text_log>(m_name +
" Controller Temperature High (WT): The internal temperature of the controller has exceeded the recommended limit for the device." ,
logPrio::LOG_WARNING);
1126 m_warnWTreported =
true;
1132 else if(warn ==
"WM")
1134 if(m_warnWMreported ==
false)
1136 MagAOXAppT::log<text_log>(m_name +
" Displaced when Stationary (WM): While not in motion, the axis has been forced out of its position." ,
logPrio::LOG_WARNING);
1137 m_warnWMreported =
true;
1143 else if(warn ==
"WR")
1145 if(m_warnWRreported ==
false)
1147 MagAOXAppT::log<text_log>(m_name +
" No Reference Position (WR): Axis has not had a reference position established. [homing required]" ,
logPrio::LOG_WARNING);
1148 m_warnWRreported =
true;
1154 else if(warn ==
"NC")
1156 if(!m_warnNCreported)
1158 MagAOXAppT::log<text_log>(m_name +
" Manual Control (NC): Axis is busy due to manual control via the knob." ,
logPrio::LOG_WARNING);
1159 m_warnNCreported =
true;
1165 else if(warn ==
"NI")
1169 if(m_homing ==
true || warnWR())
return 0;
1172 if(!m_warnNIreported)
1174 MagAOXAppT::log<text_log>(m_name +
" Command Interrupted (NI): A movement operation (command or manual control) was requested while the axis was executing another movement command." ,
logPrio::LOG_WARNING);
1175 m_warnNIreported =
true;
1181 else if(warn ==
"ND")
1183 if(!m_warnNDreported)
1185 MagAOXAppT::log<text_log>(m_name +
" Stream Discontinuity (ND): The device has slowed down while following a streamed motion path because it has run out of queued motions." ,
logPrio::LOG_WARNING);
1186 m_warnNDreported =
true;
1192 else if(warn ==
"NU")
1194 if(!m_warnNUreported)
1196 MagAOXAppT::log<text_log>(m_name +
" Setting Update Pending (NU): A setting is pending to be updated or a reset is pending." ,
logPrio::LOG_WARNING);
1197 m_warnNUreported =
true;
1203 else if(warn ==
"NJ")
1205 if(!m_warnNJreported)
1207 MagAOXAppT::log<text_log>(m_name +
" Joystick Calibrating (NJ): Joystick calibration is in progress." ,
logPrio::LOG_WARNING);
1208 m_warnNJreported =
true;
1216 MagAOXAppT::log<software_warning>({__FILE__, __LINE__, m_name +
" unknown stage warning: " + warn});
1226 template<
class parentT>
1229 size_t nwarn = std::stoi( response.substr(0, 2));
1231 if(nwarn > 0) m_warn =
true;
1233 for(
size_t n =0; n< nwarn; ++n)
1235 if(response.size() < 3 + n*3)
1239 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
1242 MagAOXAppT::log<software_error>({__FILE__, __LINE__,
"parsing incomplete warning response"});
1246 std::string warn = response.substr(3 + n*3, 2);
1248 int rv = processWarning(warn);
1253 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
1256 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
1261 if(m_warnFDreported)
1265 m_warnFDreported =
false;
1269 if(m_warnFQreported)
1273 m_warnFQreported =
false;
1277 if(m_warnFSreported)
1281 m_warnFSreported =
false;
1285 if(m_warnFTreported)
1289 m_warnFTreported =
false;
1293 if(m_warnFBreported)
1297 m_warnFBreported =
false;
1301 if(m_warnFPreported)
1305 m_warnFPreported =
false;
1309 if(m_warnFEreported)
1313 m_warnFEreported =
false;
1317 if(m_warnWHreported)
1321 m_warnWHreported =
false;
1325 if(m_warnWLreported)
1329 m_warnWLreported =
false;
1333 if(m_warnWPreported)
1337 m_warnWPreported =
false;
1341 if(m_warnWVreported)
1345 m_warnWVreported =
false;
1349 if(m_warnWTreported)
1353 m_warnWTreported =
false;
1357 if(m_warnWMreported)
1361 m_warnWMreported =
false;
1365 if(m_warnWRreported)
1369 m_warnWRreported =
false;
1373 if(m_warnNCreported)
1377 m_warnNCreported =
false;
1381 if(m_warnNIreported)
1385 m_warnNIreported =
false;
1389 if(m_warnNDreported)
1393 m_warnNDreported =
false;
1397 if(m_warnNUreported)
1401 m_warnNUreported =
false;
1405 if(m_warnNJreported)
1409 m_warnNJreported =
false;
1417 template<
class parentT>
1420 if(m_deviceAddress < 1)
1422 return MagAOXAppT::log<
software_error, -1>({__FILE__, __LINE__,
"stage " + m_name +
" with with s/n " + m_serial +
" not found in system."});
1425 std::string com =
"/" + mx::ioutils::convertToString(m_deviceAddress) +
" ";
1428 std::string response;
1430 int rv = sendCommand(response, port, com);
1434 if( m_commandStatus )
1437 return parseWarnings(response);
1444 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
1447 MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv,
"warnings Command Rejected"});
1455 if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1)
return -1;
1458 MagAOXAppT::log<software_error>({__FILE__, __LINE__});
1463 template<
class parentT>
1466 m_commandStatus =
true;
1468 m_deviceStatus =
'U';
1479 m_warnWRreported =
false;
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
A class to manage the details of one stage in a Zaber system.
long m_maxPos
The max position allowed for the device, set by config. Will be set to no larger m_maxPosHW.
int getMaxPos(z_port port)
int serial(const std::string &s)
Set the device serial.
char deviceStatus()
Get the device status.
int axisNumber(const int &an)
Set the axis number.
int getWarnings(z_port port)
Get warnings from the device.
float m_temp
The driver temperature, in C.
long rawPos()
Get the current raw position, in counts.
int processWarning(std::string &warn)
Process a single warning from the device, setting the appropriate flag.
bool warn()
Get the status of the warning flag.
std::string name()
Get the device name.
bool m_commandStatus
The status of the last command sent. true = OK, false = RJ (rejected)
long maxPos()
Get the max position, in counts.
bool homing()
Get the homing status.
long tgtPos()
Get the current tgt position, in counts.
int sendCommand(std::string &response, z_port port, const std::string &command)
int m_axisNumber
The axis number at the address (normally 0 in MagAO-X)
int deviceAddress(const int &da)
Set the device address.
int onPowerOff()
Clear all state so that when the system is powered back on we get the correct new state.
int moveAbs(z_port port, long rawPos)
int axisNumber()
Get the axis number.
zaberStage(parentT *parent)
long m_rawPos
The raw position reported by the device, in microsteps.
int updatePos(z_port port)
int parseWarnings(std::string &response)
Parse the warning response from the device.
std::string serial()
Get the device serial number.
bool commandStatus()
Get the command status.
long m_tgtPos
The tgt position last sent to the device, in microsteps.
std::string m_serial
The stage's serial number.
int updateTemp(z_port port)
int name(const std::string &n)
Set the device name.
int deviceAddress()
Get the device address.
int getResponse(std::string &response, const za_reply &rep)
Get a response from the device, after a command has been sent.
int m_deviceAddress
The device's address, a.k.a. its order in the chain.
char m_deviceStatus
Current status. Either 'I' for IDLE or 'B' for BUSY. Intializes to 'U' for UNKOWN.
float temp()
Get the temperature, in C.
int getResponse(std::string &response, const std::string &repBuff)
Get a response from the device, after a command has been sent.
std::string m_name
The stage's name.
bool warningState()
Get the warning state.
int unsetWarnings()
Sets all warning flags to false.
constexpr static logPrioT LOG_DEBUG2
Used for debugging, providing a 2nd level.
constexpr static logPrioT LOG_EMERGENCY
Normal operations of the entire system should be shut down immediately.
constexpr static logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
int za_receive(z_port port, char *destination, int length)
int za_decode(struct za_reply *destination, const char *reply, size_t sMaxSz)
int za_send(z_port port, const char *command, size_t sMaxSz)
Provides a set of functions for interacting with Zaber devices in the ASCII protocol.