polarimeter_software/User/app/data_process.c

207 lines
7.4 KiB
C
Raw Permalink Normal View History

2025-09-30 02:37:23 +00:00
/*
* @Date: 2025-07-18 09:24:34
* @Author: mypx
* @LastEditors: mypx mypx_coder@163.com
* @LastEditTime: 2025-09-26 08:58:26
* @FilePath: data_process.c
* @Description:
* Copyright (c) 2025 by mypx, All Rights Reserved.
*/
#include "data_process.h"
#include "data_sampling.h"
#include "et_log.h"
#include "pm_common.h"
#include "pm_meas.h"
#include "servo.h"
#include <rtthread.h>
#include <stdio.h>
#include <string.h>
#if (ENABLE_IIR_FILTER == 1)
#include "et_iir_filter.h"
et_iir_filter_t iir_filter;
/* 这些系数使用巴特沃斯设计,形式为:
H(z) = (b0 + b1*z^-1 + b2*z^-2) / (1 + a1*z^-1 + a2*z^-2)
a_coeffs[0] = 1.0 (1) */
float a_coeff[] = {1.000000000f, -0.855625000f, 0.212125000f}; // 分母系数 (a0=1, a1, a2)
float b_coeff[] = {0.089125000f, 0.178250000f, 0.089125000f}; // 分子系数 (b0, b1, b2)
// 对于1个二阶阶段order=2state_size=3
#define FILTER_STAGES 1 // 二阶节数量 (每个二阶节贡献2阶)
#define FILTER_ORDER (2 * FILTER_STAGES) // 实际滤波器阶数
#define STATE_SIZE (FILTER_ORDER + 1) // 状态缓冲区大小
// 状态缓冲区大小说明:
// - 对于N阶滤波器需要N+1个状态元素存储历史输入和输出
// - 例如2阶滤波器需要3个元素存储x[n], x[n-1], x[n-2]
float in_state[STATE_SIZE] = {0};
float out_state[STATE_SIZE] = {0};
et_iir_filter_t filter;
et_iir_config_t config;
#endif
static struct rt_thread data_process_thread;
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t data_process_stack[DATA_PROCESS_STACK_SIZE];
float adc_tmp_buffer[DATA_PROCESS_UNIT_COUNT] = {0};
float adc_filter_buffer[DATA_PROCESS_UNIT_COUNT] = {0};
#define ANALYSIS_SIZE DATA_PROCESS_UNIT_COUNT
static bool cali_flag = false;
static bool rdy_flag = false;
pm_meas_t pm_meas;
static double trend_buffer[TREND_BUFFER_SIZE] = {0.0};
void set_pm_stage(int argc, char **argv)
{
if (argc != 2)
{
rt_kprintf("Usage: my_cmd <int_value>\n");
return;
}
int stage = atoi(argv[1]);
pm_meas.state = stage;
}
MSH_CMD_EXPORT_ALIAS(set_pm_stage, sst, set state);
uint32_t data_count = 0;
// 只考虑校准和测量状态,其他状态由采集线程 或者主线程管理
void data_process_thread_entry(void *parameter)
{
(void)parameter;
rt_err_t result = RT_EOK;
int find_status = 0;
uint16_t *raw_buf;
uint16_t *used_buf;
while (1)
{
result = rt_mq_recv(&adc_mq, &raw_buf, sizeof(adc_raw_buffer), RT_WAITING_FOREVER);
if (result == RT_EOK)
{
data_sampling_stop();
if (get_find_zero_state(&pm_meas) == ZF_FAST_CLOSE_STAGE && fsm_state == false && pm_meas.p50 > 0.1f)
sv630p_speed_mode_stop(&sv630p_handle);
#if (ENABLE_IIR_FILTER == 1)
if (et_iir_filter_process(&iir_filter, (const void *)raw_buf, (void *)adc_filter_buffer) == IIR_OK)
{
used_buf = adc_filter_buffer;
}
#else
used_buf = raw_buf;
#endif
#if (SAMPLING_RAW_DATA == 1)
for (int i = 0; i < DATA_PROCESS_UNIT_COUNT; i++)
{
ET_DBG("r:%d, f:%d", raw_buf[i], (uint16_t)adc_filter_buffer[i]);
}
#endif
#if (SAMPLING_RAW_DATA == 0)
pm_error_led_on(); // for timing
find_status = find_zero_process(&pm_meas, (const uint16_t *)used_buf, DATA_PROCESS_UNIT_COUNT);
pm_error_led_off();
#endif
if (find_status == 0)
{
data_sampling_start();
if (get_find_zero_state(&pm_meas) == ZF_FAST_CLOSE_STAGE && fsm_state == false && pm_meas.p50 > 0.1f)
sv630p_speed_mode_resume(&sv630p_handle);
}
else
{
ET_ERR("Something wrong");
}
}
}
}
int data_process_init(void)
{
rt_err_t result;
// 初始化 pm_meas 结构体
memset(&pm_meas, 0, sizeof(pm_meas_t));
pm_meas.target_dir = MEASURE_DEF_DIR;
//etk_ringbuffer_init(&pm_meas.rb, trend_buffer, TREND_BUFFER_SIZE, ETK_RB_DOUBLE);
trend_handle_init(&pm_meas.trend_handle);
etk_slope_init(&pm_meas.slope_handle, trend_buffer, TREND_BUFFER_SIZE, ETK_RB_DOUBLE);
// 确保事件初始化时名称正确
result = rt_event_init(&pm_event, "pm_evt", RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("Event init failed: 0x%04X\n", result);
return -1;
}
//valley_seek_init(&pm_meas.valley_seek);
working_set_state(PM_MEAS_TEST_Mode);
if (et_zero_cross_create(&pm_meas.zc, 100) != 0)
{
ET_ERR("zc create failed\n");
return -1;
}
int bin_center = et_goertzel_calc_bin(50, sampling_rate, ANALYSIS_SIZE);
if (bin_center < 0)
{
ET_ERR("bin calc failed: %d\n", bin_center);
return -1;
}
if (et_goertzel_init(&pm_meas.cfg, ANALYSIS_SIZE, bin_center, DC_OFFSET_ADC_VALUE) < 0)
{
ET_ERR("goertzel init failed\n");
return -1;
}
#if (ENABLE_IIR_FILTER == 1)
config.direct_form_ii_f32.a_coeffs = a_coeff;
config.direct_form_ii_f32.b_coeffs = b_coeff;
config.direct_form_ii_f32.in_state = in_state;
config.direct_form_ii_f32.out_state = out_state;
et_iir_scale_t scale = IIR_SCALE_F32_IDENTITY;
ET_IIR_Result iir_ret = et_iir_filter_init(&iir_filter, "band-pass Filter", ARM_IIR_LATTICE_F32,
FILTER_STAGES, // 二阶节阶段数 (注意:不是滤波器总阶数)
1, // 块大小为1
&scale, &config, IIR_SCALING_DISABLED);
if (iir_ret != IIR_OK)
{
ET_ERR("IIR filter init failed: %d\n", iir_ret);
return -1;
}
#endif
etk_position_pid_init(&pm_meas.pid,
1.8f, // kp: 提高比例增益,加快响应速度
1.8f, // ki: 增加积分增益,加快接近目标时的收敛速度
0.25f, // kd: 进一步降低微分作用,减少阻尼
PID_TARGET_ZERO_POS_VAL, // 目标值设置为0.6
2.5f, // 积分限幅,允许更多积分累积加快收敛
-FZ_FAST_CLOSE_STAGE_RPM, // 最小输出(限制最大反转速度)
FZ_FAST_CLOSE_STAGE_RPM, -1);
result = rt_thread_init(&data_process_thread, // 线程控制块指针
"d-process", // 线程名称
data_process_thread_entry, // 入口函数
RT_NULL, // 入口参数
data_process_stack, // 栈起始地址
sizeof(data_process_stack), // 栈大小
DATA_PROCESS_PRIORITY, // 优先级0-255
10); // 时间片
if (result == RT_EOK)
{
rt_kprintf("d-process thread initialized successfully\n");
// 启动线程
rt_thread_startup(&data_process_thread);
}
else
{
rt_kprintf("Thread init failed: 0x%04X\n", result);
}
return 0;
}