Navigation

core.filter.mvng_av

Inputs

Name

Type

Title

Mandatory

Description

i1

core.type.f64

Input 1

True

None

i2

core.type.f64

Input 2

True

None

i3

core.type.f64

Input 3

True

None

Outputs

Name

Type

Title

Description

a1

core.type.f64

Average 1

None

a2

core.type.f64

Average 2

None

a3

core.type.f64

Average 3

None

filled

core.type.bool

Filled

Is set to TRUE when selection is initually filled

Parameters

Function has no parameters

State variables

Name

Type

Title

Description

counter

core.type.u32

None

Usage XML code snippet

core_filter_mvng_av snippet for FLOW configuration file
<f name="mvng_av" by_spec="core.filter.mvng_av">
    <in alias="i1">some_block_1/output</in>
    <in alias="i2">some_block_2/output</in>
    <in alias="i3">some_block_3/output</in>
</f>

Function’s artifacts

declaration.py
from fspeclib import *


Function(
    name='core.filter.mvng_av',
    title=LocalizedString(
        en='Moving average 3 channels function'
    ),
    has_pre_exec_init_call=True,
    inputs=[
        Input(
            name='i1',
            title='Input 1',
            value_type='core.type.f64'
        ),
        Input(
            name='i2',
            title='Input 2',
            value_type='core.type.f64'
        ),
        Input(
            name='i3',
            title='Input 3',
            value_type='core.type.f64'
        ),
    ],
    outputs=[
        Output(
            name='a1',
            title='Average 1',
            value_type='core.type.f64'
        ),
        Output(
            name='a2',
            title='Average 2',
            value_type='core.type.f64'
        ),
        Output(
            name='a3',
            title='Average 3',
            value_type='core.type.f64'
        ),
        Output(
            name='filled',
            title='Filled',
            description='Is set to TRUE when selection is initually filled',
            value_type='core.type.bool'
        ),
    ],

    state=[
        Variable(
            name='counter',
            title='',
            value_type='core.type.u32'
        ),

        # TODO allocated array of the desired type
    ],
)
core_filter_mvng_av_exec.c
#include "core_filter_mvng_av.h"

/*
 * FIXME very rough prototype dummy
 *
 * This is fake moving average, which is calculating average once at the moment of selection fill
 */

#define SELECTION_SIZE 50
static core_type_f64_t selection[SELECTION_SIZE][3];
static core_type_f64_t output[3];
static int counter = 0;

fspec_rv_t core_filter_mvng_av_pre_exec_init(core_filter_mvng_av_state_t *state) {

    return fspec_rv_ok;
}

void core_filter_mvng_av_exec(const core_filter_mvng_av_inputs_t *i, core_filter_mvng_av_outputs_t *o, core_filter_mvng_av_state_t *state)
{
    if (counter < SELECTION_SIZE) {
        selection[counter][0] = i->i1;
        selection[counter][1] = i->i2;
        selection[counter][2] = i->i3;
        counter++;

        if (counter == SELECTION_SIZE) {
            output[0] = 0;
            output[1] = 0;
            output[2] = 0;
            for (int j = 0; j < SELECTION_SIZE; j++) {
                output[0] += selection[j][0];
                output[1] += selection[j][1];
                output[2] += selection[j][2];
            }
            output[0] /= SELECTION_SIZE;
            output[1] /= SELECTION_SIZE;
            output[2] /= SELECTION_SIZE;
        }
        o->filled = FALSE;
    } else {
        o->a1 = output[0];
        o->a2 = output[1];
        o->a3 = output[2];
        o->filled = TRUE;
    }
}
core_filter_mvng_av.h
/**
 *  Automatically-generated file. Do not edit!
 */

#ifndef FSPEC_CORE_FILTER_MVNG_AV_H
#define FSPEC_CORE_FILTER_MVNG_AV_H

#include <stdint.h>
#include <eswb/types.h>

#include "function.h"

/* Include declaration of dependency types */
#include "core_type_bool.h"
#include "core_type_f64.h"
#include "core_type_u32.h"

