mirror of
https://github.com/eddyem/small_tel.git
synced 2026-08-12 09:39:28 +03:00
fixed some stupid errors
This commit is contained in:
@@ -72,8 +72,9 @@ bool setPlaceData(double longitude, double latitude, double altitude){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
place.salt = altitude;
|
place.salt = altitude;
|
||||||
place.slat = latitude;
|
place.slat = DEG2RAD(latitude);
|
||||||
place.slong = longitude;
|
place.slong = DEG2RAD(longitude);
|
||||||
|
DBG("Change place data: alt=%gm, lat=%gdeg, long=%gdeg", place.salt, RAD2DEG(place.slat), RAD2DEG(place.slong));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +107,25 @@ char *radec2str(double ra, double dec, char buf[RADEC_STR_MAXLEN]){
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// normalize azimuth to [0, 360.) and z.d. to [0, 90]
|
||||||
|
// if z>90 || z<-90 return false; if z < 0 rotate azimuth to 180
|
||||||
|
bool normAZ(double *a, double *z){
|
||||||
|
if(a){
|
||||||
|
norm_angle180(a);
|
||||||
|
if(*a < 0.) *a += 360.;
|
||||||
|
}
|
||||||
|
if(z){
|
||||||
|
norm_angle180(z);
|
||||||
|
if(*z > 90. || *z < -90.) return false;
|
||||||
|
if(*z < 0.){
|
||||||
|
*z += 90.;
|
||||||
|
*a += 180.;
|
||||||
|
if(*a >= 360.) *a -= 360.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// normalize RA/DEC to [0..24) for RA and [-90, 90] for DEC
|
// normalize RA/DEC to [0..24) for RA and [-90, 90] for DEC
|
||||||
void norm_RA(double *ra){
|
void norm_RA(double *ra){
|
||||||
if(!ra) return;
|
if(!ra) return;
|
||||||
@@ -123,11 +143,35 @@ void norm_RADEC(double *ra, double *dec){
|
|||||||
// 1: convert to (-180..+180)
|
// 1: convert to (-180..+180)
|
||||||
norm_angle180(dec);
|
norm_angle180(dec);
|
||||||
// 2: fix dec & ra together
|
// 2: fix dec & ra together
|
||||||
if(*dec > 90.) *dec = 180. - *dec;
|
if(*dec > 90.){
|
||||||
else *dec = -180. - *dec;
|
*dec = 180. - *dec;
|
||||||
*ra += 12.;
|
*ra += 12.;
|
||||||
norm_RA(ra);
|
norm_RA(ra);
|
||||||
|
}else if(*dec < -90.){
|
||||||
|
*dec = -180. - *dec;
|
||||||
|
*ra += 12.;
|
||||||
|
norm_RA(ra);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void norm_RADECr(double *ra, double *dec){
|
||||||
|
if(!ra || !dec) return;
|
||||||
|
if(*dec >= -ERFA_DPI/2. && *dec <= ERFA_DPI/2.){ // need only check RA
|
||||||
|
*ra = eraAnp(*ra);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1: convert to (-pi..+pi)
|
||||||
|
*dec = eraAnpm(*dec);
|
||||||
|
// 2: fix dec & ra together
|
||||||
|
if(*dec > ERFA_DPI/2.){
|
||||||
|
*dec = ERFA_DPI - *dec;
|
||||||
|
*ra = eraAnp(*ra + ERFA_DPI);
|
||||||
|
}else if(*dec < -ERFA_DPI/2.){
|
||||||
|
*dec = -ERFA_DPI - *dec;
|
||||||
|
*ra = eraAnp(*ra + ERFA_DPI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// normalize angle to (-180, 180]
|
// normalize angle to (-180, 180]
|
||||||
void norm_angle180(double *a){
|
void norm_angle180(double *a){
|
||||||
if(!a) return;
|
if(!a) return;
|
||||||
@@ -145,8 +189,11 @@ void norm_angle180(double *a){
|
|||||||
*/
|
*/
|
||||||
void hor2eq(horizCrds_t *h, polarCrds_t *pc, double sidTime){
|
void hor2eq(horizCrds_t *h, polarCrds_t *pc, double sidTime){
|
||||||
if(!h || !pc) return;
|
if(!h || !pc) return;
|
||||||
|
DBG("got az=%gdeg, zd=%gdeg; sidtm=%ghrs", RAD2DEG(h->az), RAD2DEG(h->zd), RAD2HRS(sidTime));
|
||||||
eraAe2hd(h->az, ERFA_DPI/2. - h->zd, place.slat, &pc->ha, &pc->dec); // A,H -> HA,DEC; phi - site latitude
|
eraAe2hd(h->az, ERFA_DPI/2. - h->zd, place.slat, &pc->ha, &pc->dec); // A,H -> HA,DEC; phi - site latitude
|
||||||
pc->ra = sidTime - pc->ha;
|
pc->ha = eraAnp(pc->ha); // normalize to [0,2pi)
|
||||||
|
pc->ra = eraAnp(sidTime - pc->ha);
|
||||||
|
DBG("dec=%gdeg, ha=%gh, ra=%gh", RAD2DEG(pc->dec), RAD2HRS(pc->ha), RAD2HRS(pc->ra));
|
||||||
pc->eo = 0.;
|
pc->eo = 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +260,7 @@ bool get_MJDt(struct timeval *tval, sMJD_t *MJD){
|
|||||||
struct tm tms;
|
struct tm tms;
|
||||||
double tSeconds;
|
double tSeconds;
|
||||||
if(!MJD){
|
if(!MJD){
|
||||||
WARNX("get_MJDt(): no input data");
|
WARNX("get_MJDt(): no output data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!tval){
|
if(!tval){
|
||||||
@@ -223,9 +270,11 @@ bool get_MJDt(struct timeval *tval, sMJD_t *MJD){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
gmtime_r(&ts.tv_sec, &tms);
|
gmtime_r(&ts.tv_sec, &tms);
|
||||||
|
//localtime_r(&ts.tv_sec, &tms);
|
||||||
tSeconds = tms.tm_sec + ((double)ts.tv_nsec)/1e9;
|
tSeconds = tms.tm_sec + ((double)ts.tv_nsec)/1e9;
|
||||||
}else{
|
}else{
|
||||||
gmtime_r(&tval->tv_sec, &tms);
|
gmtime_r(&tval->tv_sec, &tms);
|
||||||
|
//localtime_r(&tval->tv_sec, &tms);
|
||||||
tSeconds = tms.tm_sec + ((double)tval->tv_usec)/1e6;
|
tSeconds = tms.tm_sec + ((double)tval->tv_usec)/1e6;
|
||||||
}
|
}
|
||||||
int y, m, d;
|
int y, m, d;
|
||||||
@@ -238,10 +287,11 @@ bool get_MJDt(struct timeval *tval, sMJD_t *MJD){
|
|||||||
WARNX("get_MJDt(): eraDtf2d() error");
|
WARNX("get_MJDt(): eraDtf2d() error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MJD->MJD = utc1 - ERFA_DJM0 + 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->utc1 = utc1;
|
MJD->utc1 = utc1;
|
||||||
MJD->utc2 = utc2;
|
MJD->utc2 = utc2;
|
||||||
//DBG("UTC(m): %g, %.8f\n", utc1 - 2400000.5, 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;
|
||||||
@@ -263,20 +313,22 @@ bool get_MJDt(struct timeval *tval, sMJD_t *MJD){
|
|||||||
* @param LST (o) - local sidereal time (radians)
|
* @param LST (o) - local sidereal time (radians)
|
||||||
* @return true if all OK
|
* @return true if all OK
|
||||||
*/
|
*/
|
||||||
bool get_LST(sMJD_t *mjd, double dUT1, double slong, double *LST){
|
bool get_LST(sMJD_t *mjd, double *LST){
|
||||||
double ut11, ut12;
|
double ut11, ut12;
|
||||||
sMJD_t Mjd;
|
sMJD_t Mjd;
|
||||||
if(!LST) return false;
|
if(!LST) return false;
|
||||||
if(!mjd){
|
if(!mjd){
|
||||||
if(!get_MJDt(NULL, &Mjd)) return false;
|
if(!get_MJDt(NULL, &Mjd)) return false;
|
||||||
}else Mjd = *mjd;
|
}else Mjd = *mjd;
|
||||||
if(eraUtcut1(Mjd.utc1, Mjd.utc2, 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);
|
||||||
ST += slong;
|
DBG("ST0=%gh; longitude=%gh (%gdeg) STl=%gh", RAD2HRS(ST),
|
||||||
|
RAD2HRS(place.slong), RAD2DEG(place.slong), RAD2HRS(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;
|
||||||
*LST = ST;
|
*LST = ST;
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -302,14 +354,15 @@ bool get_ObsPlace(struct timeval *tval, polarCrds_t *p2000, polarCrds_t *pnow, h
|
|||||||
double wl = 0.55;
|
double wl = 0.55;
|
||||||
/* ICRS to observed. */
|
/* ICRS to observed. */
|
||||||
double aob, zob, hob, dob, rob, eo;
|
double aob, zob, hob, dob, rob, eo;
|
||||||
double p = 1000., t = 0., h = place.salt;
|
double p = 1000., t = 0., h = 0.5;
|
||||||
weather_data_t weath;
|
weather_data_t weath;
|
||||||
if(get_weather_data(&weath)){
|
if(get_weather_data(&weath)){
|
||||||
WARNX("Can't get weather - use default values");
|
WARNX("Can't get weather - use default values");
|
||||||
}else{
|
}else{
|
||||||
p = 1.3332239 * weath.pressure;
|
p = 1.3332239 * weath.pressure;
|
||||||
t = weath.exttemp;
|
t = weath.exttemp;
|
||||||
DBG("pressure=%.1fhPa, temperature=%.1fdegC", p, t);
|
h = weath.humidity / 100.;
|
||||||
|
DBG("pressure=%.1fhPa, temperature=%.1fdegC, humidity=%.1f%%", p, t, h);
|
||||||
}
|
}
|
||||||
if(eraAtco13(p2000->ra, p2000->dec,
|
if(eraAtco13(p2000->ra, p2000->dec,
|
||||||
pr, pd, px, rv,
|
pr, pd, px, rv,
|
||||||
|
|||||||
@@ -23,10 +23,10 @@
|
|||||||
|
|
||||||
#define RADEC_STR_MAXLEN 72
|
#define RADEC_STR_MAXLEN 72
|
||||||
|
|
||||||
#define RAD2DEG(angle) (angle * ERFA_DR2D)
|
#define RAD2DEG(angle) ((angle) * ERFA_DR2D)
|
||||||
#define DEG2RAD(angle) (angle * ERFA_DD2R)
|
#define DEG2RAD(angle) ((angle) * ERFA_DD2R)
|
||||||
#define RAD2HRS(angle) (angle * 24. / ERFA_DPI)
|
#define RAD2HRS(angle) ((angle) * 12. / ERFA_DPI)
|
||||||
#define HRS2RAD(hour) (hour * ERFA_DPI / 24.)
|
#define HRS2RAD(hour) ((hour) * ERFA_DPI / 12.)
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
double utc1; double utc2; // UTC JD, commonly used MJD = utc1+utc2-2400000.5
|
double utc1; double utc2; // UTC JD, commonly used MJD = utc1+utc2-2400000.5
|
||||||
@@ -65,8 +65,10 @@ typedef struct{
|
|||||||
} almDut_t;
|
} almDut_t;
|
||||||
|
|
||||||
char *radec2str(double ra, double dec, char buf[RADEC_STR_MAXLEN]);
|
char *radec2str(double ra, double dec, char buf[RADEC_STR_MAXLEN]);
|
||||||
|
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);
|
||||||
|
void norm_RADECr(double *ra, double *dec);
|
||||||
void norm_angle180(double *a);
|
void norm_angle180(double *a);
|
||||||
|
|
||||||
void hor2eq(horizCrds_t *h, polarCrds_t *pc, double sidTime);
|
void hor2eq(horizCrds_t *h, polarCrds_t *pc, double sidTime);
|
||||||
@@ -79,7 +81,7 @@ 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);
|
||||||
bool get_MJDt(struct timeval *tval, sMJD_t *MJD);
|
bool get_MJDt(struct timeval *tval, sMJD_t *MJD);
|
||||||
bool get_LST(sMJD_t *mjd, double dUT1, double slong, double *LST);
|
bool get_LST(sMJD_t *mjd, double *LST);
|
||||||
bool get_ObsPlace(struct timeval *tval, polarCrds_t *p2000, polarCrds_t *pnow, horizCrds_t *hnow);
|
bool get_ObsPlace(struct timeval *tval, polarCrds_t *p2000, polarCrds_t *pnow, horizCrds_t *hnow);
|
||||||
|
|
||||||
bool setDUT(almDut_t *D);
|
bool setDUT(almDut_t *D);
|
||||||
|
|||||||
@@ -16,25 +16,35 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <erfa.h>
|
||||||
|
#include <erfam.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
#include "angles.h"
|
#include "angles.h"
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
|
|
||||||
// emulation speed over RA & DEC (degr per sec)
|
// emulation speed over any trajectory
|
||||||
#define RA_SPEED (5.)
|
#define SPEED (DEG2RAD(5.))
|
||||||
#define DECL_SPEED (11.)
|
// limiting Zen.d.
|
||||||
|
#define ZD_LIMIT (DEG2RAD(80.))
|
||||||
|
// pointing tolerance: ~1''
|
||||||
|
#define POINTING_TOL (DEG2RAD(0.0003))
|
||||||
|
|
||||||
// current coordinates
|
// current emulation status (only MNT_S_STOPPED, MNT_S_TRACKING and MNT_S_SLEWING supported)
|
||||||
static double RA = 0., DECL = 0.;
|
static atomic_int emul_status = MNT_S_STOPPED;
|
||||||
// target coordinates
|
// current & target coordinates for stationary process
|
||||||
static double RAtarg = 0., DECLtarg = 0.;
|
static horizCrds_t CurAZ = {.az = DEG2RAD(180.), .zd = DEG2RAD(80.)}, TagAZ = {0};
|
||||||
// coordinates @ guiding start
|
// pointing to AZ and stop
|
||||||
static double RA0 = 0., DECL0 = 0.;
|
static bool pointAZ = false;
|
||||||
static double raspeed = 0.;
|
// current and target Ra/Dec
|
||||||
// pointing start time
|
static polarCrds_t CurRD = {0}, TagRD = {0};
|
||||||
static double tstart = -1.;
|
// last time user asks for coordinates or change something
|
||||||
|
static double tlast = -1.;
|
||||||
|
// flipping emulation
|
||||||
|
static bool flip_in_progress = false;
|
||||||
|
static polarCrds_t flip_target = {0}; // flipping target when dec>90deg, ra+=12h
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* send coordinates to telescope emulation
|
* send coordinates to telescope emulation
|
||||||
@@ -43,56 +53,168 @@ static double tstart = -1.;
|
|||||||
*/
|
*/
|
||||||
bool point_emulation(double ra, double decl){
|
bool point_emulation(double ra, double decl){
|
||||||
norm_RADEC(&ra, &decl);
|
norm_RADEC(&ra, &decl);
|
||||||
DBG("(emul) Send ra=%g, decl=%g", ra, decl);
|
DBG("(emul) Send ra=%ghrs, decl=%gdeg", ra, decl);
|
||||||
LOGMSG("(emul) Send ra=%g, decl=%g", ra, decl);
|
LOGMSG("(emul) Send ra=%ghrs, decl=%gdeg", ra, decl);
|
||||||
// TODO: check that Z<90!
|
double LST;
|
||||||
RAtarg = ra; DECLtarg = decl;
|
if(!get_LST(NULL, &LST)){
|
||||||
RA0 = RA; DECL0 = DECL;
|
DBG("Time error");
|
||||||
raspeed = (RAtarg > RA) ? RA_SPEED : -RA_SPEED;
|
return false;
|
||||||
if(fabs(RAtarg - RA) > 12.){ // go to opposite direction
|
|
||||||
raspeed = -raspeed;
|
|
||||||
}
|
}
|
||||||
tstart = sl_dtime();
|
// refresh coordinates
|
||||||
|
get_emul_coords(NULL, NULL);
|
||||||
|
TagRD.ra = HRS2RAD(ra); TagRD.dec = DEG2RAD(decl);
|
||||||
|
horizCrds_t hc;
|
||||||
|
eq2hor(&TagRD, &hc, LST);
|
||||||
|
if(hc.zd > ZD_LIMIT){
|
||||||
|
LOGWARN("User asks to point to object with ZD=%g", RAD2DEG(hc.zd));
|
||||||
|
DBG("Bad zd: %g", RAD2DEG(hc.zd));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tlast = sl_dtime();
|
||||||
|
pointAZ = false;
|
||||||
|
flip_in_progress = false;
|
||||||
|
atomic_store(&emul_status, MNT_S_SLEWING);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getradiff(){
|
bool pointAZ_emulation(double a, double z){
|
||||||
double diff = RAtarg - RA;
|
if(!normAZ(&a, &z)) return false;
|
||||||
if(raspeed < 0.) diff = -diff;
|
get_emul_coords(NULL, NULL);
|
||||||
if(diff > 12.) diff -= 24.;
|
TagAZ.az = DEG2RAD(a);
|
||||||
else if(diff < -12.) diff += 24.;
|
TagAZ.zd = DEG2RAD(z);
|
||||||
return fabs(diff);
|
pointAZ = true;
|
||||||
|
tlast = sl_dtime();
|
||||||
|
flip_in_progress = false;
|
||||||
|
atomic_store(&emul_status, MNT_S_SLEWING);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void chk_zlim(double LST){
|
||||||
|
if(CurAZ.zd > ZD_LIMIT){
|
||||||
|
CurAZ.zd = ZD_LIMIT;
|
||||||
|
emulation_stop();
|
||||||
|
hor2eq(&CurAZ, &CurRD, LST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// distance between `a` and `b` on sphere
|
||||||
|
static double angular_distance(const polarCrds_t *a, const polarCrds_t *b){
|
||||||
|
double dRA = a->ra - b->ra;
|
||||||
|
double sa, sb, ca, cb;
|
||||||
|
sincos(a->dec, &sa, &ca);
|
||||||
|
sincos(b->dec, &sb, &cb);
|
||||||
|
double cd = sa*sb + ca*cb*cos(dRA);
|
||||||
|
return acos(cd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// distance by axis moving
|
||||||
|
static double axdist(const polarCrds_t *a, const polarCrds_t *b){
|
||||||
|
// convert to [-pi, pi)
|
||||||
|
double dra = eraAnpm(b->ra - a->ra), ddec = eraAnpm(b->dec - a->dec);
|
||||||
|
return sqrt(dra*dra + ddec*ddec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate flip target (dec>90deg)
|
||||||
|
static void get_flip_target(const polarCrds_t *src, polarCrds_t *dst){
|
||||||
|
dst->ra = src->ra + ERFA_DPI;
|
||||||
|
if(dst->ra >= ERFA_D2PI) dst->ra -= ERFA_D2PI;
|
||||||
|
if(src->dec > 0.0)
|
||||||
|
dst->dec = ERFA_DPI - src->dec;
|
||||||
|
else
|
||||||
|
dst->dec = -ERFA_DPI - src->dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get coordinates (emulation)
|
* get coordinates (emulation)
|
||||||
*/
|
*/
|
||||||
void get_emul_coords(double *ra, double *decl){
|
void get_emul_coords(double *ra, double *decl){
|
||||||
if(tstart > 0.){
|
mount_status_t curstat = emulation_status();
|
||||||
DBG("RA/DEC: targ: %g/%g, cur: %g/%g, start: %g/%g", RAtarg, DECLtarg, RA, DECL, RA0, DECL0);
|
double LST, tcur = sl_dtime();
|
||||||
// diff < speed? stop
|
if(!get_LST(NULL, &LST)) return;
|
||||||
if((fabs(RAtarg - RA) < RA_SPEED && fabs(DECLtarg - DECL) < DECL_SPEED)){
|
if(curstat == MNT_S_STOPPED){ // just show constant A/Z
|
||||||
RA = RAtarg;
|
DBG("Stopped -> get from a=%gdeg, z=%gdeg", RAD2DEG(CurAZ.az), RAD2DEG(CurAZ.zd));
|
||||||
DECL = DECLtarg;
|
hor2eq(&CurAZ, &CurRD, LST);
|
||||||
tstart = -1.; // "guiding"
|
}else if(curstat == MNT_S_SLEWING){ // slew to target (RA/Dec or ZD/Az)
|
||||||
DBG("@ target");
|
if(pointAZ){
|
||||||
}else{ // calculate new coordinates
|
hor2eq(&TagAZ, &TagRD, LST); // refresh target coordinates
|
||||||
double radiff = getradiff(), decldiff = fabs(DECLtarg - DECL);
|
DBG("Slewing to A/Z: a=%g, z=%g", RAD2DEG(TagAZ.az), RAD2DEG(TagAZ.zd));
|
||||||
double tdiff = sl_dtime() - tstart;
|
|
||||||
RA = RA0 + raspeed * tdiff;
|
|
||||||
DBG("RA=%g", RA);
|
|
||||||
if(getradiff() > radiff) RA = RAtarg;
|
|
||||||
DBG("RA=%g", RA);
|
|
||||||
if(RA < 0.) RA += 24.;
|
|
||||||
else if(RA > 24.) RA -= 24.;
|
|
||||||
DBG("RA=%g", RA);
|
|
||||||
double sign = (DECLtarg > DECL) ? 1. : -1.;
|
|
||||||
DECL = DECL0 + sign * DECL_SPEED * tdiff;
|
|
||||||
if(fabs(DECLtarg - DECL) > decldiff) DECL = DECLtarg;
|
|
||||||
DBG("RA/DEC: targ: %g/%g, cur: %g/%g, start: %g/%g", RAtarg, DECLtarg, RA, DECL, RA0, DECL0);
|
|
||||||
}
|
}
|
||||||
|
if(!flip_in_progress){ // check if we need to flip
|
||||||
|
// distance for direct moving
|
||||||
|
double dist_direct = axdist(&CurRD, &TagRD);
|
||||||
|
// new point after flipping
|
||||||
|
polarCrds_t flip_candidate;
|
||||||
|
get_flip_target(&TagRD, &flip_candidate);
|
||||||
|
// distance for moving with flip
|
||||||
|
double dist_flip = axdist(&CurRD, &flip_candidate);
|
||||||
|
|
||||||
|
if(dist_flip < dist_direct){
|
||||||
|
// need to make flip: it's shorter
|
||||||
|
flip_target = flip_candidate;
|
||||||
|
flip_in_progress = true;
|
||||||
|
DBG("Flip chosen: direct=%.3fdeg, flip=%.3fdeg\n\n\n", RAD2DEG(dist_direct), RAD2DEG(dist_flip));
|
||||||
|
}else{
|
||||||
|
flip_in_progress = false;
|
||||||
|
DBG("Move directly: direct=%.3fdeg, flip=%.3fdeg\n\n\n", RAD2DEG(dist_direct), RAD2DEG(dist_flip));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// flip target is the same as TagRD, but with RA+=12h and dec > 90deg
|
||||||
|
polarCrds_t *target = flip_in_progress ? &flip_target : &TagRD;
|
||||||
|
// RA difference over target and last position: [-pi, pi)
|
||||||
|
double dRA = eraAnpm(target->ra - CurRD.ra);
|
||||||
|
DBG("RA difference: %gdegr", RAD2DEG(dRA));
|
||||||
|
double dDec = eraAnpm(target->dec - CurRD.dec);
|
||||||
|
DBG("DEC difference: %gdegr", RAD2DEG(dDec));
|
||||||
|
double dist = sqrt(dRA*dRA + dDec*dDec);
|
||||||
|
if(dist < POINTING_TOL){ // on position
|
||||||
|
if(pointAZ) emulation_stop(); // got A/Z position, stop
|
||||||
|
else atomic_store(&emul_status, MNT_S_TRACKING);
|
||||||
|
if(flip_in_progress){
|
||||||
|
flip_in_progress = false;
|
||||||
|
CurRD = TagRD; // fix to dec <=90
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
double dt = tcur - tlast;
|
||||||
|
double step = SPEED * dt;
|
||||||
|
if(step > dist) step = dist;
|
||||||
|
double factor = step / dist;
|
||||||
|
CurRD.ra += dRA * factor;
|
||||||
|
CurRD.dec += dDec * factor;
|
||||||
|
//if(CurRD.dec > ERFA_DPI/2.0) CurRD.dec = ERFA_DPI/2.0;
|
||||||
|
//else if(CurRD.dec < -ERFA_DPI/2.0) CurRD.dec = -ERFA_DPI/2.0;
|
||||||
|
if(CurRD.ra < 0.) CurRD.ra += ERFA_D2PI;
|
||||||
|
else if(CurRD.ra >= ERFA_D2PI) CurRD.ra -= ERFA_D2PI;
|
||||||
|
}
|
||||||
|
}else if(curstat == MNT_S_TRACKING){ // tracking -> just show static RA/Dec until Z<ZD_LIMIT
|
||||||
|
DBG("Tracking...");
|
||||||
|
eq2hor(&CurRD, &CurAZ, LST);
|
||||||
|
}
|
||||||
|
chk_zlim(LST);
|
||||||
|
tlast = tcur;
|
||||||
|
if(ra || decl){
|
||||||
|
// in flipping mode dec could be greater than 90
|
||||||
|
double curra = CurRD.ra, curdec = CurRD.dec;
|
||||||
|
norm_RADECr(&curra, &curdec);
|
||||||
|
if(ra) *ra = curra;
|
||||||
|
if(decl) *decl = curdec;
|
||||||
}
|
}
|
||||||
if(ra) *ra = RA;
|
|
||||||
if(decl) *decl = DECL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stop telescope
|
||||||
|
void emulation_stop(){
|
||||||
|
atomic_store(&emul_status, MNT_S_STOPPED);
|
||||||
|
pointAZ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start tracking from current position
|
||||||
|
void emul_start_tracking(){
|
||||||
|
if(MNT_S_TRACKING == emulation_status()) return;
|
||||||
|
atomic_store(&emul_status, MNT_S_TRACKING);
|
||||||
|
// TODO: convert current A/Z into RA/Dec and set zero speeds by both axes
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_status_t emulation_status(){
|
||||||
|
mount_status_t curstate = (mount_status_t) atomic_load(&emul_status);
|
||||||
|
return curstate;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,9 +16,14 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
bool point_emulation(double ra, double decl);
|
#include "mount.h" // mount status
|
||||||
void get_emul_coords(double *ra, double *decl);
|
|
||||||
|
|
||||||
|
bool point_emulation(double ra, double decl);
|
||||||
|
bool pointAZ_emulation(double a, double z);
|
||||||
|
mount_status_t emulation_status();
|
||||||
|
|
||||||
|
void get_emul_coords(double *ra, double *decl);
|
||||||
|
void emulation_stop();
|
||||||
|
void emul_start_tracking();
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ static sl_ringbuffer_t *RBin = NULL;
|
|||||||
// status
|
// status
|
||||||
static atomic_int mountstatus = MNT_S_ERROR;
|
static atomic_int mountstatus = MNT_S_ERROR;
|
||||||
|
|
||||||
|
// parking coordinates
|
||||||
|
static horizCrds_t ParkCoords = {.az = 0., .zd = DEG2RAD(80.)};
|
||||||
// input and current target coordinates
|
// input and current target coordinates
|
||||||
static polarCrds_t InpCoords = {0}, // input as user give (for epoch InpMJD)
|
static polarCrds_t InpCoords = {0}, // input as user give (for epoch InpMJD)
|
||||||
TagCoords = {0}; // target for Jnow after command "point to input"
|
TagCoords = {0}; // target for Jnow after command "point to input"
|
||||||
@@ -80,18 +82,18 @@ bool mount_setInpHA(double ha){
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief mount_setInpRA - set right ascension
|
* @brief mount_setInpRA - set right ascension
|
||||||
* @param ra (DEGREES!)
|
* @param ra (HOURS!!)
|
||||||
* @return fale if `ra` isn't in [0, 360)
|
* @return fale if `ra` isn't in [0, 24)
|
||||||
*/
|
*/
|
||||||
bool mount_setInpRA(double ra){
|
bool mount_setInpRA(double ra){
|
||||||
if(ra < 0. || ra >= 360.) return false;
|
if(ra < 0. || ra >= 24.) return false;
|
||||||
InpCoords.ra = DEG2RAD(ra);
|
InpCoords.ra = HRS2RAD(ra);
|
||||||
InpCTime = sl_dtime();
|
InpCTime = sl_dtime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief mount_setInpDec - set declination
|
* @brief mount_setInpDec - set declination
|
||||||
* @param dec (DEGREES!)
|
* @param dec (DEGREES!!)
|
||||||
* @return false if `dec` isn't in [-90, 90]
|
* @return false if `dec` isn't in [-90, 90]
|
||||||
*/
|
*/
|
||||||
bool mount_setInpDec(double dec){
|
bool mount_setInpDec(double dec){
|
||||||
@@ -186,7 +188,7 @@ static const char *statuses[MNT_S_STATAMOUNT] = {
|
|||||||
* @return statically allocated string with explanation
|
* @return statically allocated string with explanation
|
||||||
*/
|
*/
|
||||||
const char* mount_status_str(){
|
const char* mount_status_str(){
|
||||||
int curst = atomic_load(&mountstatus);
|
int curst = (isemulated) ? emulation_status() : atomic_load(&mountstatus);
|
||||||
if(curst > -1 && curst < MNT_S_STATAMOUNT) return statuses[curst];
|
if(curst > -1 && curst < MNT_S_STATAMOUNT) return statuses[curst];
|
||||||
return "'Unknown status'";
|
return "'Unknown status'";
|
||||||
}
|
}
|
||||||
@@ -256,10 +258,7 @@ static bool guess_speed(){
|
|||||||
|
|
||||||
// connect to mount
|
// connect to mount
|
||||||
bool mount_connect(){
|
bool mount_connect(){
|
||||||
if(isemulated){
|
if(isemulated) return true;
|
||||||
atomic_store(&mountstatus, MNT_S_STOPPED);
|
|
||||||
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()) return false;
|
||||||
@@ -277,20 +276,17 @@ bool mount_connect(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mount_disconnect(){
|
void mount_disconnect(){
|
||||||
if(isemulated) return;
|
if(isemulated){
|
||||||
|
emulation_stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
pthread_mutex_trylock(&mntdev_mutex); // at least, try
|
pthread_mutex_trylock(&mntdev_mutex); // at least, try
|
||||||
if(mount_dev) close(mount_dev->comfd);
|
if(mount_dev) close(mount_dev->comfd);
|
||||||
pthread_mutex_unlock(&mntdev_mutex);
|
pthread_mutex_unlock(&mntdev_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// point to ra/dec over serial
|
|
||||||
static bool mount_pointto(double ra, double dec){
|
|
||||||
(void) ra; (void) dec;
|
|
||||||
;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO: change angles to RAD!
|
||||||
* send input RA/Decl (j2000!) coordinates to tel
|
* send input RA/Decl (j2000!) coordinates to tel
|
||||||
* ra in hours (0..24), decl in degrees (-90..90)
|
* ra in hours (0..24), decl in degrees (-90..90)
|
||||||
* @return true if all OK
|
* @return true if all OK
|
||||||
@@ -301,9 +297,18 @@ bool mount_point(double ra, double dec){
|
|||||||
DBG("Set RA/Decl to %s", buf);
|
DBG("Set RA/Decl to %s", buf);
|
||||||
LOGMSG("Try to set RA/Decl to %s", buf);
|
LOGMSG("Try to set RA/Decl to %s", buf);
|
||||||
norm_RADEC(&ra, &dec);
|
norm_RADEC(&ra, &dec);
|
||||||
bool (*pointfunction)(double, double) = mount_pointto;
|
if(isemulated) return point_emulation(ra, dec);
|
||||||
if(isemulated) pointfunction = point_emulation;
|
// run real pointing to ra(hrs) & dec (deg)
|
||||||
return pointfunction(ra, dec);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mount_pointAZ(double A, double Z){
|
||||||
|
DBG("Point to stationary object, A=%g, Z=%g", A, Z);
|
||||||
|
if(isemulated){
|
||||||
|
return pointAZ_emulation(A, Z);
|
||||||
|
}
|
||||||
|
; // run real pointing
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_emulation_mode(){
|
void set_emulation_mode(){
|
||||||
@@ -314,9 +319,75 @@ mount_status_t mount_getcoords(double *ra, double *dec){
|
|||||||
if(!ra || !dec) return MNT_S_ERROR;
|
if(!ra || !dec) return MNT_S_ERROR;
|
||||||
if(isemulated){
|
if(isemulated){
|
||||||
get_emul_coords(ra, dec);
|
get_emul_coords(ra, dec);
|
||||||
DBG("Emulated coordinates: %g, %g", *ra, *dec);
|
DBG("Emulated coordinates: %gh, %gdeg", RAD2HRS(*ra), RAD2DEG(*dec));
|
||||||
}else{
|
return emulation_status();
|
||||||
; // get real coordinates
|
|
||||||
}
|
}
|
||||||
|
; // get real coordinates
|
||||||
return mount_status();
|
return mount_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mount_stop - stop any moving
|
||||||
|
* @return false if failed
|
||||||
|
*/
|
||||||
|
bool mount_stop(){
|
||||||
|
if(isemulated){
|
||||||
|
emulation_stop();
|
||||||
|
}else{
|
||||||
|
return mount_stop();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mount_tracking_start - start tracking from current position
|
||||||
|
* @return false if failed
|
||||||
|
*/
|
||||||
|
bool mount_tracking_start(){
|
||||||
|
if(isemulated){
|
||||||
|
emul_start_tracking();
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mount_park - start parking
|
||||||
|
* @return false if failed to run command
|
||||||
|
*/
|
||||||
|
bool mount_park(){
|
||||||
|
if(isemulated) return pointAZ_emulation(ParkCoords.az, ParkCoords.zd);
|
||||||
|
return mount_pointAZ(ParkCoords.az, ParkCoords.zd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mount_setParkAz - set parking azimuth
|
||||||
|
* @param az - [-180, 360) degrees
|
||||||
|
* @return false if az out of range
|
||||||
|
*/
|
||||||
|
bool mount_setParkAz(double az){
|
||||||
|
if(az < 0.) az += 360.;
|
||||||
|
if(az < 0. || az >= 360.) return false;
|
||||||
|
ParkCoords.az = DEG2RAD(az);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mount_setParkZD - set parking zenith distance
|
||||||
|
* @param zd - [0, 90]
|
||||||
|
* @return false if zd out of range
|
||||||
|
*/
|
||||||
|
bool mount_setParkZD(double zd){
|
||||||
|
if(zd < 0. || zd > 90.) return false;
|
||||||
|
ParkCoords.zd = DEG2RAD(zd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mount_getPark - get parking coordinates
|
||||||
|
* @param c (o) - az/zd
|
||||||
|
*/
|
||||||
|
void mount_getPark(horizCrds_t *c){
|
||||||
|
if(c) *c = ParkCoords;
|
||||||
|
}
|
||||||
|
|||||||
@@ -62,3 +62,11 @@ void mount_disconnect();
|
|||||||
|
|
||||||
mount_status_t mount_getcoords(double *ra, double *dec);
|
mount_status_t mount_getcoords(double *ra, double *dec);
|
||||||
bool mount_point(double ra, double dec);
|
bool mount_point(double ra, double dec);
|
||||||
|
bool mount_pointAZ(double A, double Z);
|
||||||
|
bool mount_stop();
|
||||||
|
bool mount_tracking_start();
|
||||||
|
bool mount_park();
|
||||||
|
|
||||||
|
bool mount_setParkAz(double az);
|
||||||
|
bool mount_setParkZD(double zd);
|
||||||
|
void mount_getPark(horizCrds_t *c);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <erfa.h>
|
||||||
|
#include <erfam.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -35,11 +37,23 @@
|
|||||||
// commands
|
// commands
|
||||||
#define CMD_UNIXT "unixt"
|
#define CMD_UNIXT "unixt"
|
||||||
#define CMD_STATUS "status"
|
#define CMD_STATUS "status"
|
||||||
#define CMD_RELAY "relay"
|
|
||||||
#define CMD_OPEN "open"
|
|
||||||
#define CMD_CLOSE "close"
|
|
||||||
#define CMD_STOP "stop"
|
#define CMD_STOP "stop"
|
||||||
#define CMD_HALF "half"
|
#define CMD_TAGRA "tagra"
|
||||||
|
#define CMD_TAGDEC "tagdec"
|
||||||
|
#define CMD_TAGHA "tagha"
|
||||||
|
#define CMD_TAGAZ "tagaz"
|
||||||
|
#define CMD_TAGZD "tagzd"
|
||||||
|
#define CMD_TELRA "telra"
|
||||||
|
#define CMD_TELDEC "teldec"
|
||||||
|
#define CMD_GOTORD "gotord"
|
||||||
|
#define CMD_GOTORH "gotorh"
|
||||||
|
#define CMD_GOTOAZ "gotoaz"
|
||||||
|
#define CMD_STOP "stop"
|
||||||
|
#define CMD_TRACK "track"
|
||||||
|
#define CMD_PARK "park"
|
||||||
|
#define CMD_PARKAZ "parkaz"
|
||||||
|
#define CMD_PARKZD "parkzd"
|
||||||
|
|
||||||
|
|
||||||
// main command socket
|
// main command socket
|
||||||
static sl_sock_t *cmd_socket = NULL;
|
static sl_sock_t *cmd_socket = NULL;
|
||||||
@@ -76,10 +90,227 @@ static sl_sock_hresult_e status(sl_sock_t *c, sl_sock_hitem_t *item, _U_ const c
|
|||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_key_value(const char *req, double *val){
|
||||||
|
if(!req) return 0; // is getter
|
||||||
|
DBG("parsing of %s", req);
|
||||||
|
double d;
|
||||||
|
if(sscanf(req, "%lf", &d) != 1) return -1; // error
|
||||||
|
if(val) *val = d;
|
||||||
|
return 1; // is setter
|
||||||
|
}
|
||||||
|
|
||||||
|
// setters of RA/DEC/HA/Az/ZD (TODO: fix `parse_key_value` for HH:MM:SS/DD:MM:SS/DDD.DD/HHH.HH formats!)
|
||||||
|
static sl_sock_hresult_e cmd_tagra(sl_sock_t *c, sl_sock_hitem_t *item, const char *req){
|
||||||
|
double val;
|
||||||
|
int res = parse_key_value(req, &val);
|
||||||
|
if(res < 0) return RESULT_BADVAL;
|
||||||
|
if(res > 0){ // setter
|
||||||
|
if(mount_setInpRA(val)) return RESULT_OK;
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}else{ // getter
|
||||||
|
polarCrds_t p;
|
||||||
|
mount_getInpCoords(&p);
|
||||||
|
double ra_h = RAD2HRS(p.ra);
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, ra_h);
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_tagdec(sl_sock_t *c, sl_sock_hitem_t *item, const char *req) {
|
||||||
|
double val;
|
||||||
|
int res = parse_key_value(req, &val);
|
||||||
|
if(res < 0) return RESULT_BADVAL;
|
||||||
|
if(res > 0){
|
||||||
|
if(mount_setInpDec(val)) return RESULT_OK;
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}else{
|
||||||
|
polarCrds_t p;
|
||||||
|
mount_getInpCoords(&p);
|
||||||
|
double dec_d = RAD2DEG(p.dec);
|
||||||
|
char buf[64];
|
||||||
|
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_tagha(sl_sock_t *c, sl_sock_hitem_t *item, const char *req) {
|
||||||
|
double val;
|
||||||
|
int res = parse_key_value(req, &val);
|
||||||
|
if(res < 0) return RESULT_BADVAL;
|
||||||
|
if(res > 0){
|
||||||
|
if(mount_setInpHA(val)) return RESULT_OK;
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}else{
|
||||||
|
polarCrds_t p;
|
||||||
|
mount_getInpCoords(&p);
|
||||||
|
double ha_h = RAD2HRS(p.ha);
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, ha_h);
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_tagaz(sl_sock_t *c, sl_sock_hitem_t *item, const char *req) {
|
||||||
|
double val;
|
||||||
|
int res = parse_key_value(req, &val);
|
||||||
|
if(res < 0) return RESULT_BADVAL;
|
||||||
|
if(res > 0){
|
||||||
|
if(mount_setInpA(val)) return RESULT_OK;
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}else{
|
||||||
|
horizCrds_t h;
|
||||||
|
mount_getInpHor(&h);
|
||||||
|
double az_d = RAD2DEG(h.az);
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, az_d);
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_tagzd(sl_sock_t *c, sl_sock_hitem_t *item, const char *req) {
|
||||||
|
double val;
|
||||||
|
int res = parse_key_value(req, &val);
|
||||||
|
if(res < 0) return RESULT_BADVAL;
|
||||||
|
if(res > 0){
|
||||||
|
if(mount_setInpZ(val)) return RESULT_OK;
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}else{
|
||||||
|
horizCrds_t h;
|
||||||
|
mount_getInpHor(&h);
|
||||||
|
double zd_d = RAD2DEG(h.zd);
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, zd_d);
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_telra(sl_sock_t *c, sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
double ra, dec;
|
||||||
|
if(mount_getcoords(&ra, &dec) == MNT_S_ERROR) return RESULT_FAIL;
|
||||||
|
char buf[64];
|
||||||
|
double ra_h = RAD2HRS(ra);
|
||||||
|
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, ra_h);
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_teldec(sl_sock_t *c, sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
double ra, dec;
|
||||||
|
if(mount_getcoords(&ra, &dec) == MNT_S_ERROR) return RESULT_FAIL;
|
||||||
|
char buf[64];
|
||||||
|
double dec_d = RAD2DEG(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_gotord(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
polarCrds_t p;
|
||||||
|
mount_getInpCoords(&p);
|
||||||
|
double ra_h = RAD2HRS(p.ra);
|
||||||
|
double dec_d = RAD2DEG(p.dec);
|
||||||
|
if(!mount_point(ra_h, dec_d)) return RESULT_FAIL;
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_gotorh(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
polarCrds_t p;
|
||||||
|
mount_getInpCoords(&p);
|
||||||
|
sMJD_t mjd;
|
||||||
|
if(!get_MJDt(NULL, &mjd)) return RESULT_FAIL;
|
||||||
|
double LST;
|
||||||
|
if(!get_LST(&mjd, &LST)) return RESULT_FAIL;
|
||||||
|
double RA_rad = eraAnp(LST - p.ha);
|
||||||
|
double ra_h = RAD2HRS(RA_rad);
|
||||||
|
double dec_d = RAD2DEG(p.dec);
|
||||||
|
if(!mount_point(ra_h, dec_d)) return RESULT_FAIL;
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_gotoaz(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
horizCrds_t h;
|
||||||
|
mount_getInpHor(&h);
|
||||||
|
if(mount_pointAZ(RAD2DEG(h.az), RAD2DEG(h.zd))) return RESULT_OK;
|
||||||
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_stop(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
mount_stop();
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// run tracking from current position
|
||||||
|
static sl_sock_hresult_e cmd_track(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req) {
|
||||||
|
if(mount_tracking_start()) return RESULT_OK;
|
||||||
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sl_sock_hresult_e cmd_park(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
||||||
|
if(mount_park()) return RESULT_OK;
|
||||||
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set/get parking coordinates
|
||||||
|
static sl_sock_hresult_e cmd_parkaz(sl_sock_t *c, sl_sock_hitem_t *item, const char *req){
|
||||||
|
double val;
|
||||||
|
int res = parse_key_value(req, &val);
|
||||||
|
if(res < 0) return RESULT_BADVAL;
|
||||||
|
if(res > 0){
|
||||||
|
if(mount_setParkAz(val)) return RESULT_OK;
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}else{
|
||||||
|
horizCrds_t h;
|
||||||
|
mount_getPark(&h);
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, RAD2DEG(h.az));
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static sl_sock_hresult_e cmd_parkzd(sl_sock_t *c, sl_sock_hitem_t *item, const char *req){
|
||||||
|
double val;
|
||||||
|
int res = parse_key_value(req, &val);
|
||||||
|
if(res < 0) return RESULT_BADVAL;
|
||||||
|
if(res > 0){
|
||||||
|
if(mount_setParkZD(val)) return RESULT_OK;
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}else{
|
||||||
|
horizCrds_t h;
|
||||||
|
mount_getPark(&h);
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "%s=%.6f\n", item->key, RAD2DEG(h.zd));
|
||||||
|
sl_sock_sendstrmessage(c, buf);
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// and all handlers collection
|
// and all handlers collection
|
||||||
static sl_sock_hitem_t handlers[] = {
|
static sl_sock_hitem_t handlers[] = {
|
||||||
{dtimeh, CMD_UNIXT, "get server's UNIX time", NULL},
|
{cmd_gotoaz, CMD_GOTOAZ, "point telescope by input Az/ZD and stop", NULL},
|
||||||
|
{cmd_gotord, CMD_GOTORD, "point telescope by input RA/Dec and start tracking", NULL},
|
||||||
|
{cmd_gotorh, CMD_GOTORH, "point telescope by input RA/HA and start tracking", NULL},
|
||||||
|
{cmd_park, CMD_PARK, "park telescope", NULL},
|
||||||
|
{cmd_parkaz, CMD_PARKAZ, "set parking azimuth (Deg: 0 - north, 90 - east)", NULL},
|
||||||
|
{cmd_parkzd, CMD_PARKZD, "set parking zenith distance (Deg)", NULL},
|
||||||
{status, CMD_STATUS, "get mount status", NULL},
|
{status, CMD_STATUS, "get mount status", NULL},
|
||||||
|
{cmd_stop, CMD_STOP, "stop telescope", NULL},
|
||||||
|
{cmd_tagaz, CMD_TAGAZ, "get/set target azimuth (Deg)", NULL},
|
||||||
|
{cmd_tagdec, CMD_TAGDEC, "get/set target declination (Deg)", NULL},
|
||||||
|
{cmd_tagha, CMD_TAGHA, "get/set target hour angle (Hrs)", NULL},
|
||||||
|
{cmd_tagra, CMD_TAGRA, "get/set target right acsention (Hrs)", NULL},
|
||||||
|
{cmd_tagzd, CMD_TAGZD, "get/set target zenith distance (Deg)", NULL},
|
||||||
|
{cmd_teldec, CMD_TELDEC, "get current telescope declination (Deg)", NULL},
|
||||||
|
{cmd_telra, CMD_TELRA, "get current telescope right acsention (Hrs)", NULL},
|
||||||
|
{cmd_track, CMD_TRACK, "start tracking from current position", NULL},
|
||||||
|
{dtimeh, CMD_UNIXT, "get server's UNIX time", NULL},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <erfam.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
@@ -68,12 +69,10 @@ STATUS (4 bytes, signed integer): status of the telescope, currently unused.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define DEG2DEC(degr) ((int32_t)(degr / 90. * ((double)0x40000000)))
|
#define RAD2DEC(rad) ((int32_t)((rad) / ERFA_DPI * ((double)0x80000000)))
|
||||||
#define DEG2RA(degr) ((uint32_t)(degr / 180. * ((double)0x80000000)))
|
#define RAD2RA(rad) ((uint32_t)((rad) / ERFA_DPI * ((double)0x80000000)))
|
||||||
#define HRS2RA(degr) ((uint32_t)(degr / 12. * ((double)0x80000000)))
|
#define DEC2DEG(i32) (((double)(i32))*90./((double)0x40000000))
|
||||||
#define DEC2DEG(i32) (((double)i32)*90./((double)0x40000000))
|
#define RA2HRS(u32) (((double)(u32))*12. /((double)0x80000000))
|
||||||
#define RA2DEG(u32) (((double)u32)*180. /((double)0x80000000))
|
|
||||||
#define RA2HRS(u32) (((double)u32)*12. /((double)0x80000000))
|
|
||||||
|
|
||||||
typedef struct __attribute__((__packed__)){
|
typedef struct __attribute__((__packed__)){
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
@@ -126,23 +125,9 @@ static bool proc_data(uint8_t *data, ssize_t len){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// convert RA/DEC to degrees
|
// convert RA/DEC to degrees
|
||||||
double tagRA = RA2DEG(ra), tagDec = DEC2DEG(dec);
|
double tagRA = RA2HRS(ra), tagDec = DEC2DEG(dec);
|
||||||
DBG("RA: %u (%g degr), DEC: %d (%g degr)", ra, tagRA, dec, tagDec);
|
DBG("RA: %u (%g hrs), DEC: %d (%g degr)", ra, tagRA, dec, tagDec);
|
||||||
LOGMSG("(stellarium) RA: %u (%g degr), DEC: %d (%g degr)", ra, tagRA, dec, tagDec);
|
LOGMSG("(stellarium) RA: %u (%g hrs), DEC: %d (%g degr)", ra, tagRA, dec, tagDec);
|
||||||
#if 0
|
|
||||||
// check RA/DEC
|
|
||||||
horizCrds_t hnow; // without refraction
|
|
||||||
polarCrds_t p2000, pnow;
|
|
||||||
p2000.ra = DEG2RAD(tagRA);
|
|
||||||
p2000.dec = DEG2RAD(tagDec);
|
|
||||||
// now J2000 obs Jnow
|
|
||||||
if(!get_ObsPlace(NULL, &p2000, &pnow, &hnow)){
|
|
||||||
WARNX("Can't convert coordinates to Jnow");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tagRA = RAD2DEG(pnow.ra - pnow.eo);
|
|
||||||
tagDec = RAD2DEG(pnow.dec);
|
|
||||||
#endif
|
|
||||||
return (mount_setInpRA(tagRA) && mount_setInpDec(tagDec) && mount_setInpMJD(ERFA_DJM00));
|
return (mount_setInpRA(tagRA) && mount_setInpDec(tagDec) && mount_setInpMJD(ERFA_DJM00));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,10 +169,9 @@ static void *handle_socket(void *sockd){
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//DBG("got : %g/%g", RA, Decl);
|
//DBG("got : %g/%g", RA, Decl);
|
||||||
dout.ra = htole32(HRS2RA(RA));
|
dout.ra = htole32(RAD2RA(RA));
|
||||||
dout.dec = (int32_t)htole32(DEG2DEC(Decl));
|
dout.dec = (int32_t)htole32(RAD2DEC(Decl));
|
||||||
if(!send_data((uint8_t*)&dout, sizeof(outdata), sock)) break;
|
if(!send_data((uint8_t*)&dout, sizeof(outdata), sock)) break;
|
||||||
//DBG("sent ra = %g, dec = %g", RA2HRS(dout.ra), DEC2DEG(dout.dec));
|
|
||||||
if(!sl_canread(sock)){
|
if(!sl_canread(sock)){
|
||||||
sleep(1);
|
sleep(1);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user