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

fixed implementation of FIR filter hook with thread local storage

This commit is contained in:
Steffen Vogel 2015-09-28 19:53:42 +02:00
parent ec26e4c346
commit acd72ea501
3 changed files with 37 additions and 24 deletions

View file

@ -52,8 +52,13 @@
{ "/etc/machine-id", "0d8399d0216314f083b9ed2053a354a8" }, \
{ "/dev/sda2", "\x53\xf6\xb5\xeb\x8b\x16\x46\xdc\x8d\x8f\x5b\x70\xb8\xc9\x1a\x2a", 0x468 } }
/* Hook function configuration */
#define HOOK_FIR_INDEX 1 /**< The first value of message should be filtered. */
/* Hard coded configuration of hook functions */
#define HOOK_FIR_INDEX 0 /**< Which value inside a message should be filtered? */
#define HOOK_FIR_COEFFS { -0.003658148158728, -0.008882653268281, 0.008001024183003, \
0.08090485991761, 0.2035239551043, 0.3040703593515, \
0.3040703593515, 0.2035239551043, 0.08090485991761, \
0.008001024183003, -0.008882653268281,-0.003658148158728 }
#define HOOK_TS_INDEX -1 /**< The last value of message should be overwritten by a timestamp. */
#define HOOK_DECIMATE_RATIO 30 /**< Only forward every 30th message to the destination nodes. */

View file

@ -53,7 +53,7 @@
}
/** Initialize a message */
#define MSG_INIT(i) (struct msg) { \
#define MSG_INIT(i) { \
.version = MSG_VERSION, \
.type = MSG_TYPE_DATA, \
.endian = MSG_ENDIAN_HOST, \

View file

@ -87,31 +87,39 @@ int hook_ts(struct path *p)
return 0;
}
REGISTER_HOOK("fir", 99, hook_fir, HOOK_POST)
REGISTER_HOOK("fir", 99, hook_fir, HOOK_MSG)
int hook_fir(struct path *p)
{
/** Simple FIR-LP: F_s = 1kHz, F_pass = 100 Hz, F_block = 300
/** Coefficients for simple FIR-LowPass:
* F_s = 1kHz, F_pass = 100 Hz, F_block = 300
*
* Tip: Use MATLAB's filter design tool and export coefficients
* with the integrated C-Header export */
static const double coeffs[] = {
-0.003658148158728, -0.008882653268281, 0.008001024183003,
0.08090485991761, 0.2035239551043, 0.3040703593515,
0.3040703593515, 0.2035239551043, 0.08090485991761,
0.008001024183003, -0.008882653268281,-0.003658148158728 };
* with the integrated C-Header export
*/
static const double coeffs[] = HOOK_FIR_COEFFS;
/** Per path thread local storage for unfiltered sample values.
* The message ringbuffer (p->pool & p->current) will contain filtered data!
*/
static __thread double *past = NULL;
/** @todo Avoid dynamic allocation at runtime */
if (!past)
alloc(p->poolsize * sizeof(double));
/* Current value of interest */
float *cur = &p->current->data[HOOK_FIR_INDEX].f;
/* Save last sample, unfiltered */
past[p->received % p->poolsize] = *cur;
/* Accumulator */
double sum = 0;
/** Trim FIR length to length of history buffer */
int len = MIN(ARRAY_LEN(coeffs), p->poolsize);
for (int i = 0; i < len; i++) {
struct msg *old = &p->pool[(p->poolsize+p->received-i) % p->poolsize];
sum += coeffs[i] * old->data[HOOK_FIR_INDEX].f;
}
p->current->data[HOOK_FIR_INDEX].f = sum;
/* Reset accumulator */
*cur = 0;
/* FIR loop */
for (int i = 0; i < MIN(ARRAY_LEN(coeffs), p->poolsize); i++)
*cur += coeffs[i] * past[p->received+p->poolsize-i];
return 0;
}