mirror of
https://github.com/eddyem/small_tel.git
synced 2026-09-29 21:30:41 +03:00
telescope is moving; need to add some more commands & write FITS-header
This commit is contained in:
43
Daemons/10micron_stellarium/10micron_commands.h
Normal file
43
Daemons/10micron_stellarium/10micron_commands.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the mountdaemon_10micron project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// commands
|
||||||
|
#define CMD_SHUTDOWN ":shutdown#" // TODO!
|
||||||
|
#define CMD_TRKSTART ":AP#"
|
||||||
|
#define CMD_TRKSTOP ":AL#"
|
||||||
|
#define CMD_GOTOAZ ":MA#"
|
||||||
|
#define CMD_SLEWRADEC ":MS#"
|
||||||
|
#define CMD_BAUDRATE ":SB0#"
|
||||||
|
#define CMD_STOP ":STOP#"
|
||||||
|
#define CMD_HIGHPREC ":U2#"
|
||||||
|
|
||||||
|
// getters
|
||||||
|
#define CMD_GETALT ":GA#"
|
||||||
|
#define CMD_GETAZIM ":GZ#"
|
||||||
|
#define CMD_GETDEC ":GD#"
|
||||||
|
#define CMD_GETSTAT ":Gstat#"
|
||||||
|
#define CMD_GETRA ":GR#"
|
||||||
|
|
||||||
|
// setters
|
||||||
|
#define CMD_SETALT ":Sa%s#"
|
||||||
|
#define CMD_SETDEC ":Sd%s#"
|
||||||
|
#define CMD_SETRA ":Sr%s#"
|
||||||
|
#define CMD_SETMINALT ":So%d#"
|
||||||
|
#define CMD_SETZD ":Sz%s#"
|
||||||
@@ -84,25 +84,37 @@ void getPlaceData(placeData_t *pd){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert RA/DEC to string in forman RA: HH:MM:SS.SS, DEC: DD:MM:SS.S
|
* @brief ra2str - convert RA to string form "HH:MM:SS.SS"
|
||||||
|
* @param ra - RA (hours)
|
||||||
|
* @param buf - output buffer
|
||||||
|
* @return pointer to buffer
|
||||||
*/
|
*/
|
||||||
char *radec2str(double ra, double dec, char buf[RADEC_STR_MAXLEN]){
|
char *ra2str(double ra, char buf[RADEC_STR_MAXLEN]){
|
||||||
|
int h = (int)ra;
|
||||||
|
ra -= h; ra *= 60.;
|
||||||
|
int m = (int)ra;
|
||||||
|
ra -= m; ra *= 60.;
|
||||||
|
snprintf(buf, RADEC_STR_MAXLEN, "%d:%d:%.2f", h,m,ra);
|
||||||
|
buf[RADEC_STR_MAXLEN-1] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief dec2str - convert Dec to string form "DD:MM:SS.S"
|
||||||
|
* @param dec - Dec (degrees)
|
||||||
|
* @param buf - output buffer
|
||||||
|
* @return pointer to buffer
|
||||||
|
*/
|
||||||
|
char *dec2str(double dec, char buf[RADEC_STR_MAXLEN]){
|
||||||
char sign = '+';
|
char sign = '+';
|
||||||
if(dec < 0){
|
if(dec < 0){
|
||||||
sign = '-';
|
sign = '-';
|
||||||
dec = -dec;
|
dec = -dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
int h = (int)ra;
|
|
||||||
ra -= h; ra *= 60.;
|
|
||||||
int m = (int)ra;
|
|
||||||
ra -= m; ra *= 60.;
|
|
||||||
|
|
||||||
int d = (int) dec;
|
int d = (int) dec;
|
||||||
dec -= d; dec *= 60.;
|
dec -= d; dec *= 60.;
|
||||||
int dm = (int)dec;
|
int dm = (int)dec;
|
||||||
dec -= dm; dec *= 60.;
|
dec -= dm; dec *= 60.;
|
||||||
snprintf(buf, RADEC_STR_MAXLEN, "%d:%d:%.2f %c%d:%d:%.1f", h,m,ra, sign,d,dm,dec);
|
snprintf(buf, RADEC_STR_MAXLEN, "%c%d:%d:%.1f",sign,d,dm,dec);
|
||||||
buf[RADEC_STR_MAXLEN-1] = 0;
|
buf[RADEC_STR_MAXLEN-1] = 0;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@@ -156,8 +168,10 @@ void norm_RADEC(double *ra, double *dec){
|
|||||||
|
|
||||||
void norm_RADECr(double *ra, double *dec){
|
void norm_RADECr(double *ra, double *dec){
|
||||||
if(!ra || !dec) return;
|
if(!ra || !dec) return;
|
||||||
|
DBG("Ra: %g, Dec: %g", RAD2DEG(*ra), RAD2DEG(*dec));
|
||||||
if(*dec >= -ERFA_DPI/2. && *dec <= ERFA_DPI/2.){ // need only check RA
|
if(*dec >= -ERFA_DPI/2. && *dec <= ERFA_DPI/2.){ // need only check RA
|
||||||
*ra = eraAnp(*ra);
|
*ra = eraAnp(*ra);
|
||||||
|
DBG("Ra become %g", RAD2DEG(*ra));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 1: convert to (-pi..+pi)
|
// 1: convert to (-pi..+pi)
|
||||||
@@ -170,6 +184,7 @@ void norm_RADECr(double *ra, double *dec){
|
|||||||
*dec = -ERFA_DPI - *dec;
|
*dec = -ERFA_DPI - *dec;
|
||||||
*ra = eraAnp(*ra + ERFA_DPI);
|
*ra = eraAnp(*ra + ERFA_DPI);
|
||||||
}
|
}
|
||||||
|
DBG("Ra become %g, dec become %g", RAD2DEG(*ra), RAD2DEG(*dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
// normalize angle to (-180, 180]
|
// normalize angle to (-180, 180]
|
||||||
@@ -249,6 +264,39 @@ void r2sDMS(double radians, char *dms, int len){
|
|||||||
eraA2af(1, radians, &pm, i);
|
eraA2af(1, radians, &pm, i);
|
||||||
snprintf(dms, len, "'%c%02d:%02d:%02d.%d'", pm, i[0],i[1],i[2],i[3]);
|
snprintf(dms, len, "'%c%02d:%02d:%02d.%d'", pm, i[0],i[1],i[2],i[3]);
|
||||||
}
|
}
|
||||||
|
// the same, but argument in degrees
|
||||||
|
void d2sDMS(double degrees, char *dms, int len){
|
||||||
|
double radians = DEG2RAD(degrees);
|
||||||
|
return r2sDMS(radians, dms, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert str into coordinate (degrees/hours)
|
||||||
|
* @param str (i) - string with angle
|
||||||
|
* @param val (o) - output angle value
|
||||||
|
* @return true if all OK
|
||||||
|
*/
|
||||||
|
bool str2coord(const char *str, double *val){
|
||||||
|
if(!str || !val) return false;
|
||||||
|
int d, m;
|
||||||
|
float s;
|
||||||
|
int sign = 1;
|
||||||
|
if(*str == '+') ++str;
|
||||||
|
else if(*str == '-'){
|
||||||
|
sign = -1;
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
int n = sscanf(str, "%d:%d:%f#", &d, &m, &s);
|
||||||
|
if(n != 3){
|
||||||
|
DBG("sscanf('%s')=%d", str, 3);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
double ang = d + ((double)m)/60. + s/3600.;
|
||||||
|
if(sign == -1) *val = -ang;
|
||||||
|
else *val = ang;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_MJDt - calculate MJD of date from argument
|
* @brief get_MJDt - calculate MJD of date from argument
|
||||||
@@ -287,11 +335,11 @@ bool get_MJDt(struct timeval *tval, sMJD_t *MJD){
|
|||||||
WARNX("get_MJDt(): eraDtf2d() error");
|
WARNX("get_MJDt(): eraDtf2d() error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DBG("y=%d, m=%d, d=%d, H=%d, M=%d, seconds=%g, UTC=%g", y, m, d, tms.tm_hour, tms.tm_min, tSeconds, utc1+utc2);
|
//DBG("y=%d, m=%d, d=%d, H=%d, M=%d, seconds=%g, UTC=%g", y, m, d, tms.tm_hour, tms.tm_min, tSeconds, utc1+utc2);
|
||||||
MJD->MJD = (utc1 - ERFA_DJM0) + utc2;
|
MJD->MJD = (utc1 - ERFA_DJM0) + utc2;
|
||||||
MJD->utc1 = utc1;
|
MJD->utc1 = utc1;
|
||||||
MJD->utc2 = utc2;
|
MJD->utc2 = utc2;
|
||||||
DBG("MJD: %g, %.8f", utc1 - ERFA_DJM0, utc2);
|
//DBG("MJD: %g, %.8f", utc1 - ERFA_DJM0, utc2);
|
||||||
if(eraUtctai(utc1, utc2, &MJD->tai1, &MJD->tai2)){
|
if(eraUtctai(utc1, utc2, &MJD->tai1, &MJD->tai2)){
|
||||||
WARNX("get_MJDt(): eraUtctai() error");
|
WARNX("get_MJDt(): eraUtctai() error");
|
||||||
return false;
|
return false;
|
||||||
@@ -322,8 +370,8 @@ bool get_LST(sMJD_t *mjd, double *LST){
|
|||||||
}else Mjd = *mjd;
|
}else Mjd = *mjd;
|
||||||
if(eraUtcut1(Mjd.utc1, Mjd.utc2, AlmDut.DUT1, &ut11, &ut12)) return false;
|
if(eraUtcut1(Mjd.utc1, Mjd.utc2, AlmDut.DUT1, &ut11, &ut12)) return false;
|
||||||
double ST = eraGst06a(ut11, ut12, Mjd.tt1, Mjd.tt2);
|
double ST = eraGst06a(ut11, ut12, Mjd.tt1, Mjd.tt2);
|
||||||
DBG("ST0=%gh; longitude=%gh (%gdeg) STl=%gh", RAD2HRS(ST),
|
//DBG("ST0=%gh; longitude=%gh (%gdeg) STl=%gh", RAD2HRS(ST),
|
||||||
RAD2HRS(place.slong), RAD2DEG(place.slong), RAD2HRS(ST+place.slong));
|
// RAD2HRS(place.slong), RAD2DEG(place.slong), RAD2HRS(ST+place.slong));
|
||||||
ST += place.slong;
|
ST += place.slong;
|
||||||
if(ST > ERFA_D2PI) ST -= ERFA_D2PI;
|
if(ST > ERFA_D2PI) ST -= ERFA_D2PI;
|
||||||
else if(ST < 0.) ST += ERFA_D2PI;
|
else if(ST < 0.) ST += ERFA_D2PI;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include <erfam.h>
|
#include <erfam.h>
|
||||||
#include <weather_data.h>
|
#include <weather_data.h>
|
||||||
|
|
||||||
#define RADEC_STR_MAXLEN 72
|
#define RADEC_STR_MAXLEN 64
|
||||||
|
|
||||||
#define RAD2DEG(angle) ((angle) * ERFA_DR2D)
|
#define RAD2DEG(angle) ((angle) * ERFA_DR2D)
|
||||||
#define DEG2RAD(angle) ((angle) * ERFA_DD2R)
|
#define DEG2RAD(angle) ((angle) * ERFA_DD2R)
|
||||||
@@ -64,7 +64,9 @@ typedef struct{
|
|||||||
double py;
|
double py;
|
||||||
} almDut_t;
|
} almDut_t;
|
||||||
|
|
||||||
char *radec2str(double ra, double dec, char buf[RADEC_STR_MAXLEN]);
|
char *ra2str(double ra, char buf[RADEC_STR_MAXLEN]);
|
||||||
|
char *dec2str(double dec, char buf[RADEC_STR_MAXLEN]);
|
||||||
|
bool str2coord(const char *str, double *val);
|
||||||
bool normAZ(double *a, double *z);
|
bool normAZ(double *a, double *z);
|
||||||
void norm_RA(double *ra);
|
void norm_RA(double *ra);
|
||||||
void norm_RADEC(double *ra, double *dec);
|
void norm_RADEC(double *ra, double *dec);
|
||||||
@@ -77,6 +79,7 @@ void eq2hor(polarCrds_t *pc, horizCrds_t *h, double sidTime);
|
|||||||
|
|
||||||
void r2sHMS(double radians, char *hms, int len);
|
void r2sHMS(double radians, char *hms, int len);
|
||||||
void r2sDMS(double radians, char *hms, int len);
|
void r2sDMS(double radians, char *hms, int len);
|
||||||
|
void d2sDMS(double degrees, char *dms, int len);
|
||||||
void hor2eq(horizCrds_t *h, polarCrds_t *pc, double sidTime);
|
void hor2eq(horizCrds_t *h, polarCrds_t *pc, double sidTime);
|
||||||
void eq2horH(polarCrds_t *pc, horizCrds_t *h);
|
void eq2horH(polarCrds_t *pc, horizCrds_t *h);
|
||||||
void eq2hor(polarCrds_t *pc, horizCrds_t *h, double sidTime);
|
void eq2hor(polarCrds_t *pc, horizCrds_t *h, double sidTime);
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
#define DEFAULT_FITSHDR "/tmp/10micron.fitsheader"
|
#define DEFAULT_FITSHDR "/tmp/10micron.fitsheader"
|
||||||
// baudrate - 115200
|
// baudrate - 115200
|
||||||
#define DEFAULT_SERSPEED 115200
|
#define DEFAULT_SERSPEED 115200
|
||||||
// serial polling timeout - 100ms
|
// serial answer polling timeout - 1s
|
||||||
#define DEFAULT_SERTMOUT 100000
|
#define DEFAULT_SERTMOUT 1.0
|
||||||
// mount name
|
// mount name
|
||||||
#define DEFAULT_MOUNT_NAME "10Micron GM4000HPS"
|
#define DEFAULT_MOUNT_NAME "10Micron GM4000HPS"
|
||||||
|
|
||||||
@@ -59,10 +59,10 @@ static parameters_t Conf = {0};
|
|||||||
{"cmdport", NEED_ARG, NULL, 'P', arg_string, APTR(&Stor.cmdnode), "port or UNIX-socket path to connect for command console (default: " DEFAULT_CMDNODE ")"}, \
|
{"cmdport", NEED_ARG, NULL, 'P', arg_string, APTR(&Stor.cmdnode), "port or UNIX-socket path to connect for command console (default: " DEFAULT_CMDNODE ")"}, \
|
||||||
{"sleept", NEED_ARG, NULL, 't', arg_int, APTR(&Stor.sleept), "time of servers' sleeping in main cycle, us (default: " STR(DEFAULT_SLEEP_T) " us)"}, \
|
{"sleept", NEED_ARG, NULL, 't', arg_int, APTR(&Stor.sleept), "time of servers' sleeping in main cycle, us (default: " STR(DEFAULT_SLEEP_T) " us)"}, \
|
||||||
{"isunix", NO_ARGS, NULL, 'U', arg_int, APTR(&Stor.isunix), "use UNIX-socket for cmdport"}, \
|
{"isunix", NO_ARGS, NULL, 'U', arg_int, APTR(&Stor.isunix), "use UNIX-socket for cmdport"}, \
|
||||||
{"sertmout",NEED_ARG, NULL, 'T', arg_int, APTR(&Stor.sertmout), "serial timeout, us (default: " STR(DEFAULT_SERTMOUT) " us)"}, \
|
{"sertmout",NEED_ARG, NULL, 'T', arg_double, APTR(&Stor.sertmout), "serial timeout, seconds (default: " STR(DEFAULT_SERTMOUT) " s)"}, \
|
||||||
{"serspeed",NEED_ARG, NULL, 'S', arg_int, APTR(&Stor.serspeed), "serial speed (default: " STR(DEFAULT_SERSPEED) ")"}, \
|
{"serspeed",NEED_ARG, NULL, 'S', arg_int, APTR(&Stor.serspeed), "serial speed (default: " STR(DEFAULT_SERSPEED) ")"}, \
|
||||||
{"maxclients",NEED_ARG, NULL, 0, arg_int, APTR(&Stor.maxclients),"max amount of clients connected to one socket (default: " STR(DEFAULT_MAXCLIENTS) ")"}, \
|
{"maxclients",NEED_ARG, NULL, 0, arg_int, APTR(&Stor.maxclients),"max amount of clients connected to one socket (default: " STR(DEFAULT_MAXCLIENTS) ")"}, \
|
||||||
{"mountname",NEED_ARG, NULL, 0, arg_string, APTR(&Stor.mountname), "mount name (default: " DEFAULT_MOUNT_NAME ")"}, \
|
{"mountname",NEED_ARG, NULL, 0, arg_string, APTR(&Stor.mountname), "mount name (default: " DEFAULT_MOUNT_NAME ")"}, \
|
||||||
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&Stor.verbose), "verbose level (each -v increases it)"}, \
|
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&Stor.verbose), "verbose level (each -v increases it)"}, \
|
||||||
|
|
||||||
|
|
||||||
@@ -105,20 +105,34 @@ static void chkint(int *conf, int *cmd, int dflt){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void chkdbl(double *conf, double *cmd, double dflt){
|
||||||
|
if(!*conf){
|
||||||
|
if(!*cmd) *cmd = dflt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!*cmd){
|
||||||
|
DBG("Conf-only parameter %g", *conf);
|
||||||
|
*cmd = *conf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define STRCHK(field) chkstr(&Conf.field, &G.field, NULL)
|
#define STRCHK(field) chkstr(&Conf.field, &G.field, NULL)
|
||||||
#define STRCHKD(field, def) chkstr(&Conf.field, &G.field, def)
|
#define STRCHKD(field, def) chkstr(&Conf.field, &G.field, def)
|
||||||
#define INTCHK(field) chkint(&Conf.field, &G.field, 0)
|
#define INTCHK(field) chkint(&Conf.field, &G.field, 0)
|
||||||
#define INTCHKD(field, def) chkint(&Conf.field, &G.field, def)
|
#define INTCHKD(field, def) chkint(&Conf.field, &G.field, def)
|
||||||
|
#define DBLCHK(field) chkdbl(&Conf.field, &G.field, 0.)
|
||||||
|
#define DBLCHKD(field, def) chkdbl(&Conf.field, &G.field, def)
|
||||||
|
|
||||||
parameters_t *parse_cmdline(int *argc, char ***argv){
|
parameters_t *parse_cmdline(int *argc, char ***argv){
|
||||||
sl_parseargs(argc, argv, cmdlnopts);
|
sl_parseargs(argc, argv, cmdlnopts);
|
||||||
if(help) sl_showhelp(-1, cmdlnopts);
|
if(help) sl_showhelp(-1, cmdlnopts);
|
||||||
if(!conffile) return &G;
|
//if(!conffile) return &G;
|
||||||
// fix for conffile
|
// fix for conffile
|
||||||
if(!sl_conf_readopts(conffile, confopts)){ // show conf help
|
if(conffile){
|
||||||
sl_conf_showhelp(-1, confopts);
|
if(!sl_conf_readopts(conffile, confopts)){ // show conf help
|
||||||
return NULL;
|
sl_conf_showhelp(-1, confopts);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// now fix for command line and check all:
|
// now fix for command line and check all:
|
||||||
DBG("Check all args");
|
DBG("Check all args");
|
||||||
@@ -133,7 +147,7 @@ parameters_t *parse_cmdline(int *argc, char ***argv){
|
|||||||
INTCHK(verbose);
|
INTCHK(verbose);
|
||||||
INTCHKD(sleept, DEFAULT_SLEEP_T);
|
INTCHKD(sleept, DEFAULT_SLEEP_T);
|
||||||
INTCHK(isunix);
|
INTCHK(isunix);
|
||||||
INTCHKD(sertmout, DEFAULT_SERTMOUT);
|
DBLCHKD(sertmout, DEFAULT_SERTMOUT);
|
||||||
INTCHKD(serspeed, DEFAULT_SERSPEED);
|
INTCHKD(serspeed, DEFAULT_SERSPEED);
|
||||||
INTCHKD(maxclients, DEFAULT_MAXCLIENTS);
|
INTCHKD(maxclients, DEFAULT_MAXCLIENTS);
|
||||||
return &G;
|
return &G;
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ typedef struct{
|
|||||||
int verbose; // verbose level
|
int verbose; // verbose level
|
||||||
int sleept; // server's sleeping in main cycle time
|
int sleept; // server's sleeping in main cycle time
|
||||||
int isunix; // use UNIX-socket for command port
|
int isunix; // use UNIX-socket for command port
|
||||||
int sertmout; // serial timeout, us
|
|
||||||
int serspeed; // serial speed, baud
|
int serspeed; // serial speed, baud
|
||||||
int maxclients; // max amount of clients connected to one socket
|
int maxclients; // max amount of clients connected to one socket
|
||||||
|
double sertmout; // serial timeout, s
|
||||||
} parameters_t;
|
} parameters_t;
|
||||||
|
|
||||||
parameters_t *parse_cmdline(int *argc, char ***argv);
|
parameters_t *parse_cmdline(int *argc, char ***argv);
|
||||||
|
|||||||
@@ -25,8 +25,9 @@
|
|||||||
#include "angles.h"
|
#include "angles.h"
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
|
|
||||||
// emulation speed over any trajectory
|
// emulation speed over axis
|
||||||
#define SPEED (DEG2RAD(5.))
|
#define RASPEED (DEG2RAD(5.))
|
||||||
|
#define DECSPEED (DEG2RAD(8.))
|
||||||
// limiting Zen.d.
|
// limiting Zen.d.
|
||||||
#define ZD_LIMIT (DEG2RAD(80.))
|
#define ZD_LIMIT (DEG2RAD(80.))
|
||||||
// pointing tolerance: ~1''
|
// pointing tolerance: ~1''
|
||||||
@@ -108,11 +109,12 @@ static double angular_distance(const polarCrds_t *a, const polarCrds_t *b){
|
|||||||
return acos(cd);
|
return acos(cd);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// distance by axis moving
|
// time to reach position b from position a
|
||||||
static double axdist(const polarCrds_t *a, const polarCrds_t *b){
|
static double reacht(const polarCrds_t *a, const polarCrds_t *b){
|
||||||
// convert to [-pi, pi)
|
// convert to [-pi, pi)
|
||||||
double dra = eraAnpm(b->ra - a->ra), ddec = eraAnpm(b->dec - a->dec);
|
double tra = fabs(eraAnpm(b->ra - a->ra)) / RASPEED, tdec = fabs(eraAnpm(b->dec - a->dec)) / DECSPEED;
|
||||||
return sqrt(dra*dra + ddec*ddec);
|
if(tra > tdec) return tra;
|
||||||
|
return tdec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate flip target (dec>90deg)
|
// calculate flip target (dec>90deg)
|
||||||
@@ -142,47 +144,49 @@ void get_emul_coords(double *ra, double *decl){
|
|||||||
}
|
}
|
||||||
if(!flip_in_progress){ // check if we need to flip
|
if(!flip_in_progress){ // check if we need to flip
|
||||||
// distance for direct moving
|
// distance for direct moving
|
||||||
double dist_direct = axdist(&CurRD, &TagRD);
|
double time_direct = reacht(&CurRD, &TagRD);
|
||||||
// new point after flipping
|
// new point after flipping
|
||||||
polarCrds_t flip_candidate;
|
polarCrds_t flip_candidate;
|
||||||
get_flip_target(&TagRD, &flip_candidate);
|
get_flip_target(&TagRD, &flip_candidate);
|
||||||
// distance for moving with flip
|
// distance for moving with flip
|
||||||
double dist_flip = axdist(&CurRD, &flip_candidate);
|
double time_flip = reacht(&CurRD, &flip_candidate);
|
||||||
|
|
||||||
if(dist_flip < dist_direct){
|
if(time_flip < time_direct){
|
||||||
// need to make flip: it's shorter
|
// need to make flip: it's shorter
|
||||||
flip_target = flip_candidate;
|
flip_target = flip_candidate;
|
||||||
flip_in_progress = true;
|
flip_in_progress = true;
|
||||||
DBG("Flip chosen: direct=%.3fdeg, flip=%.3fdeg\n\n\n", RAD2DEG(dist_direct), RAD2DEG(dist_flip));
|
DBG("Target: ra=%gdeg, dec=%gdeg; flip target: ra=%gdeg, dec=%gdec", RAD2DEG(TagRD.ra), RAD2DEG(TagRD.dec), RAD2DEG(flip_candidate.ra), RAD2DEG(flip_candidate.dec));
|
||||||
|
DBG("Flip chosen: direct=%.3fsec, flip=%.3fsec\n\n\n", RAD2DEG(time_direct), RAD2DEG(time_flip));
|
||||||
}else{
|
}else{
|
||||||
flip_in_progress = false;
|
flip_in_progress = false;
|
||||||
DBG("Move directly: direct=%.3fdeg, flip=%.3fdeg\n\n\n", RAD2DEG(dist_direct), RAD2DEG(dist_flip));
|
DBG("Move directly: direct=%.3fsec, flip=%.3fsec\n\n\n", RAD2DEG(time_direct), RAD2DEG(time_flip));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// flip target is the same as TagRD, but with RA+=12h and dec > 90deg
|
// flip target is the same as TagRD, but with RA+=12h and dec > 90deg
|
||||||
polarCrds_t *target = flip_in_progress ? &flip_target : &TagRD;
|
polarCrds_t *target = flip_in_progress ? &flip_target : &TagRD;
|
||||||
// RA difference over target and last position: [-pi, pi)
|
// RA difference over target and last position: [-pi, pi)
|
||||||
double dRA = eraAnpm(target->ra - CurRD.ra);
|
double dRA = eraAnpm(target->ra - CurRD.ra);
|
||||||
DBG("RA difference: %gdegr", RAD2DEG(dRA));
|
DBG("RA difference: %gdegr (tag: %g, cur: %g)", RAD2DEG(dRA), RAD2DEG(target->ra), RAD2DEG(CurRD.ra));
|
||||||
double dDec = eraAnpm(target->dec - CurRD.dec);
|
double dDec = eraAnpm(target->dec - CurRD.dec);
|
||||||
DBG("DEC difference: %gdegr", RAD2DEG(dDec));
|
DBG("DEC difference: %gdegr (tag: %g, cur: %g)", RAD2DEG(dDec), RAD2DEG(target->dec), RAD2DEG(CurRD.dec));
|
||||||
double dist = sqrt(dRA*dRA + dDec*dDec);
|
double dist = sqrt(dRA*dRA + dDec*dDec);
|
||||||
if(dist < POINTING_TOL){ // on position
|
double tra = fabs(dRA) / RASPEED, tdec = fabs(dDec) / DECSPEED;
|
||||||
|
double time_to_reach = (tra > tdec) ? tra : tdec;
|
||||||
|
double dt = tcur - tlast;
|
||||||
|
if(dist < POINTING_TOL || time_to_reach < dt){ // on position
|
||||||
|
DBG("ON Position, time to reach=%gs, dt=%gs\n\n\n", time_to_reach, dt);
|
||||||
if(pointAZ) emulation_stop(); // got A/Z position, stop
|
if(pointAZ) emulation_stop(); // got A/Z position, stop
|
||||||
else atomic_store(&emul_status, MNT_S_TRACKING);
|
else atomic_store(&emul_status, MNT_S_TRACKING);
|
||||||
if(flip_in_progress){
|
if(flip_in_progress) flip_in_progress = false;
|
||||||
flip_in_progress = false;
|
CurRD = TagRD; // fix to dec <=90
|
||||||
CurRD = TagRD; // fix to dec <=90
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
double dt = tcur - tlast;
|
DBG("dRA=%gdeg, dDEC=%gdegh\n\n\n", RAD2DEG(dRA), RAD2DEG(dDec));
|
||||||
double step = SPEED * dt;
|
double sign = (dRA > 0.) ? 1. : -1.;
|
||||||
if(step > dist) step = dist;
|
if(tra < dt) CurRD.ra = target->ra;
|
||||||
double factor = step / dist;
|
else CurRD.ra += dt * RASPEED * sign;
|
||||||
CurRD.ra += dRA * factor;
|
sign = (dDec > 0.) ? 1. : -1.;
|
||||||
CurRD.dec += dDec * factor;
|
if(tdec < dt) CurRD.dec = target->dec;
|
||||||
//if(CurRD.dec > ERFA_DPI/2.0) CurRD.dec = ERFA_DPI/2.0;
|
else CurRD.dec += dt * DECSPEED * sign;
|
||||||
//else if(CurRD.dec < -ERFA_DPI/2.0) CurRD.dec = -ERFA_DPI/2.0;
|
|
||||||
if(CurRD.ra < 0.) CurRD.ra += ERFA_D2PI;
|
if(CurRD.ra < 0.) CurRD.ra += ERFA_D2PI;
|
||||||
else if(CurRD.ra >= ERFA_D2PI) CurRD.ra -= ERFA_D2PI;
|
else if(CurRD.ra >= ERFA_D2PI) CurRD.ra -= ERFA_D2PI;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,14 @@
|
|||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
|
|
||||||
static pid_t childpid = -1; // PID of child process
|
static pid_t childpid = -1; // PID of child process
|
||||||
static const char *pidfile = NULL;
|
static parameters_t *G = NULL;
|
||||||
|
#ifndef EBUG
|
||||||
|
static bool isrunning = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
void signals(int sig){
|
void signals(int sig){
|
||||||
if(childpid){ // single or parent process
|
if(childpid){ // single or parent process
|
||||||
if(pidfile) unlink(pidfile); // remove pidfile
|
if(G->pidfile) unlink(G->pidfile); // remove pidfile
|
||||||
if(childpid > 0) kill(childpid, SIGTERM);
|
if(childpid > 0) kill(childpid, SIGTERM);
|
||||||
}
|
}
|
||||||
if(sig){
|
if(sig){
|
||||||
@@ -46,27 +49,42 @@ void signals(int sig){
|
|||||||
LOGWARN("Child %d died with %d", getpid(), sig);
|
LOGWARN("Child %d died with %d", getpid(), sig);
|
||||||
server_stop();
|
server_stop();
|
||||||
}
|
}
|
||||||
|
#ifndef EBUG
|
||||||
|
isrunning = true;
|
||||||
|
#endif
|
||||||
DBG("EXIT");
|
DBG("EXIT");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
sl_init();
|
sl_init();
|
||||||
parameters_t *G = parse_cmdline(&argc, &argv);
|
G = parse_cmdline(&argc, &argv);
|
||||||
if(!G) return 1;
|
if(!G) return 1;
|
||||||
sl_loglevel_e lvl = G->verbose + LOGLEVEL_ERR;
|
sl_loglevel_e lvl = G->verbose + LOGLEVEL_ERR;
|
||||||
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
||||||
DBG("verb: %d, level: %d", G->verbose, lvl);
|
DBG("verb: %d, level: %d", G->verbose, lvl);
|
||||||
int fd;
|
int fd;
|
||||||
if((fd = open(G->crdsfile, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) // test FITS-header file for writing
|
if((fd = open(G->crdsfile, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0){ // test FITS-header file for writing
|
||||||
ERR(_("Can't open %s for writing"), G->crdsfile);
|
WARN(_("Can't open %s for writing"), G->crdsfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
if(G->sleept < 1) ERRX("Sleeping time sould be positive value");
|
if(G->sleept < 1){
|
||||||
if(!server_setsleept(G->sleept)) ERRX("Can't set sleep time to %d", G->sleept);
|
WARNX("Sleeping time sould be positive value (%d)", G->sleept);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if(!server_setsleept(G->sleept)){
|
||||||
|
WARNX("Can't set sleep time to %d", G->sleept);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
if(G->emulation) set_emulation_mode();
|
if(G->emulation) set_emulation_mode();
|
||||||
else if(!mount_set_dev(G->device, G->serspeed, G->sertmout))
|
else if(!mount_set_dev(G->device, G->serspeed, G->sertmout)){
|
||||||
ERRX("Can't open device %s @ %d", G->device, G->serspeed);
|
WARNX("Can't open device %s @ %d", G->device, G->serspeed);
|
||||||
if(!mount_set_name(G->mountname))
|
return 4;
|
||||||
ERRX("Can't set mount name to %s", G->mountname);
|
}
|
||||||
|
if(!mount_set_name(G->mountname)){
|
||||||
|
WARNX("Can't set mount name to %s", G->mountname);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
signal(SIGTERM, signals);
|
signal(SIGTERM, signals);
|
||||||
signal(SIGINT, signals);
|
signal(SIGINT, signals);
|
||||||
signal(SIGQUIT, signals);
|
signal(SIGQUIT, signals);
|
||||||
@@ -78,7 +96,7 @@ int main(int argc, char **argv){
|
|||||||
LOGMSG("Started, master PID=%d", getpid());
|
LOGMSG("Started, master PID=%d", getpid());
|
||||||
#ifndef EBUG
|
#ifndef EBUG
|
||||||
time_t lastd = 0;
|
time_t lastd = 0;
|
||||||
while(1){ // guard for dead processes
|
while(isrunning){ // guard for dead processes
|
||||||
childpid = fork();
|
childpid = fork();
|
||||||
if(childpid < 0){
|
if(childpid < 0){
|
||||||
LOGERR("fork() returns error");
|
LOGERR("fork() returns error");
|
||||||
@@ -114,5 +132,5 @@ int main(int argc, char **argv){
|
|||||||
DBG("Run server");
|
DBG("Run server");
|
||||||
server_run();
|
server_run();
|
||||||
DBG("Server died");
|
DBG("Server died");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "10micron_commands.h"
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
|
|
||||||
@@ -30,12 +31,13 @@
|
|||||||
|
|
||||||
static bool isemulated = false; // ==true for emulation mode
|
static bool isemulated = false; // ==true for emulation mode
|
||||||
|
|
||||||
|
// default serial timeout, seconds
|
||||||
|
static double sertmout = 1.;
|
||||||
|
|
||||||
static char mount_name[MNAME_LEN+3] = "'noname'";
|
static char mount_name[MNAME_LEN+3] = "'noname'";
|
||||||
static sl_tty_t *mount_dev = NULL;
|
static sl_tty_t *mount_dev = NULL;
|
||||||
// device mutex, blocking only in non-local functions
|
// device mutex, blocking only in non-local functions
|
||||||
static pthread_mutex_t mntdev_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t mntdev_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
// ring buffer for data incoming from serial port
|
|
||||||
static sl_ringbuffer_t *RBin = NULL;
|
|
||||||
// status
|
// status
|
||||||
static atomic_int mountstatus = MNT_S_ERROR;
|
static atomic_int mountstatus = MNT_S_ERROR;
|
||||||
|
|
||||||
@@ -148,20 +150,25 @@ bool mount_set_name(const char *name){
|
|||||||
* @brief mount_set_dev - open mount device without checking that mount is alive
|
* @brief mount_set_dev - open mount device without checking that mount is alive
|
||||||
* @param dev - path to device
|
* @param dev - path to device
|
||||||
* @param speed - baudrate
|
* @param speed - baudrate
|
||||||
|
* @param timeout - timeout (seconds) for answer's waiting
|
||||||
* @return false if failed to open device `dev`
|
* @return false if failed to open device `dev`
|
||||||
*/
|
*/
|
||||||
bool mount_set_dev(char *dev, int speed, int timeout){
|
bool mount_set_dev(char *dev, int speed, double timeout){
|
||||||
pthread_mutex_lock(&mntdev_mutex);
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
if(mount_dev) sl_tty_close(&mount_dev);
|
if(mount_dev) sl_tty_close(&mount_dev);
|
||||||
mount_dev = sl_tty_new(dev, speed, 4096);
|
mount_dev = sl_tty_new(dev, speed, 4096);
|
||||||
if(mount_dev) mount_dev = sl_tty_open(mount_dev, 1);
|
if(mount_dev) mount_dev = sl_tty_open(mount_dev, 1);
|
||||||
if(!mount_dev){
|
if(!mount_dev){
|
||||||
pthread_mutex_unlock(&mntdev_mutex);
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
DBG("Can't init serial device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sl_tty_tmout(timeout);
|
DBG("Mount device inited and opened");
|
||||||
if(!RBin) RBin = sl_RB_new(BUFSIZ);
|
// set terminal timeout to `timeout / 10` or 100ms
|
||||||
else sl_RB_clearbuf(RBin);
|
int usecs = (timeout < 1.) ? (int)(timeout * 1e5) : 100000;
|
||||||
|
sl_tty_tmout(usecs);
|
||||||
|
sertmout = timeout;
|
||||||
|
DBG("set timeout of answer waiting to %gs", sertmout);
|
||||||
pthread_mutex_unlock(&mntdev_mutex);
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -179,7 +186,8 @@ static const char *statuses[MNT_S_STATAMOUNT] = {
|
|||||||
[MNT_S_OUTLIMIT] = "'Outside tracking limit'",
|
[MNT_S_OUTLIMIT] = "'Outside tracking limit'",
|
||||||
[MNT_S_FOLSAT]= "'Following satellite'",
|
[MNT_S_FOLSAT]= "'Following satellite'",
|
||||||
[MNT_S_DATINCOSIST]= "'Data inconsistency'",
|
[MNT_S_DATINCOSIST]= "'Data inconsistency'",
|
||||||
[MNT_S_ERROR] = "'Error (disconnected?)'"
|
[MNT_S_ERROR] = "'Error'",
|
||||||
|
[MNT_S_OFF] = "'Off'"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -187,53 +195,138 @@ static const char *statuses[MNT_S_STATAMOUNT] = {
|
|||||||
* @param status - integer status code
|
* @param status - integer status code
|
||||||
* @return statically allocated string with explanation
|
* @return statically allocated string with explanation
|
||||||
*/
|
*/
|
||||||
const char* mount_status_str(){
|
const char* mount_status_str(mount_status_t st){
|
||||||
int curst = (isemulated) ? emulation_status() : atomic_load(&mountstatus);
|
if(st < MNT_S_STATAMOUNT) return statuses[st];
|
||||||
if(curst > -1 && curst < MNT_S_STATAMOUNT) return statuses[curst];
|
|
||||||
return "'Unknown status'";
|
return "'Unknown status'";
|
||||||
}
|
}
|
||||||
// return current mount status
|
|
||||||
mount_status_t mount_status(){
|
|
||||||
return (mount_status_t)atomic_load(&mountstatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief write_cmd - try to write command to mount
|
* @brief send_cmd_resp - send command and wait for '#'-terminated response
|
||||||
* @param cmd - string with command or NULL just to clear all incoming data
|
* @param cmd - command (e.g. ":Sr12.345#")
|
||||||
* @return false on write/read error; all read information is in RBin (even if `false` returned, you SHOULD read all available strings from it)
|
* @param resp - buffer for response (may be NULL)
|
||||||
|
* @param resplen - its size
|
||||||
|
* @return true if '#'-terminated response received before timeout
|
||||||
*/
|
*/
|
||||||
static bool write_cmd(const char *cmd){
|
static bool send_cmd_resp(const char *cmd, char *resp, size_t resplen){
|
||||||
bool ret = true;
|
if(!mount_dev) return false;
|
||||||
if(cmd){
|
while(sl_tty_read(mount_dev) > 0); // clear tty buffer
|
||||||
size_t l = strlen(cmd);
|
if(!cmd) return false; // just clear buffer when cmd==NULL
|
||||||
if(sl_tty_write(mount_dev->comfd, cmd, l)) ret = false;
|
DBG("Command '%s', fd: %d", cmd, mount_dev->comfd);
|
||||||
|
if(sl_tty_write(mount_dev->comfd, cmd, strlen(cmd))){
|
||||||
|
WARN("sl_tty_write()");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
int got = 0;
|
if(resp && resplen) resp[0] = 0;
|
||||||
while((got = sl_tty_read(mount_dev)) > 0){
|
size_t pos = 0;
|
||||||
if(sl_RB_write(RBin, (uint8_t*) mount_dev->buf, got)){
|
double t0 = sl_dtime();
|
||||||
got = -1;
|
bool gotEOM = false;
|
||||||
break;
|
while(sl_dtime() - t0 < sertmout){
|
||||||
|
int got = sl_tty_read(mount_dev);
|
||||||
|
if(got < 0){
|
||||||
|
WARN("sl_tty_read()");
|
||||||
|
if(resp && resplen) resp[pos < resplen ? pos : resplen-1] = 0;
|
||||||
|
DBG("pos: %zd, resp: '%s'", pos, resp);
|
||||||
|
return false;
|
||||||
|
} else if(pos && got == 0) break; // break if we already receive the message
|
||||||
|
for(int i = 0; i < got; ++i){
|
||||||
|
char c = mount_dev->buf[i];
|
||||||
|
if(c == '\r' || c == '\n') continue; // WTF?
|
||||||
|
if(c == '#'){ // end of message
|
||||||
|
gotEOM = true;
|
||||||
|
//if(resp && resplen) resp[pos < resplen ? pos : resplen-1] = 0;
|
||||||
|
//DBG("Got end of message: '%s' (waited for %gs)", resp, );
|
||||||
|
//return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(resp && pos + 1 < resplen) resp[pos++] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(got < 0) return false;
|
DBG("Waited for %gs", sl_dtime() - t0);
|
||||||
return ret;
|
if(resp && resplen){
|
||||||
|
resp[pos < resplen ? pos : resplen-1] = 0;
|
||||||
|
DBG("pos: %zd, resp: '%s'", pos, resp);
|
||||||
|
// 10Micron/LX200-like: '0' or 'E'/'e' -> error; '1' - OK
|
||||||
|
if(gotEOM || (pos == 1 && resp[0] == '1')) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief write_cmd - try to write command to mount and check answer for not false/error
|
||||||
|
* @param cmd - string with command or NULL just to clear all incoming data
|
||||||
|
* @param haveanswer - true if mount have to answer to `cmd`
|
||||||
|
* @return false on write/read error or error in answer
|
||||||
|
*/
|
||||||
|
static bool write_cmd(const char *cmd, bool haveanswer){
|
||||||
|
char buf[128];
|
||||||
|
if(!haveanswer){
|
||||||
|
DBG("Command '%s'", cmd);
|
||||||
|
if(!mount_dev || !cmd){
|
||||||
|
DBG("no mount device?");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(sl_tty_write(mount_dev->comfd, cmd, strlen(cmd))){
|
||||||
|
DBG("Error writing request '%s'", cmd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while(sl_tty_read(mount_dev) > 0);
|
||||||
|
}else if(!send_cmd_resp(cmd, buf, 128)){
|
||||||
|
DBG("Error writing command '%s'", cmd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return current mount status
|
||||||
|
mount_status_t mount_status(){
|
||||||
|
mount_status_t curst = (mount_status_t)atomic_load(&mountstatus);
|
||||||
|
if(curst == MNT_S_OFF) return curst; // do nothing when mount if off
|
||||||
|
if(!mount_dev){
|
||||||
|
atomic_store(&mountstatus, MNT_S_OFF);
|
||||||
|
return MNT_S_OFF;
|
||||||
|
}
|
||||||
|
char resp[64];
|
||||||
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
int ntry = 0;
|
||||||
|
for(; ntry < 3; ++ntry)
|
||||||
|
if(send_cmd_resp(CMD_GETSTAT, resp, 64)) break;
|
||||||
|
if(ntry == 3){ // mount not responded -> set status OFF
|
||||||
|
curst = MNT_S_OFF;
|
||||||
|
}else{ // parsing of status
|
||||||
|
char *nxt = NULL;
|
||||||
|
long statN = strtol(resp, &nxt, 10);
|
||||||
|
//DBG("resp=%s, nxt=%s, stat=%ld", resp, nxt, statN);
|
||||||
|
if(!nxt || *nxt || statN >= MNT_S_ERROR || statN < 0) curst = MNT_S_ERROR; // wrong answer
|
||||||
|
else curst = (mount_status_t) statN;
|
||||||
|
DBG("STATUS: %s (%d)", statuses[curst], curst);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
atomic_store(&mountstatus, curst);
|
||||||
|
return curst;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if mount connected
|
// check if mount connected
|
||||||
static bool chkconn(){
|
static bool chkconn(){
|
||||||
|
FNAME();
|
||||||
int r = 0;
|
int r = 0;
|
||||||
do{ // clear incoming buffer @ start
|
do{ // clear incoming buffer @ start
|
||||||
r = sl_tty_read(mount_dev);
|
r = sl_tty_read(mount_dev);
|
||||||
}while(r > 0);
|
}while(r > 0);
|
||||||
if(r < 0) return false;
|
if(r < 0){
|
||||||
write_cmd("#"); // clear cmd buffer
|
WARN("Error reading");
|
||||||
sl_RB_clearbuf(RBin);
|
DBG("error reading: got %d", r);
|
||||||
bool w = write_cmd(":SB0#");
|
return false;
|
||||||
sl_RB_clearbuf(RBin);
|
}
|
||||||
return w;
|
write_cmd("#", false); // clear cmd buffer
|
||||||
|
bool ret = false;
|
||||||
|
for(int i = 0; i < 5; ++i){
|
||||||
|
DBG("Try %d", i+1);
|
||||||
|
ret = write_cmd(CMD_BAUDRATE, true);
|
||||||
|
if(ret) break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// try to guess serial speed & set 115200
|
// try to guess serial speed & set 115200
|
||||||
static bool guess_speed(){
|
static bool guess_speed(){
|
||||||
if(!mount_dev) return false;
|
if(!mount_dev) return false;
|
||||||
@@ -242,6 +335,7 @@ static bool guess_speed(){
|
|||||||
const int speeds[SPDBUFSZ] = {57600, 38400, 19200, 9600, 4800, 2400, 1200};
|
const int speeds[SPDBUFSZ] = {57600, 38400, 19200, 9600, 4800, 2400, 1200};
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for(; idx < SPDBUFSZ; ++idx){
|
for(; idx < SPDBUFSZ; ++idx){
|
||||||
|
DBG("try speed %d", speeds[idx]);
|
||||||
mount_dev->speed = speeds[idx];
|
mount_dev->speed = speeds[idx];
|
||||||
sl_tty_t *trydev = sl_tty_open(mount_dev, 1);
|
sl_tty_t *trydev = sl_tty_open(mount_dev, 1);
|
||||||
if(!trydev) continue;
|
if(!trydev) continue;
|
||||||
@@ -252,6 +346,7 @@ static bool guess_speed(){
|
|||||||
close(mount_dev->comfd);
|
close(mount_dev->comfd);
|
||||||
mount_dev->speed = 115200;
|
mount_dev->speed = 115200;
|
||||||
if(!sl_tty_open(mount_dev, 1)) return false;
|
if(!sl_tty_open(mount_dev, 1)) return false;
|
||||||
|
DBG("OK, opened @ 115200");
|
||||||
#undef SPDBUFSZ
|
#undef SPDBUFSZ
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -261,14 +356,16 @@ bool mount_connect(){
|
|||||||
if(isemulated) return true;
|
if(isemulated) return true;
|
||||||
if(!mount_dev) return false;
|
if(!mount_dev) return false;
|
||||||
pthread_mutex_lock(&mntdev_mutex);
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
if(!chkconn() && !guess_speed()) return false;
|
if(!chkconn() && !guess_speed()){
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
if(!write_cmd(":STOP#")) ret = false; // stop tracking after poweron
|
if(!write_cmd(CMD_STOP, false)) ret = false; // stop tracking after poweron
|
||||||
sl_RB_clearbuf(RBin);
|
if(!write_cmd(CMD_HIGHPREC, false)) ret = false; // set high precision
|
||||||
if(!write_cmd(":U2#")) ret = false; // set high precision
|
char buf[64];
|
||||||
sl_RB_clearbuf(RBin);
|
snprintf(buf, 63, CMD_SETMINALT, 10);
|
||||||
if(!write_cmd(":So10#")) ret = false; // set minimum altitude to 10 degrees
|
if(!write_cmd(buf, true)) ret = false; // set minimum altitude to 10 degrees
|
||||||
sl_RB_clearbuf(RBin);
|
|
||||||
pthread_mutex_unlock(&mntdev_mutex);
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
if(ret) LOGMSG("Connected to %s@115200", mount_dev->portname);
|
if(ret) LOGMSG("Connected to %s@115200", mount_dev->portname);
|
||||||
else LOGERR("Can't write commands to mount");
|
else LOGERR("Can't write commands to mount");
|
||||||
@@ -292,23 +389,71 @@ void mount_disconnect(){
|
|||||||
* @return true if all OK
|
* @return true if all OK
|
||||||
*/
|
*/
|
||||||
bool mount_point(double ra, double dec){
|
bool mount_point(double ra, double dec){
|
||||||
char buf[RADEC_STR_MAXLEN];
|
char rastr[RADEC_STR_MAXLEN], decstr[RADEC_STR_MAXLEN];
|
||||||
radec2str(ra, dec, buf);
|
|
||||||
DBG("Set RA/Decl to %s", buf);
|
|
||||||
LOGMSG("Try to set RA/Decl to %s", buf);
|
|
||||||
norm_RADEC(&ra, &dec);
|
norm_RADEC(&ra, &dec);
|
||||||
|
ra2str(ra, rastr);
|
||||||
|
dec2str(dec, decstr);
|
||||||
|
DBG("Set RA/Decl to %s/%s", rastr, decstr);
|
||||||
|
LOGMSG("Try to set RA/Decl to %s/%s", rastr, decstr);
|
||||||
if(isemulated) return point_emulation(ra, dec);
|
if(isemulated) return point_emulation(ra, dec);
|
||||||
// run real pointing to ra(hrs) & dec (deg)
|
if(!mount_dev) return false;
|
||||||
return false;
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
char cmd[128];
|
||||||
|
bool ret = false;
|
||||||
|
snprintf(cmd, 127, CMD_SETRA, rastr); // send RA
|
||||||
|
if(!write_cmd(cmd, true)) goto retn;
|
||||||
|
snprintf(cmd, 127, CMD_SETDEC, decstr); // send Dec
|
||||||
|
if(!write_cmd(cmd, true)) goto retn;
|
||||||
|
if(send_cmd_resp(CMD_SLEWRADEC, cmd, 127)){ // check error
|
||||||
|
if(*cmd != '0'){
|
||||||
|
WARNX("Slew error, answer: %s", cmd);
|
||||||
|
LOGWARN("Slew error, answer: %s", cmd);
|
||||||
|
goto retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = true;
|
||||||
|
retn:
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mount_pointAZ - point to stationary coordinates
|
||||||
|
* @param A - azumuth (degrees): CLOCKWISE FROM NORTH!!!
|
||||||
|
* @param Z - zenith (degrees)
|
||||||
|
* @return false if failed
|
||||||
|
*/
|
||||||
bool mount_pointAZ(double A, double Z){
|
bool mount_pointAZ(double A, double Z){
|
||||||
DBG("Point to stationary object, A=%g, Z=%g", A, Z);
|
char altstr[RADEC_STR_MAXLEN], azstr[RADEC_STR_MAXLEN];
|
||||||
|
if(!normAZ(&A, &Z)){
|
||||||
|
DBG("Wrong Z?");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
d2sDMS(A, azstr, RADEC_STR_MAXLEN);
|
||||||
|
d2sDMS(90. - Z, altstr, RADEC_STR_MAXLEN);
|
||||||
|
DBG("Point to stationary object, Az=%s, Alt=%s", azstr, altstr);
|
||||||
if(isemulated){
|
if(isemulated){
|
||||||
return pointAZ_emulation(A, Z);
|
return pointAZ_emulation(A, Z);
|
||||||
}
|
}
|
||||||
; // run real pointing
|
if(!mount_dev) return false;
|
||||||
return false;
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
bool ret = false;
|
||||||
|
char cmd[128];
|
||||||
|
snprintf(cmd, 127, CMD_SETALT, altstr);
|
||||||
|
if(!write_cmd(cmd, true)) goto retn;
|
||||||
|
snprintf(cmd, 127, CMD_SETZD, azstr);
|
||||||
|
if(!write_cmd(cmd, true)) goto retn;
|
||||||
|
if(send_cmd_resp(CMD_GOTOAZ, cmd, 127)){ // returned not '0'
|
||||||
|
if(*cmd != '0'){
|
||||||
|
WARNX("Goto error, answer: %s", cmd);
|
||||||
|
LOGWARN("Goto error, answer: %s", cmd);
|
||||||
|
goto retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = true;
|
||||||
|
retn:
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_emulation_mode(){
|
void set_emulation_mode(){
|
||||||
@@ -322,8 +467,49 @@ mount_status_t mount_getcoords(double *ra, double *dec){
|
|||||||
DBG("Emulated coordinates: %gh, %gdeg", RAD2HRS(*ra), RAD2DEG(*dec));
|
DBG("Emulated coordinates: %gh, %gdeg", RAD2HRS(*ra), RAD2DEG(*dec));
|
||||||
return emulation_status();
|
return emulation_status();
|
||||||
}
|
}
|
||||||
; // get real coordinates
|
if(!mount_dev) return MNT_S_ERROR;
|
||||||
return mount_status();
|
char resp[64];
|
||||||
|
mount_status_t st = MNT_S_ERROR;
|
||||||
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
if(!send_cmd_resp(CMD_GETRA, resp, 64)) goto retn;
|
||||||
|
if(!str2coord(resp, ra)) goto retn;
|
||||||
|
if(!send_cmd_resp(CMD_GETDEC, resp, 64)) goto retn;
|
||||||
|
if(!str2coord(resp, dec)) goto retn;
|
||||||
|
st = MNT_S_STATAMOUNT;
|
||||||
|
retn:
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
if(st == MNT_S_STATAMOUNT) st = mount_status();
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_status_t mount_getaz(double *a, double *z){
|
||||||
|
if(!a || !z) return MNT_S_ERROR;
|
||||||
|
if(isemulated){
|
||||||
|
double ra, dec;
|
||||||
|
get_emul_coords(&ra, &dec);
|
||||||
|
polarCrds_t P = {.dec = dec, .ra = ra};
|
||||||
|
horizCrds_t H;
|
||||||
|
double LST;
|
||||||
|
get_LST(NULL, &LST);
|
||||||
|
eq2hor(&P, &H, LST);
|
||||||
|
*a = H.az; *z = H.zd;
|
||||||
|
return emulation_status();
|
||||||
|
}
|
||||||
|
if(!mount_dev) return MNT_S_ERROR;
|
||||||
|
char resp[64];
|
||||||
|
mount_status_t st = MNT_S_ERROR;
|
||||||
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
if(!send_cmd_resp(CMD_GETAZIM, resp, 64)) goto retn;
|
||||||
|
if(!str2coord(resp, a)) goto retn;
|
||||||
|
if(!send_cmd_resp(CMD_GETALT, resp, 64)) goto retn;
|
||||||
|
double alt;
|
||||||
|
if(!str2coord(resp, &alt)) goto retn;
|
||||||
|
*z = 90. - alt;
|
||||||
|
st = MNT_S_STATAMOUNT;
|
||||||
|
retn:
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
if(st == MNT_S_STATAMOUNT) st = mount_status();
|
||||||
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,10 +519,27 @@ mount_status_t mount_getcoords(double *ra, double *dec){
|
|||||||
bool mount_stop(){
|
bool mount_stop(){
|
||||||
if(isemulated){
|
if(isemulated){
|
||||||
emulation_stop();
|
emulation_stop();
|
||||||
}else{
|
return true;
|
||||||
return mount_stop();
|
|
||||||
}
|
}
|
||||||
return true;
|
if(!mount_dev) return false;
|
||||||
|
bool ret = false;
|
||||||
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
if(write_cmd(CMD_STOP, false)) ret = true;
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mount_tracking_stop(){
|
||||||
|
if(isemulated){
|
||||||
|
emulation_stop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(!mount_dev) return false;
|
||||||
|
bool ret = false;
|
||||||
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
if(write_cmd(CMD_TRKSTOP, false)) ret = true;
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -346,10 +549,15 @@ bool mount_stop(){
|
|||||||
bool mount_tracking_start(){
|
bool mount_tracking_start(){
|
||||||
if(isemulated){
|
if(isemulated){
|
||||||
emul_start_tracking();
|
emul_start_tracking();
|
||||||
}else{
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
if(!mount_dev) return false;
|
||||||
|
bool ret = false;
|
||||||
|
pthread_mutex_lock(&mntdev_mutex);
|
||||||
|
write_cmd(CMD_TRKSTOP, false); // workaround from command protocol if mount was stopped with :STOP#
|
||||||
|
if(write_cmd(CMD_TRKSTART, false)) ret = true;
|
||||||
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -358,7 +566,8 @@ bool mount_tracking_start(){
|
|||||||
*/
|
*/
|
||||||
bool mount_park(){
|
bool mount_park(){
|
||||||
if(isemulated) return pointAZ_emulation(ParkCoords.az, ParkCoords.zd);
|
if(isemulated) return pointAZ_emulation(ParkCoords.az, ParkCoords.zd);
|
||||||
return mount_pointAZ(ParkCoords.az, ParkCoords.zd);
|
// TODO: set lower limit to 0deg
|
||||||
|
return mount_pointAZ(RAD2DEG(ParkCoords.az), RAD2DEG(ParkCoords.zd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,8 +34,9 @@ typedef enum{
|
|||||||
MNT_S_OUTLIMIT = 9,
|
MNT_S_OUTLIMIT = 9,
|
||||||
MNT_S_FOLSAT = 10,
|
MNT_S_FOLSAT = 10,
|
||||||
MNT_S_DATINCOSIST = 11,
|
MNT_S_DATINCOSIST = 11,
|
||||||
MNT_S_ERROR = 12, // my status
|
MNT_S_ERROR = 12, // status 98/99 (>11)
|
||||||
MNT_S_STATAMOUNT = 13 // number of statuses
|
MNT_S_OFF, // not responding -> off
|
||||||
|
MNT_S_STATAMOUNT // number of statuses
|
||||||
} mount_status_t;
|
} mount_status_t;
|
||||||
|
|
||||||
void set_emulation_mode();
|
void set_emulation_mode();
|
||||||
@@ -54,16 +55,18 @@ double mount_getInpHor(horizCrds_t *c);
|
|||||||
|
|
||||||
|
|
||||||
bool mount_set_name(const char *name);
|
bool mount_set_name(const char *name);
|
||||||
bool mount_set_dev(char *dev, int speed, int timeout);
|
bool mount_set_dev(char *dev, int speed, double timeout);
|
||||||
const char* mount_status_str();
|
const char* mount_status_str(mount_status_t st);
|
||||||
mount_status_t mount_status();
|
mount_status_t mount_status();
|
||||||
bool mount_connect();
|
bool mount_connect();
|
||||||
void mount_disconnect();
|
void mount_disconnect();
|
||||||
|
|
||||||
mount_status_t mount_getcoords(double *ra, double *dec);
|
mount_status_t mount_getcoords(double *ra, double *dec);
|
||||||
|
mount_status_t mount_getaz(double *a, double *z);
|
||||||
bool mount_point(double ra, double dec);
|
bool mount_point(double ra, double dec);
|
||||||
bool mount_pointAZ(double A, double Z);
|
bool mount_pointAZ(double A, double Z);
|
||||||
bool mount_stop();
|
bool mount_stop();
|
||||||
|
bool mount_tracking_stop();
|
||||||
bool mount_tracking_start();
|
bool mount_tracking_start();
|
||||||
bool mount_park();
|
bool mount_park();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 19.0.2, 2026-06-10T13:41:37. -->
|
<!-- Written by QtCreator 20.0.1, 2026-09-22T14:24:31. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
@@ -14,8 +14,6 @@
|
|||||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
|
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
|
||||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
<value type="QString" key="language">Cpp</value>
|
<value type="QString" key="language">Cpp</value>
|
||||||
<valuemap type="QVariantMap" key="value">
|
<valuemap type="QVariantMap" key="value">
|
||||||
@@ -30,33 +28,15 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
|
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
|
||||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">false</value>
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">false</value>
|
||||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">1</value>
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">1</value>
|
||||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
|
||||||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
|
<value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
|
||||||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
|
||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
@@ -76,11 +56,7 @@
|
|||||||
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
||||||
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
||||||
<valuemap type="QVariantMap" key="ClangTools">
|
<valuemap type="QVariantMap" key="ClangTools">
|
||||||
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
<value type="Utils::Id" key="ClangTools.DiagnosticConfig"></value>
|
||||||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
|
||||||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
|
||||||
<value type="int" key="ClangTools.ParallelJobs">4</value>
|
|
||||||
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
@@ -132,7 +108,7 @@
|
|||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
<value type="UnknownType" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"></value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
@@ -159,7 +135,7 @@
|
|||||||
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
<value type="UnknownType" key="PE.EnvironmentAspect.Changes"></value>
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
@@ -195,7 +171,7 @@
|
|||||||
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
<value type="UnknownType" key="PE.EnvironmentAspect.Changes"></value>
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
10micron_commands.h
|
||||||
angles.c
|
angles.c
|
||||||
angles.h
|
angles.h
|
||||||
args.c
|
args.c
|
||||||
|
|||||||
@@ -45,10 +45,12 @@
|
|||||||
#define CMD_TAGZD "tagzd"
|
#define CMD_TAGZD "tagzd"
|
||||||
#define CMD_TELRA "telra"
|
#define CMD_TELRA "telra"
|
||||||
#define CMD_TELDEC "teldec"
|
#define CMD_TELDEC "teldec"
|
||||||
|
#define CMD_TELAZ "telaz"
|
||||||
|
#define CMD_TELZD "telzd"
|
||||||
#define CMD_GOTORD "gotord"
|
#define CMD_GOTORD "gotord"
|
||||||
#define CMD_GOTORH "gotorh"
|
#define CMD_GOTORH "gotorh"
|
||||||
#define CMD_GOTOAZ "gotoaz"
|
#define CMD_GOTOAZ "gotoaz"
|
||||||
#define CMD_STOP "stop"
|
#define CMD_STOPTRK "stoptrk"
|
||||||
#define CMD_TRACK "track"
|
#define CMD_TRACK "track"
|
||||||
#define CMD_PARK "park"
|
#define CMD_PARK "park"
|
||||||
#define CMD_PARKAZ "parkaz"
|
#define CMD_PARKAZ "parkaz"
|
||||||
@@ -84,7 +86,8 @@ static sl_sock_hresult_e dtimeh(sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ con
|
|||||||
// statust - text format status
|
// statust - text format status
|
||||||
static sl_sock_hresult_e status(sl_sock_t *c, sl_sock_hitem_t *item, _U_ const char *req){
|
static sl_sock_hresult_e status(sl_sock_t *c, sl_sock_hitem_t *item, _U_ const char *req){
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
snprintf(buf, BUFSIZ-1, "%s=%s\n", item->key, mount_status_str());
|
mount_status_t st = mount_status();
|
||||||
|
snprintf(buf, BUFSIZ-1, "%s=%s\n", item->key, mount_status_str(st));
|
||||||
LOGDBG("Client %d asks status: %s", c->fd, buf);
|
LOGDBG("Client %d asks status: %s", c->fd, buf);
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -94,7 +97,9 @@ static int parse_key_value(const char *req, double *val){
|
|||||||
if(!req) return 0; // is getter
|
if(!req) return 0; // is getter
|
||||||
DBG("parsing of %s", req);
|
DBG("parsing of %s", req);
|
||||||
double d;
|
double d;
|
||||||
if(sscanf(req, "%lf", &d) != 1) return -1; // error
|
if(strchr(req, ':')){ // DD:MM:SS or HH:MM:SS
|
||||||
|
if(!str2coord(req, &d)) return -1;
|
||||||
|
}else if(sscanf(req, "%lf", &d) != 1) return -1; // error
|
||||||
if(val) *val = d;
|
if(val) *val = d;
|
||||||
return 1; // is setter
|
return 1; // is setter
|
||||||
}
|
}
|
||||||
@@ -112,7 +117,7 @@ static sl_sock_hresult_e cmd_tagra(sl_sock_t *c, sl_sock_hitem_t *item, const ch
|
|||||||
mount_getInpCoords(&p);
|
mount_getInpCoords(&p);
|
||||||
double ra_h = RAD2HRS(p.ra);
|
double ra_h = RAD2HRS(p.ra);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, ra_h);
|
snprintf(buf, 63, "%s=%.6f\n", item->key, ra_h);
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -130,7 +135,7 @@ static sl_sock_hresult_e cmd_tagdec(sl_sock_t *c, sl_sock_hitem_t *item, const c
|
|||||||
mount_getInpCoords(&p);
|
mount_getInpCoords(&p);
|
||||||
double dec_d = RAD2DEG(p.dec);
|
double dec_d = RAD2DEG(p.dec);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, dec_d);
|
snprintf(buf, 63, "%s=%.6f\n", item->key, dec_d);
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -148,7 +153,7 @@ static sl_sock_hresult_e cmd_tagha(sl_sock_t *c, sl_sock_hitem_t *item, const ch
|
|||||||
mount_getInpCoords(&p);
|
mount_getInpCoords(&p);
|
||||||
double ha_h = RAD2HRS(p.ha);
|
double ha_h = RAD2HRS(p.ha);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, ha_h);
|
snprintf(buf, 63, "%s=%.6f\n", item->key, ha_h);
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -166,7 +171,7 @@ static sl_sock_hresult_e cmd_tagaz(sl_sock_t *c, sl_sock_hitem_t *item, const ch
|
|||||||
mount_getInpHor(&h);
|
mount_getInpHor(&h);
|
||||||
double az_d = RAD2DEG(h.az);
|
double az_d = RAD2DEG(h.az);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, az_d);
|
snprintf(buf, 63, "%s=%.6f\n", item->key, az_d);
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -184,7 +189,7 @@ static sl_sock_hresult_e cmd_tagzd(sl_sock_t *c, sl_sock_hitem_t *item, const ch
|
|||||||
mount_getInpHor(&h);
|
mount_getInpHor(&h);
|
||||||
double zd_d = RAD2DEG(h.zd);
|
double zd_d = RAD2DEG(h.zd);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, zd_d);
|
snprintf(buf, 63, "%s=%.6f\n", item->key, zd_d);
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -194,8 +199,7 @@ static sl_sock_hresult_e cmd_telra(sl_sock_t *c, sl_sock_hitem_t *item, _U_ cons
|
|||||||
double ra, dec;
|
double ra, dec;
|
||||||
if(mount_getcoords(&ra, &dec) == MNT_S_ERROR) return RESULT_FAIL;
|
if(mount_getcoords(&ra, &dec) == MNT_S_ERROR) return RESULT_FAIL;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
double ra_h = RAD2HRS(ra);
|
snprintf(buf, 63, "%s=%.6f\n", item->key, ra);
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, ra_h);
|
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
}
|
}
|
||||||
@@ -204,8 +208,25 @@ static sl_sock_hresult_e cmd_teldec(sl_sock_t *c, sl_sock_hitem_t *item, _U_ con
|
|||||||
double ra, dec;
|
double ra, dec;
|
||||||
if(mount_getcoords(&ra, &dec) == MNT_S_ERROR) return RESULT_FAIL;
|
if(mount_getcoords(&ra, &dec) == MNT_S_ERROR) return RESULT_FAIL;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
double dec_d = RAD2DEG(dec);
|
snprintf(buf, 63, "%s=%.6f\n", item->key, dec);
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, dec_d);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_telaz(sl_sock_t *c, sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
double a, z;
|
||||||
|
if(mount_getaz(&a, &z) == MNT_S_ERROR) return RESULT_FAIL;
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, 63, "%s=%.6f\n", item->key, a);
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_telzd(sl_sock_t *c, sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
double a, z;
|
||||||
|
if(mount_getaz(&a, &z) == MNT_S_ERROR) return RESULT_FAIL;
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, 63, "%s=%.6f\n", item->key, z);
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
}
|
}
|
||||||
@@ -241,8 +262,13 @@ static sl_sock_hresult_e cmd_gotoaz(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static sl_sock_hresult_e cmd_stop(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
static sl_sock_hresult_e cmd_stop(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
mount_stop();
|
if(mount_stop()) return RESULT_OK;
|
||||||
return RESULT_OK;
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_stoptrk(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
if(mount_tracking_stop()) return RESULT_OK;
|
||||||
|
return RESULT_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run tracking from current position
|
// run tracking from current position
|
||||||
@@ -268,7 +294,7 @@ static sl_sock_hresult_e cmd_parkaz(sl_sock_t *c, sl_sock_hitem_t *item, const c
|
|||||||
horizCrds_t h;
|
horizCrds_t h;
|
||||||
mount_getPark(&h);
|
mount_getPark(&h);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, RAD2DEG(h.az));
|
snprintf(buf, 63, "%s=%.6f\n", item->key, RAD2DEG(h.az));
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -284,7 +310,7 @@ static sl_sock_hresult_e cmd_parkzd(sl_sock_t *c, sl_sock_hitem_t *item, const c
|
|||||||
horizCrds_t h;
|
horizCrds_t h;
|
||||||
mount_getPark(&h);
|
mount_getPark(&h);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, RAD2DEG(h.zd));
|
snprintf(buf, 63, "%s=%.6f\n", item->key, RAD2DEG(h.zd));
|
||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
}
|
}
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
@@ -309,6 +335,9 @@ static sl_sock_hitem_t handlers[] = {
|
|||||||
{cmd_tagzd, CMD_TAGZD, "get/set target zenith distance (Deg)", NULL},
|
{cmd_tagzd, CMD_TAGZD, "get/set target zenith distance (Deg)", NULL},
|
||||||
{cmd_teldec, CMD_TELDEC, "get current telescope declination (Deg)", NULL},
|
{cmd_teldec, CMD_TELDEC, "get current telescope declination (Deg)", NULL},
|
||||||
{cmd_telra, CMD_TELRA, "get current telescope right acsention (Hrs)", NULL},
|
{cmd_telra, CMD_TELRA, "get current telescope right acsention (Hrs)", NULL},
|
||||||
|
{cmd_telaz, CMD_TELAZ, "get current telescope azimuth (Deg)", NULL},
|
||||||
|
{cmd_telzd, CMD_TELZD, "get current telescope zenith distance (Deg)", NULL},
|
||||||
|
{cmd_stoptrk, CMD_STOPTRK, "stop tracking", NULL},
|
||||||
{cmd_track, CMD_TRACK, "start tracking from current position", NULL},
|
{cmd_track, CMD_TRACK, "start tracking from current position", NULL},
|
||||||
{dtimeh, CMD_UNIXT, "get server's UNIX time", NULL},
|
{dtimeh, CMD_UNIXT, "get server's UNIX time", NULL},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
@@ -395,20 +424,37 @@ void server_run(){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!mount_connect()){
|
if(!mount_connect()){
|
||||||
LOGERR("Can't connect to mount");
|
LOGWARN("Can't connect to mount, will try to reconnect later");
|
||||||
sl_sock_delete(&cmd_socket);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
isrunning = true;
|
isrunning = true;
|
||||||
DBG("While");
|
DBG("While");
|
||||||
|
double tcheck = 0.;
|
||||||
|
bool notlogged = true;
|
||||||
while(isrunning && cmd_socket && cmd_socket->connected){
|
while(isrunning && cmd_socket && cmd_socket->connected){
|
||||||
usleep(sleept);
|
usleep(sleept);
|
||||||
if(!cmd_socket->rthread){
|
if(!cmd_socket->rthread){
|
||||||
LOGERR("Server handlers thread is dead");
|
LOGERR("Server handlers thread is dead");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// finite state machine polling
|
// check mount state
|
||||||
//dome_poll(DOME_POLL, 0);
|
double tnow = sl_dtime();
|
||||||
|
if(tnow - tcheck >= MOUNT_CHECK_T){
|
||||||
|
tcheck = tnow;
|
||||||
|
mount_status_t curst = mount_status();
|
||||||
|
if(curst == MNT_S_OFF){ // mount is off -> try to reconnect
|
||||||
|
if(notlogged){
|
||||||
|
WARNX("Mount is OFF");
|
||||||
|
LOGWARN("Mount is OFF");
|
||||||
|
notlogged = false;
|
||||||
|
}
|
||||||
|
DBG("Try to [re]connect");
|
||||||
|
if(mount_connect()){
|
||||||
|
notlogged = true;
|
||||||
|
WARNX("Mount is ON");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG("Current status: %s", mount_status_str(curst));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DBG("Stop command socket");
|
DBG("Stop command socket");
|
||||||
sl_sock_delete(&cmd_socket);
|
sl_sock_delete(&cmd_socket);
|
||||||
|
|||||||
@@ -23,8 +23,13 @@
|
|||||||
// default and max available time for "usleep"
|
// default and max available time for "usleep"
|
||||||
#define DEFAULT_SLEEP_T 100
|
#define DEFAULT_SLEEP_T 100
|
||||||
#define MAX_SLEEP_T 10000
|
#define MAX_SLEEP_T 10000
|
||||||
|
|
||||||
|
// maximal amount of connected clients
|
||||||
#define DEFAULT_MAXCLIENTS 5
|
#define DEFAULT_MAXCLIENTS 5
|
||||||
|
|
||||||
|
// status checking interval, seconds
|
||||||
|
#define MOUNT_CHECK_T 10.
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
int cmd_isunix; // UNIX-socket instead of INET for `cmdnode`
|
int cmd_isunix; // UNIX-socket instead of INET for `cmdnode`
|
||||||
const char *stellport; // port of stellarium server; could be "localhost:port" for local-only work
|
const char *stellport; // port of stellarium server; could be "localhost:port" for local-only work
|
||||||
|
|||||||
Reference in New Issue
Block a user