1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

fixes for signal generator

This commit is contained in:
Steffen Vogel 2020-08-21 15:21:09 +02:00
parent 328b077956
commit efe2f52e60
2 changed files with 60 additions and 31 deletions

View file

@ -53,18 +53,18 @@ struct signal_generator {
CONSTANT,
MIXED,
PULSE
} type; /**< Signal type */
} *type; /**< Signal type */
double rate; /**< Sampling rate. */
double *frequency; /**< Frequency of the generated signals. */
double *amplitude; /**< Amplitude of the generated signals. */
double *stddev; /**< Standard deviation of random signals (normal distributed). */
double *offset; /**< A constant bias. */
double *pulse_width; /**< Width of a pulse with respect to the rate (duration = pulse_width/rate) */
double *pulse_low; /**< Amplitude when pulse signal is off */
double *pulse_high; /**< Amplitude when pulse signal is on */
double *phase; /**< Phase (rad) offset with respect to program start */
int monitor_missed; /**< Boolean, if set, node counts missed steps and warns user. */
int pulse_width; /**< Width of a pulse with respect to the rate (duration = pulse_width/rate) */
double pulse_low; /**< Amplitude when pulse signal is off */
double pulse_high; /**< Amplitude when pulse signal is on */
double phase; /**< Phase (rad) offset with respect to program start */
double *last; /**< The values from the previous period which are required for random walk. */

View file

@ -74,6 +74,7 @@ static const char * signal_generator_type_str(enum signal_generator::SignalType
case signal_generator::SignalType::RAMP:
return "ramp";
case signal_generator::SignalType::COUNTER:
return "counter";
@ -82,8 +83,10 @@ static const char * signal_generator_type_str(enum signal_generator::SignalType
case signal_generator::SignalType::MIXED:
return "mixed";
case signal_generator::SignalType::PULSE:
return "pulse";
default:
return nullptr;
}
@ -141,8 +144,7 @@ int signal_generator_prepare(struct node *n)
assert(vlist_length(&n->in.signals) == 0);
for (unsigned i = 0; i < s->values; i++) {
int rtype = s->type == signal_generator::SignalType::MIXED ? i % 7 : (int) s->type;
auto name = signal_generator_type_str((enum signal_generator::SignalType) rtype);
auto name = signal_generator_type_str((enum signal_generator::SignalType) s->type[i]);
auto *sig = signal_create(name, nullptr, SignalType::FLOAT);
vlist_push(&n->in.signals, sig);
@ -156,10 +158,10 @@ int signal_generator_parse(struct node *n, json_t *cfg)
struct signal_generator *s = (struct signal_generator *) n->_vd;
int ret;
const char *type = nullptr;
json_error_t err;
json_t *json_type = nullptr;
json_t *json_amplitude = nullptr;
json_t *json_offset = nullptr;
json_t *json_frequency = nullptr;
@ -169,8 +171,8 @@ int signal_generator_parse(struct node *n, json_t *cfg)
json_t *json_pulse_low = nullptr;
json_t *json_phase = nullptr;
ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: b, s?: i, s?: i, s?: F, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: b }",
"signal", &type,
ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: b, s?: i, s?: i, s?: F, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: b }",
"signal", &json_type,
"realtime", &s->rt,
"limit", &s->limit,
"values", &s->values,
@ -206,6 +208,40 @@ int signal_generator_parse(struct node *n, json_t *cfg)
{ json_phase, &s->phase, 0, "phase" }
};
size_t i;
json_t *json_value;
const char *type_str;
signal_generator::SignalType type;
s->type = new enum signal_generator::SignalType[s->values];
switch (json_typeof(json_type)) {
case JSON_ARRAY:
if (json_array_size(json_type) != s->values)
throw ConfigError(json_type, "node-config-node-signal", "Length of values must match");
json_array_foreach(json_type, i, json_value) {
type_str = json_string_value(json_type);
s->type[i] = signal_generator_lookup_type(type_str);
}
break;
case JSON_STRING:
type_str = json_string_value(json_type);
type = signal_generator_lookup_type(type_str);
for (size_t i = 0; i < s->values; i++) {
s->type[i] = (type == signal_generator::SignalType::MIXED
? (signal_generator::SignalType) (i % 7)
: type);
}
break;
default:
throw ConfigError(json_type, "node-config-node-signal", "Invalid setting 'signal' for node {}", node_name(n));
}
for (auto &a : arrays) {
if (*a.array)
delete *a.array;
@ -248,11 +284,6 @@ int signal_generator_parse(struct node *n, json_t *cfg)
}
}
if (type)
s->type = signal_generator_lookup_type(type);
else
s->type = signal_generator::SignalType::MIXED;
return 0;
}
@ -302,17 +333,8 @@ int signal_generator_read(struct node *n, struct sample *smps[], unsigned cnt, u
assert(cnt == 1);
/* Throttle output if desired */
if (s->rt) {
/* Block until 1/p->rate seconds elapsed */
steps = s->task.wait();
if (steps > 1 && s->monitor_missed) {
debug(5, "Missed steps: %u", steps-1);
s->missed_steps += steps-1;
}
if (s->rt)
ts = time_now();
}
else {
struct timespec offset = time_from_double(s->counter * 1.0 / s->rate);
@ -321,6 +343,7 @@ int signal_generator_read(struct node *n, struct sample *smps[], unsigned cnt, u
steps = 1;
}
double running = time_delta(&s->started, &ts);
t->flags = (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_DATA | (int) SampleFlags::HAS_SEQUENCE;
@ -330,9 +353,7 @@ int signal_generator_read(struct node *n, struct sample *smps[], unsigned cnt, u
t->signals = &n->in.signals;
for (unsigned i = 0; i < MIN(s->values, t->capacity); i++) {
auto rtype = (s->type != signal_generator::SignalType::MIXED) ? s->type : (signal_generator::SignalType) (i % 7);
switch (rtype) {
switch (s->type[i]) {
case signal_generator::SignalType::CONSTANT:
t->data[i].f = s->offset[i] + s->amplitude[i];
break;
@ -382,6 +403,16 @@ int signal_generator_read(struct node *n, struct sample *smps[], unsigned cnt, u
return -1;
}
/* Throttle output if desired */
if (s->rt) {
/* Block until 1/p->rate seconds elapsed */
steps = s->task.wait();
if (steps > 1 && s->monitor_missed) {
debug(5, "Missed steps: %u", steps-1);
s->missed_steps += steps-1;
}
}
s->counter += steps;
return 1;
@ -391,10 +422,8 @@ char * signal_generator_print(struct node *n)
{
struct signal_generator *s = (struct signal_generator *) n->_vd;
char *buf = nullptr;
const char *type = signal_generator_type_str(s->type);
strcatf(&buf, "signal=%s, rt=%s, rate=%.2f, values=%d",
type, s->rt ? "yes" : "no", s->rate, s->values);
strcatf(&buf, "rt=%s, rate=%.2f, values=%d", s->rt ? "yes" : "no", s->rate, s->values);
if (s->limit > 0)
strcatf(&buf, ", limit=%d", s->limit);