mirror of
https://github.com/eddyem/BTA_utils.git
synced 2025-12-06 02:35:13 +03:00
416 lines
12 KiB
C
416 lines
12 KiB
C
/*
|
|
* bta_print.c
|
|
*
|
|
* Copyright Vladimir S. Shergin <vsher@sao.ru>
|
|
*
|
|
* some changes (2013) Edward V. Emelianoff <eddy@sao.ru>
|
|
*
|
|
* 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 2 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <math.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/times.h>
|
|
#include <crypt.h>
|
|
#include <assert.h>
|
|
#include <slamac.h> // SLA macros
|
|
|
|
//#include "sofa.h"
|
|
|
|
#include "bta_shdata.h"
|
|
#define BTA_PRINT_C
|
|
#include "bta_json.h"
|
|
|
|
#define BUFSZ 255
|
|
static char buf[BUFSZ+1];
|
|
|
|
char *double_asc(double d, char *fmt){
|
|
if(!fmt) snprintf(buf, BUFSZ, "%.6f", d);
|
|
else snprintf(buf, BUFSZ, fmt, d);
|
|
return buf;
|
|
}
|
|
|
|
char *time_asc(double t){
|
|
int h, min;
|
|
double sec;
|
|
h = (int)(t/3600.);
|
|
min = (int)((t - (double)h*3600.)/60.);
|
|
sec = t - (double)h*3600. - (double)min*60.;
|
|
h %= 24;
|
|
if(sec>59.99) sec=59.99;
|
|
snprintf(buf, BUFSZ, "\"%02d:%02d:%05.2f\"", h,min,sec);
|
|
return buf;
|
|
}
|
|
|
|
char *angle_asc(double a){
|
|
char s;
|
|
int d, min;
|
|
double sec;
|
|
if (a >= 0.)
|
|
s = '+';
|
|
else {
|
|
s = '-'; a = -a;
|
|
}
|
|
d = (int)(a/3600.);
|
|
min = (int)((a - (double)d*3600.)/60.);
|
|
sec = a - (double)d*3600. - (double)min*60.;
|
|
d %= 360;
|
|
if(sec>59.9) sec=59.9;
|
|
snprintf (buf, BUFSZ, "\"%c%02d:%02d:%04.1f\"", s,d,min,sec);
|
|
return buf;
|
|
}
|
|
|
|
char *angle_fmt(double a, char *format){
|
|
char s, *p;
|
|
int d, min, n;
|
|
double sec, msec;
|
|
char *newformat = calloc(strlen(format) + 3, 1);
|
|
assert(newformat);
|
|
sprintf(newformat, "\"%s\"", format);
|
|
if (a >= 0.)
|
|
s = '+';
|
|
else {
|
|
s = '-'; a = -a;
|
|
}
|
|
d = (int)(a/3600.);
|
|
min = (int)((a - (double)d*3600.)/60.);
|
|
sec = a - (double)d*3600. - (double)min*60.;
|
|
d %= 360;
|
|
if ((p = strchr(format,'.')) == NULL)
|
|
msec=59.;
|
|
else if (*(p+2) == 'f' ) {
|
|
n = *(p+1) - '0';
|
|
msec = 60. - pow(10.,(double)(-n));
|
|
} else
|
|
msec=60.;
|
|
if(sec>msec) sec=msec;
|
|
if (strstr(format,"%c"))
|
|
snprintf(buf, BUFSZ, newformat, s,d,min,sec);
|
|
else
|
|
snprintf(buf, BUFSZ, newformat, d,min,sec);
|
|
free(newformat);
|
|
return buf;
|
|
}
|
|
|
|
#ifndef PI
|
|
#define PI 3.14159265358979323846 /* pi */
|
|
#endif
|
|
|
|
#define R2D 180./PI /* rad. to degr. */
|
|
#define D2R PI/180. /* degr. to rad. */
|
|
#define R2S 648000./PI /* rad. to sec */
|
|
#define S2R PI/648000. /* sec. to rad. */
|
|
#define S360 1296000. /* sec in 360degr */
|
|
|
|
const double longitude=149189.175; /* SAO longitude 41 26 29.175 (-2:45:45.945)*/
|
|
const double Fi=157152.7; /* SAO latitude 43 39 12.7 */
|
|
const double cos_fi=0.7235272793; /* Cos of SAO latitude */
|
|
const double sin_fi=0.6902957888; /* Sin --- "" ----- */
|
|
|
|
static void calc_AZ(double alpha, double delta, double stime, double *az, double *zd){
|
|
double sin_t,cos_t, sin_d,cos_d, cos_z;
|
|
double t, d, z, a, x, y;
|
|
|
|
t = (stime - alpha) * 15.;
|
|
if (t < 0.)
|
|
t += S360; // +360degr
|
|
t *= S2R; // -> rad
|
|
d = delta * S2R;
|
|
sin_t = sin(t);
|
|
cos_t = cos(t);
|
|
sin_d = sin(d);
|
|
cos_d = cos(d);
|
|
|
|
cos_z = cos_fi * cos_d * cos_t + sin_fi * sin_d;
|
|
z = acos(cos_z);
|
|
|
|
y = cos_d * sin_t;
|
|
x = cos_d * sin_fi * cos_t - cos_fi * sin_d;
|
|
a = atan2(y, x);
|
|
|
|
*zd = z * R2S;
|
|
*az = a * R2S;
|
|
}
|
|
|
|
static double calc_PA(double alpha, double delta, double stime){
|
|
double sin_t,cos_t, sin_d,cos_d;
|
|
double t, d, p, sp, cp;
|
|
|
|
t = (stime - alpha) * 15.;
|
|
if (t < 0.)
|
|
t += S360; // +360degr
|
|
t *= S2R; // -> rad
|
|
d = delta * S2R;
|
|
sin_t = sin(t);
|
|
cos_t = cos(t);
|
|
sin_d = sin(d);
|
|
cos_d = cos(d);
|
|
|
|
sp = sin_t * cos_fi;
|
|
cp = sin_fi * cos_d - sin_d * cos_fi * cos_t;
|
|
p = atan2(sp, cp);
|
|
if (p < 0.0)
|
|
p += 2.0*PI;
|
|
|
|
return(p * R2S);
|
|
}
|
|
|
|
/*
|
|
void calc2000(double *ra, double *dec){
|
|
double elong, phi, utc1, utc2;
|
|
struct tm tms;
|
|
time_t t = time(NULL);
|
|
gmtime_r(&t, &tms);
|
|
int y, m, d;
|
|
y = 1900 + tms.tm_year;
|
|
m = tms.tm_mon + 1;
|
|
d = tms.tm_mday;
|
|
iauDtf2d("UTC", y, m, d, tms.tm_hour, tms.tm_min, tms.tm_sec, &utc1, &utc2);
|
|
iauAf2a ( '+', 41, 26, 29.175, &elong );
|
|
iauAf2a ( '+', 43, 39, 12.69, &phi );
|
|
//iauAtoc13("R", val_Alp * DS2R, val_Del * DAS2R, utc1, utc2, DUT1,
|
|
iauAtoc13("R", InpAlpha * DS2R, InpDelta * DAS2R, utc1, utc2, DUT1,
|
|
elong, phi, 2070.0, polarX, polarY, Pressure/0.76, Temper,
|
|
val_Hmd/100., 0.55, ra, dec);
|
|
int i[4];
|
|
char pm;
|
|
iauA2tf ( 7, *ra, &pm, i );
|
|
printf ( " %2.2d %2.2d %2.2d.%7.7d", i[0],i[1],i[2],i[3] );
|
|
iauA2af ( 6, *dec, &pm, i );
|
|
printf ( " %c%2.2d %2.2d %2.2d.%6.6d\n", pm, i[0],i[1],i[2],i[3] );
|
|
printf("DUT: %g, x:%g, y:%g, pres: %g, temp: %g, hum: %g%%\n", DUT1,
|
|
polarX, polarY, Pressure/0.76, Temper, val_Hmd/100.);
|
|
}*/
|
|
|
|
extern void sla_amp(double*, double*, double*, double*, double*, double*);
|
|
|
|
void slaamp(double ra, double da, double date, double eq, double *rm, double *dm ){
|
|
double r = ra, d = da, mjd = date, equi = eq;
|
|
sla_amp(&r, &d, &mjd, &equi, rm, dm);
|
|
}
|
|
const double jd0 = 2400000.5; // JD for MJD==0
|
|
/**
|
|
* convert apparent coordinates (nowadays) to mean (JD2000)
|
|
* appRA, appDecl in seconds
|
|
* r, d in seconds
|
|
*/
|
|
void calc_mean(double appRA, double appDecl, double *r, double *d){
|
|
double ra, dec;
|
|
appRA *= DS2R;
|
|
appDecl *= DAS2R;
|
|
DBG("appRa: %g, appDecl: %g", appRA, appDecl);
|
|
double mjd = JDate - jd0;
|
|
slaamp(appRA, appDecl, mjd, 2000.0, &ra, &dec);
|
|
ra *= DR2S;
|
|
dec *= DR2AS;
|
|
if(r) *r = ra;
|
|
if(d) *d = dec;
|
|
}
|
|
|
|
void make_JSON(int sock, bta_pars *par){
|
|
bool ALL = par->ALL;
|
|
// print next JSON pair; par, val - strings
|
|
void sendstr(char *str){
|
|
size_t L = strlen(str);
|
|
if(send(sock, str, L, 0) != L) exit(-1);
|
|
}
|
|
int json_send(char *par, char *val){
|
|
char buf[256];
|
|
int L = snprintf(buf, 255, ",\n\"%s\": %s", par, val);
|
|
if(send(sock, buf, L, 0) != L) return -1;
|
|
return 0;
|
|
}
|
|
int json_send_s(char *par, char *val){
|
|
char buf[256];
|
|
int L = snprintf(buf, 255, ",\n\"%s\": \"%s\"", par, val);
|
|
if(send(sock, buf, L, 0) != L) return -1;
|
|
return 0;
|
|
}
|
|
#define JSON(p, val) do{if(json_send(p, val)) exit(-1);} while(0)
|
|
#define JSONSTR(p, val) do{if(json_send_s(p, val)) exit(-1);} while(0)
|
|
get_shm_block( &sdat, ClientSide);
|
|
char *str;
|
|
if(!check_shm_block(&sdat)) exit(-1);
|
|
// beginning of json object
|
|
sendstr("{\n\"ACS_BTA\": true");
|
|
|
|
// mean local time
|
|
if(ALL || par->mtime)
|
|
JSON("M_time", time_asc(M_time+DUT1));
|
|
// Mean Sidereal Time
|
|
if(ALL || par->sidtime){
|
|
#ifdef EE_time
|
|
JSON("JDate", double_asc(JDate, NULL));
|
|
str = time_asc(S_time-EE_time);
|
|
#else
|
|
str = time_asc(S_time);
|
|
#endif
|
|
JSON("S_time", str);
|
|
}
|
|
// Telecope mode
|
|
if(ALL || par->telmode){
|
|
if(Tel_Hardware == Hard_Off) str = "Off";
|
|
else if(Tel_Mode != Automatic) str = "Manual";
|
|
else{
|
|
switch (Sys_Mode){
|
|
default:
|
|
case SysStop : str = "Stopping"; break;
|
|
case SysWait : str = "Waiting"; break;
|
|
case SysPointAZ :
|
|
case SysPointAD : str = "Pointing"; break;
|
|
case SysTrkStop :
|
|
case SysTrkStart:
|
|
case SysTrkMove :
|
|
case SysTrkSeek : str = "Seeking"; break;
|
|
case SysTrkOk : str = "Tracking"; break;
|
|
case SysTrkCorr : str = "Correction";break;
|
|
case SysTest : str = "Testing"; break;
|
|
}
|
|
}
|
|
JSONSTR("Tel_Mode", str);
|
|
}
|
|
// Telescope focus
|
|
if(ALL || par->telfocus){
|
|
switch (Tel_Focus){
|
|
default:
|
|
case Prime : str = "Prime"; break;
|
|
case Nasmyth1 : str = "Nasmyth1"; break;
|
|
case Nasmyth2 : str = "Nasmyth2"; break;
|
|
}
|
|
JSONSTR("Tel_Focus", str);
|
|
JSON("ValFoc", double_asc(val_F, "%0.2f"));
|
|
}
|
|
// Telescope target
|
|
if(ALL || par->target){
|
|
switch (Sys_Target) {
|
|
default:
|
|
case TagObject : str = "Object"; break;
|
|
case TagPosition : str = "A/Z-Pos."; break;
|
|
case TagNest : str = "Nest"; break;
|
|
case TagZenith : str = "Zenith"; break;
|
|
case TagHorizon : str = "Horizon"; break;
|
|
}
|
|
JSONSTR("Tel_Taget", str);
|
|
}
|
|
// Mode of P2
|
|
if(ALL || par->p2mode){
|
|
if(Tel_Hardware == Hard_On){
|
|
switch (P2_State) {
|
|
default:
|
|
case P2_Off : str = "Stop"; break;
|
|
case P2_On : str = "Track"; break;
|
|
case P2_Plus : str = "Move+"; break;
|
|
case P2_Minus : str = "Move-"; break;
|
|
}
|
|
} else str = "Off";
|
|
JSONSTR("P2_Mode", str);
|
|
}
|
|
// Equatorial coordinates
|
|
if(ALL || par->eqcoor){
|
|
JSON("CurAlpha", time_asc(CurAlpha));
|
|
JSON("CurDelta", angle_asc(CurDelta));
|
|
JSON("SrcAlpha", time_asc(SrcAlpha));
|
|
JSON("SrcDelta", angle_asc(SrcDelta));
|
|
JSON("InpAlpha", time_asc(InpAlpha));
|
|
JSON("InpDelta", angle_asc(InpDelta));
|
|
JSON("TelAlpha", time_asc(val_Alp));
|
|
JSON("TelDelta", angle_asc(val_Del));
|
|
double a2000, d2000;
|
|
calc_mean(InpAlpha, InpDelta, &a2000, &d2000);
|
|
JSON("InpRA2000", time_asc(a2000));
|
|
JSON("InpDec2000", angle_asc(d2000));
|
|
calc_mean(CurAlpha, CurDelta, &a2000, &d2000);
|
|
JSON("CurRA2000", time_asc(a2000));
|
|
JSON("CurDec2000", angle_asc(d2000));
|
|
}
|
|
// Horizontal coordinates
|
|
if(ALL || par->horcoor){
|
|
JSON("InpAzim", angle_fmt(InpAzim,"%c%03d:%02d:%04.1f"));
|
|
JSON("InpZenD", angle_fmt(InpZdist,"%02d:%02d:%04.1f"));
|
|
JSON("CurAzim", angle_fmt(tag_A,"%c%03d:%02d:%04.1f"));
|
|
JSON("CurZenD", angle_fmt(tag_Z,"%02d:%02d:%04.1f"));
|
|
JSON("CurPA", angle_fmt(tag_P,"%03d:%02d:%04.1f"));
|
|
JSON("SrcPA", angle_fmt(calc_PA(SrcAlpha,SrcDelta,S_time),"%03d:%02d:%04.1f"));
|
|
JSON("InpPA", angle_fmt(calc_PA(InpAlpha,InpDelta,S_time),"%03d:%02d:%04.1f"));
|
|
JSON("TelPA", angle_fmt(calc_PA(val_Alp, val_Del, S_time),"%03d:%02d:%04.1f"));
|
|
}
|
|
// Values from sensors
|
|
if(ALL || par->valsens){
|
|
JSON("ValAzim", angle_fmt(val_A,"%c%03d:%02d:%04.1f"));
|
|
JSON("ValZenD", angle_fmt(val_Z,"%02d:%02d:%04.1f"));
|
|
JSON("ValP2", angle_fmt(val_P,"%03d:%02d:%04.1f"));
|
|
JSON("ValDome", angle_fmt(val_D,"%c%03d:%02d:%04.1f"));
|
|
}
|
|
// Differences
|
|
if(ALL || par->diff){
|
|
JSON("DiffAzim", angle_fmt(Diff_A,"%c%03d:%02d:%04.1f"));
|
|
JSON("DiffZenD", angle_fmt(Diff_Z,"%c%02d:%02d:%04.1f"));
|
|
JSON("DiffP2", angle_fmt(Diff_P,"%c%03d:%02d:%04.1f"));
|
|
JSON("DiffDome", angle_fmt(val_A-val_D,"%c%03d:%02d:%04.1f"));
|
|
}
|
|
// Velocities
|
|
if(ALL || par->vel){
|
|
JSON("VelAzim", angle_fmt(vel_A,"%c%02d:%02d:%04.1f"));
|
|
JSON("VelZenD", angle_fmt(vel_Z,"%c%02d:%02d:%04.1f"));
|
|
JSON("VelP2", angle_fmt(vel_P,"%c%02d:%02d:%04.1f"));
|
|
JSON("VelPA", angle_fmt(vel_objP,"%c%02d:%02d:%04.1f"));
|
|
JSON("VelDome", angle_fmt(vel_D,"%c%02d:%02d:%04.1f"));
|
|
}
|
|
// Correction
|
|
if(ALL || par->corr){
|
|
double curA,curZ,srcA,srcZ;
|
|
double corAlp,corDel,corA,corZ;
|
|
if(Sys_Mode==SysTrkSeek||Sys_Mode==SysTrkOk||Sys_Mode==SysTrkCorr){
|
|
corAlp = CurAlpha-SrcAlpha;
|
|
corDel = CurDelta-SrcDelta;
|
|
if(corAlp > 23*3600.) corAlp -= 24*3600.;
|
|
if(corAlp < -23*3600.) corAlp += 24*3600.;
|
|
calc_AZ(SrcAlpha, SrcDelta, S_time, &srcA, &srcZ);
|
|
calc_AZ(CurAlpha, CurDelta, S_time, &curA, &curZ);
|
|
corA=curA-srcA;
|
|
corZ=curZ-srcZ;
|
|
}else{
|
|
corAlp = corDel = corA = corZ = 0.;
|
|
}
|
|
JSON("CorrAlpha", angle_fmt(corAlp,"%c%01d:%02d:%05.2f"));
|
|
JSON("CorrDelta", angle_fmt(corDel,"%c%01d:%02d:%04.1f"));
|
|
JSON("CorrAzim", angle_fmt(corA,"%c%01d:%02d:%04.1f"));
|
|
JSON("CorrZenD", angle_fmt(corZ,"%c%01d:%02d:%04.1f"));
|
|
}
|
|
// meteo
|
|
if(ALL || par->meteo){
|
|
JSON("ValTout", double_asc(val_T1, "%05.1f"));
|
|
JSON("ValTind", double_asc(val_T2, "%05.1f"));
|
|
JSON("ValTmir", double_asc(val_T3, "%05.1f"));
|
|
JSON("ValPres", double_asc(val_B, "%05.1f"));
|
|
JSON("ValWind", double_asc(val_Wnd, "%04.1f"));
|
|
if(Wnd10_time>0.1 && Wnd10_time<=M_time) {
|
|
JSON("Blast10", double_asc((M_time-Wnd10_time)/60, "%.1f"));
|
|
JSON("Blast15", double_asc((M_time-Wnd15_time)/60, "%.1f"));
|
|
}
|
|
JSON("ValHumd", double_asc(val_Hmd, "%04.1f"));
|
|
if(Precip_time>0.1 && Precip_time<=M_time)
|
|
JSON("Precipt", double_asc((M_time-Precip_time)/60, "%.1f"));
|
|
}
|
|
// end of json onject
|
|
sendstr("\n}\n");
|
|
}
|
|
|