Navigation

core.source.sin

Inputs

Function has no inputs

Outputs

Name

Type

Title

Description

out

core.type.f64

Sinus value

None

Parameters

Name

Type

Title

Mandatory

Default value

Description

period

core.type.f64

Sinus period

True

None

None

phase

core.type.f64

Initial phase

False

0

None

omega

core.type.f64

Cyclic frequency

False

None

None

State variables

Name

Type

Title

Description

time

core.type.f64

Free run time accumulator

None

Usage XML code snippet

core_source_sin snippet for FLOW configuration file
<f name="sin" by_spec="core.source.sin">
    <param alias="period">0.0</param>
    <param alias="phase">0.0</param>   <!-- optional -->
    <param alias="omega">0.0</param>   <!-- optional -->
</f>

Function’s artifacts

declaration.py
from fspeclib import *

Function(
    name='core.source.sin',
    title=LocalizedString(
        en='Sinus with constant period'
    ),
    description=None,
    parameters=[
        Parameter(
            name='period',
            title='Sinus period',
            value_type='core.type.f64',
            constraints=[
                ThisValue() > 0
            ]
        ),
        Parameter(
            name='phase',
            title='Initial phase',
            value_type='core.type.f64',
            default=0,
        ),
        ComputedParameter(
            name='omega',
            title='Cyclic frequency',
            value_type='core.type.f64'
        )
    ],
    outputs=[
        Output(
            name='out',
            title='Sinus value',
            value_type='core.type.f64'
        )
    ],
    state=[
        Variable(
        name='time',
        title='Free run time accumulator',
        value_type='core.type.f64'
        )
    ],
    injection=Injection(
        timedelta=True
    )
)
core_source_sin_exec.c
#include "core_source_sin.h"
#include <math.h>

void core_source_sin_exec(
    core_source_sin_outputs_t *o,
    const core_source_sin_params_t *p,
    core_source_sin_state_t *state,
    const core_source_sin_injection_t *injection
)
{
    state->time += injection->dt;
    o->out = sin(p->phase + p->omega * state->time);
}
core_source_sin_compute_params.c
#include "core_source_sin.h"
#include "error.h"
#include <math.h>

void core_source_sin_compute_params(
    core_source_sin_params_t *old_p,
    core_source_sin_params_t *new_p,
    core_source_sin_params_flags_t *flags
)
{
    new_p->omega = (1.0 / new_p->period) * M_2_PI;
}
core_source_sin_set_params.c
#include "core_source_sin.h"
#include "conv.h"

#include <string.h>

#include "error.h"

fspec_rv_t core_source_sin_set_params(
    core_source_sin_params_t *params,
    const func_param_t *param_pairs,
    int initial_call
)
{
    // Get parameters
    core_source_sin_params_t p = *params;

    core_source_sin_params_flags_t flags;
    memset(&flags, 0, sizeof(flags));

    int violation_count = 0;
    conv_rv_t crv = conv_rv_ok;

    // Parse parameters
    for (int i = 0; param_pairs[i].alias != NULL; i++) {
        if (strcmp(param_pairs[i].alias, "period") == 0) {
            if ((crv = conv_str_double(param_pairs[i].value, &p.period)) == conv_rv_ok) {
                flags.changed_param_period = 1;
            }
        } else if (strcmp(param_pairs[i].alias, "phase") == 0) {
            if ((crv = conv_str_double(param_pairs[i].value, &p.phase)) == conv_rv_ok) {
                flags.changed_param_phase = 1;
            }
        } else if (strcmp(param_pairs[i].alias, "omega") == 0) {
            if ((crv = conv_str_double(param_pairs[i].value, &p.omega)) == conv_rv_ok) {
                flags.changed_param_omega = 1;
            }
        } else {
            error("failed unsupported parameter '%s'", param_pairs[i].alias);
            violation_count ++;
        }

        if (crv != conv_rv_ok) {
            error("Parameter '%s' format error (%s)", param_pairs[i].alias, param_pairs[i].value);
            violation_count++;
        }
    }

    if (initial_call) {
        // Check all mandatory parameters are set
        if (!flags.changed_param_period) {
            error("failed missed mandatory parameter 'period'");
            violation_count ++;
        }

        // Set default value for non mandatory parameters which are not set
        if (!flags.changed_param_phase) {
            p.phase = 0;
            flags.changed_param_phase = 1;
        }
    }

    if (violation_count > 0) {
        return fspec_rv_inval_param;
    }

    // Validate parameters
    if (!(p.period > 0)) {
        error("failed constraint (period > 0)");
        return fspec_rv_inval_param;
    }

    // Compute parameters
    core_source_sin_compute_params(params, &p, &flags);

    // Set parameters
    *params = p;

    return fspec_rv_ok;
}
core_source_sin.h
/**
 *  Automatically-generated file. Do not edit!
 */

#ifndef FSPEC_CORE_SOURCE_SIN_H
#define FSPEC_CORE_SOURCE_SIN_H

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

#include "function.h"

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

/**
 * @brief Parameters of `core.source.sin` function
 */
typedef struct core_source_sin_params_{
    core_type_f64_t period;  /// Sinus period
    core_type_f64_t phase;  /// Initial phase
    core_type_f64_t omega;  /// Cyclic frequency
} core_source_sin_params_t;

/**
 * @brief Outputs of `core.source.sin` function
 */
typedef struct core_source_sin_outputs_ {
    core_type_f64_t out; /// Sinus value

} core_source_sin_outputs_t;