/**
 * @brief Inputs of `core.filter.mvng_av` function
 */
typedef struct core_filter_mvng_av_inputs_ {
    core_type_f64_t i1;  /// Input 1
    core_type_f64_t i2;  /// Input 2
    core_type_f64_t i3;  /// Input 3

} core_filter_mvng_av_inputs_t;

/**
 * @brief Outputs of `core.filter.mvng_av` function
 */
typedef struct core_filter_mvng_av_outputs_ {
    core_type_f64_t a1; /// Average 1

    core_type_f64_t a2; /// Average 2

    core_type_f64_t a3; /// Average 3

    core_type_bool_t filled; /// Filled

} core_filter_mvng_av_outputs_t;

/**
 * @brief State variables of `core.filter.mvng_av` function
 */
typedef struct core_filter_mvng_av_state_ {
    core_type_u32_t counter;  ///
} core_filter_mvng_av_state_t;

/**
 * @brief Parameter flags of `core.filter.mvng_av` function
 */
typedef struct core_filter_mvng_av_params_flags_ {
} core_filter_mvng_av_params_flags_t;

typedef struct core_filter_mvng_av_eswb_descriptors_ {
    eswb_topic_descr_t in_i1;
    eswb_topic_descr_t in_i2;
    eswb_topic_descr_t in_i3;
    eswb_topic_descr_t out_all;
} core_filter_mvng_av_eswb_descriptors_t;

typedef struct core_filter_mvng_av_interface_ {
    core_filter_mvng_av_inputs_t i;
    core_filter_mvng_av_outputs_t o;
    core_filter_mvng_av_state_t state;
    core_filter_mvng_av_eswb_descriptors_t eswb_descriptors;
} core_filter_mvng_av_interface_t;

fspec_rv_t core_filter_mvng_av_pre_exec_init(core_filter_mvng_av_state_t *state);
void core_filter_mvng_av_exec(
    const core_filter_mvng_av_inputs_t *i,
    core_filter_mvng_av_outputs_t *o,
    core_filter_mvng_av_state_t *state
);

#endif // FSPEC_CORE_FILTER_MVNG_AV_H
core_filter_mvng_av_spec.c
/**
 *  Automatically-generated file. Do not edit!
 */

#include "core_filter_mvng_av.h"
#include <eswb/types.h>

static const param_spec_t *params[1] = {
    NULL
};

static const input_spec_t i_i1 = {
    .name = "i1",
    .annotation = "Input 1",
    .flags = 0
};

static const input_spec_t i_i2 = {
    .name = "i2",
    .annotation = "Input 2",
    .flags = 0
};

static const input_spec_t i_i3 = {
    .name = "i3",
    .annotation = "Input 3",
    .flags = 0
};

static const input_spec_t *inputs[4] = {
    &i_i1,
    &i_i2,
    &i_i3,
    NULL
};

static const output_spec_t o_a1 = {
    .name = "a1",
    .annotation = "Average 1",
    .flags = 0
};

static const output_spec_t o_a2 = {
    .name = "a2",
    .annotation = "Average 2",
    .flags = 0
};

static const output_spec_t o_a3 = {
    .name = "a3",
    .annotation = "Average 3",
    .flags = 0
};

static const output_spec_t o_filled = {
    .name = "filled",
    .annotation = "Filled",
    .flags = 0
};

static const output_spec_t *outputs[5] = {
    &o_a1,
    &o_a2,
    &o_a3,
    &o_filled,
    NULL
};

fspec_rv_t core_filter_mvng_av_call_init_inputs(
    void *dh,
    const func_conn_spec_t *conn_spec,
    eswb_topic_descr_t mounting_td
);

fspec_rv_t core_filter_mvng_av_call_init_outputs(
    void *dh,
    const func_conn_spec_t *conn_spec,
    eswb_topic_descr_t mounting_td,
    const char *func_name
);

fspec_rv_t core_filter_mvng_av_call_pre_exec_init(void *dh);

