Instrument Neutral Distributed Interface INDI  2.0.2
skywatcherAPI.h
Go to the documentation of this file.
1 
17 #pragma once
18 
19 #include <string>
20 #include <map>
21 
22 #define INDI_DEBUG_LOGGING
23 #ifdef INDI_DEBUG_LOGGING
24 #include "inditelescope.h"
25 #define MYDEBUG(priority, msg) \
26  INDI::Logger::getInstance().print(pChildTelescope->getDeviceName(), priority, __FILE__, __LINE__, msg)
27 #define MYDEBUGF(priority, msg, ...) \
28  INDI::Logger::getInstance().print(pChildTelescope->getDeviceName(), priority, __FILE__, __LINE__, msg, __VA_ARGS__)
29 #else
30 #define MYDEBUG(priority, msg)
31 #define MYDEBUGF(priority, msg, ...)
32 #endif
33 
34 struct AXISSTATUS
35 {
37  : FullStop(false), Slewing(false), SlewingTo(false), SlewingForward(false), HighSpeed(false),
38  NotInitialized(true)
39  {
40  }
41  bool FullStop;
42  bool Slewing;
43  bool SlewingTo;
45  bool HighSpeed;
47 
48  void SetFullStop();
49  void SetSlewing(bool forward, bool highspeed);
50  void SetSlewingTo(bool forward, bool highspeed);
51 };
52 
54 {
55  public:
56  enum AXISID
57  {
58  AXIS1 = 0,
59  AXIS2 = 1
60  };
61 
62  // Types
64  {
65  Initialize = 'F',
76  SetSnapPort = 'O', // EQ8/AZEQ6/AZEQ5/EQ6-R/AZ-GTi only
81  SetBreakStep = 'U',
83  StartMotion = 'J',
84  GetStepPeriod = 'D', // See Merlin protocol http://www.papywizard.org/wiki/DevelopGuide
85  ActivateMotor = 'B', // See eq6direct implementation http://pierre.nerzic.free.fr/INDI/
87  GetHomePosition = 'd', // Get Home position encoder count (default at startup)
88  SetFeatureCmd = 'W', // EQ8/AZEQ6/AZEQ5 only
89  GetFeatureCmd = 'q', // EQ8/AZEQ6/AZEQ5 only
90  InquireAuxEncoder = 'd', // EQ8/AZEQ6/AZEQ5 only
92  };
93 
95  {
97  GET_FEATURES_CMD = 0x01
98  };
99 
101  {
111  };
112 
113 
114  // These values are in radians per second
115  static constexpr double SIDEREALRATE { (2 * M_PI / 86164.09065) };
116  static constexpr double MAX_SPEED { 500.0 };
117  static constexpr double LOW_SPEED_MARGIN { 128.0 * SIDEREALRATE };
118 
119  SkywatcherAPI();
120  virtual ~SkywatcherAPI() = default;
121 
122  unsigned long BCDstr2long(std::string &String);
123  unsigned long Highstr2long(std::string &String);
124  bool CheckIfDCMotor();
125 
128  //bool IsVirtuosoMount() const;
129 
132  bool IsMerlinMount() const;
133 
136  //bool IsAZGTiMount() const;
137 
143  long DegreesPerSecondToClocksTicksPerMicrostep(AXISID Axis, double DegreesPerSecond);
144 
149  long DegreesToMicrosteps(AXISID Axis, double AngleInDegrees);
150 
154  bool GetEncoder(AXISID Axis);
155 
159 
165 
171 
173 
175 
185 
186  bool GetStatus(AXISID Axis);
187 
192 
193  // Optional: inquire axis features from mount.
194  bool InquireFeatures();
195 
196  bool InitializeMC();
197 
200  bool InitMount();
201 
202  bool HasHomeIndexers();
203  bool HasAuxEncoders();
204  bool HasPPEC();
205  bool HasSnapPort1();
206  bool HasSnapPort2();
207  bool HasPolarLed();
208 
209  void TurnEncoder(AXISID axis, bool on);
210  void TurnRAEncoder(bool on);
211  void TurnDEEncoder(bool on);
212  void SetFeature(AXISID axis, uint32_t command);
213 
219  bool InstantStop(AXISID Axis);
220 
221  void Long2BCDstr(long Number, std::string &String);
222 
227  double MicrostepsToDegrees(AXISID Axis, long Microsteps);
228 
233  double MicrostepsToRadians(AXISID Axis, long Microsteps);
234 
235  void PrepareForSlewing(AXISID Axis, double Speed);
236 
242  long RadiansPerSecondToClocksTicksPerMicrostep(AXISID Axis, double RadiansPerSecond);
243 
248  long RadiansToMicrosteps(AXISID Axis, double AngleInRadians);
249 
254  bool SetEncoder(AXISID Axis, long Microsteps);
255 
260  bool SetGotoTargetOffset(AXISID Axis, long OffsetInMicrosteps);
261 
273  bool SetAxisMotionMode(AXISID Axis, char Func, char Direction);
274 
277  void SetSerialPort(int port)
278  {
279  MyPortFD = port;
280  }
281 
284  bool SetClockTicksPerMicrostep(AXISID Axis, long ClockTicksPerMicrostep);
285 
290  bool SetSlewModeDeccelerationRampLength(AXISID Axis, long Microsteps);
291 
296  bool SetSlewToModeDeccelerationRampLength(AXISID Axis, long Microsteps);
297 
300  bool toggleSnapPort(bool enabled);
301 
306  void Slew(AXISID Axis, double SpeedInRadiansPerSecond, bool IgnoreSilentMode = true);
307 
313  void SlewTo(AXISID Axis, long OffsetInMicrosteps, bool verbose = true);
314 
319  bool SlowStop(AXISID Axis);
320 
325 
326  bool TalkWithAxis(AXISID Axis, SkywatcherCommand Command, std::string &cmdDataStr, std::string &responseStr);
327 
331  bool IsInMotion(AXISID Axis);
332 
333  // Skywatcher mount status variables
334  unsigned long MCVersion { 0 }; // Motor control board firmware version
335 
336  static const char *mountTypeToString(uint8_t type);
337 
339  {
340  EQ6 = 0x00,
341  HEQ5 = 0x01,
342  EQ5 = 0x02,
343  EQ3 = 0x03,
344  EQ8 = 0x04,
345  AZEQ6 = 0x05,
346  AZEQ5 = 0x06,
348  EQ8R_PRO = 0x20,
349  AZEQ6_PRO = 0x22,
350  EQ6_PRO = 0x23,
351  EQ5_PRO = 0x31,
352  GT = 0x80,
353  MF = 0x81,
354  _114GT = 0x82,
355  DOB = 0x90,
356  AZGTE = 0xA2,
357  AZGTI = 0xA5,
358  };
359 
360  typedef struct SkyWatcherFeatures
361  {
362  bool inPPECTraining = false;
363  bool inPPEC = false;
364  bool hasEncoder = false;
365  bool hasPPEC = false;
366  bool hasHomeIndexer = false;
367  bool isAZEQ = false;
368  bool hasPolarLed = false;
369  bool hasCommonSlewStart = false; // supports :J3
371  bool hasWifi = false;
373 
374 
375  unsigned long MountCode { 0 };
376  bool IsDCMotor { false };
377  bool SilentSlewMode { true };
378 
379  // Values from mount
380  long MicrostepsPerRevolution[2]; // Number of microsteps for 360 degree revolution
381  long StepperClockFrequency[2]; // The stepper clock timer interrupt frequency in ticks per second
382  long HighSpeedRatio[2]; // The speed multiplier for high speed mode.
383  long MicrostepsPerWormRevolution[2]; // Number of microsteps for one revolution of the worm gear.
385 
386  // Calculated values
392 
393  // SlewTo debugging
395 
402 
404  double SlewingSpeed[2];
405 
406  protected:
407  // Custom debug level
408  unsigned int DBG_SCOPE { 0 };
409 
410  private:
411  int MyPortFD { 0 };
412  // In seconds.
413  static constexpr uint8_t SKYWATCHER_MAX_RETRTY {3};
414  static constexpr uint8_t SKYWATCHER_TIMEOUT {5};
415  static constexpr uint8_t SKYWATCHER_MAX_CMD {16};
416 
417  static const std::map<int, std::string> errorCodes;
418 
419 #ifdef INDI_DEBUG_LOGGING
420  public:
422 #endif
423 };
The Axis class Implements a generic Axis which can be used for equatorial or AltAz mounts for both ax...
bool SetGotoTargetOffset(AXISID Axis, long OffsetInMicrosteps)
Set the goto target offset per the specified axis.
double MicrostepsToRadians(AXISID Axis, long Microsteps)
Convert microsteps to angle in radians.
bool GetHighSpeedRatio(AXISID Axis)
Set the HighSpeedRatio status variable to the ratio between high and low speed stepping modes.
bool IsMerlinMount() const
Check if the current mount is a Virtuoso (AltAz)
unsigned long BCDstr2long(std::string &String)
SkyWatcherFeatures AxisFeatures[2]
void TurnRAEncoder(bool on)
unsigned long Highstr2long(std::string &String)
long LastSlewToTarget[2]
void SetSerialPort(int port)
Set the serail port to be usb for mount communication.
long LowSpeedGotoMargin[2]
bool SetSlewModeDeccelerationRampLength(AXISID Axis, long Microsteps)
Set the length of the deccelaration ramp for Slew mode.
PositiveRotationSense_t GetPositiveRotationDirection(AXISID Axis)
Returns the rotation direction for a positive step on the designated axis.
static constexpr double SIDEREALRATE
bool GetMotorBoardVersion(AXISID Axis)
static constexpr double LOW_SPEED_MARGIN
double MicrostepsToDegrees(AXISID Axis, long Microsteps)
Convert microsteps to angle in degrees.
unsigned long MountCode
bool GetStepperClockFrequency(AXISID Axis)
Set the StepperClockFrequency status variable to fixed PIC timer interrupt frequency (ticks per secon...
void TurnEncoder(AXISID axis, bool on)
bool InquireFeatures()
void SlewTo(AXISID Axis, long OffsetInMicrosteps, bool verbose=true)
Slew to the given offset and stop.
void SetFeature(AXISID axis, uint32_t command)
long ZeroPositionEncoders[2]
Zero position encoder values (microsteps).
double MicrostepsPerRadian[2]
unsigned int DBG_SCOPE
long CurrentEncoders[2]
Current encoder values (microsteps).
bool GetStatus(AXISID Axis)
bool GetMicrostepsPerRevolution(AXISID Axis)
Set the MicrostepsPerRevolution status variable to the number of microsteps for a 360 degree revoluti...
unsigned long MCVersion
long RadiansToMicrosteps(AXISID Axis, double AngleInRadians)
Convert angle in radians to microsteps.
bool GetMicrostepsPerWormRevolution(AXISID Axis)
Set the MicrostepsPermWormRevolution status variable to the number of microsteps for a 360 degree rev...
struct SkywatcherAPI::SkyWatcherFeatures SkyWatcherFeatures
double RadiansPerMicrostep[2]
bool SetEncoder(AXISID Axis, long Microsteps)
Set axis encoder to the specified value.
void PrepareForSlewing(AXISID Axis, double Speed)
long DegreesPerSecondToClocksTicksPerMicrostep(AXISID Axis, double DegreesPerSecond)
Check if the current mount is AZ GTi.
bool InstantStop(AXISID Axis)
Bring the axis to an immediate halt. N.B. This command could cause damage to the mount or telescope a...
@ DISABLE_FULL_CURRENT_LOW_SPEED_CMD
@ ENABLE_FULL_CURRENT_LOW_SPEED_CMD
void TurnDEEncoder(bool on)
virtual ~SkywatcherAPI()=default
long PolarisPositionEncoders[2]
Polaris position (initial) encoder values (microsteps).
bool GetEncoder(AXISID Axis)
Set the CurrentEncoders status variable to the current encoder value in microsteps for the specified ...
long MicrostepsPerWormRevolution[2]
long HighSpeedRatio[2]
double SlewingSpeed[2]
double MicrostepsPerDegree[2]
long DegreesToMicrosteps(AXISID Axis, double AngleInDegrees)
Convert angle in degrees to microsteps.
@ InquireTimerInterruptFreq
Definition: skywatcherAPI.h:68
@ InquireGridPerRevolution
Definition: skywatcherAPI.h:67
@ InquireMotorBoardVersion
Definition: skywatcherAPI.h:66
double DegreesPerMicrostep[2]
bool SlowStop(AXISID Axis)
Bring the axis to slow stop in the distance specified by SetSlewModeDeccelerationRampLength.
bool StartAxisMotion(AXISID Axis)
Start the axis slewing in the prevously selected mode.
bool InitMount()
Initialize the communication to the mount.
bool HasHomeIndexers()
bool SetSlewToModeDeccelerationRampLength(AXISID Axis, long Microsteps)
Set the length of the deccelaration ramp for SlewTo mode.
long RadiansPerSecondToClocksTicksPerMicrostep(AXISID Axis, double RadiansPerSecond)
Convert a slewing rate in radians per second into the required clock ticks per microstep setting.
void Slew(AXISID Axis, double SpeedInRadiansPerSecond, bool IgnoreSilentMode=true)
Start the axis slewing at the given rate.
bool TalkWithAxis(AXISID Axis, SkywatcherCommand Command, std::string &cmdDataStr, std::string &responseStr)
static constexpr double MAX_SPEED
bool SetAxisMotionMode(AXISID Axis, char Func, char Direction)
Set the motion mode per the specified axis.
long MicrostepsPerRevolution[2]
bool IsInMotion(AXISID Axis)
Check if an axis is moving.
long StepperClockFrequency[2]
bool toggleSnapPort(bool enabled)
Toggle the snap port on or off.
bool SetClockTicksPerMicrostep(AXISID Axis, long ClockTicksPerMicrostep)
Set the PIC internal divider variable which determines how many clock interrupts have to occur betwee...
INDI::Telescope * pChildTelescope
static const char * mountTypeToString(uint8_t type)
void Long2BCDstr(long Number, std::string &String)
AXISSTATUS AxesStatus[2]
const char * Direction[]
Command
The Command enum includes all the command types sent to the various devices (motor,...
__le16 type
Definition: pwc-ioctl.h:0
bool NotInitialized
Definition: skywatcherAPI.h:46
void SetSlewingTo(bool forward, bool highspeed)
bool SlewingTo
Definition: skywatcherAPI.h:43
bool HighSpeed
Definition: skywatcherAPI.h:45
void SetFullStop()
bool SlewingForward
Definition: skywatcherAPI.h:44
void SetSlewing(bool forward, bool highspeed)