/* * ThetaNullEstimate.cpp * * Created on: 23 нояб. 2016 г. * Author: titov */ #include "ThetaNullEstimate.hh" //#include "../system/DebugConsole.hh" using technological::commissioning::ThetaNullEstimate; using algorithm::LinearRegressionCirc; ThetaNullEstimate::ThetaNullEstimate() : null_calculator(nullptr), buff_resource(nullptr) { enable = false; sector_setpoint = 0; Np = 0; speed = 0; Ts = 0; count = 0; data_collection = false; data_analysis = false; direction = forward; count_rise = 0; count_next = 0; sector = 0; errorEstimate = 0; previous_feedback = NAN; delta_previous = 0; } bool ThetaNullEstimate::configure(const TSetting & setting) { bool result = false; if(setting.isValid()) { Ts = setting.Ts; Np = static_cast(setting.Np); //Допустимое отклонение. errorEstimate = setting.valid_mismatch_theta_1; totalError = setting.valid_error; result = true; } return result; } bool ThetaNullEstimate::start(float average_speed, unsigned int number_sector, float rise_to_hold) { //Результат инициализации. bool result = false; //Проверка допустимости исходных данных. if( !enable and buff_resource && rise_to_hold > 0.0f && rise_to_hold < 1.0f && number_sector > 5 && average_speed > 0.0f ) { //Расчет дельта delta_previous = math::constants::pi_3 / (Np * 2); //Исходные данные. float k = 1 / rise_to_hold; speed = average_speed * k; sector_setpoint = number_sector; //Расчет количества отсчетов для сектора. count = 0; sector = 0; count_rise = math::constants::pi_3 / (Ts * speed * Np); count_next = count_rise * k; direction = forward; //Количество данных. unsigned int row = number_sector * 2; //Количество строк равно количеству измеряемых точек. unsigned int col = 2; //Количество столбцов равно количеству признаков. // // null_calculator = nullptr; buff_resource->release(); std::pmr::polymorphic_allocator alloca = std::pmr::polymorphic_allocator(buff_resource); LinearRegressionCirc * temp = alloca.allocate(1); alloca.construct( temp, row, col, buff_resource ); null_calculator = temp; //Параметры обучения. float tempTheta[2] = {0.0f, math::constants::pi_3}; float alfa = 0.1f; unsigned int num_iteration = 2000; //Если создалось, инициализируем. if( null_calculator && null_calculator->init(alfa, tempTheta, num_iteration) ) { result = true; data_collection = true; enable = true; } } return result; } void ThetaNullEstimate::stop() { data_collection = false; data_analysis = false; if(null_calculator) (void) null_calculator->stopCalc(); enable = false; } void ThetaNullEstimate::add_data(float theta_feedback) { // //Проверка. // if(std::fabs(previous_feedback - theta_feedback) < delta_previous) { // //Generate Error! // stop(); // } previous_feedback = theta_feedback; //Данные. float data[2]; float y; //Номер сектора и последняя позиция. data[0] = 1.0f; data[1] = sector % 6; y = std::fmod(theta_feedback * Np, math::constants::pi2); //Добавление данных null_calculator->addData(data, y); } void ThetaNullEstimate::execute(float theta_feedback, float & iota) { float angle; if(data_collection) { if(count < count_rise) { angle = speed * Np * count * Ts; } else { angle = speed * Np * count_rise * Ts; } if(direction == forward) { if(count == count_next && sector != sector_setpoint) { //Добавление данных. add_data(theta_feedback); } if(count >= count_next) { //Обновление сектора. sector++; count = 0; angle = 0.0f; } count++; } if(direction == backward) { if(count == count_rise && sector != sector_setpoint) { //Добавление данных. add_data(theta_feedback); } if(count == 0) { //Обновление сектора. sector--; count = count_next; angle = math::constants::pi_3; } count--; } angle = angle + (sector % 6) * math::constants::pi_3; if(direction == forward && sector > sector_setpoint) { direction = backward; count = count_next; sector = sector_setpoint; } if(direction == backward && sector < 0) { data_collection = false; (void) null_calculator->startCalc(); sector = 0; count = 0; } iota = angle; } else { //if(data_collection) iota = 0; } } void ThetaNullEstimate::process() { data_analysis = null_calculator && null_calculator->calculation(); } bool technological::commissioning::ThetaNullEstimate::setBuffer( std::pmr::monotonic_buffer_resource * buffer ) { if( enable ) return false; stop(); if( buff_resource ) { buff_resource->release(); null_calculator = nullptr; } return buff_resource = buffer; } void technological::commissioning::ThetaNullEstimate::resetBuffer() { stop(); if( buff_resource ) { buff_resource->release(); null_calculator = nullptr; } buff_resource = nullptr; }