7#ifndef tcsInterface_hpp
8#define tcsInterface_hpp
12#include "../../libMagAOX/libMagAOX.hpp"
13#include "../../magaox_git_version.h"
16#include "../../libMagAOX/app/dev/telemeter.hpp"
221 const std::string &
xmsstr
431 config.add(
"labMode",
"",
"labMode", argType::Required,
"",
"labMode",
false,
"bool",
"Flag to enable lab mode. Default is true.");
433 config.add(
"pyrNudger.C_00",
"",
"pyrNudger.C_00", argType::Required,
"pyrNudger",
"C_00",
false,
"float",
"Pyramid to AEG control matrix [0,0] of a 2x2 matrix");
434 config.add(
"pyrNudger.C_01",
"",
"pyrNudger.C_01", argType::Required,
"pyrNudger",
"C_01",
false,
"float",
"Pyramid to AEG control matrix [0,1] of a 2x2 matrix ");
435 config.add(
"pyrNudger.C_10",
"",
"pyrNudger.C_10", argType::Required,
"pyrNudger",
"C_10",
false,
"float",
"Pyramid to AEG control matrix [1,0] of a 2x2 matrix ");
436 config.add(
"pyrNudger.C_11",
"",
"pyrNudger.C_11", argType::Required,
"pyrNudger",
"C_11",
false,
"float",
"Pyramid to AEG control matrix [1,1] of a 2x2 matrix ");
438 config.add(
"pyrNudger.ang",
"",
"pyrNudger.ang", argType::Required,
"pyrNudger",
"ang",
false,
"float",
"");
439 config.add(
"pyrNudger.ang0",
"",
"pyrNudger.ang0", argType::Required,
"pyrNudger0",
"ang0",
false,
"float",
"");
440 config.add(
"pyrNudger.parity",
"",
"pyrNudger.parity", argType::Required,
"pyrNudger",
"parity",
false,
"float",
"");
442 config.add(
"pyrNudger.F_sign",
"",
"pyrNudger.F_sign", argType::Required,
"pyrNudger",
"F_sign",
false,
"int",
"Pyramid to AEG control matrix [1,1] of a 2x2 matrix ");
444 config.add(
"acqFromGuider.zdSign",
"",
"acqFromGuider.zdSign", argType::Required,
"acqFromGuider",
"zdSign",
false,
"int",
"Sign of the Zd to rotation angle, +1 or -1, -1 default");
445 config.add(
"acqFromGuider.az0",
"",
"acqFromGuider.az0", argType::Required,
"acqFromGuider",
"az0",
false,
"float",
"az component of acquisition vector a 0 zd.");
446 config.add(
"acqFromGuider.azoff",
"",
"acqFromGuider.azoff", argType::Required,
"acqFromGuider",
"azoff",
false,
"float",
"static offset to az component of acquisition vector");
447 config.add(
"acqFromGuider.el0",
"",
"acqFromGuider.el0", argType::Required,
"acqFromGuider",
"el0",
false,
"float",
"el component of acquisition vector a 0 zd.");
448 config.add(
"acqFromGuider.eloff",
"",
"acqFromGuider.eloff", argType::Required,
"acqFromGuider",
"eloff",
false,
"float",
"static offset to el component of acquisition vector");
449 config.add(
"acqFromGuider.focus",
"",
"acqFromGuider.focus", argType::Required,
"acqFromGuider",
"focus",
false,
"float",
"static offset for focus acquisition");
451 config.add(
"offload.TT_avgInt",
"",
"offload.TT_avgInt", argType::Required,
"offload",
"TT_avgInt",
false,
"float",
"Woofer to Telescope T/T offload averaging interval [sec] ");
452 config.add(
"offload.TT_gain",
"",
"offload.TT_gain", argType::Required,
"offload",
"TT_gain",
false,
"float",
"Woofer to Telescope T/T offload gain");
453 config.add(
"offload.TT_thresh",
"",
"offload.TT_thresh", argType::Required,
"offload",
"TT_thresh",
false,
"float",
"Woofer to Telescope T/T offload threshold");
455 config.add(
"offload.lab_TT_C_00",
"",
"offload.lab_TT_C_00", argType::Required,
"offload",
"lab_TT_C_00",
false,
"float",
"Woofer to TTM T/T offload control matrix [0,0] of a 2x2 matrix");
456 config.add(
"offload.lab_TT_C_01",
"",
"offload.lab_TT_C_01", argType::Required,
"offload",
"lab_TT_C_01",
false,
"float",
"Woofer to TTM T/T offload control matrix [0,1] of a 2x2 matrix ");
457 config.add(
"offload.lab_TT_C_10",
"",
"offload.lab_TT_C_10", argType::Required,
"offload",
"lab_TT_C_10",
false,
"float",
"Woofer to TTM T/T offload control matrix [1,0] of a 2x2 matrix ");
458 config.add(
"offload.lab_TT_C_11",
"",
"offload.lab_TT_C_11", argType::Required,
"offload",
"lab_TT_C_11",
false,
"float",
"Woofer to TTM T/T offload control matrix [1,1] of a 2x2 matrix ");
460 config.add(
"offload.TT_C_00",
"",
"offload.TT_C_00", argType::Required,
"offload",
"TT_C_00",
false,
"float",
"Woofer to Telescope T/T offload control matrix [0,0] of a 2x2 matrix");
461 config.add(
"offload.TT_C_01",
"",
"offload.TT_C_01", argType::Required,
"offload",
"TT_C_01",
false,
"float",
"Woofer to Telescope T/T offload control matrix [0,1] of a 2x2 matrix ");
462 config.add(
"offload.TT_C_10",
"",
"offload.TT_C_10", argType::Required,
"offload",
"TT_C_10",
false,
"float",
"Woofer to Telescope T/T offload control matrix [1,0] of a 2x2 matrix ");
463 config.add(
"offload.TT_C_11",
"",
"offload.TT_C_11", argType::Required,
"offload",
"TT_C_11",
false,
"float",
"Woofer to Telescope T/T offload control matrix [1,1] of a 2x2 matrix ");
466 config.add(
"offload.F_avgInt",
"",
"offload.F_avgInt", argType::Required,
"offload",
"F_avgInt",
false,
"float",
"Woofer to Telescope Focus offload averaging interval [sec] ");
467 config.add(
"offload.F_gain",
"",
"offload.F_gain", argType::Required,
"offload",
"F_gain",
false,
"float",
"Woofer to Telescope Focus offload gain");
468 config.add(
"offload.F_thresh",
"",
"offload.F_thresh", argType::Required,
"offload",
"F_thresh",
false,
"float",
"Woofer to Telescope Focus offload threshold");
470 config.add(
"offload.CFocus00",
"",
"offload.CFocus00", argType::Required,
"offload",
"CFocus00",
false,
"float",
"Woofer to Telescope Focus offload control scale factor.");
472 config.add(
"offload.CComa00",
"",
"offload.CComa00", argType::Required,
"offload",
"CComa00",
false,
"float",
"Woofer to Telescope Coma offload control matrix [0,0] of a 2x2 matrix");
473 config.add(
"offload.CComa01",
"",
"offload.CComa01", argType::Required,
"offload",
"CComa01",
false,
"float",
"Woofer to Telescope Coma offload control matrix [0,1] of a 2x2 matrix ");
474 config.add(
"offload.CComa10",
"",
"offload.CComa10", argType::Required,
"offload",
"CComa10",
false,
"float",
"Woofer to Telescope Coma offload control matrix [1,0] of a 2x2 matrix ");
475 config.add(
"offload.CComa11",
"",
"offload.CComa11", argType::Required,
"offload",
"CComa11",
false,
"float",
"Woofer to Telescope Coma offload control matrix [1,1] of a 2x2 matrix ");
477 config.add(
"device.address",
"",
"device.address", argType::Required,
"device",
"address",
false,
"string",
"The IP address or resolvable name of the TCS.");
478 config.add(
"device.port",
"",
"device.port", argType::Required,
"device",
"port",
false,
"int",
"The IP port for TCS communications. Should be the command port. Default is 5811.");
567 indi::addNumberElement<double>(
m_indiP_teltime,
"sidereal_time", 0, std::numeric_limits<double>::max(), 0,
"%0.6f");
572 indi::addNumberElement<double>(
m_indiP_telpos,
"epoch", 0, std::numeric_limits<double>::max(), 0,
"%0.6f");
574 indi::addNumberElement<double>(
m_indiP_telpos,
"ra", 0, 360, 0,
"%0.6f");
576 indi::addNumberElement<double>(
m_indiP_telpos,
"dec", -90, 90, 0,
"%0.6f");
578 indi::addNumberElement<double>(
m_indiP_telpos,
"el", 0, 90, 0,
"%0.6f");
580 indi::addNumberElement<double>(
m_indiP_telpos,
"ha", -180, 160, 0,
"%0.6f");
582 indi::addNumberElement<double>(
m_indiP_telpos,
"am", 0, 4, 0,
"%0.2f");
584 indi::addNumberElement<double>(
m_indiP_telpos,
"rotoff", 0, 360, 0,
"%0.6f");
593 indi::addNumberElement<int>(
m_indiP_teldata,
"tracking", 0, 1, 1,
"%d");
595 indi::addNumberElement<int>(
m_indiP_teldata,
"guiding", 0, 1, 1,
"%d");
597 indi::addNumberElement<int>(
m_indiP_teldata,
"slewing", 0, 1, 1,
"%d");
599 indi::addNumberElement<int>(
m_indiP_teldata,
"guider_moving", 0, 1, 1,
"%d");
601 indi::addNumberElement<double>(
m_indiP_teldata,
"az", 0, 360, 0,
"%0.6f");
603 indi::addNumberElement<double>(
m_indiP_teldata,
"zd", 0, 90, 0,
"%0.6f");
605 indi::addNumberElement<double>(
m_indiP_teldata,
"pa", 0, 360, 0,
"%0.6f");
607 indi::addNumberElement<double>(
m_indiP_teldata,
"dome_az", 0, 360, 0,
"%0.6f");
609 indi::addNumberElement<int>(
m_indiP_teldata,
"dome_stat", 0, 1, 1,
"%d");
622 indi::addNumberElement<double>(
m_indiP_catdata,
"ra", 0, 360, 0,
"%0.6f");
624 indi::addNumberElement<double>(
m_indiP_catdata,
"dec", -90, 90, 0,
"%0.6f");
626 indi::addNumberElement<double>(
m_indiP_catdata,
"epoch", 0, std::numeric_limits<double>::max(), 0,
"%0.6f");
628 indi::addNumberElement<double>(
m_indiP_catdata,
"rotoff", 0, 360, 0,
"%0.6f");
636 indi::addNumberElement<double>(
m_indiP_vaneend,
"secz", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
638 indi::addNumberElement<double>(
m_indiP_vaneend,
"encz", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
640 indi::addNumberElement<double>(
m_indiP_vaneend,
"secx", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
642 indi::addNumberElement<double>(
m_indiP_vaneend,
"encx", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
644 indi::addNumberElement<double>(
m_indiP_vaneend,
"secy", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
646 indi::addNumberElement<double>(
m_indiP_vaneend,
"ency", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
648 indi::addNumberElement<double>(
m_indiP_vaneend,
"sech", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
650 indi::addNumberElement<double>(
m_indiP_vaneend,
"ench", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
652 indi::addNumberElement<double>(
m_indiP_vaneend,
"secv", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
654 indi::addNumberElement<double>(
m_indiP_vaneend,
"encv", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.6f");
661 indi::addNumberElement<double>(
m_indiP_env,
"temp-out", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
663 indi::addNumberElement<double>(
m_indiP_env,
"pressure", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
665 indi::addNumberElement<double>(
m_indiP_env,
"humidity", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
667 indi::addNumberElement<double>(
m_indiP_env,
"wind", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
669 indi::addNumberElement<double>(
m_indiP_env,
"winddir", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
671 indi::addNumberElement<double>(
m_indiP_env,
"temp-truss", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
673 indi::addNumberElement<double>(
m_indiP_env,
"temp-cell", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
675 indi::addNumberElement<double>(
m_indiP_env,
"temp-seccell", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
677 indi::addNumberElement<double>(
m_indiP_env,
"temp-amb", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
679 indi::addNumberElement<double>(
m_indiP_env,
"dewpoint", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
685 indi::addNumberElement<unsigned>(
m_indiP_seeing,
"dimm_time", std::numeric_limits<unsigned>::lowest(), std::numeric_limits<unsigned>::max(), 0,
"%d");
687 indi::addNumberElement<double>(
m_indiP_seeing,
"dimm_el", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
689 indi::addNumberElement<double>(
m_indiP_seeing,
"dimm_fwhm", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
691 indi::addNumberElement<double>(
m_indiP_seeing,
"dimm_fwhm_corr", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
693 indi::addNumberElement<unsigned>(
m_indiP_seeing,
"mag1_time", std::numeric_limits<unsigned>::lowest(), std::numeric_limits<unsigned>::max(), 0,
"%d");
695 indi::addNumberElement<double>(
m_indiP_seeing,
"mag1_el", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
697 indi::addNumberElement<double>(
m_indiP_seeing,
"mag1_fwhm", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
699 indi::addNumberElement<double>(
m_indiP_seeing,
"mag1_fwhm_corr", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
701 indi::addNumberElement<unsigned>(
m_indiP_seeing,
"mag2_time", std::numeric_limits<unsigned>::lowest(), std::numeric_limits<unsigned>::max(), 0,
"%d");
703 indi::addNumberElement<double>(
m_indiP_seeing,
"mag2_el", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
705 indi::addNumberElement<double>(
m_indiP_seeing,
"mag2_fwhm", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
707 indi::addNumberElement<double>(
m_indiP_seeing,
"mag2_fwhm_corr", std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), 0,
"%0.2f");
875 std::stringstream
logs;
977 const std::string &statreq
985 #ifdef LOG_TCS_STATUS
1014 #ifdef LOG_TCS_STATUS
1032 #ifdef LOG_TCS_STATUS
1059 #ifdef LOG_TCS_STATUS
1070 std::vector<std::string>
vres;
1078 pos1 =
tdat.find_first_not_of(
" " , 0);
1080 if(pos1 == -1) pos1 = 0;
1082 pos2 =
tdat.find_first_of(
" ", pos1);
1086 tok =
tdat.substr(pos1, pos2-pos1);
1093 pos2 =
tdat.find_first_not_of(
" ", pos1);
1098 pos2 =
tdat.find_first_of(
" ", pos1);
1104 pos2 =
tdat.length();
1106 tok =
tdat.substr(pos1, pos2-pos1);
1108 pos2 =
tok.find_first_of(
" \n\r", 0);
1110 if(pos2 >= 0)
tok.erase(pos2,
tok.length()-pos2);
1122 const std::string & xmsstr
1133 if(
en == std::string::npos)
1151 catch(
const std::exception &
e)
1159 x = std::stod(
xstr);
1161 catch(
const std::exception &
e)
1168 if(std::signbit(x))
sgn = -1;
1176 if(
en == std::string::npos)
1194 catch(
const std::exception &
e)
1204 catch(
const std::exception &
e)
1223 catch(
const std::exception &
e)
1233 catch(
const std::exception &
e)
1247 std::vector<std::string>
pdat;
1266 if(
pdat.size() != 3)
1289 std::vector<std::string>
pdat;
1308 if(
pdat.size() != 6)
1361 std::vector<std::string>
tdat;
1379 if(
tdat.size() != 10)
1390 char bit[2] = {0,0};
1430 std::vector<std::string>
cdat;
1449 if(
cdat.size() != 6)
1453 if(
cdat.size() == 7)
1455 if(
cdat[6] ==
"Pointing")
1466 for(
size_t n = 0;
n <
cdat.size(); ++
n)
1468 std::cerr <<
n <<
" " <<
cdat[
n] <<
"\n";
1517 std::vector<std::string>
vedat;
1528 if(
vedat[0] ==
"-1")
1535 if(
vedat.size() != 10)
1566 std::vector<std::string>
edat;
1584 if(
edat.size() != 10)
1622 int rv =
system(
"query_seeing > /dev/null");
1638 fin.open(
"/tmp/dimm.tsv");
1661 if(
dt < 0)
dt = 86400-
dt;
1674 fin.open(
"/tmp/mag1.tsv");
1697 if(
dt < 0)
dt = 86400-
dt;
1710 fin.open(
"/tmp/mag2.tsv");
1733 if(
dt < 0)
dt = 86400-
dt;
2180 static double lastRA = 0;
2182 static double lastEl = 0;
2183 static double lastHA = 0;
2184 static double lastAM = 0;
2217 static double lastAz = 0;
2218 static double lastZd = 0;
2219 static double lastPA = 0;
2399 telem<telem_telsee>({
m_dimm_time,
m_dimm_el,
m_dimm_fwhm, -1,
m_mag1_time,
m_mag1_el,
m_mag1_fwhm,
m_mag1_fwhm_corr,
m_mag2_time,
m_mag2_el,
m_mag2_fwhm,
m_mag2_fwhm_corr});
2425 if(x != 0 || y != 0)
2499 t->offloadThreadExec();
2678 pcf::IndiProperty
ip(pcf::IndiProperty::Number);
2679 ip.setDevice(
"modwfs");
2680 ip.setName(
"offset12");
2681 ip.add(pcf::IndiElement(
"dC1"));
2682 ip.add(pcf::IndiElement(
"dC2"));
2752 if(!
ipRecv.find(
"toggle"))
2754 return log<
software_error,-1>({__FILE__,__LINE__,
"no toggle element"});
2759 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
2768 if(m_labMode == labMode)
2773 m_labMode = labMode;
2778 updateSwitchIfChanged(m_indiP_labMode,
"toggle", pcf::IndiElement::On,
INDI_OK);
2783 updateSwitchIfChanged(m_indiP_labMode,
"toggle", pcf::IndiElement::Off,
INDI_OK);
2799 x =
ipRecv[
"y"].get<
float>();
2804 y =
ipRecv[
"x"].get<
float>();
2809 z =
ipRecv[
"z"].get<
float>();
2812 return sendPyrNudge(x, y, z);
2819 if(!
ipRecv.find(
"request"))
2824 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2826 return acquireFromGuider();
2836 if(!
ipRecv.find(
"toggle"))
return 0;
2838 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
2854 if(m_loopState != 2)
return 0;
2856 size_t nextReq = m_lastRequest + 1;
2858 if(nextReq >= m_offloadRequests[0].size()) nextReq = 0;
2861 float tt0 =
ipRecv[
"00"].get<
float>();
2862 float tt1 =
ipRecv[
"01"].get<
float>();
2866 m_offloadRequests[0][nextReq] = m_lab_offlTT_C_00 * tt0 + m_lab_offlTT_C_01 * tt1;
2867 m_offloadRequests[1][nextReq] = m_lab_offlTT_C_10 * tt0 + m_lab_offlTT_C_11 * tt1;
2871 m_offloadRequests[0][nextReq] = m_offlTT_C_00 * tt0 + m_offlTT_C_01 * tt1;
2872 m_offloadRequests[1][nextReq] = m_offlTT_C_10 * tt0 + m_offlTT_C_11 * tt1;
2876 float f0 =
ipRecv[
"02"].get<
float>();
2878 m_offloadRequests[2][nextReq] = m_offlCFocus_00 * f0;
2882 float c0 =
ipRecv[
"03"].get<
float>();
2883 float c1 =
ipRecv[
"04"].get<
float>();
2885 m_offloadRequests[3][nextReq] = m_offlCComa_00 * c0 + m_offlCComa_01 * c1;
2886 m_offloadRequests[4][nextReq] = m_offlCComa_10 * c0 + m_offlCComa_11 * c1;
2889 m_lastRequest = nextReq;
2891 if(m_nRequests > m_offloadRequests[0].size()) ++m_firstRequest;
2892 if(m_firstRequest >= m_offloadRequests[0].size()) m_firstRequest = 0;
2900 if(
ipRecv.getName() != m_indiP_offlTTenable.getName())
2902 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
2906 if(!
ipRecv.find(
"toggle"))
return 0;
2908 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On && m_offlTT_enabled ==
false)
2910 updateSwitchIfChanged(m_indiP_offlTTenable,
"toggle", pcf::IndiElement::On,
INDI_OK);
2912 m_offlTT_enabled =
true;
2914 else if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off && m_offlTT_enabled ==
true)
2916 updateSwitchIfChanged(m_indiP_offlTTenable,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2918 m_offlTT_enabled =
false;
2929 if(!
ipRecv.find(
"request"))
return 0;
2931 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2933 updateSwitchIfChanged(m_indiP_offlTTdump,
"request", pcf::IndiElement::On,
INDI_OK);
2935 m_offlTT_dump =
true;
2948 if( indiTargetUpdate( m_indiP_offlTTavgInt, target,
ipRecv,
true) < 0)
2950 log<software_error>({__FILE__,__LINE__});
2954 m_offlTT_avgInt = target;
2965 if( indiTargetUpdate( m_indiP_offlTTgain, target,
ipRecv,
true) < 0)
2967 log<software_error>({__FILE__,__LINE__});
2971 m_offlTT_gain = target;
2982 if( indiTargetUpdate( m_indiP_offlTTthresh, target,
ipRecv,
true) < 0)
2984 log<software_error>({__FILE__,__LINE__});
2988 m_offlTT_thresh = target;
2998 if(!
ipRecv.find(
"toggle"))
return 0;
3000 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On && m_offlF_enabled ==
false)
3002 updateSwitchIfChanged(m_indiP_offlFenable,
"toggle", pcf::IndiElement::On,
INDI_OK);
3004 m_offlF_enabled =
true;
3006 else if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off && m_offlF_enabled ==
true)
3008 updateSwitchIfChanged(m_indiP_offlFenable,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
3010 m_offlF_enabled =
false;
3021 if(!
ipRecv.find(
"request"))
return 0;
3023 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
3025 updateSwitchIfChanged(m_indiP_offlFdump,
"request", pcf::IndiElement::On,
INDI_OK);
3027 m_offlF_dump =
true;
3040 if( indiTargetUpdate( m_indiP_offlFavgInt, target,
ipRecv,
true) < 0)
3042 log<software_error>({__FILE__,__LINE__});
3046 m_offlF_avgInt = target;
3057 if( indiTargetUpdate( m_indiP_offlFgain, target,
ipRecv,
true) < 0)
3059 log<software_error>({__FILE__,__LINE__});
3063 m_offlF_gain = target;
3074 std::cerr <<
"Got offl thresh\n";
3076 if( indiTargetUpdate( m_indiP_offlFthresh, target,
ipRecv,
true) < 0)
3078 log<software_error>({__FILE__,__LINE__});
3082 m_offlF_thresh = target;
The base-class for MagAO-X applications.
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI property element value if it has changed.
int createStandardIndiRequestSw(pcf::IndiProperty &prop, const std::string &name, const std::string &label="", const std::string &group="")
Create a standard R/W INDI switch with a single request element.
stateCodes::stateCodeT state()
Get the current state code.
int registerIndiPropertyNew(pcf::IndiProperty &prop, int(*)(void *, const pcf::IndiProperty &))
Register an INDI property which is exposed for others to request a New Property for.
int createStandardIndiToggleSw(pcf::IndiProperty &prop, const std::string &name, const std::string &label="", const std::string &group="")
Create a standard R/W INDI switch with a single toggle element.
int createStandardIndiNumber(pcf::IndiProperty &prop, const std::string &name, const T &min, const T &max, const T &step, const std::string &format, const std::string &label="", const std::string &group="")
Create a standard R/W INDI Number property with target and current elements.
int shutdown()
Get the value of the shutdown flag.
indiDriver< MagAOXApp > * m_indiDriver
The INDI driver wrapper. Constructed and initialized by execute, which starts and stops communication...
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI switch element value if it has changed.
int stateLogged()
Updates and returns the value of m_stateLogged. Will be 0 on first call after a state change,...
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
int createROIndiNumber(pcf::IndiProperty &prop, const std::string &propName, const std::string &propLabel="", const std::string &propGroup="")
Create a ReadOnly INDI Number property.
int registerIndiPropertyReadOnly(pcf::IndiProperty &prop)
Register an INDI property which is read only.
int createROIndiText(pcf::IndiProperty &prop, const std::string &propName, const std::string &elName, const std::string &propLabel="", const std::string &propGroup="", const std::string &elLabel="")
Create a standard ReadOnly INDI Text property, with at least one element.
int threadStart(std::thread &thrd, bool &thrdInit, pid_t &tpid, pcf::IndiProperty &thProp, int thrdPrio, const std::string &cpuset, const std::string &thrdName, thisPtr *thrdThis, Function &&thrdStart)
Start a thread, using this class's privileges to set priority, etc.
int sendNewProperty(const pcf::IndiProperty &ipSend, const std::string &el, const T &newVal)
Send a newProperty command to another device (using the INDI Client interface)
The MagAO-X Clay Telescope TCS Interface.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlFgain)
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlTTgain)
double m_dimm_el
DIMM elevation at time of seeing measurement.
pcf::IndiProperty m_indiP_offlTTdump
double m_wxdewpoint
Dew point from weather station.
int recordTelem(const telem_telpos *)
virtual int appLogic()
Implementation of the FSM for tcsInterface.
pcf::IndiProperty m_indiP_offlFgain
pcf::IndiProperty m_indiP_acqFromGuider
Property used to request a pyramid nudge.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlTTthresh)
~tcsInterface() noexcept
D'tor, declared and defined for noexcept.
pcf::IndiProperty m_indiP_seeing
INDI Property for seeing.
double m_mag1_fwhm
MAG1 raw FWHM.
double m_telDomeAz
dome azimuth
int m_telGuiding
guider moving state
int sendMagTelCommand(const std::string &command, int timeout)
int recordTelCat(bool force=false)
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlFavgInt)
double m_catRA
Catalog right ascension [degrees].
pcf::IndiProperty m_indiP_teltime
double m_mag1_el
MAG1 elevation at time of seeing measurement.
double m_dimm_fwhm_corr
DIMM elevation corrected FWHM.
pcf::IndiProperty m_indiP_labMode
int m_telGuiderMoving
guider moving state
pcf::IndiProperty m_indiP_env
INDI Property for environment.
int sendTToffload(float TT_0, float TT_1)
pcf::IndiProperty m_indiP_pyrNudge
Property used to request a pyramid nudge.
int recordTelPos(bool force=false)
int recordTelEnv(bool force=false)
pcf::IndiProperty m_indiP_telpos
int recordTelData(bool force=false)
double m_telPA
parallactic angle
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlTTenable)
double m_wxpres
Outside pressue, millibars.
std::string m_catObj
Catalog object name.
int m_mag2_time
Seconds since midnight of MAG2 measurement.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlFthresh)
pcf::IndiProperty m_indiP_offloadCoeffs
Property used to report the latest woofer modal coefficients for offloading.
pcf::IndiProperty m_offloadThreadProp
Offload thread INDI property.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_pyrNudge)
pcf::IndiProperty m_indiP_offlTTgain
pcf::IndiProperty m_indiP_catdata
INDI Property for the catalog data.
bool m_offloadThreadInit
Initialization flag for the offload thread.
int m_mag1_time
Seconds since midnight of MAG1 measurement.
double m_mag2_el
MAG2 elevation at time of seeing measurement.
std::thread m_offloadThread
The offloading thread.
double m_telZd
zenith distance
friend class tcsInterface_test
void offloadThreadExec()
Offload thread function.
int getMagTelStatus(std::string &response, const std::string &statreq)
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlFdump)
virtual void loadConfig()
double m_catDec
Catalog declination [degrees].
double m_wxwind
outside wind intensity, mph
pcf::IndiProperty m_indiP_teldata
int parse_xms(double &x, double &m, double &s, const std::string &xmsstr)
int m_devicePort
The IP port for TCS communications. Should be the command port. Default is 5811.
std::mutex m_tcsMutex
Mutex for locking TCS communications.
double m_mag2_fwhm_corr
MAG2 elevation corrected FWHM.
double m_tcell
Primary mirror cell temperature, Celsius.
double m_mag1_fwhm_corr
MAG1 elevation corrected FWHM.
virtual void setupConfig()
std::string m_deviceAddr
The IP address or resolvable name of the TCS.
pid_t m_offloadThreadID
Offload thread pid.
pcf::IndiProperty m_indiP_vaneend
INDI Property for the vane end positions.
std::string m_catRm
Catalog rotator mode.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_acqFromGuider)
pcf::IndiProperty m_indiP_offlFenable
INDI_SETCALLBACK_DECL(tcsInterface, m_indiP_offloadCoeffs)
int m_dimm_time
Seconds since midnight of DIMM measurement.
pcf::IndiProperty m_indiP_offlFdump
double m_catEp
Catalog epoch.
double m_tambient
Dome air temperature, Celsius.
tcsInterface()
Default c'tor.
int sendFoffload(float F_0)
pcf::IndiProperty m_indiP_offlTTenable
double m_ttruss
Telescope truss temperature, Celsius.
int doTToffload(float TT_0, float TT_1)
pcf::IndiProperty m_indiP_catalog
INDI Property for the catalog text information.
double m_wxhumid
Outside humidity, percent.
virtual int appStartup()
Startup function.
int recordTelVane(bool force=false)
virtual int appShutdown()
Shutdown the app.
int recordTelSee(bool force=false)
int doFoffload(float F_0)
int m_telDomeStat
dome status
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
int m_telSlewing
slewing state
int m_telROI
The rotator of interest.
int m_telTracking
tracking state
double m_catRo
Catalog rotator offset.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlFenable)
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_labMode)
double m_wxtemp
Outside temperature, Celsius.
pcf::IndiProperty m_indiP_offlTTavgInt
double m_dimm_fwhm
DIMM raw FWHM.
static void offloadThreadStart(tcsInterface *t)
Offload thread starter function.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlTTdump)
pcf::IndiProperty m_indiP_loopState
Property used to report the loop state.
INDI_NEWCALLBACK_DECL(tcsInterface, m_indiP_offlTTavgInt)
double m_mag2_fwhm
MAG2 raw FWHM.
double m_wxwdir
outside wind direction, degrees
double m_tseccell
Secondary mirror cell temperature, Celsius.
pcf::IndiProperty m_indiP_offlFavgInt
std::vector< std::string > parse_teldata(std::string &tdat)
pcf::IndiProperty m_indiP_offlFthresh
pcf::IndiProperty m_indiP_offlTTthresh
std::vector< std::vector< float > > m_offloadRequests
int sendPyrNudge(float x, float y, float z)
INDI_SETCALLBACK_DECL(tcsInterface, m_indiP_loopState)
#define INDI_NEWCALLBACK_DEFN(class, prop)
Define the callback for a new property request.
#define CREATE_REG_INDI_NEW_TOGGLESWITCH(prop, name)
Create and register a NEW INDI property as a standard toggle switch, using the standard callback name...
#define REG_INDI_NEWPROP(prop, propName, type)
Register a NEW INDI property with the class, using the standard callback name.
#define INDI_SETCALLBACK_DEFN(class, prop)
Define the callback for a set property request.
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
@ ERROR
The application has encountered an error, from which it is recovering (with or without intervention)
@ CONNECTED
The application has connected to the device or service.
@ NOTCONNECTED
The application is not connected to the device or service.
std::string ttyErrorString(int ec)
Get a text explanation of a TTY_E_ error code.
#define INDI_VALIDATE_CALLBACK_PROPS(prop1, prop2)
Standard check for matching INDI properties in a callback.
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &newVal, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the value of the INDI element, but only if it has changed.
const pcf::IndiProperty & ipRecv
static constexpr logPrioT LOG_NOTICE
A normal but significant condition.
static constexpr logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
static constexpr logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
#define NETSERIAL_E_NOERROR
An input/output capable device.
int loadConfig(mx::app::appConfigurator &config)
Load the device section from an application configurator.
int appStartup()
Perform application startup steps specific to an ioDevice.
int setupConfig(mx::app::appConfigurator &config)
Setup an application configurator for the device section.
unsigned m_readTimeout
The read timeout [msec].
A device base class which saves telemetry.
int loadConfig(appConfigurator &config)
Load the device section from an application configurator.
int setupConfig(appConfigurator &config)
Setup an application configurator for the device section.
Log entry recording the build-time git state.
Log entry recording the build-time git state.
Log entry recording the build-time git state.
Log entry recording the build-time git state.
Log entry recording the build-time git state.
Log entry recording the build-time git state.
Manage a connectio to a serial device over a network.
int serialOut(const char *buf, int len)
int serialInString(char *buf, int len, int timeout, char terminator)
int serialInit(const char *address, int port)