加了个滤波
This commit is contained in:
parent
c362ffe265
commit
602a6a2728
184
User/lib/filter.c
Normal file
184
User/lib/filter.c
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
各类滤波器。
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
#include "user_math.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample_freq 采样频率
|
||||||
|
* @param cutoff_freq 截止频率
|
||||||
|
*/
|
||||||
|
void LowPassFilter2p_Init(LowPassFilter2p_t *f, float sample_freq,
|
||||||
|
float cutoff_freq) {
|
||||||
|
if (f == NULL) return;
|
||||||
|
|
||||||
|
f->cutoff_freq = cutoff_freq;
|
||||||
|
|
||||||
|
f->delay_element_1 = 0.0f;
|
||||||
|
f->delay_element_2 = 0.0f;
|
||||||
|
|
||||||
|
if (f->cutoff_freq <= 0.0f) {
|
||||||
|
/* no filtering */
|
||||||
|
f->b0 = 1.0f;
|
||||||
|
f->b1 = 0.0f;
|
||||||
|
f->b2 = 0.0f;
|
||||||
|
|
||||||
|
f->a1 = 0.0f;
|
||||||
|
f->a2 = 0.0f;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const float fr = sample_freq / f->cutoff_freq;
|
||||||
|
const float ohm = tanf(M_PI / fr);
|
||||||
|
const float c = 1.0f + 2.0f * cosf(M_PI / 4.0f) * ohm + ohm * ohm;
|
||||||
|
|
||||||
|
f->b0 = ohm * ohm / c;
|
||||||
|
f->b1 = 2.0f * f->b0;
|
||||||
|
f->b2 = f->b0;
|
||||||
|
|
||||||
|
f->a1 = 2.0f * (ohm * ohm - 1.0f) / c;
|
||||||
|
f->a2 = (1.0f - 2.0f * cosf(M_PI / 4.0f) * ohm + ohm * ohm) / c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 施加一次滤波计算
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
float LowPassFilter2p_Apply(LowPassFilter2p_t *f, float sample) {
|
||||||
|
if (f == NULL) return 0.0f;
|
||||||
|
|
||||||
|
/* do the filtering */
|
||||||
|
float delay_element_0 =
|
||||||
|
sample - f->delay_element_1 * f->a1 - f->delay_element_2 * f->a2;
|
||||||
|
|
||||||
|
if (isinf(delay_element_0)) {
|
||||||
|
/* don't allow bad values to propagate via the filter */
|
||||||
|
delay_element_0 = sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float output = delay_element_0 * f->b0 + f->delay_element_1 * f->b1 +
|
||||||
|
f->delay_element_2 * f->b2;
|
||||||
|
|
||||||
|
f->delay_element_2 = f->delay_element_1;
|
||||||
|
f->delay_element_1 = delay_element_0;
|
||||||
|
|
||||||
|
/* return the value. Should be no need to check limits */
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重置滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
float LowPassFilter2p_Reset(LowPassFilter2p_t *f, float sample) {
|
||||||
|
if (f == NULL) return 0.0f;
|
||||||
|
|
||||||
|
const float dval = sample / (f->b0 + f->b1 + f->b2);
|
||||||
|
|
||||||
|
if (isfinite(dval)) {
|
||||||
|
f->delay_element_1 = dval;
|
||||||
|
f->delay_element_2 = dval;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
f->delay_element_1 = sample;
|
||||||
|
f->delay_element_2 = sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LowPassFilter2p_Apply(f, sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample_freq 采样频率
|
||||||
|
* @param notch_freq 中心频率
|
||||||
|
* @param bandwidth 带宽
|
||||||
|
*/
|
||||||
|
void NotchFilter_Init(NotchFilter_t *f, float sample_freq, float notch_freq,float bandwidth)
|
||||||
|
{
|
||||||
|
if (f == NULL) return;
|
||||||
|
|
||||||
|
f->notch_freq = notch_freq;
|
||||||
|
f->bandwidth = bandwidth;
|
||||||
|
|
||||||
|
f->delay_element_1 = 0.0f;
|
||||||
|
f->delay_element_2 = 0.0f;
|
||||||
|
|
||||||
|
if (notch_freq <= 0.0f) {
|
||||||
|
/* no filtering */
|
||||||
|
f->b0 = 1.0f;
|
||||||
|
f->b1 = 0.0f;
|
||||||
|
f->b2 = 0.0f;
|
||||||
|
|
||||||
|
f->a1 = 0.0f;
|
||||||
|
f->a2 = 0.0f;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float alpha = tanf(M_PI * bandwidth / sample_freq);
|
||||||
|
const float beta = -cosf(M_2PI * notch_freq / sample_freq);
|
||||||
|
const float a0_inv = 1.0f / (alpha + 1.0f);
|
||||||
|
|
||||||
|
f->b0 = a0_inv;
|
||||||
|
f->b1 = 2.0f * beta * a0_inv;
|
||||||
|
f->b2 = a0_inv;
|
||||||
|
|
||||||
|
f->a1 = f->b1;
|
||||||
|
f->a2 = (1.0f - alpha) * a0_inv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 施加一次滤波计算
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
inline float NotchFilter_Apply(NotchFilter_t *f, float sample) {
|
||||||
|
if (f == NULL) return 0.0f;
|
||||||
|
|
||||||
|
/* Direct Form II implementation */
|
||||||
|
const float delay_element_0 = sample - f->delay_element_1 * f->a1 - f->delay_element_2 * f->a2;
|
||||||
|
const float output = delay_element_0 * f->b0 + f->delay_element_1 * f->b1 +
|
||||||
|
f->delay_element_2 * f->b2;
|
||||||
|
|
||||||
|
f->delay_element_2 = f->delay_element_1;
|
||||||
|
f->delay_element_1 = delay_element_0;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重置滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
float NotchFilter_Reset(NotchFilter_t *f, float sample) {
|
||||||
|
if (f == NULL) return 0.0f;
|
||||||
|
|
||||||
|
float dval = sample;
|
||||||
|
|
||||||
|
if (fabsf(f->b0 + f->b1 + f->b2) > FLT_EPSILON) {
|
||||||
|
dval = dval / (f->b0 + f->b1 + f->b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
f->delay_element_1 = dval;
|
||||||
|
f->delay_element_2 = dval;
|
||||||
|
|
||||||
|
return NotchFilter_Apply(f, sample);
|
||||||
|
}
|
104
User/lib/filter.h
Normal file
104
User/lib/filter.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
各类滤波器。
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "user_math.h"
|
||||||
|
|
||||||
|
/* 二阶低通滤波器 */
|
||||||
|
typedef struct {
|
||||||
|
float cutoff_freq; /* 截止频率 */
|
||||||
|
|
||||||
|
float a1;
|
||||||
|
float a2;
|
||||||
|
|
||||||
|
float b0;
|
||||||
|
float b1;
|
||||||
|
float b2;
|
||||||
|
|
||||||
|
float delay_element_1;
|
||||||
|
float delay_element_2;
|
||||||
|
|
||||||
|
} LowPassFilter2p_t;
|
||||||
|
|
||||||
|
/* 带阻滤波器 */
|
||||||
|
typedef struct {
|
||||||
|
float notch_freq; /* 阻止频率 */
|
||||||
|
float bandwidth; /* 带宽 */
|
||||||
|
|
||||||
|
float a1;
|
||||||
|
float a2;
|
||||||
|
|
||||||
|
float b0;
|
||||||
|
float b1;
|
||||||
|
float b2;
|
||||||
|
float delay_element_1;
|
||||||
|
float delay_element_2;
|
||||||
|
|
||||||
|
} NotchFilter_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample_freq 采样频率
|
||||||
|
* @param cutoff_freq 截止频率
|
||||||
|
*/
|
||||||
|
void LowPassFilter2p_Init(LowPassFilter2p_t *f, float sample_freq,
|
||||||
|
float cutoff_freq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 施加一次滤波计算
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
float LowPassFilter2p_Apply(LowPassFilter2p_t *f, float sample);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重置滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
float LowPassFilter2p_Reset(LowPassFilter2p_t *f, float sample);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample_freq 采样频率
|
||||||
|
* @param notch_freq 中心频率
|
||||||
|
* @param bandwidth 带宽
|
||||||
|
*/
|
||||||
|
void NotchFilter_Init(NotchFilter_t *f, float sample_freq, float notch_freq,
|
||||||
|
float bandwidth);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 施加一次滤波计算
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
float NotchFilter_Apply(NotchFilter_t *f, float sample);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重置滤波器
|
||||||
|
*
|
||||||
|
* @param f 滤波器
|
||||||
|
* @param sample 采样的值
|
||||||
|
* @return float 滤波后的值
|
||||||
|
*/
|
||||||
|
float NotchFilter_Reset(NotchFilter_t *f, float sample);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
65
User/lib/kalman.c
Normal file
65
User/lib/kalman.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* @author Liu heng
|
||||||
|
* 一阶卡尔曼滤波器来自RoboMaster论坛
|
||||||
|
* 一维卡尔曼滤波器
|
||||||
|
* 使用时先定义一个kalman指针,然后调用kalmanCreate()创建一个滤波器
|
||||||
|
* 每次读取到传感器数据后即可调用KalmanFilter()来对数据进行滤波
|
||||||
|
* 使用示例
|
||||||
|
* extKalman p; //定义一个卡尔曼滤波器结构体
|
||||||
|
* float SersorData; //需要进行滤波的数据
|
||||||
|
* KalmanCreate(&p,20,200); //初始化该滤波器的Q=20 R=200参数
|
||||||
|
* while(1)
|
||||||
|
* {
|
||||||
|
* SersorData = sersor(); //获取数据
|
||||||
|
* SersorData = KalmanFilter(&p,SersorData); //对数据进行滤波
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kalman.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name kalmanCreate
|
||||||
|
* @brief 创建一个卡尔曼滤波器
|
||||||
|
* @param p: 滤波器
|
||||||
|
* T_Q:系统噪声协方差
|
||||||
|
* T_R:测量噪声协方差
|
||||||
|
*
|
||||||
|
* @retval none
|
||||||
|
* @attention R固定,Q越大,代表越信任侧量值,Q无穷代表只用测量值
|
||||||
|
* 反之,Q越小代表越信任模型预测值,Q为零则是只用模型预测
|
||||||
|
*/
|
||||||
|
void KalmanCreate(extKalman_t *p,float T_Q,float T_R)
|
||||||
|
{
|
||||||
|
p->X_last = (float)0;
|
||||||
|
p->P_last = 0;
|
||||||
|
p->Q = T_Q;
|
||||||
|
p->R = T_R;
|
||||||
|
p->A = 1;
|
||||||
|
p->B = 0;
|
||||||
|
p->H = 1;
|
||||||
|
p->X_mid = p->X_last;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name KalmanFilter
|
||||||
|
* @brief 卡尔曼滤波器
|
||||||
|
* @param p: 滤波器
|
||||||
|
* dat:待滤波数据
|
||||||
|
* @retval 滤波后的数据
|
||||||
|
* @attention Z(k)是系统输入,即测量值 X(k|k)是卡尔曼滤波后的值,即最终输出
|
||||||
|
* A=1 B=0 H=1 I=1 W(K) V(k)是高斯白噪声,叠加在测量值上了,可以不用管
|
||||||
|
* 以下是卡尔曼的5个核心公式
|
||||||
|
* 一阶H'即为它本身,否则为转置矩阵
|
||||||
|
*/
|
||||||
|
|
||||||
|
float KalmanFilter(extKalman_t* p,float dat)
|
||||||
|
{
|
||||||
|
p->X_mid =p->A*p->X_last; //百度对应公式(1) x(k|k-1) = A*X(k-1|k-1)+B*U(k)+W(K)
|
||||||
|
p->P_mid = p->A*p->P_last+p->Q; //百度对应公式(2) p(k|k-1) = A*p(k-1|k-1)*A'+Q
|
||||||
|
p->kg = p->P_mid/(p->P_mid+p->R); //百度对应公式(4) kg(k) = p(k|k-1)*H'/(H*p(k|k-1)*H'+R)
|
||||||
|
p->X_now = p->X_mid+p->kg*(dat-p->X_mid); //百度对应公式(3) x(k|k) = X(k|k-1)+kg(k)*(Z(k)-H*X(k|k-1))
|
||||||
|
p->P_now = (1-p->kg)*p->P_mid; //百度对应公式(5) p(k|k) = (I-kg(k)*H)*P(k|k-1)
|
||||||
|
p->P_last = p->P_now; //状态更新
|
||||||
|
p->X_last = p->X_now;
|
||||||
|
return p->X_now; //输出预测结果x(k|k)
|
||||||
|
}
|
28
User/lib/kalman.h
Normal file
28
User/lib/kalman.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* @author Liu heng
|
||||||
|
* 卡尔曼滤波器来自RoboMaster论坛
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KALMAN_H
|
||||||
|
#define _KALMAN_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float X_last; //上一时刻的最优结果 X(k-|k-1)
|
||||||
|
float X_mid; //当前时刻的预测结果 X(k|k-1)
|
||||||
|
float X_now; //当前时刻的最优结果 X(k|k)
|
||||||
|
float P_mid; //当前时刻预测结果的协方差 P(k|k-1)
|
||||||
|
float P_now; //当前时刻最优结果的协方差 P(k|k)
|
||||||
|
float P_last; //上一时刻最优结果的协方差 P(k-1|k-1)
|
||||||
|
float kg; //kalman增益
|
||||||
|
float A; //系统参数
|
||||||
|
float B;
|
||||||
|
float Q;
|
||||||
|
float R;
|
||||||
|
float H;
|
||||||
|
}extKalman_t;
|
||||||
|
|
||||||
|
void KalmanCreate(extKalman_t *p,float T_Q,float T_R);
|
||||||
|
float KalmanFilter(extKalman_t* p,float dat);
|
||||||
|
|
||||||
|
#endif
|
@ -32,8 +32,8 @@ Ball ::Ball()
|
|||||||
PID_init(&extend_speed_pid,PID_POSITION,Extend_speed_PID,3000, 200);
|
PID_init(&extend_speed_pid,PID_POSITION,Extend_speed_PID,3000, 200);
|
||||||
PID_init(&extend_angle_pid,PID_POSITION,Extend_angle_PID,3000, 200);
|
PID_init(&extend_angle_pid,PID_POSITION,Extend_angle_PID,3000, 200);
|
||||||
|
|
||||||
// e_result = 0;
|
e_result = 0;
|
||||||
// angleSet = 0;
|
angleSet = 0;
|
||||||
//三摩擦轮
|
//三摩擦轮
|
||||||
for(int i = 0;i < MOTOR_NUM;i ++)
|
for(int i = 0;i < MOTOR_NUM;i ++)
|
||||||
{
|
{
|
||||||
@ -47,11 +47,24 @@ Ball ::Ball()
|
|||||||
speedSet[i] = 0;
|
speedSet[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//状态机状态初始化
|
//状态机状态初始化
|
||||||
currentState1= BALL_IDLE;
|
currentState1= BALL_IDLE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ball :: Filter_init(float target_freq)
|
||||||
|
{
|
||||||
|
for(int i = 0;i < MOTOR_NUM;i ++)
|
||||||
|
{
|
||||||
|
//摩擦轮滤波器初始化
|
||||||
|
LowPassFilter2p_Init(filter.in + i , target_freq,
|
||||||
|
-1.0f);
|
||||||
|
LowPassFilter2p_Init(filter.out + i, target_freq,
|
||||||
|
-1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Ball ::Extend_control(int angle)
|
void Ball ::Extend_control(int angle)
|
||||||
{
|
{
|
||||||
int16_t delta;
|
int16_t delta;
|
||||||
@ -72,6 +85,11 @@ void Ball ::Extend_control(int angle)
|
|||||||
void Ball ::Spin(float speed,float speed2)
|
void Ball ::Spin(float speed,float speed2)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
for(int i = 0;i < MOTOR_NUM;i ++)
|
||||||
|
{
|
||||||
|
hand_Motor[i]->speed_rpm=LowPassFilter2p_Apply(filter.in + i, hand_Motor[i]->speed_rpm);
|
||||||
|
}
|
||||||
|
|
||||||
speedSet[MOTOR_1] = -speed;
|
speedSet[MOTOR_1] = -speed;
|
||||||
result[MOTOR_1] = PID_calc(&speed_pid[MOTOR_1],hand_Motor[MOTOR_1]->speed_rpm,speedSet[MOTOR_1]);
|
result[MOTOR_1] = PID_calc(&speed_pid[MOTOR_1],hand_Motor[MOTOR_1]->speed_rpm,speedSet[MOTOR_1]);
|
||||||
|
|
||||||
@ -81,6 +99,11 @@ void Ball ::Spin(float speed,float speed2)
|
|||||||
speedSet[MOTOR_3] = speed2;
|
speedSet[MOTOR_3] = speed2;
|
||||||
result[MOTOR_3] = PID_calc(&speed_pid[MOTOR_3],hand_Motor[MOTOR_3]->speed_rpm,speedSet[MOTOR_3]);
|
result[MOTOR_3] = PID_calc(&speed_pid[MOTOR_3],hand_Motor[MOTOR_3]->speed_rpm,speedSet[MOTOR_3]);
|
||||||
|
|
||||||
|
for(int i = 0;i < MOTOR_NUM;i ++)
|
||||||
|
{
|
||||||
|
result[i]=LowPassFilter2p_Apply(filter.out + i, result[i]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int flag =0;
|
int flag =0;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "bsp_delay.h"
|
#include "bsp_delay.h"
|
||||||
#include "djiMotor.h"
|
#include "djiMotor.h"
|
||||||
#include "pid.h"
|
#include "pid.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
// 定义状态枚举
|
// 定义状态枚举
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -33,6 +34,12 @@ typedef enum
|
|||||||
MOTOR_NUM
|
MOTOR_NUM
|
||||||
}motorhangd_e;
|
}motorhangd_e;
|
||||||
|
|
||||||
|
/* 滤波器 */
|
||||||
|
typedef struct {
|
||||||
|
LowPassFilter2p_t *in; /* 反馈值滤波器 */
|
||||||
|
LowPassFilter2p_t *out; /* 输出值滤波器 */
|
||||||
|
} Filter;
|
||||||
|
|
||||||
// 定义光电传感器检测宏
|
// 定义光电传感器检测宏
|
||||||
#define IS_PHOTOELECTRIC_BALL() (HAL_GPIO_ReadPin(up_ball_GPIO_Port, up_ball_Pin) == GPIO_PIN_RESET)
|
#define IS_PHOTOELECTRIC_BALL() (HAL_GPIO_ReadPin(up_ball_GPIO_Port, up_ball_Pin) == GPIO_PIN_RESET)
|
||||||
|
|
||||||
@ -40,6 +47,7 @@ class Ball
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Ball();
|
Ball();
|
||||||
|
void Filter_init(float target_freq);
|
||||||
void Spin(float speed,float speed2);
|
void Spin(float speed,float speed2);
|
||||||
void ballHadling(void);
|
void ballHadling(void);
|
||||||
void Send_control(void);
|
void Send_control(void);
|
||||||
@ -59,6 +67,9 @@ public:
|
|||||||
volatile uint32_t flag_thread;//接收传回的线程通知
|
volatile uint32_t flag_thread;//接收传回的线程通知
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//滤波一下
|
||||||
|
Filter filter;
|
||||||
|
|
||||||
//三个摩擦轮
|
//三个摩擦轮
|
||||||
static const float M3508_speed_PID[3];
|
static const float M3508_speed_PID[3];
|
||||||
static const float M3508_angle_PID[3];
|
static const float M3508_angle_PID[3];
|
||||||
|
Loading…
Reference in New Issue
Block a user