Skip to content

Commit

Permalink
SCT focuser interface compliance (#2026) (#2031)
Browse files Browse the repository at this point in the history
  • Loading branch information
ijessen authored Mar 20, 2024
1 parent 24bc019 commit dcaa4ce
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 64 deletions.
74 changes: 38 additions & 36 deletions drivers/focuser/celestron.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@
static std::unique_ptr<CelestronSCT> 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
Expand All @@ -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);
Expand Down Expand Up @@ -131,7 +134,7 @@ bool CelestronSCT::updateProperties()
{
//defineProperty(&FocusBacklashNP);

defineProperty(&FocusMinPosNP);
// defineProperty(&FocusMinPosNP);

defineProperty(&CalibrateSP);
defineProperty(&CalibrateStateTP);
Expand All @@ -145,7 +148,7 @@ bool CelestronSCT::updateProperties()
else
{
//deleteProperty(FocusBacklashNP.name);
deleteProperty(FocusMinPosNP.name);
// deleteProperty(FocusMinPosNP.name);
deleteProperty(CalibrateSP.name);
deleteProperty(CalibrateStateTP.name);
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -358,16 +357,19 @@ 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<uint8_t>((position >> 16) & 0xFF),
static_cast<uint8_t>((position >> 8) & 0xFF),
static_cast<uint8_t>(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);
}
Expand Down Expand Up @@ -461,7 +463,7 @@ void CelestronSCT::TimerHit()
{
IUUpdateMinMax(&FocusAbsPosNP);
IDSetNumber(&FocusMaxPosNP, nullptr);
IDSetNumber(&FocusMinPosNP, nullptr);
// IDSetNumber(&FocusMinPosNP, nullptr);
}
}
else
Expand Down
19 changes: 17 additions & 2 deletions drivers/focuser/celestron.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
///////////////////////////////////////////////////////////////////////////////
Expand All @@ -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;
Expand Down
51 changes: 28 additions & 23 deletions drivers/telescope/celestrongps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -518,7 +522,7 @@ bool CelestronGPS::updateProperties()
INDI::Telescope::updateProperties();

FI::updateProperties();
deleteProperty(FocusMinPosNP.name);
//deleteProperty(FocusMinPosNP.name);

//GUIDE Delete properties.
deleteProperty(GuideNSNP.name);
Expand Down Expand Up @@ -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);
Expand All @@ -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");
}
Expand Down Expand Up @@ -1640,7 +1644,7 @@ bool CelestronGPS::saveConfigItems(FILE *fp)
IUSaveConfigSwitch(fp, &CelestronTrackModeSP);
IUSaveConfigSwitch(fp, &DSTSettingSP);

IUSaveConfigNumber(fp, &FocusMinPosNP);
// IUSaveConfigNumber(fp, &FocusMinPosNP);

return true;
}
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
13 changes: 10 additions & 3 deletions drivers/telescope/celestrongps.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;}

};

0 comments on commit dcaa4ce

Please sign in to comment.