telescope is moving; need to add some more commands & write FITS-header

This commit is contained in:
2026-09-24 17:51:41 +03:00
parent eb40fec59a
commit 8e796ce419
13 changed files with 553 additions and 183 deletions

View 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#"

View File

@@ -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;

View File

@@ -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);

View File

@@ -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,7 +59,7 @@ 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 ")"}, \
@@ -105,21 +105,35 @@ 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(conffile){
if(!sl_conf_readopts(conffile, confopts)){ // show conf help if(!sl_conf_readopts(conffile, confopts)){ // show conf help
sl_conf_showhelp(-1, confopts); sl_conf_showhelp(-1, confopts);
return NULL; 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");
STRCHKD(device, DEFAULT_COMDEV); STRCHKD(device, DEFAULT_COMDEV);
@@ -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;

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
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; break;
} }
if(resp && pos + 1 < resplen) resp[pos++] = c;
} }
if(got < 0) return false; }
return ret; DBG("Waited for %gs", sl_dtime() - t0);
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 mount_stop();
}
return true; 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 false;
}
return true; 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));
} }
/** /**

View File

@@ -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();

View File

@@ -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&lt;int&gt;" key="Analyzer.Valgrind.VisibleErrorKinds"></value> <value type="QList&lt;int&gt;" 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&lt;int&gt;" key="Analyzer.Valgrind.VisibleErrorKinds"></value> <value type="QList&lt;int&gt;" 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>

View File

@@ -1,3 +1,4 @@
10micron_commands.h
angles.c angles.c
angles.h angles.h
args.c args.c

View File

@@ -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);

View File

@@ -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