void core_filter_mvng_av_call_exec(void *dh);

const function_spec_t atomic_core_filter_mvng_av_spec = {
    .name = "core.filter.mvng_av",
    .annotation = "Moving average 3 channels function",
    .inputs = inputs,
    .outputs = outputs,
    .params = params
};

const function_calls_t atomic_core_filter_mvng_av_calls = {
    .interface_handle_size = sizeof(core_filter_mvng_av_interface_t),
    .init = NULL,
    .init_inputs = core_filter_mvng_av_call_init_inputs,
    .init_outputs = core_filter_mvng_av_call_init_outputs,
    .pre_exec_init = core_filter_mvng_av_call_pre_exec_init,
    .exec = core_filter_mvng_av_call_exec,
    .set_params = NULL
};

const function_handler_t atomic_core_filter_mvng_av_handler = {
    .spec = &atomic_core_filter_mvng_av_spec,
    .calls = &atomic_core_filter_mvng_av_calls,
    .extension_handler = NULL
};
core_filter_mvng_av_interface.c
/**
 *  Automatically-generated file. Do not edit!
 */

#include "core_filter_mvng_av.h"

#include "error.h"
#include <eswb/api.h>
#include <eswb/topic_proclaiming_tree.h>
#include <eswb/errors.h>

int core_filter_mvng_av_interface_inputs_init(
    core_filter_mvng_av_interface_t *interface,
    const func_conn_spec_t *conn_spec,
    eswb_topic_descr_t mounting_td
)
{
    eswb_rv_t rv;
    int errcnt_no_topic = 0;
    int errcnt_no_input = 0;
    const char *topic_path_in_i1 = fspec_find_path2connect(conn_spec,"i1");
    const char *topic_path_in_i2 = fspec_find_path2connect(conn_spec,"i2");
    const char *topic_path_in_i3 = fspec_find_path2connect(conn_spec,"i3");

    // Connecting mandatory input "i1"
    if (topic_path_in_i1 != NULL) {
        rv = eswb_connect_nested(mounting_td, topic_path_in_i1, &interface->eswb_descriptors.in_i1);
        if(rv != eswb_e_ok) {
            error("failed connect input \"i1\" to topic \"%s\": %s", topic_path_in_i1, eswb_strerror(rv));
            errcnt_no_topic++;
        }
    } else {
        error("mandatory input \"i1\" is not speicifed");
        errcnt_no_input++;
    }

    // Connecting mandatory input "i2"
    if (topic_path_in_i2 != NULL) {
        rv = eswb_connect_nested(mounting_td, topic_path_in_i2, &interface->eswb_descriptors.in_i2);
        if(rv != eswb_e_ok) {
            error("failed connect input \"i2\" to topic \"%s\": %s", topic_path_in_i2, eswb_strerror(rv));
            errcnt_no_topic++;
        }
    } else {
        error("mandatory input \"i2\" is not speicifed");
        errcnt_no_input++;
    }

    // Connecting mandatory input "i3"
    if (topic_path_in_i3 != NULL) {
        rv = eswb_connect_nested(mounting_td, topic_path_in_i3, &interface->eswb_descriptors.in_i3);
        if(rv != eswb_e_ok) {
            error("failed connect input \"i3\" to topic \"%s\": %s", topic_path_in_i3, eswb_strerror(rv));
            errcnt_no_topic++;
        }
    } else {
        error("mandatory input \"i3\" is not speicifed");
        errcnt_no_input++;
    }

    if ((errcnt_no_input > 0) || (errcnt_no_topic > 0)) {
        if (errcnt_no_input > errcnt_no_topic) {
            return fspec_rv_no_input;
        } else {
            return fspec_rv_no_topic;
        }
    }
    return fspec_rv_ok;
}

