Commit 22055514 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Add console_dt_model to manage the DT model for all trackers.

Also add dt_model.ini file for loading dt_model parameters
parent 0e2c9c21
......@@ -28,6 +28,8 @@
#define CONSOLE_SUN_CMD_PORT 11071
#define CONSOLE_MOON_STAT_PORT 11080
#define CONSOLE_MOON_CMD_PORT 11081
#define CONSOLE_DT_MODEL_STAT_PORT 11090
#define CONSOLE_DT_MODEL_CMD_PORT 11091
#define CONSOLE_LOG_PORT 11200
......
......@@ -22,6 +22,11 @@
#include <unistd.h>
#include <math.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include "dt_model.h"
......@@ -48,40 +53,26 @@ r: refractie
za: scheefstand rail
aa: kompasrichting scheefstand
Gevonden parameters (in graden):
a0: -0.012 +/- 0.012
c1: 0.058 +/- 0.017
c2: 0.015 +/- 0.014
e0: -0.041 +/- 0.003
b: -0.046 +/- 0.004
za: -0.008 +/- 0.010
aa: -2.9 +/- 3.6
De gemiddelde pointing-error was 0.11 graden, en wordt hiermee teruggebracht naar 0.007 graden.
*/
static double a0 = -0.012;
static double c1 = 0.058;
static double c2 = 0.015;
static double e0 = -0.041;
static double b = -0.046;
static double za = -0.008;
static double aa = -2.900;
static double r = 0.0;
static struct dt_model_params dt_model_default;
struct dt_model_params *params = &dt_model_default;
double dt_model_azimuth_delta(double az, double el)
{
double delta_az;
double c1_div_cos_el = c1 / cos(el);
double c1_div_cos_el = params->c1 / cos(el);
if (isnan(c1_div_cos_el))
c1_div_cos_el = 0.0;
delta_az =
a0
+ c1 / cos(el)
- c2 * tan(el)
- za * sin(az - aa) * tan(el);
params->a0
+ params->c1 / cos(el)
- params->c2 * tan(el)
- params->za * sin(az - params->aa) * tan(el);
return delta_az;
}
......@@ -95,16 +86,11 @@ double dt_model_azimuth_delta_rev(double az, double el)
double dt_model_elevation_delta(double az, double el)
{
double delta_el;
double r_div_sin_el = r / sin(el);
if (isnan(r_div_sin_el))
r_div_sin_el = 0.0;
delta_el =
e0
+ b * cos(el)
- r_div_sin_el
- za * cos(az - aa);
params->e0
+ params->b * cos(el)
- params->za * cos(az - params->aa);
return delta_el;
}
......@@ -114,3 +100,62 @@ double dt_model_elevation_delta_rev(double az, double el)
/* No reverse model available, (ab)use the forward model */
return -dt_model_elevation_delta(az, el);
}
int dt_model_init(void)
{
int fd;
fd = shm_open("/dt_model",
O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0)
return -1;
if((ftruncate(fd, sizeof(struct dt_model_params))) == -1){
printf("ftruncate failure\n");
return -1;
}
params = mmap(NULL, sizeof(struct dt_model_params),
PROT_READ,
MAP_SHARED, fd, 0);
return params != NULL;
}
int dt_model_init_server(void)
{
int fd;
fd = shm_open("/dt_model",
O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0)
return -1;
if((ftruncate(fd, sizeof(struct dt_model_params))) == -1){
printf("ftruncate failure\n");
return -1;
}
params = mmap(NULL, sizeof(struct dt_model_params),
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
return params != NULL;
}
int dt_model_params_set(struct dt_model_params *newparams)
{
memcpy(params, newparams, sizeof(struct dt_model_params));
return 0;
}
int dt_model_params_get(struct dt_model_params *getparams)
{
memcpy(getparams, params, sizeof(struct dt_model_params));
}
......@@ -23,7 +23,26 @@
#include <unistd.h>
#include <math.h>
int dt_model_init(void);
double dt_model_azimuth_delta(double az, double el);
double dt_model_azimuth_delta_rev(double az, double el);
double dt_model_elevation_delta(double az, double el);
double dt_model_elevation_delta_rev(double az, double el);
#define DT_MODEL_NAME_SIZE 256
struct dt_model_params {
double a0;
double c1;
double c2;
double e0;
double b;
double za;
double aa;
char name[DT_MODEL_NAME_SIZE];
};
int dt_model_init_server(void);
int dt_model_params_set(struct dt_model_params *params);
int dt_model_params_get(struct dt_model_params *params);
......@@ -10,7 +10,7 @@ LIBTOOL=libtool
%.o : %.c
@echo " CC $<"
@$(CC) -MMD $(CFLAGS) -c $<
@$(CC) -MMD $(CFLAGS) $($@_CFLAGS) -c $<
%: %.o
@echo " LD $@"
......@@ -18,7 +18,7 @@ LIBTOOL=libtool
%.lo: %.c
@echo "LT CC $<"
@${LIBTOOL} --quiet --mode=compile --tag=CC $(CC) -MMD $(CFLAGS) -c $<
@${LIBTOOL} --quiet --mode=compile --tag=CC $(CC) -MMD $(CFLAGS) $($@_CFLAGS) -c $<
%.la:
@echo "LIBTOOL $@"
......
await_controller
command_shell
console_azel
console_dt_model
console_easycomm
console_httpline
console_httptrace
......
......@@ -17,7 +17,7 @@ all: lib/libaa.la lib/libpredict.la \
console_j2000tracker console_j2000tracer console_j2000_indi \
log_proxy spg_auth console_idle console_zenith \
console_suntracker console_azel console_manual \
console_weather \
console_weather console_dt_model \
await_controller \
console_sattracker \
status.cgi_install command.cgi_install shell.cgi_install
......@@ -63,7 +63,12 @@ console_suntracker: console_suntracker.o setpoint.o lib/libaa.la
console_idle: console_idle.o setpoint.o
console_weather: console_weather.o -lpthread
console_weather_LDFLAGS= -lpthread
console_weather: console_weather.o
console_dt_model.o_CFLAGS+=`pkg-config --cflags glib-2.0`
console_dt_model_LDFLAGS+=`pkg-config --libs glib-2.0`
console_dt_model: console_dt_model.o
console_zenith: console_zenith.o setpoint.o
......@@ -117,12 +122,13 @@ lib/libpredict.la:
clean:
rm -rf *.o *.d lib/* *.lo *.a *.la .libs
rm -f \
await_controller \
command.cgi \
command_shell \
console_joystick \
console_dt_model \
console_easycomm \
spg_list \
console_httptrace \
trace_proxy \
console_manual \
console_moontracker \
console_suntracker \
......@@ -134,16 +140,16 @@ clean:
console_sattracker \
console_weather \
console_zenith \
trace_proxy \
trace.cgi \
trace_log \
log_proxy \
shell.cgi \
spg_auth \
spg_list \
spg_log_parser \
shell.cgi \
await_controller \
command.cgi \
status.cgi
trace_proxy \
trace_proxy \
trace_log \
trace.cgi \
$(MAKE) -C aalib clean
$(MAKE) -C doc clean
$(MAKE) -C predictlib clean
......
......@@ -61,6 +61,8 @@ int main(int argc, char **argv)
port = CONSOLE_AZEL_PORT;
else if (!strcmp(buffer, "manual"))
port = CONSOLE_MANUAL_CMD_PORT;
else if (!strcmp(buffer, "dt_model"))
port = CONSOLE_DT_MODEL_CMD_PORT;
alarm(10);
......
/*
Console interface to the DT model
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2013
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/>.
*/
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <signal.h>
#include <ctype.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdbool.h>
#include <glib.h>
#include "tcp_connect.h"
#include "tcp_listen.h"
#include "dt_model.h"
#include "dt_port_numbers.h"
int stat_port = CONSOLE_DT_MODEL_STAT_PORT;
int cmd_port = CONSOLE_DT_MODEL_CMD_PORT;
#define OUTPUT_RATE 3
/************************************/
static int load_ini(void)
{
GKeyFile *keyfile;
gboolean loaded;
gchar *keyfilename = "dt_model.ini";
int ret = 0;
int i;
char *active_name = "none";
struct dt_model_params params = {};
keyfile = g_key_file_new();
loaded = g_key_file_load_from_file(
keyfile,
keyfilename,
G_KEY_FILE_KEEP_COMMENTS,
NULL);
if (loaded) {
gsize groups_nr;
gchar **groups;
groups = g_key_file_get_groups(keyfile, &groups_nr);
printf("Number of groups in ini file: %d\n", (int)groups_nr);
for (i = 0; i < groups_nr; i++) {
if (!strcmp(groups[i], "global")) {
if (g_key_file_has_key(keyfile, groups[i], "active", NULL)) {
active_name =
g_key_file_get_string(keyfile, groups[i], "active", NULL);
printf("Active params: '%s'\n", active_name);
}
}
}
for (i = 0; i < groups_nr; i++) {
if (strcmp(groups[i], "global")) {
if (g_key_file_has_key(keyfile, groups[i], "a0", NULL)) {
params.a0 =
g_key_file_get_double(keyfile, groups[i], "a0", NULL);
}
if (g_key_file_has_key(keyfile, groups[i], "c1", NULL)) {
params.c1 =
g_key_file_get_double(keyfile, groups[i], "c1", NULL);
}
if (g_key_file_has_key(keyfile, groups[i], "c2", NULL)) {
params.c2 =
g_key_file_get_double(keyfile, groups[i], "c2", NULL);
}
if (g_key_file_has_key(keyfile, groups[i], "e0", NULL)) {
params.e0 =
g_key_file_get_double(keyfile, groups[i], "e0", NULL);
}
if (g_key_file_has_key(keyfile, groups[i], "b", NULL)) {
params.b =
g_key_file_get_double(keyfile, groups[i], "b", NULL);
}
if (g_key_file_has_key(keyfile, groups[i], "za", NULL)) {
params.za =
g_key_file_get_double(keyfile, groups[i], "za", NULL);
}
if (g_key_file_has_key(keyfile, groups[i], "aa", NULL)) {
params.aa =
g_key_file_get_double(keyfile, groups[i], "aa", NULL);
}
strncpy(params.name, groups[i], DT_MODEL_NAME_SIZE);
params.name[DT_MODEL_NAME_SIZE-1] = 0;
if (!strcmp(groups[i], active_name)) {
printf("Set params: %d\n",
dt_model_params_set(&params));
}
}
}
} else {
printf("ini file load failed\n");
ret = -1;
}
g_key_file_free(keyfile);
return ret;
}
/************************************/
struct stat_client {
struct stat_client *next;
int fd;
};
struct stat_client *stat_clients = NULL;
struct cmd_client {
struct cmd_client *next;
int fd;
char buffer[200];
int buflen;
};
struct cmd_client *cmd_clients = NULL;
void new_stat_client(int fd_stat)
{
struct stat_client *new_stat;
int fd;
fd = tcp_accept(fd_stat);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_stat = malloc(sizeof(struct stat_client));
if (!new_stat) {
close(fd);
return;
}
new_stat->fd = fd;
new_stat->next = stat_clients;
stat_clients = new_stat;
}
void new_cmd_client(int fd_cmd)
{
struct cmd_client *new_cmd;
int fd;
fd = tcp_accept(fd_cmd);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_cmd = malloc(sizeof(struct cmd_client));
if (!new_cmd) {
close(fd);
return;
}
new_cmd->fd = fd;
new_cmd->buflen = 0;
new_cmd->next = cmd_clients;
cmd_clients = new_cmd;
}
void fdset_cmd_clients(fd_set *fdset_rx, int *high)
{
struct cmd_client *cmd;
for (cmd = cmd_clients; cmd; cmd = cmd->next) {
FD_SET(cmd->fd, fdset_rx);
if (cmd->fd >= *high)
*high = cmd->fd + 1;
}
}
void handle_cmd(struct cmd_client *cmd)
{
char *switches, *ptr;
switches = cmd->buffer;
printf("command: %s\n", switches);
if (switches) {
char *name, *val;
name = strtok_r(switches, ",=", &ptr);
val = strtok_r(NULL, ",=", &ptr);
printf("name %s value %s\n", name, val);
if (!strcmp(name, "reload"))
load_ini();
}
}
void check_cmd_clients(fd_set *fdset_rx)
{
struct cmd_client **cmdp, **nextp = NULL;
for (cmdp = &cmd_clients; *cmdp; cmdp = nextp) {
int ret;
nextp = &(*cmdp)->next;
if (!FD_ISSET((*cmdp)->fd, fdset_rx))
continue;
do {
ret = read((*cmdp)->fd, (*cmdp)->buffer+(*cmdp)->buflen, 1);
if ((ret < 0 && errno != EAGAIN) || ret == 0) {
struct cmd_client *tmp;
tmp = *cmdp;
close((*cmdp)->fd);
*cmdp = (*cmdp)->next;
free(tmp);
nextp = cmdp;
} else if (ret == 1) {
(*cmdp)->buflen += 1;
if ((*cmdp)->buffer[(*cmdp)->buflen-1] == '\n' ||
(*cmdp)->buffer[(*cmdp)->buflen-1] == '\r') {
if ((*cmdp)->buflen > 1) {
(*cmdp)->buffer[(*cmdp)->buflen] = 0;
handle_cmd(*cmdp);
(*cmdp)->buffer[0] = '9';
}
(*cmdp)->buflen = 0;
}
if ((*cmdp)->buflen >= 200)
(*cmdp)->buflen = 0;
}
} while (ret > 0);
}
}
void output(void)
{
static time_t last = 0;
time_t now;
struct stat_client **stat_clientp, **nextp;
char statline[800];
char *statlinepos;
struct dt_model_params params;
now = time(NULL);
if (now <= last)
return;
last = now;
statlinepos = statline;
dt_model_params_get(&params);
sprintf(statlinepos,
"name=%s,a0=%f,c1=%f,c2=%f,e0=%f,b=%f,za=%f,aa=%f\n",
params.name, params.a0, params.c1, params.c2, params.e0,
params.b, params.za, params.aa);
for (stat_clientp = &stat_clients; *stat_clientp; stat_clientp = nextp){
int ret;
ret = write((*stat_clientp)->fd, statline, strlen(statline));
if (ret <= 0) {
struct stat_client *tmp;
tmp = *stat_clientp;
close((*stat_clientp)->fd);
*stat_clientp = (*stat_clientp)->next;
free(tmp);
nextp = stat_clientp;
} else {
nextp = &(*stat_clientp)->next;
}
}
}
int main(int argc, char **argv)
{
int fd_stat, fd_cmd;
dt_model_init_server();
load_ini();
signal(SIGPIPE, SIG_IGN);
fd_cmd = tcp_listen(cmd_port, 0, 100);
if (fd_cmd < 0) {
printf("Could not open listen port for commands\n");
} else {
ioctl(fd_cmd, FIONBIO, &(int){ 1 });
}
fd_stat = tcp_listen(stat_port, 0, 100);
if (fd_stat < 0) {
printf("Could not open listen port for status\n");
} else {
ioctl(fd_stat, FIONBIO, &(int){ 1 });
}
while (1)
{
int high = 0;
fd_set fdset_rx;