完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
小弟才接触Arduino 最近想做一个Arduino自平衡小车 三轴角加速度传感器用ADXL335 陀螺仪用IDG300 电机采用Pololu的29:1减速电机( 用串口传输方式进行调速,范围0~127) 控制思路采用卡尔曼滤波+PID控制的方法 但是遇到两个问题 第一是卡尔曼滤波后发现计算所得的角度值有一定的滞后 其次是在调试PID参数Kp时发现小车在晃动的同时会不由自主的变快最后无法控制,不知这是否和卡尔曼滤波没有处理好有关 想请各位大侠帮忙,能否告知一二 以下是我的代码(PID参数还未设定): #include #include SoftwareSerial mySerial(5, 6); const int xpin = A0; // x-axis of the accelerometer const int ypin = A1; // y-axis const int zpin = A2; // z-axis (only on 3-axis models) const int x_gyro = A4; int e, motor_speed, x_g; long z_average, y_average; float z_acc, angle_sum, y_acc, x_rate; double Kp, Ki,Kd, angle_acc, actAngle0, actAngle; int sensorValue[2] = { 0, 0}; //y,z accelerameter int sensorZero[2] = { 336, 340}; //y,z accelerameter int STD_LOOP_tiME = 9; int lastLoopTime = STD_LOOP_TIME; int lastLoopUsefulTime = STD_LOOP_TIME; unsigned long loopStartTime = 0; void setup() { Serial.begin(9600); /***************电机初始化******************/ mySerial.begin(19200); mySerial.write(0xAA); mySerial.write(0x88); mySerial.write(127); mySerial.write(0xAA); mySerial.write(0x8E); mySerial.write(127); /*********************************************/ Kp = 0; Ki = 0; Kd = 0; } void loop() { getangle_accelerameter(); getangle_gyro(); lastLoopUsefulTime = millis()-loopStartTime; if(lastLoopUsefulTime delay(STD_LOOP_TIME-lastLoopUsefulTime); lastLoopTime = millis() - loopStartTime; loopStartTime = millis(); actAngle = kalmanCalculate(angle_acc, x_rate, lastLoopTime); /*******************PID算法**************************/ e = actAngle - actAngle0; angle_sum += actAngle; actAngle0 = actAngle; if (angle_sum>50) angle_sum = 50; if (angle_sum<-50) angle_sum = -50; motor_speed = (Kp * actAngle) + (Ki * angle_sum) + (Kd * e); /*****************************************************/ if(motor_speed > 0) //run forward { motor_speed = motor_speed; mySerial.write(0x8A); mySerial.write(motor_speed); mySerial.write(0x8C); mySerial.write(motor_speed); } if(motor_speed < 0) //run backward { motor_speed = 0 - motor_speed; mySerial.write(0x88); mySerial.write(motor_speed); mySerial.write(0x8E); mySerial.write(motor_speed); } } void getangle_accelerameter() { y_average = 0; z_average = 0; for(int i=0;i<15;i++) { for(int n=0;n<2;n++) sensorValue[n]=analogRead(n+1)-sensorZero[n]; y_average = y_average + sensorValue[0]; z_average = z_average + sensorValue[1]; } y_acc = y_average / 15.0; z_acc = z_average / 15.0; angle_acc = atan(z_acc/y_acc) * 180 / 3.14 - 2; } void getangle_gyro() { x_g = analogRead(4); x_rate = (x_g - 308) * 2.44; } /*************************卡尔曼滤波(从网上参考的)**************/ float Q_angle = 0.001; float Q_gyro = 0.003; float R_angle = 0.03; float x_angle = 0; float x_bias = 0; float P_00 = 0, P_01 = 0, P_10 = 0, P_11 = 0; float dt, y, S; float K_0, K_1; float kalmanCalculate(float newAngle, float newRate,int looptime) { dt = float(looptime)/1000; x_angle += dt * (newRate - x_bias); P_00 += - dt * (P_10 + P_01) + Q_angle * dt; P_01 += - dt * P_11; P_10 += - dt * P_11; P_11 += + Q_gyro * dt; y = newAngle - x_angle; S = P_00 + R_angle; K_0 = P_00 / S; K_1 = P_10 / S; x_angle += K_0 * y; x_bias += K_1 * y; P_00 -= K_0 * P_00; P_01 -= K_0 * P_01; P_10 -= K_1 * P_00; P_11 -= K_1 * P_01; return x_angle; } |
|
相关推荐
2个回答
|
|
学习了!!!!!
|
|
|
|
{:12:}
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
使用Keil建立完整的工程,并使用外部中断0触发数码管显示903
280 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
1083 浏览 0 评论
846 浏览 0 评论
886 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
869 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11824 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-30 11:31 , Processed in 0.719457 second(s), Total 73, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号