MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/technological/commissioning/ThetaNullEstimate.cpp
2024-06-07 11:12:56 +03:00

229 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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<unsigned int>(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<LinearRegressionCirc> alloca = std::pmr::polymorphic_allocator<LinearRegressionCirc>(buff_resource);
LinearRegressionCirc * temp = alloca.allocate(1);
alloca.construct<LinearRegressionCirc>( 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;
}