rm_balance/User/component/lqr_test.c
2025-09-17 03:41:35 +08:00

164 lines
4.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.

/*
* LQR控制器测试程序
*/
#include "lqr.h"
#include <stdio.h>
#include <assert.h>
/* 测试用的增益矩阵 */
extern LQR_GainMatrix_t example_lqr_gains;
/* 测试函数 */
void test_lqr_init(void);
void test_lqr_gain_calculation(void);
void test_lqr_control(void);
void test_lqr_polynomial_calc(void);
int main(void) {
printf("开始LQR控制器测试...\n");
test_lqr_polynomial_calc();
test_lqr_init();
test_lqr_gain_calculation();
test_lqr_control();
printf("所有测试通过!\n");
return 0;
}
void test_lqr_polynomial_calc(void) {
printf("测试多项式计算...\n");
/* 测试多项式计算函数 */
float coeff[4] = {1.0f, 2.0f, 3.0f, 4.0f}; // L^3 + 2*L^2 + 3*L + 4
float L = 0.25f;
float expected = 1.0f * 0.25f * 0.25f * 0.25f +
2.0f * 0.25f * 0.25f +
3.0f * 0.25f +
4.0f;
float result = LQR_PolynomialCalc(coeff, L);
printf(" 多项式计算: L=%.2f, 期望=%.4f, 实际=%.4f\n", L, expected, result);
assert(fabsf(result - expected) < 1e-4f);
printf(" 多项式计算测试通过\n");
}
void test_lqr_init(void) {
printf("测试LQR初始化...\n");
LQR_Controller_t lqr;
int8_t result = LQR_Init(&lqr, 10.0f, 5.0f);
assert(result == 0);
assert(lqr.initialized == true);
assert(lqr.param.max_wheel_torque == 10.0f);
assert(lqr.param.max_joint_torque == 5.0f);
assert(lqr.current_leg_length == 0.25f);
printf(" LQR初始化测试通过\n");
}
void test_lqr_gain_calculation(void) {
printf("测试增益矩阵计算...\n");
LQR_Controller_t lqr;
LQR_Init(&lqr, 10.0f, 5.0f);
LQR_SetGainMatrix(&lqr, &example_lqr_gains);
/* 测试不同腿长的增益计算 */
float test_lengths[] = {0.15f, 0.25f, 0.35f};
int num_tests = sizeof(test_lengths) / sizeof(test_lengths[0]);
for (int i = 0; i < num_tests; i++) {
float L = test_lengths[i];
int8_t result = LQR_CalculateGainMatrix(&lqr, L);
assert(result == 0);
assert(lqr.current_leg_length == L);
/* 检查增益矩阵是否合理 */
for (int j = 0; j < LQR_INPUT_DIM; j++) {
for (int k = 0; k < LQR_STATE_DIM; k++) {
assert(!isnan(lqr.K_matrix[j][k]));
assert(!isinf(lqr.K_matrix[j][k]));
}
}
printf(" 腿长%.2fm的增益矩阵计算通过\n", L);
printf(" K11=%.2f, K12=%.2f, K13=%.2f\n",
lqr.K_matrix[0][0], lqr.K_matrix[0][1], lqr.K_matrix[0][2]);
}
printf(" 增益矩阵计算测试通过\n");
}
void test_lqr_control(void) {
printf("测试LQR控制计算...\n");
LQR_Controller_t lqr;
LQR_Init(&lqr, 10.0f, 5.0f);
LQR_SetGainMatrix(&lqr, &example_lqr_gains);
/* 设置测试状态 */
LQR_State_t test_state = {
.theta = 0.1f, /* 摆杆角度 */
.d_theta = 0.05f, /* 摆杆角速度 */
.x = 0.02f, /* 位置 */
.d_x = 0.1f, /* 速度 */
.phi = 0.05f, /* 俯仰角 */
.d_phi = 0.02f /* 俯仰角速度 */
};
LQR_State_t target_state = {0}; /* 平衡状态 */
/* 更新状态 */
int8_t result = LQR_UpdateState(&lqr, &test_state);
assert(result == 0);
result = LQR_SetTargetState(&lqr, &target_state);
assert(result == 0);
/* 执行控制计算 */
result = LQR_Control(&lqr);
assert(result == 0);
/* 获取控制输出 */
LQR_Input_t output;
result = LQR_GetOutput(&lqr, &output);
assert(result == 0);
/* 检查输出是否合理 */
assert(!isnan(output.T));
assert(!isnan(output.Tp));
assert(!isinf(output.T));
assert(!isinf(output.Tp));
assert(fabsf(output.T) <= lqr.param.max_wheel_torque);
assert(fabsf(output.Tp) <= lqr.param.max_joint_torque);
printf(" 控制输出: T=%.3f N·m, Tp=%.3f N·m\n", output.T, output.Tp);
printf(" LQR控制计算测试通过\n");
}
/* 如果没有math.h中的函数提供简单实现 */
#ifndef __has_include
#define __has_include(x) 0
#endif
#if !__has_include(<math.h>)
float fabsf(float x) {
return x < 0 ? -x : x;
}
int isnan(float x) {
return x != x;
}
int isinf(float x) {
return (x == x) && ((x - x) != 0);
}
#endif