fspec_rv_t core_filter_mvng_av_interface_inputs_update(core_filter_mvng_av_interface_t *interface)
{
    eswb_rv_t rv;

    rv = eswb_read(interface->eswb_descriptors.in_i1, &interface->i.i1);
    if(rv != eswb_e_ok) {
        /*FIXME nothing to do yet*/
    }

    rv = eswb_read(interface->eswb_descriptors.in_i2, &interface->i.i2);
    if(rv != eswb_e_ok) {
        /*FIXME nothing to do yet*/
    }

    rv = eswb_read(interface->eswb_descriptors.in_i3, &interface->i.i3);
    if(rv != eswb_e_ok) {
        /*FIXME nothing to do yet*/
    }

    return 0;
}

fspec_rv_t core_filter_mvng_av_interface_outputs_init(
    core_filter_mvng_av_interface_t *interface,
    const func_conn_spec_t *conn_spec,
    eswb_topic_descr_t mounting_td,
    const char *func_name
)
{
    TOPIC_TREE_CONTEXT_LOCAL_DEFINE(cntx, 5);
    core_filter_mvng_av_outputs_t out;
    eswb_rv_t rv;

    topic_proclaiming_tree_t *rt = usr_topic_set_struct(cntx, out, func_name);

    usr_topic_add_struct_child(cntx, rt, core_filter_mvng_av_outputs_t, a1, "a1", tt_double);
    usr_topic_add_struct_child(cntx, rt, core_filter_mvng_av_outputs_t, a2, "a2", tt_double);
    usr_topic_add_struct_child(cntx, rt, core_filter_mvng_av_outputs_t, a3, "a3", tt_double);
    usr_topic_add_struct_child(cntx, rt, core_filter_mvng_av_outputs_t, filled, "filled", tt_int32);
    rv = eswb_proclaim_tree(mounting_td, rt, cntx->t_num, &interface->eswb_descriptors.out_all);
    if (rv != eswb_e_ok) {
        return fspec_rv_publish_err;
    }

    return fspec_rv_ok;
}

fspec_rv_t core_filter_mvng_av_interface_outputs_update(core_filter_mvng_av_interface_t *interface)
{
    eswb_rv_t rv;

    rv = eswb_update_topic(interface->eswb_descriptors.out_all, &interface->o);
    if (rv != eswb_e_ok) {
        return 1;
    }

    return 0;
}

fspec_rv_t core_filter_mvng_av_interface_pre_exec_init(core_filter_mvng_av_interface_t *interface)
{
    return core_filter_mvng_av_pre_exec_init(&interface->state);
}

void core_filter_mvng_av_interface_update(core_filter_mvng_av_interface_t *interface)
{
    core_filter_mvng_av_interface_inputs_update(interface);
    core_filter_mvng_av_exec(&interface->i, &interface->o, &interface->state);
    core_filter_mvng_av_interface_outputs_update(interface);
}

fspec_rv_t core_filter_mvng_av_call_init_inputs(
    void *dh,
    const func_conn_spec_t *conn_spec,
    eswb_topic_descr_t mounting_td
)
{
    core_filter_mvng_av_interface_t *interface = (core_filter_mvng_av_interface_t*) dh;
    return core_filter_mvng_av_interface_inputs_init(interface, conn_spec, mounting_td);
}

fspec_rv_t core_filter_mvng_av_call_init_outputs(
    void *dh,
    const func_conn_spec_t *conn_spec,
    eswb_topic_descr_t mounting_td,
    const char *func_name
)
{
    core_filter_mvng_av_interface_t *interface = (core_filter_mvng_av_interface_t*) dh;
    return core_filter_mvng_av_interface_outputs_init(interface, conn_spec, mounting_td, func_name);
}

fspec_rv_t core_filter_mvng_av_call_pre_exec_init(void *dh)
{
    core_filter_mvng_av_interface_t *interface = (core_filter_mvng_av_interface_t*) dh;
    return core_filter_mvng_av_interface_pre_exec_init(interface);
}

void core_filter_mvng_av_call_exec(void *dh)
{
    core_filter_mvng_av_interface_t *interface = (core_filter_mvng_av_interface_t*) dh;
    core_filter_mvng_av_interface_update(interface);
}