polarimeter_software/User/app/data_process.c
2025-09-30 10:37:23 +08:00

207 lines
7.4 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.

/*
* @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;
}