From 62ab8c22bec268b2e0687ace63ce7148825fb428 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Jan 2023 18:37:44 +0000 Subject: add tracking rate control to lxd650, make tracking on celestron configurable --- indi-celestronaux/celestronaux.cpp | 71 ++++++++++++++----- indi-celestronaux/celestronaux.h | 2 + indi-lxd650/lxd650.cpp | 136 +++++++++++++++++++++++++++++-------- indi-lxd650/lxd650.h | 32 ++++++--- 4 files changed, 183 insertions(+), 58 deletions(-) diff --git a/indi-celestronaux/celestronaux.cpp b/indi-celestronaux/celestronaux.cpp index 51583ad..ccf15a0 100644 --- a/indi-celestronaux/celestronaux.cpp +++ b/indi-celestronaux/celestronaux.cpp @@ -788,6 +788,8 @@ bool CelestronAUX::ISNewSwitch(const char *dev, const char *name, ISState *state TrackMethodSP.update(states, names, n); TrackMethodSP.setState(IPS_OK); TrackMethodSP.apply(); + + track_method_changed(); return true; } @@ -797,6 +799,8 @@ bool CelestronAUX::ISNewSwitch(const char *dev, const char *name, ISState *state DriverTrackMethodSP.update(states, names, n); DriverTrackMethodSP.setState(IPS_OK); DriverTrackMethodSP.apply(); + + track_method_changed(); return true; } @@ -1213,8 +1217,9 @@ bool CelestronAUX::ReadScopeStatus() // For equatorial mounts, engage tracking. if ((TrackMethodSP[TRACK_METHOD_MOUNT].getState() == ISS_ON) && \ - (MountTypeSP[EQUATORIAL].getState() == ISS_ON)) - SetTrackMode(IUFindOnSwitchIndex(&TrackModeSP)); + (MountTypeSP[EQUATORIAL].getState() == ISS_ON)) + SetTrackMode(IUFindOnSwitchIndex(&TrackModeSP)); + LOG_INFO("Tracking started."); } else @@ -1496,7 +1501,9 @@ void CelestronAUX::calculate_tracking_vector(double &mt_ra, double &mt_dec) double delta = 1./3600.; double ra1 = m_SkyTrackingTarget.rightascension; double ra2 = ra1 + delta; - double dec= m_SkyTrackingTarget.declination; + double dec = m_SkyTrackingTarget.declination; + int mode = IUFindOnSwitchIndex(&TrackModeSP); + double rate = 0.0; TelescopeDirectionVector TDV; INDI::IEquatorialCoordinates m1 { ra1, dec }; @@ -1528,8 +1535,15 @@ void CelestronAUX::calculate_tracking_vector(double &mt_ra, double &mt_dec) int d_a1 = e2[0] - e1[0]; int d_a2 = e2[1] - e1[1]; - r_ra *= TRACKRATE_SIDEREAL; - r_dec *= TRACKRATE_SIDEREAL * (24. / 360.); + if (mode == TRACK_SIDEREAL) + rate = TRACKRATE_SIDEREAL; + else if (mode == TRACK_SOLAR) + rate = TRACKRATE_SOLAR; + else if (mode == TRACK_LUNAR) + rate = TRACKRATE_LUNAR; + + r_ra *= rate; + r_dec *= rate * (24. / 360.); mt_ra = std::abs(r_ra); mt_dec = std::abs(r_dec); @@ -1668,23 +1682,23 @@ void CelestronAUX::TimerHit() trackByRate(AXIS_ALT, trackRates[AXIS_ALT]); } } else if (TrackMethodSP[TRACK_METHOD_DRIVER].getState() == ISS_ON) { - double r_ra, r_dec; + double r_ra, r_dec; - calculate_tracking_vector(r_ra, r_dec); + calculate_tracking_vector(r_ra, r_dec); - if ((TrackRateN[AXIS_AZ].value != r_ra) || (TrackRateN[AXIS_ALT].value != r_dec)) { + if ((TrackRateN[AXIS_AZ].value != r_ra) || (TrackRateN[AXIS_ALT].value != r_dec)) { TrackRateN[AXIS_AZ].value = r_ra; TrackRateN[AXIS_ALT].value = r_dec; - IDSetNumber(&TrackRateNP, nullptr); + IDSetNumber(&TrackRateNP, nullptr); } #if 0 if (IUFindOnSwitchIndex(&TrackModeSP) != TRACK_CUSTOM) { - IUResetSwitch(&TrackModeSP); - TrackModeS[TRACK_CUSTOM].s=ISS_ON; - TrackModeSP.s = IPS_ALERT; - IDSetSwitch(&TrackModeSP, nullptr); - } + IUResetSwitch(&TrackModeSP); + TrackModeS[TRACK_CUSTOM].s=ISS_ON; + TrackModeSP.s = IPS_ALERT; + IDSetSwitch(&TrackModeSP, nullptr); + } #endif CelestronAUX::SetTrackRate(r_ra, r_dec); @@ -1712,6 +1726,28 @@ void CelestronAUX::TimerHit() } } + +bool CelestronAUX::track_method_changed(void) +{ + if (TrackState != SCOPE_TRACKING) return false; + + if (TrackMethodSP[TRACK_METHOD_MOUNT].getState() == ISS_ON) { + if (IUFindOnSwitchIndex(&TrackModeSP) == TRACK_CUSTOM) + return SetTrackRate(TrackRateN[AXIS_AZ].value, TrackRateN[AXIS_ALT].value); + else + return SetTrackMode(IUFindOnSwitchIndex(&TrackModeSP)); + } + + if (TrackMethodSP[TRACK_METHOD_NONE].getState() == ISS_ON) { + syslog_proxy("CelestronAUX::trackByRate 0 0"); + trackByRate(AXIS_AZ, 0); + trackByRate(AXIS_ALT, 0); + return true; + } + + return true; +} + ///////////////////////////////////////////////////////////////////////////////////// /// ///////////////////////////////////////////////////////////////////////////////////// @@ -2228,6 +2264,7 @@ bool CelestronAUX::SetTrackEnabled(bool enabled) else { TrackState = SCOPE_IDLE; + syslog_proxy("CelestronAUX::trackByRate 0 0"); trackByRate(AXIS_AZ, 0); trackByRate(AXIS_ALT, 0); @@ -2256,7 +2293,7 @@ bool CelestronAUX::SetTrackRate(double raRate, double deRate) // rate = (steps) * gain steps[AXIS_AZ] = raRate * STEPS_PER_ARCSEC * GAIN_STEPS; steps[AXIS_ALT] = deRate * STEPS_PER_ARCSEC * GAIN_STEPS; - syslog_proxy("CelestronAUX::trackByRate %.2f %.2f", steps[AXIS_AZ], step[AXIS_ALT]); + syslog_proxy("CelestronAUX::trackByRate %.2f %.2f", steps[AXIS_AZ], steps[AXIS_ALT]); trackByRate(AXIS_AZ, steps[AXIS_AZ]); trackByRate(AXIS_ALT, steps[AXIS_ALT]); } @@ -2289,7 +2326,7 @@ bool CelestronAUX::SetTrackMode(uint8_t mode) // rate = (steps) * gain steps[AXIS_AZ] = m_TrackRates[AXIS_AZ] * STEPS_PER_ARCSEC * GAIN_STEPS; steps[AXIS_ALT] = m_TrackRates[AXIS_ALT] * STEPS_PER_ARCSEC * GAIN_STEPS; - syslog_proxy("CelestronAUX::trackByRate %.2f %.2f", steps[AXIS_AZ], step[AXIS_ALT]); + syslog_proxy("CelestronAUX::trackByRate %.2f %.2f", steps[AXIS_AZ], steps[AXIS_ALT]); trackByRate(AXIS_AZ, steps[AXIS_AZ]); trackByRate(AXIS_ALT, steps[AXIS_ALT]); } @@ -2587,7 +2624,7 @@ bool CelestronAUX::processResponse(AUXCommand &m) } #if 0 // This turned out to be a stupid idea else if (m.destination() == 0xdd) { - fwrite((const unsigned char *) (&m.data()[0]),m.dataSize(),1,stderr); + fwrite((const unsigned char *) (&m.data()[0]),m.dataSize(),1,stderr); } #endif else diff --git a/indi-celestronaux/celestronaux.h b/indi-celestronaux/celestronaux.h index 3200ffd..7cd4bbf 100644 --- a/indi-celestronaux/celestronaux.h +++ b/indi-celestronaux/celestronaux.h @@ -283,6 +283,8 @@ class CelestronAUX : int sendBuffer(AUXBuffer buf); void formatVersionString(char *s, int n, uint8_t *verBuf); void calculate_tracking_vector(double &mt_ra, double &mt_dec); + bool track_method_changed(void); + // GPS Emulation diff --git a/indi-lxd650/lxd650.cpp b/indi-lxd650/lxd650.cpp index 7a67d61..9dfe8a0 100644 --- a/indi-lxd650/lxd650.cpp +++ b/indi-lxd650/lxd650.cpp @@ -54,7 +54,13 @@ LXD650::LXD650() DBG_SCOPE = INDI::Logger::getInstance().addDebugLevel("Scope Verbose", "SCOPE"); - SetTelescopeCapability(TELESCOPE_CAN_SYNC | TELESCOPE_CAN_GOTO | TELESCOPE_CAN_ABORT | TELESCOPE_HAS_LOCATION | TELESCOPE_HAS_TIME , 4); + SetTelescopeCapability(TELESCOPE_CAN_SYNC | + TELESCOPE_CAN_GOTO | + TELESCOPE_CAN_ABORT | + TELESCOPE_HAS_LOCATION | + TELESCOPE_HAS_TIME, + 4); + LOG_DEBUG("Initializing from LX200 Basic device..."); @@ -92,6 +98,19 @@ bool LXD650::initProperties() IUFillNumberVector(&SlewAccuracyNP, SlewAccuracyN, NARRAY(SlewAccuracyN), getDeviceName(), "Slew Accuracy", "", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); + LXDTrackModeSP[LXD_TRACK_SIDEREAL].fill("TRACK_SIDEREAL", "Sidereal", ISS_ON); + LXDTrackModeSP[LXD_TRACK_SOLAR].fill("TRACK_SOLAR", "Solar", ISS_OFF); + LXDTrackModeSP[LXD_TRACK_LUNAR].fill("TRACK_LUNAR", "Lunar", ISS_OFF); + LXDTrackModeSP[LXD_TRACK_CUSTOM].fill("TRACK_CUSTOM", "Custom", ISS_OFF); + LXDTrackModeSP.fill(getDeviceName(), "LXD_TRACK_MODE", "Track Mode", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE); + + IUFillNumber(&LXDTrackRateN, "LXD_TRACK_RATE_RA", "RA (arcsecs/s)", "%.6f", -16384.0, 16384.0, 0.000001, + TRACKRATE_SIDEREAL); + IUFillNumberVector(&LXDTrackRateNP, &LXDTrackRateN, 1, getDeviceName(), "LXD_TRACK_RATE", "Track Rates", MAIN_CONTROL_TAB, + IP_RW, 60, IPS_IDLE); + + + addAuxControls(); currentRA = get_local_sidereal_time(LocationN[LOCATION_LONGITUDE].value); @@ -124,24 +143,22 @@ bool LXD650::updateProperties() if (isConnected()) { defineProperty(&SlewAccuracyNP); + defineProperty(&LXDTrackModeSP); + defineProperty(&LXDTrackRateNP); defineProperty(&GuideNSNP); defineProperty(&GuideWENP); defineProperty(&GuideRateNP); -#if 0 - // We don't support NSWE controls (yet) - deleteProperty(MovementNSSP.name); - deleteProperty(MovementWESP.name); -#endif - getBasicData(); } else { - deleteProperty(GuideNSNP.name); - deleteProperty(GuideWENP.name); deleteProperty(GuideRateNP.getName()); + deleteProperty(GuideWENP.name); + deleteProperty(GuideNSNP.name); + deleteProperty(LXDTrackRateNP.name); + deleteProperty(LXDTrackModeSP.getName()); deleteProperty(SlewAccuracyNP.name); } @@ -216,6 +233,17 @@ bool LXD650::ReadScopeStatus() return false; } + int mode = IUFindOnSwitchIndex(&LXDTrackModeSP); + + if (mode != LXD_TRACK_CUSTOM) { + double rate; + if (!getTrackFreq(PortFD, &rate)) { + LXDTrackRateN.value = rate * (TRACKRATE_SOLAR / 60.); + IDSetNumber(&LXDTrackRateNP, nullptr); + } + } + + if (TrackState == SCOPE_SLEWING) { // Check if LX200 is done slewing @@ -232,8 +260,8 @@ bool LXD650::ReadScopeStatus() double sky_RA, sky_DEC; if (!TelescopeEquatorialToSky(currentRA, currentDEC, sky_RA, sky_DEC)) { - sky_RA = currentRA; - sky_DEC = currentDEC; + sky_RA = currentRA; + sky_DEC = currentDEC; } NewRaDec(sky_RA, sky_DEC); @@ -257,8 +285,8 @@ bool LXD650::Goto(double r, double d) double mount_r, mount_d; if (!SkyToTelescopeEquatorial(r, d, mount_r, mount_d)) { - mount_r = r; - mount_d = d; + mount_r = r; + mount_d = d; } show_alignment("Sky->Mount", r, d, mount_r, mount_d); @@ -566,6 +594,18 @@ bool LXD650::ISNewNumber(const char *dev, const char *name, double values[], cha return true; } + // Guide Rate + if (!strcmp(name, LXDTrackRateNP.name)) + { + if (IUUpdateNumber(&LXDTrackRateNP, values, names, n) < 0) + return false; + + LXDTrackRateNP.s = IPS_OK; + + IDSetNumber(&LXDTrackRateNP, nullptr); + + return LXDSetTrackRate(LXDTrackRateN.value); + } // Guide Rate if (GuideRateNP.isNameMatch(name)) @@ -595,12 +635,20 @@ bool LXD650::ISNewSwitch(const char *dev, const char *name, ISState *states, cha { // Process alignment properties ProcessAlignmentSwitchProperties(this, name, states, names, n); - } + if (LXDTrackModeSP.isNameMatch(name)) + { + LXDTrackModeSP.update(states, names, n); + LXDTrackModeSP.setState(IPS_OK); + LXDTrackModeSP.apply(); + + return LXDSetTrackMode(IUFindOnSwitchIndex(&LXDTrackModeSP)); + } + } return INDI::Telescope::ISNewSwitch(dev, name, states, names, n); } -///////////////////////////////////////////////////////////////////////////////////// + /// ///////////////////////////////////////////////////////////////////////////////////// bool LXD650::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) @@ -612,6 +660,34 @@ bool LXD650::ISNewText(const char *dev, const char *name, char *texts[], char *n } +bool LXD650::LXDSetTrackRate(double rate) +{ + rate *= 60. / TRACKRATE_SOLAR; + + selectTrackingMode(PortFD, LX200_TRACK_SIDEREAL); //not sideral but "Quartz" + + if (setTrackFreq(PortFD, rate)) + return false; + + return true; +} + +bool LXD650::LXDSetTrackMode(uint8_t mode) +{ + double rate = TRACKRATE_SIDEREAL; + + if (mode == LXD_TRACK_SOLAR) + rate = TRACKRATE_SOLAR; + else if (mode == LXD_TRACK_LUNAR) + rate = TRACKRATE_LUNAR; + else if (mode == LXD_TRACK_CUSTOM) + rate = TrackRateN[AXIS_RA].value; + + return LXDSetTrackRate(rate); +} + + + ///////////////////////////////////////////////////////////////////////////////////// /// @@ -790,7 +866,7 @@ void LXD650::set_slew_rate_from_property(void) enum TSlew rates[]={LX200_SLEW_GUIDE,LX200_SLEW_FIND,LX200_SLEW_CENTER,LX200_SLEW_GUIDE}; if (rate>=(sizeof(rates)/sizeof(rates[0]))) - return; + return; setSlewMode(PortFD, rates[rate]); } @@ -801,19 +877,19 @@ void LXD650::set_slew_rate_from_property(void) bool LXD650::MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) { if (command == MOTION_START) { - set_slew_rate_from_property(); + set_slew_rate_from_property(); - if (dir == DIRECTION_NORTH) { + if (dir == DIRECTION_NORTH) { MoveTo(PortFD, LX200_NORTH); - } else { + } else { MoveTo(PortFD, LX200_SOUTH); - } + } } else { - if (dir == DIRECTION_NORTH) { + if (dir == DIRECTION_NORTH) { HaltMovement(PortFD, LX200_NORTH); - } else { + } else { HaltMovement(PortFD, LX200_SOUTH); - } + } } return true; @@ -825,19 +901,19 @@ bool LXD650::MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) bool LXD650::MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) { if (command == MOTION_START) { - set_slew_rate_from_property(); + set_slew_rate_from_property(); - if (dir == DIRECTION_WEST) { + if (dir == DIRECTION_WEST) { MoveTo(PortFD, LX200_WEST); - } else { + } else { MoveTo(PortFD, LX200_EAST); - } + } } else { - if (dir == DIRECTION_WEST) { + if (dir == DIRECTION_WEST) { HaltMovement(PortFD, LX200_WEST); - } else { + } else { HaltMovement(PortFD, LX200_EAST); - } + } } return true; diff --git a/indi-lxd650/lxd650.h b/indi-lxd650/lxd650.h index 0e24976..65f1341 100644 --- a/indi-lxd650/lxd650.h +++ b/indi-lxd650/lxd650.h @@ -48,10 +48,10 @@ class LXD650 : public INDI::Telescope, virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override; virtual bool ISSnoopDevice(XMLEle *root) override; - static void GuideNorthProxy(void *context); - static void GuideSouthProxy(void *context); - static void GuideWestProxy(void *context); - static void GuideEastProxy(void *context); + static void GuideNorthProxy(void *context); + static void GuideSouthProxy(void *context); + static void GuideWestProxy(void *context); + static void GuideEastProxy(void *context); protected: @@ -76,6 +76,7 @@ class LXD650 : public INDI::Telescope, virtual bool updateLocation(double latitude, double longitude, double elevation) override; + protected: bool isSlewComplete(); void slewError(int slewCode); @@ -89,14 +90,23 @@ class LXD650 : public INDI::Telescope, uint32_t DBG_SCOPE = 0; private: + bool LXDSetTrackMode(uint8_t mode); + bool LXDSetTrackRate(double rate); + + INumber LXDTrackRateN; + INumberVectorProperty LXDTrackRateNP; + + INDI::PropertySwitch LXDTrackModeSP {4}; + enum { LXD_TRACK_SIDEREAL, LXD_TRACK_SOLAR, LXD_TRACK_LUNAR, LXD_TRACK_CUSTOM }; + INDI::PropertyNumber GuideRateNP {2}; bool guidePulse(INDI_EQ_AXIS axis, uint32_t ms, int8_t rate); void show_alignment(const char *wot, double ra1,double dec1, double ra2,double dec2); - int GuideNorth_TID {0}; - int GuideSouth_TID {0}; - int GuideWest_TID {0}; - int GuideEast_TID {0}; + int GuideNorth_TID {0}; + int GuideSouth_TID {0}; + int GuideWest_TID {0}; + int GuideEast_TID {0}; void GuideNorthCB(void); void GuideSouthCB(void); @@ -106,9 +116,9 @@ class LXD650 : public INDI::Telescope, virtual bool setLocalDate(uint8_t days, uint8_t months, uint16_t years); virtual bool setLocalTime24(uint8_t hour, uint8_t minute, uint8_t second); virtual bool setUTCOffset(double offset); - - void set_slew_rate_from_property(void); - void show_guide (const char *dir, int ms); + + void set_slew_rate_from_property(void); + void show_guide (const char *dir, int ms); }; -- cgit v1.2.3