Commit 7b55edea authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Add trace_proxy and command_proxy options to console configuration file.

Default is set to true, if set to false console_httpd will directly connect
to the controller instead of the proxies.

Add test for quadrature decoder and optimize it a bit.

Optimize oneshot block a bit.

Add test blocks for sint32 inputs and outputs.
Also add tests for them to test.ctrl
parent f363dcfb
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013, 2014
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2013, 2014, 2015
Copyright Stichting C.A. Muller Radioastronomiestation, 2013
This program is free software: you can redistribute it and/or modify
......@@ -22,18 +22,23 @@
#include <string.h>
#include "dt_host.h"
/* Default values if no config file is found */
static char *controller_host = "localhost";
static char *console_host = "localhost";
static char *log_path = "/var/log/dt/";
static char *htdocs_path = "/var/www/htdocs/";
static char *traces_path = "/var/log/dt/traces/";
static unsigned short htdocs_port = 80;
static bool trace_proxy = true;
static bool command_proxy = true;
static bool init_done = false;
static int load_config(void)
{
GKeyFile *keyfile;
gboolean loaded = false;
/* First try global file, then try local file, after that give up.. */
gchar *keyfilename[] ={ "/etc/dt/dt_host.ini", "dt_host.ini" };
int ret = 0;
int i;
......@@ -67,6 +72,14 @@ static int load_config(void)
console_host = strdup(
g_key_file_get_string(keyfile, groups[i], "host", NULL));
}
if (g_key_file_has_key(keyfile, groups[i], "trace_proxy", NULL)) {
trace_proxy =
g_key_file_get_boolean(keyfile, groups[i], "trace_proxy", NULL);
}
if (g_key_file_has_key(keyfile, groups[i], "command_proxy", NULL)) {
command_proxy =
g_key_file_get_boolean(keyfile, groups[i], "command_proxy", NULL);
}
}
if (!strcmp(groups[i], "log")) {
if (g_key_file_has_key(keyfile, groups[i], "path", NULL)) {
......@@ -147,3 +160,13 @@ unsigned short dt_host_htdocs_port(void)
return htdocs_port;
}
bool dt_host_trace_proxy(void)
{
return trace_proxy;
}
bool dt_host_command_proxy(void)
{
return command_proxy;
}
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013, 2014
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2013, 2014, 2015
Copyright Stichting C.A. Muller Radioastronomiestation, 2013
This program is free software: you can redistribute it and/or modify
......@@ -20,11 +20,15 @@
#ifndef _INCLUDE_DT_HOST_H_
#define _INCLUDE_DT_HOST_H_
#include <stdbool.h>
char *dt_host_console(void);
char *dt_host_controller(void);
char *dt_host_log_path(void);
char *dt_host_htdocs_path(void);
char *dt_host_traces_path(void);
unsigned short dt_host_htdocs_port(void);
bool dt_host_trace_proxy(void);
bool dt_host_command_proxy(void);
#endif /* _INCLUDE_DT_HOST_H_ */
......@@ -448,11 +448,20 @@ static void start_trace(struct libwebsocket *wsi, int freq, char *variable)
struct timespec t_int;
enum trace_interval_type type;
int fd;
char *host;
int port;
if (count_traces + 1 >= MAX_TRACE_ELEMENTS)
return;
trace = trace_open("localhost", 10000);
if (dt_host_trace_proxy()) {
host = dt_host_console();
port = CONSOLE_TRACE_PORT;
} else {
host = dt_host_controller();
port = CTRL_TRACE_PORT;
}
trace = trace_open(host, port);
if (!trace)
return;
......@@ -491,8 +500,6 @@ static void start_trace(struct libwebsocket *wsi, int freq, char *variable)
count_traces++;
}
static char *command_host = "localhost";
static int command_port = CONSOLE_COMMAND_PORT;
static void do_command(char *ident, char *command)
{
......@@ -545,7 +552,17 @@ static struct command *get_command(
{
struct command *command = NULL;
int i;
char *host;
int port;
if (dt_host_trace_proxy()) {
host = dt_host_console();
port = CONSOLE_COMMAND_PORT;
} else {
host = dt_host_controller();
port = CTRL_COMMAND_PORT;
}
for (i = 0; i < nr_commands; i++) {
if (!strcmp(commands[i]->name, name)) {
command = commands[i];
......@@ -561,7 +578,7 @@ static struct command *get_command(
goto err;
commands = cl;
command = command_open_simple(command_host, command_port,
command = command_open_simple(host, port,
name, "override", vtype);
if (!command)
goto err;
......
......@@ -84,11 +84,13 @@ static void calculate(struct controller_block *block)
bool reset = INPUT(reset);
uint32_t period = priv->period;
uint32_t ticks_left = priv->ticks_left;
uint32_t setmask = (uint32_t)0 - set;
uint32_t resetmask = (uint32_t)0 - reset;
/* set counter to period if set true */
ticks_left += (period - ticks_left) * set;
ticks_left += (period - ticks_left) & setmask;
/* reset counter if reset true */
ticks_left -= ticks_left * reset;
ticks_left -= ticks_left & resetmask;
/* if counter not zero output is true */
out = ticks_left;
/* decrement, but not below zero */
......
......@@ -107,29 +107,22 @@ static int increment_lut[4][4] = {
static void calculate(struct controller_block *block)
{
int iq;
int increment;
int32_t pos = OUTPUT(pos);
iq = (INPUT(i) ? I_HIGH : I_LOW) |
(INPUT(q) ? Q_HIGH : Q_LOW);
increment = increment_lut[VAR(last_iq)][iq];
pos += increment_lut[VAR(last_iq)][iq];
if ((INPUT(home) == true) && (VAR(last_home) == false)) {
// rising edge on 'home' input
if (OUTPUT(pos) != 0) {
log_send(LOG_T_DEBUG, "homing @ %d\n", OUTPUT(pos));
if (pos != 0) {
log_send(LOG_T_DEBUG, "homing @ %d\n", pos);
}
OUTPUT(pos) = 0;
} else {
// add increment to position
OUTPUT(pos) += increment;
pos = 0;
}
// printf("i=%d q=%d\n", INPUT(i), INPUT(q));
// printf("enc: pos=%d increment=%d iq=%x last=%x\n",
// OUTPUT(pos), increment, iq, VAR(last_iq));
OUTPUT(pos) = pos;
VAR(last_iq) = iq;
VAR(last_home) = INPUT(home);
}
......
trigger {
{ "immediate" }
}
blocks (10.0, 0.0) {
{ "test_input_bool", "i" }
{ "test_input_bool", "q" }
{ "test_input_bool", "home" }
{ "quadrature_decoder", "qd" }
{ "test_output_sint32", "pos" }
}
links {
{ "i", "value", "qd", "i", true }
{ "q", "value", "qd", "q", true }
{ "home", "value", "qd", "home", true }
{ "qd", "pos", "pos", "value", true }
}
params {
{ "i", "value", 20, (int) {
false, true, true, true, true,
false, true, true, true, false,
false, true, true, false, false,
false, false, true, true, false
}
}
{ "q", "value", 20, (int) {
false, false, true, false, true,
true, true, false, true, true,
false, false, true, true, false,
false, true, true, false, false
}
}
{ "home", "value", 10, (int) {
false, false, false, false, true,
true, true, true, false, false
}
}
{ "pos", "value", 20, (int) {
0, 1, 2, 1, 0,
1, 0, -1, 0, 1,
2, 3, 4, 5, 6,
6, 5, 4, 3, 2
}
}
}
......@@ -100,5 +100,6 @@ CTRL_TESTS += \
$(DIR)/block_setpoint_generator_3d.test.ctrl \
$(DIR)/block_servo_state.test.ctrl \
$(DIR)/block_state_machine.test.ctrl \
$(DIR)/block_quadrature_decoder.test.ctrl \
$(DIR)/block_quantize.test.ctrl
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2015
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <controller/controller_block.h>
#include <test/test_block.h>
#include <log/log.h>
/*
outputs
nr name
-----------------
| |
| 0 value |----
| |
-----------------
*/
struct controller_block_private {
int32_t value;
int32_t *values;
int values_nr;
int values_cur;
};
static void calculate_test_input_sint32(struct controller_block *block)
{
struct controller_block_private *priv = block->private;
if (priv->values_cur < priv->values_nr) {
priv->value = priv->values[priv->values_cur];
}
priv->values_cur++;
if (priv->values_cur == priv->values_nr ||
(priv->values_nr == 0 && priv->values_cur == 1)) {
test_block_done(block, true);
}
}
static int param_set(struct controller_block *block, char *param, int argc,
va_list val)
{
struct controller_block_private *priv = block->private;
int nr = va_arg(val, int);
int *values = va_arg(val, int *);
int i;
/* we have only one parameter... */
priv->values = calloc(nr, sizeof(int32_t));
for (i = 0; i < nr; i++)
priv->values[i] = values[i];
priv->values_nr = nr;
log_send(LOG_T_INFO, "%s: %d test values", block->name, nr);
return 0;
}
static struct controller_block_param_list params[] = {
{ "value", false, param_set, .args = { "int,int*", NULL } },
{ NULL },
};
static struct controller_block_outterm_list outterms[] = {
{
.name = "value",
.type = CONTROLLER_BLOCK_TERM_SINT32,
.priv_offset = offsetof(struct controller_block_private, value)
},
{ NULL }
};
static struct controller_block * block_test_input_sint32_create(char *name, int argc, va_list val)
{
struct controller_block *block;
if (!(block = controller_block_alloc("test_input_sint32", name,
sizeof(struct controller_block_private))))
return NULL;
if (controller_block_outterm_list_init(block, outterms))
goto err_output;
block->calculate = calculate_test_input_sint32;
if (controller_block_param_list_add(block, params))
goto err_param;
if (controller_block_add(block))
goto err_add;
test_block_add(block);
return block;
err_add:
err_param:
err_output:
controller_block_free(block);
return NULL;
}
BLOCK_CREATE(test_input_sint32) = {
.create = block_test_input_sint32_create,
.args = { NULL },
};
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2014
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2015
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
......
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2015
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <controller/controller_block.h>
#include <test/test_block.h>
#include <log/log.h>
/*
inputs
nr name
-----------------
| |
----| 0 value |
| |
-----------------
*/
struct controller_block_private {
int32_t *value;
int32_t *values;
int values_nr;
int values_cur;
int values_ok;
};
static void calculate_test_output_sint32(struct controller_block *block)
{
struct controller_block_private *priv = block->private;
if (priv->values_cur < priv->values_nr) {
int32_t value = *priv->value;
if (value != priv->values[priv->values_cur]) {
log_send(LOG_T_ERROR,
"%s: value %d does not match: "
"%" PRIu32 " (%" PRIx32 ") != "
"%" PRIu32 " (%" PRIx32 ")",
block->name, priv->values_cur,
value, value,
priv->values[priv->values_cur],
priv->values[priv->values_cur]);
} else {
priv->values_ok++;
}
}
priv->values_cur++;
if (priv->values_cur == priv->values_nr ||
(priv->values_nr == 0 && priv->values_cur == 1)) {
bool good = priv->values_ok == priv->values_cur;
test_block_done(block, good);
}
}
static int param_set(struct controller_block *block, char *param, int argc,
va_list val)
{
struct controller_block_private *priv = block->private;
int nr = va_arg(val, int);
int *values = va_arg(val, int *);
int i;
/* we have only one parameter... */
priv->values = calloc(nr, sizeof(int32_t));
for (i = 0; i < nr; i++)
priv->values[i] = values[i];
priv->values_nr = nr;
log_send(LOG_T_INFO, "%s: %d test values", block->name, nr);
return 0;
}
static struct controller_block_param_list params[] = {
{ "value", false, param_set, .args = { "int,int*", NULL } },
{ NULL },
};
static struct controller_block_interm_list interms[] = {
{
.name = "value",
.type = CONTROLLER_BLOCK_TERM_SINT32,
.priv_offset = offsetof(struct controller_block_private, value)
},
{ NULL }
};
static struct controller_block * block_test_output_sint32_create(char *name, int argc, va_list val)
{
struct controller_block *block;
if (!(block = controller_block_alloc("test_output_sint32", name,
sizeof(struct controller_block_private))))
return NULL;
if (controller_block_interm_list_init(block, interms))
goto err_input;
block->calculate = calculate_test_output_sint32;
if (controller_block_param_list_add(block, params))
goto err_param;
if (controller_block_add(block))
goto err_add;
test_block_add(block);
return block;
err_add:
err_param:
err_input:
controller_block_free(block);
return NULL;
}
BLOCK_CREATE(test_output_sint32) = {
.create = block_test_output_sint32_create,
.args = { NULL },
};
......@@ -2,9 +2,11 @@
TEST_BLOCKS := \
test_input_bool \
test_input_float \
test_input_sint32 \
test_input_uint32 \
test_output_bool \
test_output_float \
test_output_sint32 \
test_output_uint32 \
test_command
......
......@@ -9,10 +9,12 @@ trigger{}
blocks (100.0, 0.0) {
{ "test_input_bool", "input_bool" }
{ "test_input_uint32", "input_uint32" }
{ "test_input_sint32", "input_sint32" }
{ "test_input_float", "input_float" }
{ "test_output_bool", "output_bool" }
{ "test_output_uint32", "output_uint32" }
{ "test_output_sint32", "output_sint32" }
{ "test_output_float", "output_float" }
}
......@@ -27,8 +29,9 @@ alias {
alias{}
links {
{ $<input_bool>, "output_bool", "value", true }
{ $<input_bool>, "output_bool", "value", true }
{ "input_uint32", "value", "output_uint32", "value", true }
{ "input_sint32", "value", "output_sint32", "value", true }
{ "input_float", "value", "output_float", "value", true }
}
......@@ -44,6 +47,9 @@ params {
{ "input_uint32", "value", 4, (int) { 0, 1, (int)0xdeadbeef, 123456789 } }
{ "output_uint32", "value", 4, (int) { 0, 1, (int)0xdeadbeef, 123456789 } }
{ "input_sint32", "value", 4, (int) { 0, 1, -42, 123456789 } }
{ "output_sint32", "value", 4, (int) { 0, 1, -42, 123456789 } }
}
#empty params
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment