30#define TEMMA_SLEW_RATES 2
31#define TEMMA_TIMEOUT 5
32#define TEMMA_BUFFER 64
33#define TEMMA_SLEWRATE 5
42static std::unique_ptr<TemmaMount> temma(
new TemmaMount());
59 Longitude = std::numeric_limits<double>::quiet_NaN();
60 Latitude = std::numeric_limits<double>::quiet_NaN();
67 return "Temma Takahashi";
89 InitAlignmentProperties(
this);
140 char *formats[],
char *names[],
int n)
196bool TemmaMount::sendCommand(
const char *
cmd,
char *response)
198 int bytesWritten = 0, bytesRead = 0, rc = 0;
203 int cmd_size = strlen(cmd_temma);
210 cmd_temma[cmd_size] = 0xD;
211 cmd_temma[cmd_size + 1] = 0xA;
216 std::string
binary = std::bitset<8>(
cmd[1]).to_string();
224 if (response ==
nullptr)
236 if (TemmaInitialized ==
false || std::isnan(Longitude))
241 snprintf(response,
TEMMA_BUFFER,
"%02d%02d%02d", (
int)lst, ((
int)(lst * 60)) % 60, ((
int)(lst * 3600)) % 60);
249 double dec = currentDEC;
261 snprintf(response,
TEMMA_BUFFER,
"E%.2d%.2d%.2d%c%.2d%.2d%.1d%c", (
int)currentRA, (
int)(currentRA * (
double)60) % 60,
262 ((
int)(currentRA * (
double)6000)) % 100, sign, (
int)
dec, (
int)(
dec * (
double)60) % 60,
263 ((
int)(
dec * (
double)600)) % 10, state);
270 currentDEC = targetDEC;
288 tcflush(
PortFD, TCIOFLUSH);
299 if (response ==
nullptr)
311 tcflush(
PortFD, TCIOFLUSH);
313 response[bytesRead - 2] = 0;
320bool TemmaMount::getCoords()
324 bool rc = sendCommand(
"E", response);
328 if (response[0] !=
'E')
332 sscanf(response + 1,
"%02d%02d%02d", &d, &m, &s);
337 sscanf(response + 8,
"%02d%02d%01d", &d, &m, &s);
339 currentDEC = d * 3600 + m * 60 + s * 6;
341 if(response[7] ==
'-')
344 char side = response[13];
357 if (strstr(response,
"F") !=
nullptr)
365 setMotorsEnabled(
false);
382 if (TemmaInitialized ==
false)
391 bool rc = getCoords();
397 alignedDEC = currentDEC;
401 if (IsAlignmentSubsystemActive())
403 const char *maligns[3] = {
"ZENITH",
"NORTH",
"SOUTH"};
404 double juliandate, lst;
408 juliandate = ln_get_julian_from_sys();
409 lst = ln_get_apparent_sidereal_time(juliandate) + (LocationN[1].value * 24.0 / 360.0);
411 RaDec.ra = ((lst -
currentRA) * 360.0) / 24.0;
417 "Status: Mnt. Algnt. %s LST %lf RA %lf DEC %lf HA %lf TDV(x %lf y %lf z %lf)",
422 if (!TransformTelescopeToCelestialJD(TDV, alignedRA, alignedDEC, ln_get_julian_from_sys()))
426 "Failed TransformTelescopeToCelestial: Scope RA=%g Scope DE=%f, Aligned RA=%f DE=%f",
currentRA,
currentDEC, alignedRA,
432 "TransformTelescopeToCelestial: Scope RA=%f Scope DE=%f, Aligned RA=%f DE=%f",
currentRA,
currentDEC, alignedRA,
437 if (!aligned && (syncdata.lst != 0.0))
439 DEBUGF(DBG_SCOPE_STATUS,
"Aligning with last sync delta RA %g DE %g", syncdata.deltaRA, syncdata.deltaDEC);
441 alignedRA += syncdata.deltaRA;
442 alignedDEC += syncdata.deltaDEC;
443 if (alignedDEC > 90.0 || alignedDEC < -90.0)
446 if (alignedDEC > 0.0)
447 alignedDEC = 180.0 - alignedDEC;
449 alignedDEC = -180.0 - alignedDEC;
451 alignedRA =
range24(alignedRA);
464 sendCommand(
cmd,
nullptr);
484 LOG_DEBUG(
"Sending LST --> Z --> LST before Sync.");
497 snprintf(
cmd,
TEMMA_BUFFER,
"D%.2d%.2d%.2d%c%.2d%.2d%.1d", (
int)
ra, (
int)(
ra * (
double)60) % 60,
498 ((
int)(
ra * (
double)6000)) % 100, sign, (
int)
dec, (
int)(
dec * (
double)60) % 60,
499 ((
int)(
dec * (
double)600)) % 10);
501 if (sendCommand(
cmd, res) ==
false)
532 if (MotorStatus ==
false)
535 setMotorsEnabled(
true);
548 snprintf(
cmd,
TEMMA_BUFFER,
"P%.2d%.2d%.2d%c%.2d%.2d%.1d", (
int)
ra, (
int)(
ra * (
double)60) % 60,
549 ((
int)(
ra * (
double)6000)) % 100, sign, (
int)
dec, (
int)(
dec * (
double)60) % 60,
550 ((
int)(
dec * (
double)600)) % 10);
552 if (sendCommand(
cmd, res) ==
false)
584 LOG_INFO(
"Parking is in progress...");
600 setMotorsEnabled(
true);
629 if (sendCommand(
"PS") ==
false)
632 if (sendCommand(
"s", res) ==
false)
642 LOGF_DEBUG(
"Temma::MoveNS %d dir %d", command, dir);
644 setMotorsEnabled(
true);
651 LOGF_DEBUG(
"Temma::MoveNS %d dir %d", command, dir);
681 return sendCommand(
cmd);
689 setMotorsEnabled(
true);
696 LOGF_DEBUG(
"Temma::MoveWE %d dir %d", command, dir);
723 return sendCommand(
cmd);
849 Longitude = longitude;
856 if (TemmaInitialized ==
false)
858 setLatitude(latitude);
861 TemmaInitialized =
true;
865 LOGF_DEBUG(
"Temma is initialized. Latitude: %.2f LST: %.2f", latitude, lst);
888 setMotorsEnabled(
false);
904 double RightAscension, Declination;
907 if (GetAlignmentDatabase().size() > 1)
936 lha = lha * 360 / 24;
939 TDV = TelescopeDirectionVectorFromLocalHourAngleDeclination(
eq);
941 if (TransformTelescopeToCelestialJD(TDV, RightAscension, Declination, ln_get_julian_from_sys()))
961 eq.ra = RightAscension;
962 eq.dec = Declination;
970 double RightAscension, Declination;
975 if (GetAlignmentDatabase().size() > 1)
980 if (TransformCelestialToTelescopeJD(
ra,
dec, ln_get_julian_from_sys(), TDV))
1006 LocalHourAngleDeclinationFromTelescopeDirectionVector(TDV,
eq);
1009 eq.ra =
eq.ra * 24 / 360;
1010 RightAscension = lst -
eq.ra;
1011 RightAscension =
range24(RightAscension);
1012 Declination =
eq.dec;
1016 LOGF_INFO(
"Transform failed, using raw co-ordinates %g %g",
ra,
dec);
1017 RightAscension =
ra;
1023 RightAscension =
ra;
1027 eq.ra = RightAscension;
1028 eq.dec = Declination;
1035bool TemmaMount::getVersion()
1038 for (
int i = 0; i < 3; i++)
1040 if (sendCommand(
"v", res) && res[0] ==
'v')
1052 LOGF_INFO(
"Detected version: %s", res + 1);
1057bool TemmaMount::motorsEnabled()
1061 if (sendCommand(
"STN-COD", res) ==
false)
1064 if (strstr(res,
"off") !=
nullptr)
1067 MotorStatus =
false;
1074bool TemmaMount::setMotorsEnabled(
bool enable)
1082 rc = sendCommand(
"STN-OFF", res);
1084 rc = sendCommand(
"STN-ON", res);
1095bool TemmaMount::getLST(
double &lst)
1099 if (sendCommand(
"g", res) ==
false)
1102 int hh = 0, mm = 0, ss = 0;
1103 if (sscanf(res + 1,
"%02d%02d%02d", &hh, &mm, &ss) == 3)
1105 lst = hh + mm / 60.0 + ss / 3600.0;
1112bool TemmaMount::setLST()
1116 snprintf(
cmd,
TEMMA_BUFFER,
"T%.2d%.2d%.2d", (
int)lst, ((
int)(lst * 60)) % 60, ((
int)(lst * 3600)) % 60);
1118 return sendCommand(
cmd);
1121bool TemmaMount::getLatitude(
double &lat)
1125 if (sendCommand(
"i", res) ==
false)
1128 int dd = 0, mm = 0, parial_m = 0;
1129 if (sscanf(res + 1,
"%02d%02d%01d", &dd, &mm, &parial_m) == 3)
1131 lat = dd + mm / 60.0 + parial_m / 600.0;
1138bool TemmaMount::setLatitude(
double lat)
1162 return sendCommand(
cmd);
1176 if (getVersion() ==
false)
1183 TemmaInitialized =
true;
1188 TemmaInitialized =
false;
1197int TemmaMount::TemmaRead(
char *buf,
int size)
1217 if (buf[ptr - 1] == 13)
1229 fprintf(stderr,
"timed out reading %d\n", count);
1230 LOGF_DEBUG(
"We timed out reading bytes %d", count);
1235 fprintf(stderr,
"Read error after %d bytes\n", bytesRead);
1236 LOGF_DEBUG(
"Read return error after %d bytes", bytesRead);
1244 return sendCommand(
"LL");
1246 return sendCommand(
"LK");
1255 setMotorsEnabled(
true);
1260 setMotorsEnabled(
false);
1261 return sendCommand(
"PS");
1265void TemmaMount::mountSim()
1267 static struct timeval ltv;
1269 double dt = 0, da = 0, dx = 0;
1273 gettimeofday(&tv,
nullptr);
1275 if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
1278 dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec) / 1e6;
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
void setParity(const uint8_t &value)
setParity Set parity to be used in the serial connection. Default 0 (NONE)
INDI::PropertySwitch getSwitch(const char *name) const
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
bool isSimulation() const
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
uint32_t getDriverInterface() const
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Process the client newBLOB command.
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void initProperties(const char *groupName)
Initialize guider properties. It is recommended to call this function within initProperties() of your...
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Call this function whenever client updates GuideNSNP or GuideWSP properties in the primary device....
int findOnSwitchIndex() const
TelescopeStatus TrackState
void SetAxis1Park(double value)
SetRAPark Set current RA/AZ parking position. The data park file (stored in ~/.indi/ParkData....
void SetAxis1ParkDefault(double steps)
SetRAPark Set default RA/AZ parking position.
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
double GetAxis1Park() const
virtual bool SetSlewRate(int index)
SetSlewRate Set desired slew rate index.
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
double GetAxis2Park() const
bool isParked()
isParked is mount currently parked?
virtual int AddTrackMode(const char *name, const char *label, bool isDefault=false)
AddTrackMode.
Connection::Serial * serialConnection
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
virtual bool updateTime(ln_date *utc, double utc_offset)
Update telescope time, date, and UTC offset.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
@ TELESCOPE_HAS_PIER_SIDE
@ TELESCOPE_HAS_TRACK_MODE
@ TELESCOPE_CAN_CONTROL_TRACK
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
void setPierSide(TelescopePierSide side)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
void SetAxis2Park(double steps)
SetDEPark Set current DEC/ALT parking position. The data park file (stored in ~/.indi/ParkData....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
void SetParkDataType(TelescopeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
void SetAxis2ParkDefault(double steps)
SetDEParkDefault Set default DEC/ALT parking position.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) override
Process the client newBLOB command.
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
virtual const char * getDefaultName() override
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
virtual IPState GuideSouth(uint32_t ms) override
Guide south for ms milliseconds. South is defined as DEC-.
virtual bool Goto(double ra, double dec) override
Move the scope to the supplied RA and DEC coordinates.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) override
Move the telescope in the direction dir.
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
virtual bool Park() override
Park the telescope to its home position.
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) override
Start or Stop the telescope motion in the direction dir.
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual IPState GuideEast(uint32_t ms) override
Guide east for ms milliseconds. East is defined as RA+.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
INDI::PropertyNumber TrackRateNP
INDI::PropertySwitch TrackModeSP
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
double range24(double r)
range24 Limits a number to be between 0-24 range.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
double get_local_hour_angle(double sideral_time, double ra)
get_local_hour_angle Returns local hour angle of an object
Implementations for common driver routines.
double get_local_sidereal_time(double longitude)
get_local_sidereal_time Returns local sidereal time given longitude and system clock.
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
#define DEBUGF(priority, msg,...)
#define TRACKRATE_SIDEREAL
Namespace to encapsulate the INDI Alignment Subsystem classes. For more information see "INDI Alignme...
@ binary
binary array (ordered collection of bytes)
Holds a normalised direction vector (direction cosines)