diff --git a/drivers/focuser/celestron.cpp b/drivers/focuser/celestron.cpp index ba590f0fbe..670947456a 100644 --- a/drivers/focuser/celestron.cpp +++ b/drivers/focuser/celestron.cpp @@ -34,11 +34,14 @@ static std::unique_ptr celestronSCT(new CelestronSCT()); CelestronSCT::CelestronSCT() : + truePosMax(0xffffffff), + truePosMin(0), backlashMove(false), finalPosition(0), calibrateInProgress(false), calibrateState(0), focuserIsCalibrated(false) + { // Can move in Absolute & Relative motions, can AbortFocuser motion. // CR variable speed and sync removed @@ -63,10 +66,10 @@ bool CelestronSCT::initProperties() // IUFillNumberVector(&FocusBacklashNP, FocusBacklashN, 1, getDeviceName(), "FOCUS_BACKLASH", "Backlash", // MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE); - // Focuser min limit - IUFillNumber(&FocusMinPosN[0], "FOCUS_MIN_VALUE", "Steps", "%.f", 0, 40000., 1., 0.); - IUFillNumberVector(&FocusMinPosNP, FocusMinPosN, 1, getDeviceName(), "FOCUS_MIN", "Min. Position", - MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE); + // // Focuser min limit + // IUFillNumber(&FocusMinPosN[0], "FOCUS_MIN_VALUE", "Steps", "%.f", 0, 40000., 1., 0.); + // IUFillNumberVector(&FocusMinPosNP, FocusMinPosN, 1, getDeviceName(), "FOCUS_MIN", "Min. Position", + // MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE); // focuser calibration IUFillSwitch(&CalibrateS[0], "START", "Start Calibration", ISS_OFF); @@ -131,7 +134,7 @@ bool CelestronSCT::updateProperties() { //defineProperty(&FocusBacklashNP); - defineProperty(&FocusMinPosNP); + // defineProperty(&FocusMinPosNP); defineProperty(&CalibrateSP); defineProperty(&CalibrateStateTP); @@ -145,7 +148,7 @@ bool CelestronSCT::updateProperties() else { //deleteProperty(FocusBacklashNP.name); - deleteProperty(FocusMinPosNP.name); + // deleteProperty(FocusMinPosNP.name); deleteProperty(CalibrateSP.name); deleteProperty(CalibrateStateTP.name); } @@ -194,9 +197,9 @@ bool CelestronSCT::readPosition() if (!communicator.sendCommand(PortFD, Aux::Target::FOCUSER, Aux::Command::MC_GET_POSITION, reply)) return false; - int position = (reply[0] << 16) + (reply[1] << 8) + reply[2]; - LOGF_DEBUG("Position %i", position); - FocusAbsPosN[0].value = position; + int truePos = (reply[0] << 16) + (reply[1] << 8) + reply[2]; + LOGF_DEBUG("True Position %i", truePos); + FocusAbsPosN[0].value = absPos(truePos); return true; } @@ -215,34 +218,29 @@ bool CelestronSCT::readLimits() if(!communicator.sendCommand(PortFD, Aux::Target::FOCUSER, Aux::Command::FOC_GET_HS_POSITIONS, reply)) return false; - int lo = (reply[0] << 24) + (reply[1] << 16) + (reply[2] << 8) + reply[3]; - int hi = (reply[4] << 24) + (reply[5] << 16) + (reply[6] << 8) + reply[7]; + truePosMin = (reply[0] << 24) + (reply[1] << 16) + (reply[2] << 8) + reply[3]; + truePosMax = (reply[4] << 24) + (reply[5] << 16) + (reply[6] << 8) + reply[7]; - FocusAbsPosN[0].max = hi; - FocusAbsPosN[0].min = lo; - FocusAbsPosNP.s = IPS_OK; - IUUpdateMinMax(&FocusAbsPosNP); + // check on integrity of values + if (truePosMax <= truePosMin){ + focuserIsCalibrated = false; + LOGF_INFO("Focus range %i to %i invalid", truePosMin, truePosMax); + return false; + } - FocusMaxPosN[0].value = hi; + // absolute direction is reverse from true + FocusAbsPosN[0].max = FocusMaxPosN[0].value = absPos(truePosMin); + FocusAbsPosNP.s = IPS_OK; FocusMaxPosNP.s = IPS_OK; + IUUpdateMinMax(&FocusAbsPosNP); IDSetNumber(&FocusMaxPosNP, nullptr); - FocusMinPosN[0].value = lo; - FocusMinPosNP.s = IPS_OK; - IDSetNumber(&FocusMinPosNP, nullptr); + // FocusMinPosN[0].value = lo; + // FocusMinPosNP.s = IPS_OK; + // IDSetNumber(&FocusMinPosNP, nullptr); - // check on integrity of values, they must be sensible and the range must be more than 2 turns - if (hi > 0 && lo > 0 && hi - lo > 2000 && hi <= 60000 && lo < 50000) - { - focuserIsCalibrated = true; - LOGF_INFO("Focus range %i to %i valid", hi, lo); - } - else - { - focuserIsCalibrated = false; - LOGF_INFO("Focus range %i to %i invalid", hi, lo); - return false; - } + focuserIsCalibrated = true; + LOGF_INFO("Focus range %i to %i valid", truePosMin, truePosMax); return true; } @@ -333,8 +331,9 @@ IPState CelestronSCT::MoveAbsFocuser(uint32_t targetTicks) } // the focuser seems happy to move 500 steps past the soft limit so don't check backlash - if (targetTicks > FocusMaxPosN[0].value || - targetTicks < FocusMinPosN[0].value) + if (targetTicks > FocusMaxPosN[0].value) + // targetTicks < FocusMinPosN[0].value) + { LOGF_ERROR("Move to %i not allowed because it is out of range", targetTicks); return IPS_ALERT; @@ -358,8 +357,11 @@ IPState CelestronSCT::MoveAbsFocuser(uint32_t targetTicks) return IPS_BUSY; } -bool CelestronSCT::startMove(uint32_t position) +bool CelestronSCT::startMove(uint32_t absPos) { + + int position = truePos(absPos); + Aux::buffer data = { static_cast((position >> 16) & 0xFF), @@ -367,7 +369,7 @@ bool CelestronSCT::startMove(uint32_t position) static_cast(position & 0xFF) }; - LOGF_DEBUG("startMove %i, %x %x %x", position, data[0], data[1], data[2]); + LOGF_DEBUG("startMove to true position %i, %x %x %x", position, data[0], data[1], data[2]); return communicator.commandBlind(PortFD, Aux::Target::FOCUSER, Aux::Command::MC_GOTO_FAST, data); } @@ -461,7 +463,7 @@ void CelestronSCT::TimerHit() { IUUpdateMinMax(&FocusAbsPosNP); IDSetNumber(&FocusMaxPosNP, nullptr); - IDSetNumber(&FocusMinPosNP, nullptr); + // IDSetNumber(&FocusMinPosNP, nullptr); } } else diff --git a/drivers/focuser/celestron.h b/drivers/focuser/celestron.h index 12956e3ddd..c41e568439 100644 --- a/drivers/focuser/celestron.h +++ b/drivers/focuser/celestron.h @@ -82,6 +82,18 @@ class CelestronSCT : public INDI::Focuser // Get initial focuser parameters when we first connect bool getStartupParameters(); + // truePos vs absPos: + // servo encoder values increase in CCW direction + // CCW travel moves primary mirror toward corrector plate, shifting focal plane away from OTA (i.e. increasingly "inside focus") + // max CCW travel corresponds to intrafocal limit + + // "absPos" is the position referenced to the INDI focus interface (0 = intrafocal limit, increasing values toward extrafocal limit) + inline uint32_t absPos(uint32_t truePos) { return truePosMax - truePos;} + + // "truePos" is the position of the servo motor encoder reported over serial connection + inline uint32_t truePos(uint32_t absPos) { return truePosMax - absPos;} + + /////////////////////////////////////////////////////////////////////////////// /// Read Data From Controller /////////////////////////////////////////////////////////////////////////////// @@ -103,8 +115,11 @@ class CelestronSCT : public INDI::Focuser // INumber BacklashN[1]; // INumberVectorProperty BacklashNP; - INumber FocusMinPosN[1]; - INumberVectorProperty FocusMinPosNP; + // INumber FocusMinPosN[1]; + // INumberVectorProperty FocusMinPosNP; + + uint32_t truePosMax; + uint32_t truePosMin; bool backlashMove; // set if a final move is needed uint32_t finalPosition; diff --git a/drivers/telescope/celestrongps.cpp b/drivers/telescope/celestrongps.cpp index 58a4241d62..b0eab20312 100644 --- a/drivers/telescope/celestrongps.cpp +++ b/drivers/telescope/celestrongps.cpp @@ -77,6 +77,9 @@ CelestronGPS::CelestronGPS() : FI(this) // focuser FI::SetCapability(FOCUSER_CAN_ABS_MOVE | FOCUSER_CAN_REL_MOVE | FOCUSER_CAN_ABORT | FOCUSER_HAS_BACKLASH); + focusTrueMax = 0; + focusTrueMin = 0xffffffff; + // Set minimum properties. // ISGetProperties in INDI::Telescope checks for CanGOTO which must be set. SetTelescopeCapability(TELESCOPE_CAN_GOTO | TELESCOPE_CAN_ABORT, 9); @@ -230,9 +233,9 @@ bool CelestronGPS::initProperties() // FOCUS_TAB, IP_RW, 0, IPS_IDLE); // Focuser min limit, read from the hardware - IUFillNumber(&FocusMinPosN[0], "FOCUS_MIN_VALUE", "Steps", "%.f", 0, 40000., 1., 0.); - IUFillNumberVector(&FocusMinPosNP, FocusMinPosN, 1, getDeviceName(), "FOCUS_MIN", "Min. Position", - FOCUS_TAB, IP_RO, 0, IPS_IDLE); + // IUFillNumber(&FocusMinPosN[0], "FOCUS_MIN_VALUE", "Steps", "%.f", 0, 40000., 1., 0.); + // IUFillNumberVector(&FocusMinPosNP, FocusMinPosN, 1, getDeviceName(), "FOCUS_MIN", "Min. Position", + // FOCUS_TAB, IP_RO, 0, IPS_IDLE); return true; } @@ -492,13 +495,14 @@ bool CelestronGPS::updateProperties() if (fwInfo.hasFocuser) { //defineProperty(&FocusBacklashNP); - defineProperty(&FocusMinPosNP); + //defineProperty(&FocusMinPosNP); + if (focusReadLimits()) { IUUpdateMinMax(&FocusAbsPosNP); IDSetNumber(&FocusMaxPosNP, nullptr); - IDSetNumber(&FocusMinPosNP, nullptr); + // IDSetNumber(&FocusMinPosNP, nullptr); // focuser move capability is only set if the focus limits are valid FI::SetCapability(FOCUSER_CAN_ABS_MOVE | FOCUSER_CAN_REL_MOVE | FOCUSER_CAN_ABORT); setDriverInterface(getDriverInterface() | FOCUSER_INTERFACE); @@ -518,7 +522,7 @@ bool CelestronGPS::updateProperties() INDI::Telescope::updateProperties(); FI::updateProperties(); - deleteProperty(FocusMinPosNP.name); + //deleteProperty(FocusMinPosNP.name); //GUIDE Delete properties. deleteProperty(GuideNSNP.name); @@ -955,10 +959,10 @@ bool CelestronGPS::ReadScopeStatus() // Check position double lastPosition = FocusAbsPosN[0].value; - int pos = driver.foc_position(); - if (pos >= 0) + int absPos = focusTrue2Abs(driver.foc_position()); + if (absPos >= 0) { - FocusAbsPosN[0].value = pos; + FocusAbsPosN[0].value = absPos; // Only update if there is actual change if (fabs(lastPosition - FocusAbsPosN[0].value) > 1) IDSetNumber(&FocusAbsPosNP, nullptr); @@ -975,8 +979,8 @@ bool CelestronGPS::ReadScopeStatus() if (focusBacklashMove) { focusBacklashMove = false; - if (driver.foc_move(focusPosition)) - LOGF_INFO("Focus final move %i", focusPosition); + if (driver.foc_move(focusAbs2True(focusAbsPosition))) + LOGF_INFO("Focus final move %i", focusAbsPosition); else LOG_INFO("Backlash move failed"); } @@ -1640,7 +1644,7 @@ bool CelestronGPS::saveConfigItems(FILE *fp) IUSaveConfigSwitch(fp, &CelestronTrackModeSP); IUSaveConfigSwitch(fp, &DSTSettingSP); - IUSaveConfigNumber(fp, &FocusMinPosNP); + // IUSaveConfigNumber(fp, &FocusMinPosNP); return true; } @@ -2024,7 +2028,7 @@ bool CelestronGPS::savePecData() // focus control IPState CelestronGPS::MoveAbsFocuser(uint32_t targetTicks) { - uint32_t position = targetTicks; + uint32_t absPosition = targetTicks; if (!focuserIsCalibrated) { @@ -2039,13 +2043,13 @@ IPState CelestronGPS::MoveAbsFocuser(uint32_t targetTicks) (FocusBacklashN[0].value > 0 && delta < 0)) { focusBacklashMove = true; - focusPosition = position; - position -= FocusBacklashN[0].value; + focusAbsPosition = absPosition; + absPosition -= FocusBacklashN[0].value; } - LOGF_INFO("Focus %s move %d", focusBacklashMove ? "backlash" : "direct", position); + LOGF_INFO("Focus %s move %d", focusBacklashMove ? "backlash" : "direct", absPosition); - if(!driver.foc_move(position)) + if(!driver.foc_move(focusAbs2True(absPosition))) return IPS_ALERT; return IPS_BUSY; @@ -2076,18 +2080,19 @@ bool CelestronGPS::focusReadLimits() int low, high; bool valid = driver.foc_limits(&low, &high); - FocusAbsPosN[0].max = high; - FocusAbsPosN[0].min = low; + focusTrueMax = high; + focusTrueMin = low; + + FocusAbsPosN[0].max = FocusMaxPosN[0].value = focusTrue2Abs(focusTrueMin); FocusAbsPosNP.s = IPS_OK; IUUpdateMinMax(&FocusAbsPosNP); - FocusMaxPosN[0].value = high; FocusMaxPosNP.s = IPS_OK; IDSetNumber(&FocusMaxPosNP, nullptr); - FocusMinPosN[0].value = low; - FocusMinPosNP.s = IPS_OK; - IDSetNumber(&FocusMinPosNP, nullptr); + // FocusMinPosN[0].value = low; + // FocusMinPosNP.s = IPS_OK; + // IDSetNumber(&FocusMinPosNP, nullptr); focuserIsCalibrated = valid; diff --git a/drivers/telescope/celestrongps.h b/drivers/telescope/celestrongps.h index 59d3ede720..6509b33365 100644 --- a/drivers/telescope/celestrongps.h +++ b/drivers/telescope/celestrongps.h @@ -190,11 +190,18 @@ class CelestronGPS : public INDI::Telescope, public INDI::GuiderInterface, publi // INumber FocusBacklashN[1]; // INumberVectorProperty FocusBacklashNP; - INumber FocusMinPosN[1]; - INumberVectorProperty FocusMinPosNP; + // INumber FocusMinPosN[1]; + // INumberVectorProperty FocusMinPosNP; bool focusBacklashMove; // set if a final move is needed - uint32_t focusPosition; + uint32_t focusAbsPosition; bool focusReadLimits(); bool focuserIsCalibrated; + + uint32_t focusTrueMax; + uint32_t focusTrueMin; + + inline uint32_t focusTrue2Abs(uint32_t truePos) {return focusTrueMax - truePos;} + inline uint32_t focusAbs2True(uint32_t absPos) {return focusTrueMax - absPos;} + };