Commit 8cfc3505 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Add new module keyword.

Add module code in controller_module
Introduce new test for module
Use module in azimuth and elevation simulators
Remove dedicated simulator blocks
parent 37bd37d2
......@@ -71,8 +71,7 @@ static struct controller_block * block_command_bool_create(char *name, int argc,
controller_block_add(cmd);
cmd->private->command = controller_command_create(
cmd, name, "Boolean");
cmd->private->command = controller_command_create(cmd, name, "Boolean");
cmd->private->command->value_type = COMMAND_VALUE_TYPE_BOOL;
cmd->private->command->command_types[0] = COMMAND_PTYPE_SETPOINT;
......
......@@ -8,6 +8,7 @@ CONTROLLER_SRCS= \
$(DIR)/controller_bus.c \
$(DIR)/controller_command.c \
$(DIR)/controller_mem.c \
$(DIR)/controller_module.c \
$(DIR)/controller_time.c \
$(DIR)/controller_trace.c \
$(DIR)/controller_sample.c \
......
......@@ -82,6 +82,7 @@ boolcast "("[ \t]*"bool"[ \t]*")"
"alias" { return ALIASSYM; }
"trigger" { return TRIGGERSYM; }
"blocks" { return BLOCKSSYM; }
"module" { return MODULESYM; }
"links" { return LINKSSYM; }
"traces" { return TRACESSYM; }
"params" { return PARAMSSYM; }
......
......@@ -30,6 +30,7 @@
#include <controller/controller_trace.h>
#include <controller/controller_sample.h>
#include <controller/controller_time.h>
#include <controller/controller_module.h>
#define YYERROR_VERBOSE
......@@ -63,6 +64,7 @@ void yyerror(yyscan_t *scanner, char const *s);
%token <ul> UNSIGNEDLONGSYM
%token TRIGGERSYM
%token BLOCKSSYM
%token MODULESYM
%token LINKSSYM
%token TRACESSYM
%token PARAMSSYM
......@@ -181,7 +183,9 @@ blocks : BLOCKSSYM PARENTHESESOPENSYM doublevar COMMASYM doublevar
PARENTHESESCLOSESYM BRACEOPENSYM blocklist BRACECLOSESYM
blocklist: block
| module
| block blocklist
| module blocklist
;
block : BRACEOPENSYM
......@@ -199,6 +203,48 @@ block : BRACEOPENSYM
}
;
module : MODULESYM
PARENTHESESOPENSYM stringvar PARENTHESESCLOSESYM
BRACEOPENSYM
BRACEOPENSYM moduleinputlist BRACECLOSESYM
BRACEOPENSYM moduleoutputlist BRACECLOSESYM
BRACECLOSESYM
{
if (controller_module_create($3)) {
yyerror(scanner, "Error creating module");
YYERROR;
}
}
;
moduleinputlist : moduleinput
| moduleinput moduleinputlist
;
moduleinput : BRACEOPENSYM
stringvar COMMASYM stringvar COMMASYM stringvar
{
if (controller_module_input_add($2, $4, $6)) {
yyerror(scanner, "Error adding module input");
YYERROR;
}
}
BRACECLOSESYM
moduleoutputlist : moduleoutput
| moduleoutput moduleoutputlist
;
moduleoutput : BRACEOPENSYM
stringvar COMMASYM stringvar COMMASYM stringvar
{
if (controller_module_output_add($2, $4, $6)) {
yyerror(scanner, "Error adding module output");
YYERROR;
}
}
BRACECLOSESYM
params : PARAMSSYM BRACEOPENSYM paramlist BRACECLOSESYM
paramlist: param
......
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2013
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
......@@ -17,16 +16,14 @@
*/
#include <controller/controller_module.h>
#include <controller/controller_block.h>
#include <log/log.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <controller/controller_block.h>
struct controller_block_private {
bool *ba1;
bool *ba2;
};
struct ghost_term {
char *name;
......@@ -34,113 +31,129 @@ struct ghost_term {
char *realname;
};
static struct ghost_term ghost_outputs[] = {
{ "position", "dt_az_pos_quantize", "out" },
{ "speed", "dt_az_accelerate", "out" },
{ "torque", "dt_az_torque_limit", "out" },
{ "enabled", "dt_az_enabled", "output" },
{ "be1", "dt_az_safety_n_not", "output" },
{ "be2", "dt_az_safety_n", "value" },
{ "be3", "dt_az_safety_p_not", "output" },
{ "be4", "dt_az_safety_p", "value" },
{ "be5", "dt_az_bex", "value" },
{ "ae1", "dt_az_focusbox", "value" },
{ "external_enable", "dt_az_bex", "value" },
{ NULL },
};
static struct ghost_term *in_terms = NULL;
static struct ghost_term *out_terms = NULL;
static int in_term_nr = 0;
static int out_term_nr = 0;
static struct ghost_term ghost_inputs[] = {
{ "speed", "dt_az_speed_limit", "in" },
{ "torque", "dt_az_torque_limit", "limit" },
{ "enable", "dt_az_enabled", "input" },
{ NULL },
};
int controller_module_input_add(char *name, char *blockname, char *inputname)
{
in_term_nr++;
in_terms = realloc(in_terms, sizeof(struct ghost_term) * in_term_nr);
in_terms[in_term_nr-1].name = strdup(name);
in_terms[in_term_nr-1].realblock = strdup(blockname);
in_terms[in_term_nr-1].realname = strdup(inputname);
return 0;
}
static struct controller_block *block_dt_az_stoeber_sim_create(char *name, int argc, va_list ap)
int controller_module_output_add(char *name, char *blockname, char *outputname)
{
struct controller_block *stoeber;
out_term_nr++;
out_terms = realloc(out_terms, sizeof(struct ghost_term) * out_term_nr);
out_terms[out_term_nr-1].name = strdup(name);
out_terms[out_term_nr-1].realblock = strdup(blockname);
out_terms[out_term_nr-1].realname = strdup(outputname);
return 0;
}
int controller_module_create(char *name)
{
struct controller_block *module;
int i;
if (!(stoeber = controller_block_alloc("dt_az_stoeber_sim", name, sizeof(struct controller_block_private))))
goto err_malloc;
if (!(module = controller_block_alloc("module", name, 0)))
goto err_alloc;
for (i = 0; ghost_outputs[i].name; i++);
stoeber->outputs = i;
stoeber->output = malloc(sizeof(struct controller_block_outterm)*i);
if (!stoeber->output)
goto err_output;
for (i = 0; ghost_outputs[i].name; i++) {
module->inputs = in_term_nr;
module->input = calloc(in_term_nr, sizeof(struct controller_block_interm));
if (!module->input)
goto err_input;
for (i = 0; i < in_term_nr; i++) {
struct controller_block *subblock;
int j;
stoeber->output[i].name = ghost_outputs[i].name;
subblock = controller_block_find(ghost_outputs[i].realblock);
module->input[i].name = in_terms[i].name;
subblock = controller_block_find(in_terms[i].realblock);
if (!subblock) {
printf("block %s not found", ghost_outputs[i].realblock);
log_send(LOG_T_ERROR, "block %s not found",
in_terms[i].realblock);
goto err_output;
}
for (j = 0; j < subblock->outputs; j++) {
if (!strcmp(subblock->output[j].name,
ghost_outputs[i].realname)) {
stoeber->output[i].value =
subblock->output[j].value;
stoeber->output[i].type =
subblock->output[j].type;
stoeber->output[i].source = subblock->output[j].source;
stoeber->output[i].sourceterm = &subblock->output[j];
for (j = 0; j < subblock->inputs; j++) {
if (!strcmp(subblock->input[j].name,
in_terms[i].realname)) {
module->input[i].value =
subblock->input[j].value;
module->input[i].type =
subblock->input[j].type;
module->input[i].ghostof =
&subblock->input[j];
break;
}
}
if (j == subblock->inputs) {
log_send(LOG_T_ERROR,
"Block %s does not have an input %s",
in_terms[i].realblock, in_terms[i].realname);
goto err_input;
}
free(in_terms[i].realblock);
}
for (i = 0; ghost_inputs[i].name; i++);
stoeber->inputs = i + 2;
stoeber->input = malloc(sizeof(struct controller_block_interm)*stoeber->inputs);
if (!stoeber->input)
goto err_input;
for (i = 0; ghost_inputs[i].name; i++) {
module->outputs = out_term_nr;
module->output = calloc(out_term_nr, sizeof(struct controller_block_outterm));
if (!module->output)
goto err_output;
for (i = 0; i < out_term_nr; i++) {
struct controller_block *subblock;
int j;
stoeber->input[i].name = ghost_inputs[i].name;
subblock = controller_block_find(ghost_inputs[i].realblock);
for (j = 0; j < subblock->inputs; j++) {
if (!strcmp(subblock->input[j].name,
ghost_inputs[i].realname)) {
stoeber->input[i].value =
subblock->input[j].value;
stoeber->input[i].type =
subblock->input[j].type;
stoeber->input[i].ghostof =
&subblock->input[j];
module->output[i].name = out_terms[i].name;
subblock = controller_block_find(out_terms[i].realblock);
if (!subblock) {
log_send(LOG_T_ERROR, "block %s not found",
out_terms[i].realblock);
goto err_output;
}
for (j = 0; j < subblock->outputs; j++) {
if (!strcmp(subblock->output[j].name,
out_terms[i].realname)) {
module->output[i].value =
subblock->output[j].value;
module->output[i].type =
subblock->output[j].type;
module->output[i].source = subblock->output[j].source;
module->output[i].sourceterm = &subblock->output[j];
break;
}
}
if (j == subblock->outputs) {
log_send(LOG_T_ERROR,
"Block %s does not have an output %s",
out_terms[i].realblock, out_terms[i].realname);
goto err_output;
}
free(out_terms[i].realblock);
}
stoeber->input[i].name = "ba1";
stoeber->input[i].value.b = &stoeber->private->ba1;
stoeber->input[i].type = CONTROLLER_BLOCK_TERM_BOOL;
stoeber->input[i].ghostof = NULL;
i++;
stoeber->input[i].name = "ba2";
stoeber->input[i].value.b = &stoeber->private->ba2;
stoeber->input[i].type = CONTROLLER_BLOCK_TERM_BOOL;
stoeber->input[i].ghostof = NULL;
stoeber->calculate = NULL;
free(in_terms);
in_terms = NULL;
free(out_terms);
out_terms = NULL;
in_term_nr = 0;
out_term_nr = 0;
controller_block_add(stoeber);
controller_block_add(module);
return stoeber;
return 0;
err_input:
free(stoeber->output);
err_output:
controller_block_free(stoeber);
err_malloc:
return NULL;
controller_block_free(module);
err_alloc:
return -1;
}
BLOCK_CREATE(dt_az_stoeber_sim) = {
.create = block_dt_az_stoeber_sim_create,
.args = { NULL },
};
/*
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/>.
*/
#ifndef _INCLUDE_CONTROLLER_MODULE_H_
#define _INCLUDE_CONTROLLER_MODULE_H_
int controller_module_create(char *name);
int controller_module_input_add(char *name, char *blockname, char *inputname);
int controller_module_output_add(char *name, char *blockname, char *outputname);
#endif /* _INCLUDE_CONTROLLER_MODULE_H_ */
......@@ -3,8 +3,7 @@ DT_AZIMUTH_TARGETS += $(LIBDIR)/libdt_azimuth.la
DT_AZIMUTH_SRCS = \
$(DIR)/dt_az_safety.c \
$(DIR)/dt_az_stoeber_sim.c
$(DIR)/dt_az_safety.c
DT_AZIMUTH_OBJS := $(DT_AZIMUTH_SRCS:.c=.lo)
......@@ -15,7 +14,7 @@ $(LIBDIR)/libdt_azimuth.la_LDFLAGS += -lcontroller -llog
$(LIBDIR)/libdt_azimuth.la: $(DT_AZIMUTH_OBJS)
$(LIB_LINK)
CTRL_BLOCKS += dt_az_safety dt_az_stoeber_sim
CTRL_BLOCKS += dt_az_safety
CTRL_BLOCK_LIBS += libdt_azimuth.la
TARGETS += $(DT_AZIMUTH_TARGETS)
......
......@@ -17,8 +17,31 @@ blocks ($(frequency), $(delay)) {
{ "not", "dt_az_safety_p_not" }
{ "value_bool", "dt_az_bex" }
{ "value", "dt_az_focusbox" }
{ "not", "dt_az_ba1" }
{ "not", "dt_az_ba2" }
{ "dt_az_stoeber_sim", "dt_az" }
module ("dt_az") {
{
{ "speed", "dt_az_speed_limit", "in" }
{ "torque", "dt_az_torque_limit", "limit" }
{ "enable", "dt_az_enabled", "input" }
{ "ba1", "dt_az_ba1", "input" }
{ "ba2", "dt_az_ba2", "input" }
}
{
{ "position", "dt_az_pos_quantize", "out" }
{ "speed", "dt_az_accelerate", "out" }
{ "torque", "dt_az_torque_limit", "out" }
{ "enabled", "dt_az_enabled", "output" }
{ "be1", "dt_az_safety_n_not", "output" }
{ "be2", "dt_az_safety_n", "value" }
{ "be3", "dt_az_safety_p_not", "output" }
{ "be4", "dt_az_safety_p", "value" }
{ "be5", "dt_az_bex", "value" }
{ "ae1", "dt_az_focusbox", "value" }
{ "external_enable", "dt_az_bex", "value" }
}
}
}
links {
......@@ -32,8 +55,8 @@ links {
{ "dt_az_accelerate", "out", "dt_az_speed_fb", "negative", false }
{ "dt_az_accelerate", "out", "dt_az_friction", "speed", false }
{ "dt_az_speed2pos", "out", "dt_az_offset_add", "in0", false }
{ "dt_az_offset", "value", "dt_az_offset_add", "in1", false }
{ "dt_az_speed2pos", "out", "dt_az_offset_add", "in0", true }
{ "dt_az_offset", "value", "dt_az_offset_add", "in1", true }
{ "dt_az_offset_add", "out", "dt_az_pos_quantize", "in", false }
......
......@@ -38,9 +38,56 @@ blocks ($(frequency), $(delay)) {
{ "not", "dt_el_safety_b_not" }
{ "value_bool", "dt_el_bex" }
{ "value", "dt_el_ae1" }
{ "not", "dt_el_ba1_r" }
{ "not", "dt_el_ba2_r" }
{ "not", "dt_el_ba1_l" }
{ "not", "dt_el_ba2_l" }
{ "dt_el_stoeber_r_sim", "dt_el_r" }
{ "dt_el_stoeber_l_sim", "dt_el_l" }
module ("dt_el_r") {
{
{ "speed", "dt_el_speed_limit_r", "in" }
{ "torque", "dt_el_torque_gain_r", "in" }
{ "enable", "dt_el_enabled", "input" }
{ "ba1", "dt_el_ba1_r", "input" }
{ "ba2", "dt_el_ba2_r", "input" }
}
{
{ "position", "dt_el_pos_quantize_r", "out" }
{ "speed", "dt_el_accelerate_r", "out" }
{ "torque", "dt_el_torque_limit_r", "out" }
{ "enabled", "dt_el_enabled", "output" }
{ "be1", "dt_el_bex", "value" }
{ "be2", "dt_el_bex", "value" }
{ "be3", "dt_el_bex", "value" }
{ "be4", "dt_el_bex", "value" }
{ "be5", "dt_el_bex", "value" }
{ "ae1", "dt_el_ae1", "value" }
{ "external_enable", "dt_el_bex", "value" }
}
}
module ("dt_el_l") {
{
{ "speed", "dt_el_speed_limit_l", "in" }
{ "torque", "dt_el_torque_gain_l", "in" }
{ "enable", "dt_el_enabled", "input" }
{ "ba1", "dt_el_ba1_l", "input" }
{ "ba2", "dt_el_ba2_l", "input" }
}
{
{ "position", "dt_el_pos_quantize_l", "out" }
{ "speed", "dt_el_accelerate_l", "out" }
{ "torque", "dt_el_torque_limit_l", "out" }
{ "enabled", "dt_el_enabled", "output" }
{ "be1", "dt_el_safety_b_not", "output" }
{ "be2", "dt_el_safety_b", "value" }
{ "be3", "dt_el_safety_t_not", "output" }
{ "be4", "dt_el_safety_t", "value" }
{ "be5", "dt_el_bex", "value" }
{ "ae1", "dt_el_ae1", "value" }
{ "external_enable", "dt_el_bex", "value" }
}
}
}
params {
......
......@@ -3,9 +3,7 @@ DT_ELEVATION_TARGETS += $(LIBDIR)/libdt_elevation.la
DT_ELEVATION_SRCS = \
$(DIR)/dt_el_safety.c \
$(DIR)/dt_el_stoeber_r_sim.c \
$(DIR)/dt_el_stoeber_l_sim.c
$(DIR)/dt_el_safety.c
DT_ELEVATION_OBJS := $(DT_ELEVATION_SRCS:.c=.lo)
......
/*
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 <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <controller/controller_block.h>
#include <log/log.h>
struct controller_block_private {
bool *ba1;
bool *ba2;
};
struct ghost_term {
char *name;
char *realblock;
char *realname;
};
static struct ghost_term ghost_outputs[] = {
{ "position", "dt_el_pos_quantize_l", "out" },
{ "speed", "dt_el_accelerate_l", "out" },
{ "torque", "dt_el_torque_limit_l", "out" },
{ "enabled", "dt_el_enabled", "output" },
{ "be1", "dt_el_safety_b_not", "output" },
{ "be2", "dt_el_safety_b", "value" },
{ "be3", "dt_el_safety_t_not", "output" },
{ "be4", "dt_el_safety_t", "value" },
{ "be5", "dt_el_bex", "value" },
{ "ae1", "dt_el_ae1", "value" },
{ "external_enable", "dt_el_bex", "value" },
{ NULL },
};
static struct ghost_term ghost_inputs[] = {
{ "speed", "dt_el_speed_limit_l", "in" },
{ "torque", "dt_el_torque_gain_l", "in" },
{ "enable", "dt_el_enabled", "input" },
{ NULL },
};
static struct controller_block *block_dt_el_stoeber_l_sim_create(char *name, int argc, va_list ap)
{
struct controller_block *stoeber;
int i;
if (!(stoeber = controller_block_alloc("dt_el_stoeber_l_sim", name, sizeof(struct controller_block_private))))
goto err_malloc;
for (i = 0; ghost_outputs[i].name; i++);
stoeber->outputs = i;
stoeber->output = malloc(sizeof(struct controller_block_outterm)*i);
if (!stoeber->output)
goto err_output;
for (i = 0; ghost_outputs[i].name; i++) {
struct controller_block *subblock;
int j;
stoeber->output[i].name = ghost_outputs[i].name;
subblock = controller_block_find(ghost_outputs[i].realblock);
if (!subblock) {
log_send(LOG_T_ERROR, "subblock %s not found", ghost_outputs[i].realblock);
goto err_ghost_output;
}
for (j = 0; j < subblock->outputs; j++) {
if (!strcmp(subblock->output[j].name,
ghost_outputs[i].realname)) {
stoeber->output[i].value =
subblock->output[j].value;
stoeber->output[i].type =
subblock->output[j].type;
stoeber->output[i].source = subblock->output[j].source;
stoeber->output[i].sourceterm = &subblock->output[j];
break;
}
}
if (j == subblock->outputs) {
log_send(LOG_T_ERROR, "Could not find subblock output %s",
ghost_outputs[i].realname);
goto err_ghost_output;
}
}