/**
 * @brief State variables of `core.source.sin` function
 */
typedef struct core_source_sin_state_ {
    core_type_f64_t time;  /// Free run time accumulator
} core_source_sin_state_t;

/**
 * @brief Injections for `core.source.sin` function
 */
typedef struct core_source_sin_injection_ {
    core_type_f64_t dt;  /// Time delta from previous iteration (measured in seconds)

} core_source_sin_injection_t;

/**
 * @brief Parameter flags of `core.source.sin` function
 */
typedef struct core_source_sin_params_flags_ {
    uint64_t changed_param_period:1;
    uint64_t changed_param_phase:1;
    uint64_t changed_param_omega:1;
} core_source_sin_params_flags_t;

typedef struct core_source_sin_eswb_descriptors_ {
    eswb_topic_descr_t out_all;
} core_source_sin_eswb_descriptors_t;

typedef struct core_source_sin_interface_ {
    core_source_sin_outputs_t o;
    core_source_sin_params_t p;
    core_source_sin_state_t state;
    core_source_sin_injection_t injection;
    struct timespec prev_exec_time;
    int prev_exec_time_inited;
    core_source_sin_eswb_descriptors_t eswb_descriptors;
} core_source_sin_interface_t;

fspec_rv_t core_source_sin_set_params(
    core_source_sin_params_t *params,
    const func_param_t *param_pairs,
    int initial_call
);

void core_source_sin_compute_params(
    core_source_sin_params_t *old_p,
    core_source_sin_params_t *new_p,
    core_source_sin_params_flags_t *flags
);

void core_source_sin_exec(
    core_source_sin_outputs_t *o,
    const core_source_sin_params_t *p,
    core_source_sin_state_t *state,
    const core_source_sin_injection_t *injection
);

#endif // FSPEC_CORE_SOURCE_SIN_H
core_source_sin_spec.c
/**
 *  Automatically-generated file. Do not edit!
 */

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

static const param_spec_t param_period = {
    .name = "period",
    .default_value = "0.0",
    .annotation = "Sinus period",
    .flags = 0
};

static const param_spec_t param_phase = {
    .name = "phase",
    .default_value = "0.0",
    .annotation = "Initial phase",
    .flags = 0
};

static const param_spec_t param_omega = {
    .name = "omega",
    .default_value = "0.0",
    .annotation = "Cyclic frequency",
    .flags = 0
};

static const param_spec_t *params[4] = {
    &param_period,
    &param_phase,
    &param_omega,
    NULL
};

static const input_spec_t *inputs[1] = {
    NULL
};

static const output_spec_t o_out = {
    .name = "out",
    .annotation = "Sinus value",
    .flags = 0
};

static const output_spec_t *outputs[2] = {
    &o_out,
    NULL
};

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

void core_source_sin_call_exec(void *dh);

fspec_rv_t core_source_sin_call_set_params(void *dh, const func_param_t *param_pairs, int initial_call);

const function_spec_t atomic_core_source_sin_spec = {
    .name = "core.source.sin",
    .annotation = "Sinus with constant period",
    .inputs = inputs,
    .outputs = outputs,
    .params = params
};

const function_calls_t atomic_core_source_sin_calls = {
    .interface_handle_size = sizeof(core_source_sin_interface_t),
    .init = NULL,
    .init_inputs = NULL,
    .init_outputs = core_source_sin_call_init_outputs,
    .pre_exec_init = NULL,
    .exec = core_source_sin_call_exec,
    .set_params = core_source_sin_call_set_params
};

const function_handler_t atomic_core_source_sin_handler = {
    .spec = &atomic_core_source_sin_spec,
    .calls = &atomic_core_source_sin_calls,
    .extension_handler = NULL
};
core_source_sin_interface.c
/**
 *  Automatically-generated file. Do not edit!
 */

#include "core_source_sin.h"

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

fspec_rv_t core_source_sin_interface_outputs_init(
    core_source_sin_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, 2);
    core_source_sin_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_source_sin_outputs_t, out, "out", tt_double);
    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_source_sin_interface_outputs_update(core_source_sin_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;
}

void core_source_sin_interface_update(core_source_sin_interface_t *interface)
{
    if (interface->prev_exec_time_inited) {
        function_getdeltatime(ft_monotonic, &interface->prev_exec_time, dtp_update_prev, &interface->injection.dt);
    } else {
        function_gettime(ft_monotonic, &interface->prev_exec_time);
        interface->prev_exec_time_inited = -1;
        interface->injection.dt = 0;
    }

    core_source_sin_exec(&interface->o, &interface->p, &interface->state, &interface->injection);
    core_source_sin_interface_outputs_update(interface);
}

fspec_rv_t core_source_sin_call_set_params(void *dh, const func_param_t *param_pairs, int initial_call)
{
    core_source_sin_interface_t *interface = (core_source_sin_interface_t*) dh;
    return core_source_sin_set_params(&interface->p, param_pairs, initial_call);
}

fspec_rv_t core_source_sin_call_init_outputs(
    void *dh,
    const func_conn_spec_t *conn_spec,
    eswb_topic_descr_t mounting_td,
    const char *func_name
)
{
    core_source_sin_interface_t *interface = (core_source_sin_interface_t*) dh;
    return core_source_sin_interface_outputs_init(interface, conn_spec, mounting_td, func_name);
}

void core_source_sin_call_exec(void *dh)
{
    core_source_sin_interface_t *interface = (core_source_sin_interface_t*) dh;
    core_source_sin_interface_update(interface);
}