5#include <block/cblock.h>
7#include <entity/visitor.h>
8#include <utils/logging.h>
10blocks::CBlock::CBlock(CBlockHAL *hardware) : FunctionBlock(
"C", hardware), hardware(hardware) {
11 classifier.class_enum = CLASS_;
14blocks::CBlock::CBlock() : CBlock(new CBlockHALDummy()) {}
16float blocks::CBlock::get_factor(uint8_t idx) {
22const std::array<float, blocks::CBlock::NUM_COEFF> &blocks::CBlock::get_factors()
const {
26bool blocks::CBlock::set_factor(uint8_t idx,
float factor) {
29 if (factor > MAX_FACTOR or factor < MIN_FACTOR)
31 factors_[idx] = factor;
35void blocks::CBlock::set_factors(
const std::array<float, NUM_COEFF> &factors) { factors_ = factors; }
37utils::status blocks::CBlock::write_to_hardware() {
38 if (!write_factors_to_hardware()) {
39 LOG(ANABRID_PEDANTIC, __PRETTY_FUNCTION__);
40 return utils::status::failure();
42 return utils::status::success();
45bool blocks::CBlock::write_factors_to_hardware() {
46 for (
size_t i = 0; i < factors_.size(); i++) {
47 auto factor = factors_[i] * gain_corrections_[i];
48 if (!hardware->write_factor(i, factor))
54void blocks::CBlock::reset(entities::ResetAction action) {
55 FunctionBlock::reset(action);
57 if (action.has(entities::ResetAction::CIRCUIT_RESET))
58 for (
size_t i = 0; i < NUM_COEFF; i++)
59 (
void)set_factor(i, 1.0f);
61 if (action.has(entities::ResetAction::CALIBRATION_RESET))
62 reset_gain_corrections();
65float blocks::CBlock::get_gain_correction(uint8_t idx)
const {
68 return gain_corrections_[idx];
71const std::array<float, blocks::CBlock::NUM_COEFF> &blocks::CBlock::get_gain_corrections()
const {
72 return gain_corrections_;
75void blocks::CBlock::reset_gain_corrections() {
76 std::fill(gain_corrections_.begin(), gain_corrections_.end(), 1.0f);
79void blocks::CBlock::set_gain_corrections(
const std::array<float, NUM_COEFF> &corrections) {
80 gain_corrections_ = corrections;
83bool blocks::CBlock::set_gain_correction(
const uint8_t coeff_idx,
const float correction) {
84 if (coeff_idx > NUM_COEFF)
87 if (correction < 0.0f || correction > MAX_GAIN_CORRECTION_ABS + 1.0f)
90 gain_corrections_[coeff_idx] = correction;
94ConfigResult blocks::CBlock::config(
const pb_Config &cfg) {
95#ifdef ANABRID_DEBUG_ENTITY_CONFIG
96 Serial.println(__PRETTY_FUNCTION__);
98 if (cfg.which_kind != pb_Config_coef_config_tag)
99 return ConfigResult::err(
"expected coef block config");
101 auto& coef_config = cfg.kind.coef_config;
102 return _apply_elements(coef_config);
105ConfigResult blocks::CBlock::_apply_elements(
const pb_CoefConfig &cfg) {
107 for (
size_t elem_idx = 0; elem_idx < cfg.elements_count; ++elem_idx) {
108 auto& element = cfg.elements[elem_idx];
109 if (!set_factor(element.idx, element.factor))
110 return ConfigResult::err_fmt(
"CBlock factor %f is out of valid bounds", element.factor);
113 return ConfigResult::ok(
true);
116void blocks::CBlock::extract(entities::ExtractVisitor &collector) {
117 auto& cfg = collector.create(pb_Config_coef_config_tag);
118 auto& coef_config = cfg.kind.coef_config;
119 coef_config.elements_count = NUM_COEFF;
120 auto& idx = coef_config.elements_count = 0;
121 for (;idx < NUM_COEFF; ++idx) {
122 auto& elem = coef_config.elements[idx];
124 elem.factor = factors_[idx];