Commit 5f2203f7 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Add gain by ratio block with absolute output.

Can be used to calculate a voltage limit based on the current voltage and
current and a current limit.
parent bc126ab5
/*
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>
/*
inputs outputs
nr name nr name
----------------------
| |
---| 0 in 0 out |----
| |
---| 1 num |
| |
---| 2 denom |
----------------------
*/
struct controller_block_private {
float *in;
float *num;
float *denom;
float out;
};
static void gain_ra_calculate(struct controller_block *gain)
{
struct controller_block_private *priv = gain->private;
priv->out = fabs((*priv->in * *priv->num)/ *priv->denom);
}
static struct controller_block_interm_list interms[] = {
{ "in", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, in) },
{ "num", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, num) },
{ "denom", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, denom) },
{ NULL }
};
static struct controller_block_outterm_list outterms[] = {
{ "out", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, out) },
{ NULL }
};
struct controller_block * block_gain_ra_create(char *name, int argc,
va_list ap)
{
struct controller_block *gain;
if (!(gain = controller_block_alloc("gain_ratio_abs", name, sizeof(struct controller_block_private))))
return NULL;
gain->private->out = 0.0;
if (controller_block_interm_list_init(gain, interms))
goto err_block;
if (controller_block_outterm_list_init(gain, outterms))
goto err_block;
gain->calculate = gain_ra_calculate;
if (controller_block_add(gain))
goto err_block;
return gain;
err_block:
controller_block_free(gain);
return NULL;
}
BLOCK_CREATE(gain_ratio_abs) = {
.create = block_gain_ra_create,
.args = { NULL },
};
trigger {
{ "immediate" }
}
blocks (100.0, 0.0) {
{ "gain_ratio_abs", "gain" }
{ "test_input_float", "test_in" }
{ "test_input_float", "test_num" }
{ "test_input_float", "test_denom" }
{ "test_output_float", "test_out" }
}
links {
{ "test_in", "value", "gain", "in", true }
{ "test_num", "value", "gain", "num", true }
{ "test_denom", "value", "gain", "denom", true }
{ "gain", "out", "test_out", "value", true }
}
params {
{ "test_in", "value", 8, (float) {
0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0 } }
{ "test_num", "value", 8, (float) {
0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 50.0, -12.5 } }
{ "test_denom", "value", 8, (float) {
0.0, 0.0, 1.0, 1.0, 0.0, 0.00001, 1.0, 1.0, 2.0, -0.5 } }
{ "test_out", "value", 8,
(float) { 0.0, 0.0, 0.0, 0.0, 0.0, 100000.0, 0.0, 1.0, 25.0 },
(float) { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }
}
}
......@@ -17,6 +17,7 @@ BLOCKS := \
filter_lp \
friction \
gain \
gain_ratio_abs \
gain_var \
i2t \
inverse_proportional \
......@@ -101,6 +102,7 @@ CTRL_TESTS += \
$(DIR)/block_command_bool.test.output \
$(DIR)/block_command_float.test.output \
$(DIR)/block_gain.test.output \
$(DIR)/block_gain_ratio_abs.test.output \
$(DIR)/block_i2t.test.output \
$(DIR)/block_limit.test.output \
$(DIR)/block_limit_switch.test.output \
......
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