Instrument Neutral Distributed Interface INDI 2.2.5
celestrondriver.h
Go to the documentation of this file.
1/*
2 Celestron driver
3
4 Copyright (C) 2015 Jasem Mutlaq
5 Copyright (C) 2017 Juan Menendez
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22/*
23 Version with experimental pulse guide support. GC 04.12.2015
24*/
25
26#pragma once
27
28#include <string>
29#include "indicom.h"
30
31#include <stdint.h>
32
33//#include <thread>
34//#include <condition_variable>
35//#include <atomic>
36
37/* Starsense specific constants */
38#define ISNEXSTAR 0x11
39#define ISSTARSENSE 0x13
40#define MINSTSENSVER 1.18
41#define MAX_RESP_SIZE 20
42
43// device IDs
44#define CELESTRON_DEV_RA 0x10
45#define CELESTRON_DEV_DEC 0x11
46#define CELESTRON_DEV_GPS 0xb0
47// focuser device
48#define CELESTRON_DEV_FOC 0x12
49
50// motor commands
51#define MC_GET_POSITION 0x01 // return 24 bit position
52#define MC_GOTO_FAST 0x02 // send 24 bit target
53#define MC_SET_POS_GUIDERATE 0x06 // use the 2 byte CelestronTrackRates to set the rate
54#define MC_SET_NEG_GUIDERATE 0x07 // for Southern hemisphere, track mode EQ_S
55#define MC_LEVEL_START 0x0b // move to switch position
56#define MC_PEC_RECORD_START 0x0C // n/a Ack Start recording PEC position
57#define MC_PEC_PLAYBACK 0x0D // 8 bits Ack Start(01)/stop(00) PEC playback
58
59#define MTR_PECBIN 0x0E // current PEC index - 1 byte 0 - 255(88)
60
61#define MC_LEVEL_DONE 0x12 // return 0xFF when move finished
62#define MC_SLEW_DONE 0x13 // return 0xFF when move finished
63#define MC_PEC_RECORD_DONE 0x15 // n/a 8 bits != 0 is PEC record completed
64#define MC_PEC_RECORD_STOP 0x16 // n/a n/a Stop PEC recording
65
66#define MC_GOTO_SLOW 0x17 // 16/24 bits Ack Goto position with slow, variable rate. Either 16 or 24 bit accuracy.
67// Position is a signed fraction of a full rotation
68#define MC_AT_INDEX 0x18 // n/a 8 bits FFH at index, 00H not
69#define MC_SEEK_INDEX 0x19 // n/a n/a Seek PEC Index
70#define MC_MOVE_POS 0x24 // start move positive direction, rate 0-9, 0 is stop
71#define MC_MOVE_NEG 0x25 // start move negative direction, rate 0-9, 0 is stop
72
73#define MTR_AUX_GUIDE 0x26 // aux guide command, rate -100 to 100, duration centiseconds
74#define MTR_IS_AUX_GUIDE_ACTIVE 0x27 // return 0x00 when aux guide is not in progress
75
76// command 0x30 and 0x31 are read/ write memory commands
77#define MC_PEC_READ_DATA 0x30 // 8 PEC data value return 1 byte of data:
78// 0x3f number of PEC bins (88)
79// 0x40+i PEC data for bin i
80#define MC_PEC_WRITE_DATA 0x31 // 16 PEC data address, PEC data value
81// 0x40+i, value bin i
82
83#define MC_SET_AUTOGUIDE_RATE 0x46 // 0 to 99 as % sidereal
84#define MC_GET_AUTOGUIDE_RATE 0x47 // 0 to 99 as % sidereal
85
86// focuser passthrough commands
87#define FOC_CALIB_ENABLE 42 // send 0 to start or 1 to stop
88#define FOC_CALIB_DONE 43 // returns 2 bytes [0] done, [1] state 0-12
89#define FOC_GET_HS_POSITIONS 44 // returns 2 ints, low and high limits
90
91// generic device commands
92#define GET_VER 0xfe // return 2 or 4 bytes major.minor.build
93
100
101
102// PEC state machine
103// the order matters because it's used to check what states are available.
104// they do not match the the base TelescopePECState
105typedef enum
106{
107 NotKnown, // PEC has not been checked.
108
113
119
124
130
136
141
143
144// These values are sent to the hour angle axis motor using the MC_SET_POS|NEG_GUIDERATE
145// commands to set the tracking rate.
146typedef enum
147{
148 CTR_SIDEREAL = 0xFFFF,
149 CTR_SOLAR = 0xFFFE,
150 CTR_LUNAR = 0xFFFD
152
153typedef struct
154{
155 std::string Model;
156 std::string Version;
157 //std::string GPSFirmware;
158 std::string RAFirmware;
159 std::string DEFirmware;
162 bool isGem;
163 bool canPec;
168
182
183
184/**************************************************************************
185 Utility functions
186**************************************************************************/
187namespace Celestron
188{
189double trimDecAngle(double angle);
190uint16_t dd2nex(double angle);
191uint32_t dd2pnex(double angle);
192double nex2dd(uint32_t value);
193double pnex2dd(uint32_t value);
194}
195
197{
198 public:
200 virtual ~CelestronDriver() = default;
201
202 // Misc.
203 const char *getDeviceName();
204 void set_port_fd(int port_fd)
205 {
206 fd = port_fd;
207 }
208 void set_simulation(bool enable)
209 {
210 simulation = enable;
211 }
212 void set_device(const char *name);
213
214 // Simulation
216 {
217 sim_data.slewRate = val;
218 }
227 void set_sim_slewing(bool isSlewing)
228 {
229 sim_data.isSlewing = isSlewing;
230 }
231 void set_sim_ra(double ra)
232 {
233 sim_data.ra = ra;
234 }
235 void set_sim_dec(double dec)
236 {
237 sim_data.dec = dec;
238 }
239 void set_sim_az(double az)
240 {
241 sim_data.az = az;
242 }
243 void set_sim_alt(double alt)
244 {
245 sim_data.alt = alt;
246 }
247 double get_sim_ra()
248 {
249 return sim_data.ra;
250 }
251 double get_sim_dec()
252 {
253 return sim_data.dec;
254 }
259 void move_sim_foc(int offset)
260 {
261 sim_data.foc_position += offset;
262 }
263
264 bool echo();
265 bool check_connection();
266
267 // Get info
268 bool get_firmware(FirmwareInfo *info);
269 bool get_version(char *version, size_t size);
270 bool get_variant(char *variant);
271 int model(); // returns model number, -1 if failed
272 bool get_model(char *model, size_t size, bool *isGem, bool *canPec, bool *hasHomeIndex);
273 bool get_dev_firmware(int dev, char *version, size_t size);
274 bool get_radec(double *ra, double *dec, bool precise);
275 bool get_azalt(double *az, double *alt, bool precise);
276 bool get_utc_date_time(double *utc_hours, int *yy, int *mm, int *dd, int *hh, int *minute, int *ss, bool *dst,
277 bool precise);
278
279 // Motion
282 bool abort();
283 bool slew_radec(double ra, double dec, bool precise);
284 bool slew_azalt(double az, double alt, bool precise);
285 bool sync(double ra, double dec, bool precise);
286 bool unsync();
287
288 // Time & Location
289 bool set_location(double longitude, double latitude);
290 bool get_location(double* longitude, double *latitude);
291 bool set_datetime(struct ln_date *utc, double utc_offset, bool dst = false, bool precise = false);
292
293 // Track Mode, this is not the Indi track mode
296
297 bool is_slewing(bool *slewing);
298
299 // Hibernate/Wakeup/ align
300 bool hibernate();
301 bool wakeup();
302 bool lastalign();
303 bool startmovetoindex();
304 bool indexreached(bool *atIndex);
305
306 // Pulse Guide
307 size_t send_pulse(CELESTRON_DIRECTION direction, unsigned char rate, unsigned char duration_msec);
309
310 // get and set guide rate
311 // 0 to 255 corresponding to 0 to 100% sidereal
312 bool get_guide_rate(CELESTRON_AXIS axis, uint8_t * rate);
313 bool set_guide_rate(CELESTRON_AXIS axis, uint8_t rate);
314
315 // Pointing state, pier side, returns 'E' or 'W'
316 bool get_pier_side(char * sop);
317
318 // check if the mount is aligned using the mount J command
319 bool check_aligned(bool *isAligned);
320
321 // set the tracking rate, sidereal, solar or lunar
323
324 // focuser commands
325 bool foc_exists(); // read version
326 int foc_position(); // read position, return -1 if failed
327 bool foc_move(uint32_t steps); // start move
328 bool foc_moving(); // return true if moving
329 bool foc_limits(int * low, int * high); // read limits
330 bool foc_abort(); // stop move
331
332 // PEC management
333
335
337
338 bool PecSeekIndex();
339 bool isPecAtIndex(bool force = false); // returns true if the PEC index has been found
340
341 size_t pecIndex(); // reads the current PEC index
342 int getPecValue(size_t index); // reads the current PEC value
343 bool setPecValue(size_t index, int data);
344
345 bool PecPlayback(bool start);
346
347 bool PecRecord(bool start);
348 bool isPecRecordDone();
349
350 size_t getPecNumBins();
351
352 const char *PecStateStr(PEC_STATE);
353 const char *PecStateStr();
354
355 // PEC simulation properties
358 bool simSeekIndex = false;
359
360 protected:
361 void set_sim_response(const char *fmt, ...);
362 virtual int serial_write(const char *cmd, int nbytes, int *nbytes_written);
363 virtual int serial_read(int nbytes, int *nbytes_read);
364 virtual int serial_read_section(char stop_char, int *nbytes_read);
365
366 size_t send_command(const char *cmd, size_t cmd_len, char *resp, size_t resp_len,
367 bool ascii_cmd, bool ascii_resp);
368 size_t send_passthrough(int dest, int cmd_id, const char *payload,
369 size_t payload_len, char *resp, size_t response_len);
370
372 bool simulation = false;
374 int fd = 0;
375
378};
379
381{
382 public:
383 PecData();
384
385 // save PEC data to a file
386 bool Save(const char * filename);
387
388 // saves PEC data to mount
389 bool Save(CelestronDriver * driver);
390
391 // Loads PEC data from mount
392 bool Load(CelestronDriver * driver);
393
394 // Loads PEC data from file
395 bool Load(const char * fileName);
396
397 size_t NumBins()
398 {
399 return numBins;
400 }
401
402 void RemoveDrift();
403
404 const char *getDeviceName();
405 // void set_device(const char *name);
406
407 private:
408 double wormArcSeconds = 7200;
409 double rateScale = 1024;
410 size_t numBins = 88;
411 const double SIDEREAL_ARCSEC_PER_SEC = 360.0 * 60.0 * 60.0 / (23.0 * 3600.0 + 56 * 60 + 4.09);
412
413 double data[255]; // numbins + 1 values, accumulated PEC offset in arc secs. First one zero
414
415 void Kalman(PecData newData, int num);
416};
417
418
std::string fmt(const char *fmt,...)
Definition Utils.cpp:241
CELESTRON_DIRECTION
@ CELESTRON_W
@ CELESTRON_N
@ CELESTRON_S
@ CELESTRON_E
CELESTRON_FIRMWARE
@ FW_CAN_AUX
@ FW_MODEL
@ FW_ISGEM
@ FW_VERSION
@ FW_DEC
@ FW_HAS_FOC
@ FW_RA
CELESTRON_SLEW_RATE
@ SR_1
@ SR_6
@ SR_8
@ SR_5
@ SR_4
@ SR_9
@ SR_2
@ SR_7
@ SR_3
CELESTRON_TRACK_MODE
@ CTM_EQN
@ CTM_ALTAZ
@ CTM_EQS
@ CTM_OFF
@ CTM_RADEC
#define MAX_RESP_SIZE
CELESTRON_TRACK_RATE
@ CTR_SIDEREAL
@ CTR_SOLAR
@ CTR_LUNAR
PEC_STATE
@ NotKnown
@ PEC_SEEKING
The PEC index is being searched for, goes to PEC_INDEXED when found.
@ PEC_AVAILABLE
PEC is available but inactive, can seek index Seek index is only available command.
@ PEC_PLAYBACK
PEC is being played back, stays in this state until stopped equivalent to TelescopePECState PEC_ON.
@ PEC_RECORDING
PEC is being recorded, goes to PEC_INDEXED when completed.
@ PEC_NOT_AVAILABLE
PEC is not available, hardware has been checked, no other state is possible.
@ PEC_INDEXED
the PEC index has been found, can go to Playback or Recording this is equivalent to TelescopePECState...
CELESTRON_AXIS
@ DEC_AXIS
@ RA_AXIS
CELESTRON_GPS_STATUS
@ GPS_OFF
@ GPS_ON
bool slew_radec(double ra, double dec, bool precise)
bool get_azalt(double *az, double *alt, bool precise)
bool set_guide_rate(CELESTRON_AXIS axis, uint8_t rate)
void set_port_fd(int port_fd)
bool indexreached(bool *atIndex)
bool check_aligned(bool *isAligned)
void set_sim_alt(double alt)
bool set_datetime(struct ln_date *utc, double utc_offset, bool dst=false, bool precise=false)
bool set_location(double longitude, double latitude)
bool stop_motion(CELESTRON_DIRECTION dir)
int getPecValue(size_t index)
void set_sim_track_mode(CELESTRON_TRACK_MODE val)
bool get_firmware(FirmwareInfo *info)
bool sync(double ra, double dec, bool precise)
bool foc_limits(int *low, int *high)
bool PecPlayback(bool start)
bool get_dev_firmware(int dev, char *version, size_t size)
size_t send_pulse(CELESTRON_DIRECTION direction, unsigned char rate, unsigned char duration_msec)
size_t send_passthrough(int dest, int cmd_id, const char *payload, size_t payload_len, char *resp, size_t response_len)
bool get_radec(double *ra, double *dec, bool precise)
bool get_track_mode(CELESTRON_TRACK_MODE *mode)
void move_sim_foc(int offset)
void set_device(const char *name)
void set_simulation(bool enable)
bool set_track_rate(CELESTRON_TRACK_RATE rate, CELESTRON_TRACK_MODE mode)
bool set_track_mode(CELESTRON_TRACK_MODE mode)
void set_sim_az(double az)
bool get_model(char *model, size_t size, bool *isGem, bool *canPec, bool *hasHomeIndex)
bool get_version(char *version, size_t size)
size_t send_command(const char *cmd, size_t cmd_len, char *resp, size_t resp_len, bool ascii_cmd, bool ascii_resp)
char response[MAX_RESP_SIZE]
virtual int serial_read(int nbytes, int *nbytes_read)
const char * PecStateStr()
void set_sim_gps_status(CELESTRON_GPS_STATUS val)
void set_sim_response(const char *fmt,...)
virtual ~CelestronDriver()=default
bool PecRecord(bool start)
bool isPecAtIndex(bool force=false)
bool get_variant(char *variant)
bool get_location(double *longitude, double *latitude)
void set_sim_ra(double ra)
const char * getDeviceName()
bool get_pulse_status(CELESTRON_DIRECTION direction)
void set_sim_slewing(bool isSlewing)
virtual int serial_write(const char *cmd, int nbytes, int *nbytes_written)
PEC_STATE updatePecState()
virtual int serial_read_section(char stop_char, int *nbytes_read)
bool get_guide_rate(CELESTRON_AXIS axis, uint8_t *rate)
void set_sim_dec(double dec)
bool slew_azalt(double az, double alt, bool precise)
void set_sim_slew_rate(CELESTRON_SLEW_RATE val)
bool setPecValue(size_t index, int data)
bool foc_move(uint32_t steps)
bool get_pier_side(char *sop)
bool is_slewing(bool *slewing)
bool get_utc_date_time(double *utc_hours, int *yy, int *mm, int *dd, int *hh, int *minute, int *ss, bool *dst, bool precise)
bool start_motion(CELESTRON_DIRECTION dir, CELESTRON_SLEW_RATE rate)
PecData()
PecData class.
const char * getDeviceName()
size_t NumBins()
bool Load(CelestronDriver *driver)
bool Save(const char *filename)
double ra
double dec
Implementations for common driver routines.
double pnex2dd(uint32_t value)
uint32_t dd2pnex(double angle)
uint16_t dd2nex(double angle)
double trimDecAngle(double angle)
double nex2dd(uint32_t value)
uint8_t cmd[4]
Definition pwc-ioctl.h:2
double controllerVersion
std::string Version
std::string RAFirmware
CELESTRON_TRACK_MODE celestronTrackMode
std::string Model
std::string DEFirmware
CELESTRON_SLEW_RATE slewRate
uint32_t foc_position
CELESTRON_GPS_STATUS gpsStatus
CELESTRON_TRACK_MODE trackMode
uint32_t foc_target