diff --git a/jsonbta/Makefile b/jsonbta/Makefile index 2fb1875..83fd68e 100644 --- a/jsonbta/Makefile +++ b/jsonbta/Makefile @@ -1,14 +1,14 @@ -LOADLIBES = -lm -lcrypt -SRCS = bta_json.c bta_print.c ../daemon.c +LOADLIBES = -lm -lcrypt -lsla +SRCS = bta_json.c bta_print.c daemon.c CC = gcc -DEFINES = +#DEFINES = -DEBUG CXX = gcc CPPFLAGS = -Wall -Werror $(DEFINES) OBJS = $(SRCS:.c=.o) all : bta_json client_streaming $(OBJS): bta_json.h bta_shdata.h bta_json : $(OBJS) - $(CC) $(CPPFLAGS) $(OBJS) $(LOADLIBES) -o bta_json + $(CC) $(CPPFLAGS) $(OBJS) $(LOADLIBES) -o bta_json client_streaming: client_streaming.o $(CC) $(CPPFLAGS) -lm -ljson client_streaming.o -o client_streaming clean: diff --git a/jsonbta/bta_print.c b/jsonbta/bta_print.c index 5920b16..aa1512f 100644 --- a/jsonbta/bta_print.c +++ b/jsonbta/bta_print.c @@ -30,6 +30,9 @@ #include #include #include +#include // SLA macros + +//#include "sofa.h" #include "bta_shdata.h" #define BTA_PRINT_C @@ -170,31 +173,57 @@ static double calc_PA(double alpha, double delta, double stime){ } /* -static void calc_AD(double az, double zd, double stime, double *alpha, double *delta){ - double sin_d, sin_a,cos_a, sin_z,cos_z; - double t, d, z, a, p , x, y, s; - a = az * S2R; - z = zd * S2R; - sin_a = sin(a); - cos_a = cos(a); - sin_z = sin(z); - cos_z = cos(z); - - y = sin_z * sin_a; - x = cos_a * sin_fi * sin_z + cos_fi * cos_z; - t = atan2(y, x); - if (t < 0.0) - t += 2.0*PI; - - sin_d = sin_fi * cos_z - cos_fi * cos_a * sin_z; - d = asin(sin_d); - - *delta = d * R2S; - *alpha = (stime - t * R2S / 15.); - if (*alpha < 0.0) - *alpha += S360/15.; // +24h +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 @@ -303,6 +332,13 @@ void make_JSON(int sock, bta_pars *par){ 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){ @@ -360,6 +396,7 @@ void make_JSON(int sock, bta_pars *par){ } // 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")); @@ -376,5 +413,3 @@ void make_JSON(int sock, bta_pars *par){ sendstr("\n}\n"); } - -// конец файла diff --git a/jsonbta/daemon.c b/jsonbta/daemon.c new file mode 100644 index 0000000..d21209e --- /dev/null +++ b/jsonbta/daemon.c @@ -0,0 +1,140 @@ +/* + * daemon.c - functions for running in background like a daemon + * + * Copyright 2013 Edward V. Emelianoff + * + * 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. + */ + +#define PROC_BASE "/proc" + +#include // printf, fopen, ... +#include // getpid +#include // perror +#include // opendir +#include // opendir +#include // stat +#include // fcntl +#include // exit +#include // memset + +/** + * read process name from /proc/PID/cmdline + * @param pid - PID of interesting process + * @return filename or NULL if not found + * don't use this function twice for different names without copying + * its returning by strdup, because `name` contains in static array + */ +char *readname(pid_t pid){ + static char name[256]; + char *pp = name, byte, path[256]; + FILE *file; + int cntr = 0; + size_t sz; + snprintf (path, 255, PROC_BASE "/%d/cmdline", pid); + file = fopen(path, "r"); + if(!file) return NULL; // there's no such file + do{ // read basename + sz = fread(&byte, 1, 1, file); + if(sz != 1) break; + if(byte != '/') *pp++ = byte; + else{ + pp = name; + cntr = 0; + } + }while(byte && cntr++ < 255); + name[cntr] = 0; + fclose(file); + return name; +} + +void iffound_default(pid_t pid){ + fprintf(stderr, "\nFound running process (pid=%d), exit.\n", pid); + exit(0); +} + +/** + * check wether there is a same running process + * exit if there is a running process or error + * Checking have 3 steps: + * 1) lock executable file + * 2) check pidfile (if you run a copy?) + * 3) check /proc for executables with the same name (no/wrong pidfile) + * @param argv - argument of main() or NULL for non-locking, call this function before getopt() + * @param pidfilename - name of pidfile or NULL if none + * @param iffound - action to run if file found or NULL for exit(0) + */ +void check4running(char **argv, char *pidfilename, void (*iffound)(pid_t pid)){ + DIR *dir; + FILE *pidfile, *fself; + struct dirent *de; + struct stat s_buf; + pid_t pid = 0, self; + struct flock fl; + char *name, *myname; + if(!iffound) iffound = iffound_default; + if(argv){ // block self + fself = fopen(argv[0], "r"); // open self binary to lock + memset(&fl, 0, sizeof(struct flock)); + fl.l_type = F_WRLCK; + if(fcntl(fileno(fself), F_GETLK, &fl) == -1){ // check locking + perror("fcntl"); + exit(1); + } + if(fl.l_type != F_UNLCK){ // file is locking - exit + printf("Found locker, PID = %d!\n", fl.l_pid); + exit(1); + } + fl.l_type = F_RDLCK; + if(fcntl(fileno(fself), F_SETLKW, &fl) == -1){ + perror("fcntl"); + exit(1); + } + } + self = getpid(); // get self PID + if(!(dir = opendir(PROC_BASE))){ // open /proc directory + perror(PROC_BASE); + exit(1); + } + if(!(name = readname(self))){ // error reading self name + perror("Can't read self name"); + exit(1); + } + myname = strdup(name); + if(pidfilename && stat(pidfilename, &s_buf) == 0){ // pidfile exists + pidfile = fopen(pidfilename, "r"); + if(pidfile){ + fscanf(pidfile, "%d", &pid); // read PID of (possibly) running process + fclose(pidfile); + if((name = readname(pid)) && strncmp(name, myname, 255) == 0) + iffound(pid); + } + } + // There is no pidfile or it consists a wrong record + while((de = readdir(dir))){ // scan /proc + if(!(pid = (pid_t)atoi(de->d_name)) || pid == self) // pass non-PID files and self + continue; + if((name = readname(pid)) && strncmp(name, myname, 255) == 0) + iffound(pid); + } + closedir(dir); + if(pidfilename){ + pidfile = fopen(pidfilename, "w"); + fprintf(pidfile, "%d\n", self); // write self PID to pidfile + fclose(pidfile); + } + free(myname); +} diff --git a/jsonbta/makefile_from_tb b/jsonbta/makefile_from_tb deleted file mode 100644 index 5ce518c..0000000 --- a/jsonbta/makefile_from_tb +++ /dev/null @@ -1,16 +0,0 @@ -LOADLIBES = -lm -lcrypt -SRCS = bta_json.c bta_print.c ../daemon.c -CC = gcc -DEFINES = -CXX = gcc -CPPFLAGS = -Wall $(DEFINES) -I/Users/eddy/include -OBJS = $(SRCS:.c=.o) -all : bta_json client_streaming -$(OBJS): bta_json.h bta_shdata.h -bta_json : $(OBJS) - $(CC) $(CPPFLAGS) $(OBJS) $(LOADLIBES) -o bta_json -client_streaming: client_streaming.o - $(CC) $(CPPFLAGS) client_streaming.o /Users/eddy/lib/libjson.a -lm -o client_streaming -clean: - /bin/rm -f *.o *~ - diff --git a/jsonbta/manual.pdf b/jsonbta/manual.pdf index 6530462..af5aadb 100644 Binary files a/jsonbta/manual.pdf and b/jsonbta/manual.pdf differ diff --git a/jsonbta/manual.tex b/jsonbta/manual.tex index 1f2c3de..54c3716 100644 --- a/jsonbta/manual.tex +++ b/jsonbta/manual.tex @@ -86,40 +86,44 @@ $$ \begin{lstlisting}[language=JSON] { "ACS_BTA": true, -"M_time": "13:58:57.74", -"JDate": 2456432.915943, -"S_time": "04:37:37.01", +"M_time": "11:19:02.65", +"JDate": 2457496.846559, +"S_time": "00:52:20.42", "Tel_Mode": "Stopping", -"Tel_Focus": "Prime", -"ValFoc": 98.77, -"Tel_Taget": "Zenith", +"Tel_Focus": "Nasmyth2", +"ValFoc": 141.67, +"Tel_Taget": "Nest", "P2_Mode": "Stop", -"CurAlpha": "04:12:28.25", -"CurDelta": "+39:56:53.4", -"SrcAlpha": "06:25:53.48", -"SrcDelta": "+10:00:00.0", -"InpAlpha": "11:41:52.03", -"InpDelta": "+24:40:36.4", -"TelAlpha": "04:57:06.82", -"TelDelta": "+39:57:14.6", -"InpAzim": "-118:27:18.0", -"InpZenD": "83:52:29.3", -"CurAzim": "+053:55:21.3", -"CurZenD": "05:57:00.7", -"CurPA": "049:36:52.7", -"SrcPA": "329:54:01.0", -"InpPA": "315:37:58.0", -"TelPA": "317:08:11.1", -"ValAzim": "-045:59:40.4", -"ValZenD": "05:09:31.2", -"ValP2": "219:33:16.7", -"ValDome": "+134:55:41.6", +"CurAlpha": "17:00:46.09", +"CurDelta": "+25:23:19.3", +"SrcAlpha": "20:03:06.61", +"SrcDelta": "+30:07:03.6", +"InpAlpha": "20:03:06.61", +"InpDelta": "+30:07:03.6", +"TelAlpha": "20:06:48.56", +"TelDelta": "+25:26:04.6", +"InpRA2000": "20:02:27.39", +"InpDec2000": "+30:04:26.0", +"CurRA2000": "17:00:05.25", +"CurDec2000": "+25:24:46.6", +"InpAzim": "+102:24:34.6", +"InpZenD": "57:30:02.4", +"CurAzim": "+127:00:42.7", +"CurZenD": "90:33:43.6", +"CurPA": "039:45:18.4", +"SrcPA": "054:46:17.1", +"InpPA": "054:46:17.1", +"TelPA": "052:36:08.9", +"ValAzim": "+097:25:17.8", +"ValZenD": "59:37:00.4", +"ValP2": "220:17:30.6", +"ValDome": "-225:20:43.1", "DiffAzim": "+000:00:00.0", "DiffZenD": "+00:00:00.0", -"DiffP2": "+000:00:00.0", -"DiffDome": "-180:55:22.0", -"VelAzim": "+00:00:00.0", -"VelZenD": "-00:00:00.0", +"DiffP2": "+086:31:52.6", +"DiffDome": "+322:46:01.0", +"VelAzim": "-00:00:00.0", +"VelZenD": "+00:00:00.0", "VelP2": "+00:00:00.0", "VelPA": "+00:00:00.0", "VelDome": "+00:00:00.0", @@ -127,14 +131,15 @@ $$ "CorrDelta": "+0:00:00.0", "CorrAzim": "+0:00:00.0", "CorrZenD": "+0:00:00.0", -"ValTind": 010.4, -"ValTmir": 010.3, -"ValPres": 595.8, -"ValWind": 01.7, -"Blast10": 18633.4, -"Blast15": 59794.7, -"ValHumd": 86.3, -"Precipt": 1087.4 +"ValTout": 007.8, +"ValTind": 005.7, +"ValTmir": 005.8, +"ValPres": 596.6, +"ValWind": 03.1, +"Blast10": 2503.7, +"Blast15": 2566.1, +"ValHumd": 46.8, +"Precipt": 2364.3 } \end{lstlisting} @@ -193,6 +198,12 @@ SrcAlpha& SrcDelta& Текущие координаты цели ($\delta$)& угол & eqcoor\\ InpAlpha& Введенные пользователем координаты ($\alpha$)& время & eqcoor\\ InpDelta& Введенные пользователем координаты ($\delta$)& угол & eqcoor\\ +InpRA2000& Обратное преобразование (с использованием библиотеки sla) введенных + координат на эпоху J2000 & угол & eqcoor\\ +InpDec2000& InpDelta $\Longrightarrow$ J2000& угол & eqcoor\\ +CurRA2000& CurAlpha $\Longrightarrow$ J2000& угол & eqcoor\\ +CurDec2000& CurDelta $\Longrightarrow$ J2000& угол & eqcoor\\ + TelAlpha& Текущие координаты телескопа ($\alpha$)& время & eqcoor\\ TelDelta& Текущие координаты телескопа ($\delta$)& угол & eqcoor\\ InpAzim& Введенные горизонтальные координаты ($A$~-- азимут)& угол & horcoor\\