你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。
chrome
firefox
safari
ie8及以上
ST
意法半导体官网
STM32
中文官网
ST
全球论坛
登录/注册
首页
技术问答
话题
资源
创客秀
视频
标签
积分商城
每日签到
【MCU实战经验】+基于stm32两轮平衡车制作
[复制链接]
思考的大兵
发布时间:2014-4-12 20:54
阅读主题, 点击返回1楼
赞
3
收藏
24
评论
180
分享
发布时间:2014-4-12 20:54
请先
登录
后回复
180个回答
hxl520521
回答时间:2016-8-6 05:52:43
a8a.1 0b0c
一下载谢谢了
赞
评论
回复
支持
反对
hxl520521
回答时间:2016-8-6 05:54:15
a8a.1 0b0c
以下载谢谢了
赞
评论
回复
支持
反对
hxl520521
回答时间:2016-8-7 08:28:48
a8a.1 0b0c
好厉害,有图纸吗
赞
评论
回复
支持
反对
jj_feng
回答时间:2016-8-9 15:16:58
a0a.1 0b0c
厉害,谢谢分享
赞
评论
回复
支持
反对
孤独的文艺青年
回答时间:2016-8-9 18:34:51
a0a.1 0b0c
我用printf("%0.2f %0.2f %0.2f\r\n",Angle,Angle_ax,Gyro_y);函数分别读取的加速度,角速度和倾角,我发现当我快速的改变板子的倾角的时候,比如快速变化10度,Angle(卡尔曼滤波后的倾角)瞬时变化非常快,可能会瞬间变化几十度然后回到正常角度,而当我缓慢变化10度的时候,Angle变化是正常线性变化到10度,在这两种变化中,Angle_ax(从MPU6050读取的值经过处理后的陀螺仪的Y轴数据)的变化一直都是线性正常的,并且Angle的值特别接近Angle_ax的值
问题:1,我快速改变板子倾角时Angle的变化正常吗?
2,Angle正常变化的时候是应该与Angle_ax的值相近吗?
现在情况就是,就算我是在减小倾角,只要我快速地改变,它显示的倾角都会先增大再减小,而如果我慢速改变的话,倾角就会缓慢减小而不会出现中间的角度增大
*************读取数据********************
//定义MPU6050内部地址
#define SMPLRT_DIV 0x19 //陀螺仪采样率 典型值 0X07 125Hz
#define CONFIG 0x1A //低通滤波频率 典型值 0x00
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围 典型值 0x18 不自检 2000deg/s
#define ACCEL_CONFIG 0x1C //加速度计自检及测量范围及高通滤波频率 典型值 0x01 不自检 2G 5Hz
#define INT_PIN_CFG 0x37
#define INT_ENABLE 0x38
#define INT_STATUS 0x3A //只读
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
//读取寄存器原生数据
MPU6050_Raw_Data.Accel_X = (buf[0]<<8 | buf[1]);
MPU6050_Raw_Data.Accel_Y = (buf[2]<<8 | buf[3]);
MPU6050_Raw_Data.Accel_Z = (buf[4]<<8 | buf[5]);
MPU6050_Raw_Data.Temp = (buf[6]<<8 | buf[7]);
MPU6050_Raw_Data.Gyro_X = (buf[8]<<8 | buf[9]);
MPU6050_Raw_Data.Gyro_Y = (buf[10]<<8 | buf[11]);
MPU6050_Raw_Data.Gyro_Z = (buf[12]<<8 | buf[13]);
//将原生数据转换为实际值,计算公式跟寄存器的配置有关
MPU6050_Real_Data.Accel_X = -(float)(MPU6050_Raw_Data.Accel_X)/8192.0;
MPU6050_Real_Data.Accel_Y = -(float)(MPU6050_Raw_Data.Accel_Y)/8192.0;
MPU6050_Real_Data.Accel_Z = (float)(MPU6050_Raw_Data.Accel_Z)/8192.0;
MPU6050_Real_Data.Gyro_X=-(float)(MPU6050_Raw_Data.Gyro_X - gyroADC_X_offset)/65.5;
MPU6050_Real_Data.Gyro_Y=-(float)(MPU6050_Raw_Data.Gyro_Y - gyroADC_Y_offset)/65.5;
MPU6050_Real_Data.Gyro_Z=(float)(MPU6050_Raw_Data.Gyro_Z - gyroADC_Z_offset)/65.5;
}
//******卡尔曼参数************
const float Q_angle=0.001;
const float Q_gyro=0.003;
const float R_angle=0.5;
const float dt=0.01; //dt为kalman滤波器采样时间;
const char C_0 = 1;
float Q_bias, Angle_err;
float PCt_0, PCt_1, E;
float K_0, K_1, t_0, t_1;
float Pdot[4] ={0,0,0,0};
float PP[2][2] = { { 1, 0 },{ 0, 1 } };
/*****************卡尔曼滤波**************************************************/
void Kalman_Filter(float Accel,float Gyro)
{
Angle+=(Gyro - Q_bias) * dt; //先验估计
Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分
Pdot[1]= -PP[1][1];
Pdot[2]= -PP[1][1];
Pdot[3]=Q_gyro;
PP[0][0] += Pdot[0] * dt; // Pk-先验估计误差协方差微分的积分
PP[0][1] += Pdot[1] * dt; // =先验估计误差协方差
PP[1][0] += Pdot[2] * dt;
PP[1][1] += Pdot[3] * dt;
Angle_err = Accel - Angle; //zk-先验估计
PCt_0 = C_0 * PP[0][0];
PCt_1 = C_0 * PP[1][0];
E = R_angle + C_0 * PCt_0;
K_0 = PCt_0 / E;
K_1 = PCt_1 / E;
t_0 = PCt_0;
t_1 = C_0 * PP[0][1];
PP[0][0] -= K_0 * t_0; //后验估计误差协方差
PP[0][1] -= K_0 * t_1;
PP[1][0] -= K_1 * t_0;
PP[1][1] -= K_1 * t_1;
Angle += K_0 * Angle_err; //后验估计
Q_bias += K_1 * Angle_err; //后验估计
Gyro_y = Gyro - Q_bias; //输出值(后验估计)的微分=角速度
}
******************倾角计算*****************
void Angle_Calculate(void)
{
/****************************加速度****************************************/
Accel_x = MPU6050_Real_Data.Accel_X; //读取X轴加速度
Angle_ax = Accel_x*1.2*180/3.14; //弧度转换为度
/****************************角速度****************************************/
Gyro_y = MPU6050_Real_Data.Gyro_Y;
时间dt,所以此处不用积分
/***************************卡尔曼融合*************************************/
Kalman_Filter(Angle_ax,Gyro_y); //卡尔曼滤波计算倾角
赞
评论
回复
支持
反对
jj_feng
回答时间:2016-8-10 14:14:07
a1024a.1 0b0c
谢谢分享
赞
评论
回复
支持
反对
大哥的诱惑
回答时间:2016-8-10 14:43:19
a0a.1 0b0c
谢谢您的分享,不错的帖子哦!
赞
评论
回复
支持
反对
nashchen17
回答时间:2016-8-11 12:58:14
a0a.1 0b0c
太感謝了,好一篇分享文章
赞
评论
回复
支持
反对
zbmxu
回答时间:2016-8-11 16:11:33
a0a.1 0b0c
滤波学习下,谢谢
赞
评论
回复
支持
反对
kernel_sa
回答时间:2016-9-20 01:03:14
a0a.1 0b0c
楼主这么强,学习一下
赞
评论
回复
支持
反对
airuoshahen
回答时间:2016-10-28 11:48:26
a0a.1 0b0c
好佩服楼主,厉害了我的哥!
赞
评论
回复
支持
反对
悬崖上的废墟
回答时间:2016-11-20 11:45:58
a0a.1 0b0c
谢谢楼主分享
赞
评论
回复
支持
反对
andypanfan
回答时间:2016-12-9 08:53:35
a0a.1 0b0c
正需要呢,顶一个!!!
赞
评论
回复
支持
反对
5265325
回答时间:2016-12-9 10:49:51
a1024a.1 0b0c
赞
评论
回复
支持
反对
maiunjour
回答时间:2016-12-9 17:12:03
a1024a.1 0b0c
特来学习~!
赞
评论
回复
支持
反对
1 ...
4
5
6
7
8
9
10
11
12
13
/ 13 页
下一页
所属标签
关于
意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号
手机版
快速回复
返回顶部
返回列表
问题:1,我快速改变板子倾角时Angle的变化正常吗?
2,Angle正常变化的时候是应该与Angle_ax的值相近吗?
现在情况就是,就算我是在减小倾角,只要我快速地改变,它显示的倾角都会先增大再减小,而如果我慢速改变的话,倾角就会缓慢减小而不会出现中间的角度增大
*************读取数据********************
//定义MPU6050内部地址
#define SMPLRT_DIV 0x19 //陀螺仪采样率 典型值 0X07 125Hz
#define CONFIG 0x1A //低通滤波频率 典型值 0x00
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围 典型值 0x18 不自检 2000deg/s
#define ACCEL_CONFIG 0x1C //加速度计自检及测量范围及高通滤波频率 典型值 0x01 不自检 2G 5Hz
#define INT_PIN_CFG 0x37
#define INT_ENABLE 0x38
#define INT_STATUS 0x3A //只读
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
//读取寄存器原生数据
MPU6050_Raw_Data.Accel_X = (buf[0]<<8 | buf[1]);
MPU6050_Raw_Data.Accel_Y = (buf[2]<<8 | buf[3]);
MPU6050_Raw_Data.Accel_Z = (buf[4]<<8 | buf[5]);
MPU6050_Raw_Data.Temp = (buf[6]<<8 | buf[7]);
MPU6050_Raw_Data.Gyro_X = (buf[8]<<8 | buf[9]);
MPU6050_Raw_Data.Gyro_Y = (buf[10]<<8 | buf[11]);
MPU6050_Raw_Data.Gyro_Z = (buf[12]<<8 | buf[13]);
//将原生数据转换为实际值,计算公式跟寄存器的配置有关
MPU6050_Real_Data.Accel_X = -(float)(MPU6050_Raw_Data.Accel_X)/8192.0;
MPU6050_Real_Data.Accel_Y = -(float)(MPU6050_Raw_Data.Accel_Y)/8192.0;
MPU6050_Real_Data.Accel_Z = (float)(MPU6050_Raw_Data.Accel_Z)/8192.0;
MPU6050_Real_Data.Gyro_X=-(float)(MPU6050_Raw_Data.Gyro_X - gyroADC_X_offset)/65.5;
MPU6050_Real_Data.Gyro_Y=-(float)(MPU6050_Raw_Data.Gyro_Y - gyroADC_Y_offset)/65.5;
MPU6050_Real_Data.Gyro_Z=(float)(MPU6050_Raw_Data.Gyro_Z - gyroADC_Z_offset)/65.5;
}
//******卡尔曼参数************
const float Q_angle=0.001;
const float Q_gyro=0.003;
const float R_angle=0.5;
const float dt=0.01; //dt为kalman滤波器采样时间;
const char C_0 = 1;
float Q_bias, Angle_err;
float PCt_0, PCt_1, E;
float K_0, K_1, t_0, t_1;
float Pdot[4] ={0,0,0,0};
float PP[2][2] = { { 1, 0 },{ 0, 1 } };
/*****************卡尔曼滤波**************************************************/
void Kalman_Filter(float Accel,float Gyro)
{
Angle+=(Gyro - Q_bias) * dt; //先验估计
Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分
Pdot[1]= -PP[1][1];
Pdot[2]= -PP[1][1];
Pdot[3]=Q_gyro;
PP[0][0] += Pdot[0] * dt; // Pk-先验估计误差协方差微分的积分
PP[0][1] += Pdot[1] * dt; // =先验估计误差协方差
PP[1][0] += Pdot[2] * dt;
PP[1][1] += Pdot[3] * dt;
Angle_err = Accel - Angle; //zk-先验估计
PCt_0 = C_0 * PP[0][0];
PCt_1 = C_0 * PP[1][0];
E = R_angle + C_0 * PCt_0;
K_0 = PCt_0 / E;
K_1 = PCt_1 / E;
t_0 = PCt_0;
t_1 = C_0 * PP[0][1];
PP[0][0] -= K_0 * t_0; //后验估计误差协方差
PP[0][1] -= K_0 * t_1;
PP[1][0] -= K_1 * t_0;
PP[1][1] -= K_1 * t_1;
Angle += K_0 * Angle_err; //后验估计
Q_bias += K_1 * Angle_err; //后验估计
Gyro_y = Gyro - Q_bias; //输出值(后验估计)的微分=角速度
}
******************倾角计算*****************
void Angle_Calculate(void)
{
/****************************加速度****************************************/
Accel_x = MPU6050_Real_Data.Accel_X; //读取X轴加速度
Angle_ax = Accel_x*1.2*180/3.14; //弧度转换为度
/****************************角速度****************************************/
Gyro_y = MPU6050_Real_Data.Gyro_Y;
时间dt,所以此处不用积分
/***************************卡尔曼融合*************************************/
Kalman_Filter(Angle_ax,Gyro_y); //卡尔曼滤波计算倾角
楼主这么强,学习一下