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:
parent
328b077956
commit
efe2f52e60
2 changed files with 60 additions and 31 deletions
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue