///* // * bsp_IMU.c // * // * Created on: Oct 26, 2023 // * Author: shiya // */ //#include "BSP/bsp_IMU.h" //#include "BSP/bsp_include.h" // //#define NNN 4 //#define NNN_1 4 //float Factor_G= 1; ////#define MPU_ACCEL_OFFS_REG 0X06 //accel_offs寄存器,可读取版本号,寄存器手册未提到 ////#define MPU_PROD_ID_REG 0X0C //prod id寄存器,在寄存器手册未提到 //#define MPU_SELF_TESTX_REG 0X0D //自检寄存器X //#define MPU_SELF_TESTY_REG 0X0E //自检寄存器Y //#define MPU_SELF_TESTZ_REG 0X0F //自检寄存器Z //#define MPU_SELF_TESTA_REG 0X10 //自检寄存器A //#define MPU_SAMPLE_RATE_REG 0X19 //采样频率分频器 //#define MPU_CFG_REG 0X1A //配置寄存器 //#define MPU_GYRO_CFG_REG 0X1B //陀螺仪配置寄存器 //#define MPU_ACCEL_CFG_REG 0X1C //加速度计配置寄存器 //#define MPU_MOTION_DET_REG 0X1F //运动检测阀值设置寄存器 //#define MPU_FIFO_EN_REG 0X23 //FIFO使能寄存器 //#define MPU_I2CMST_CTRL_REG 0X24 //IIC主机控制寄存器 //#define MPU_I2CSLV0_ADDR_REG 0X25 //IIC从机0器件地址寄存器 //#define MPU_I2CSLV0_REG 0X26 //IIC从机0数据地址寄存器 //#define MPU_I2CSLV0_CTRL_REG 0X27 //IIC从机0控制寄存器 //#define MPU_I2CSLV1_ADDR_REG 0X28 //IIC从机1器件地址寄存器 //#define MPU_I2CSLV1_REG 0X29 //IIC从机1数据地址寄存器 //#define MPU_I2CSLV1_CTRL_REG 0X2A //IIC从机1控制寄存器 //#define MPU_I2CSLV2_ADDR_REG 0X2B //IIC从机2器件地址寄存器 //#define MPU_I2CSLV2_REG 0X2C //IIC从机2数据地址寄存器 //#define MPU_I2CSLV2_CTRL_REG 0X2D //IIC从机2控制寄存器 //#define MPU_I2CSLV3_ADDR_REG 0X2E //IIC从机3器件地址寄存器 //#define MPU_I2CSLV3_REG 0X2F //IIC从机3数据地址寄存器 //#define MPU_I2CSLV3_CTRL_REG 0X30 //IIC从机3控制寄存器 //#define MPU_I2CSLV4_ADDR_REG 0X31 //IIC从机4器件地址寄存器 //#define MPU_I2CSLV4_REG 0X32 //IIC从机4数据地址寄存器 //#define MPU_I2CSLV4_DO_REG 0X33 //IIC从机4写数据寄存器 //#define MPU_I2CSLV4_CTRL_REG 0X34 //IIC从机4控制寄存器 //#define MPU_I2CSLV4_DI_REG 0X35 //IIC从机4读数据寄存器 // //#define MPU_I2CMST_STA_REG 0X36 //IIC主机状态寄存器 //#define MPU_INTBP_CFG_REG 0X37 //中断/旁路设置寄存器 //#define MPU_INT_EN_REG 0X38 //中断使能寄存器 //#define MPU_INT_STA_REG 0X3A //中断状态寄存器 // //#define MPU_ACCEL_XOUTH_REG 0X3B //加速度值,X轴高8位寄存器 //#define MPU_ACCEL_XOUTL_REG 0X3C //加速度值,X轴低8位寄存器 //#define MPU_ACCEL_YOUTH_REG 0X3D //加速度值,Y轴高8位寄存器 //#define MPU_ACCEL_YOUTL_REG 0X3E //加速度值,Y轴低8位寄存器 //#define MPU_ACCEL_ZOUTH_REG 0X3F //加速度值,Z轴高8位寄存器 //#define MPU_ACCEL_ZOUTL_REG 0X40 //加速度值,Z轴低8位寄存器 // //#define MPU_TEMP_OUTH_REG 0X41 //温度值高八位寄存器 //#define MPU_TEMP_OUTL_REG 0X42 //温度值低8位寄存器 // //#define MPU_GYRO_XOUTH_REG 0X43 //陀螺仪值,X轴高8位寄存器 //#define MPU_GYRO_XOUTL_REG 0X44 //陀螺仪值,X轴低8位寄存器 //#define MPU_GYRO_YOUTH_REG 0X45 //陀螺仪值,Y轴高8位寄存器 //#define MPU_GYRO_YOUTL_REG 0X46 //陀螺仪值,Y轴低8位寄存器 //#define MPU_GYRO_ZOUTH_REG 0X47 //陀螺仪值,Z轴高8位寄存器 //#define MPU_GYRO_ZOUTL_REG 0X48 //陀螺仪值,Z轴低8位寄存器 // //#define MPU_I2CSLV0_DO_REG 0X63 //IIC从机0数据寄存器 //#define MPU_I2CSLV1_DO_REG 0X64 //IIC从机1数据寄存器 //#define MPU_I2CSLV2_DO_REG 0X65 //IIC从机2数据寄存器 //#define MPU_I2CSLV3_DO_REG 0X66 //IIC从机3数据寄存器 // //#define MPU_I2CMST_DELAY_REG 0X67 //IIC主机延时管理寄存器 //#define MPU_SIGPATH_RST_REG 0X68 //信号通道复位寄存器 //#define MPU_MDETECT_CTRL_REG 0X69 //运动检测控制寄存器 //#define MPU_USER_CTRL_REG 0X6A //用户控制寄存器 //#define MPU_PWR_MGMT1_REG 0X6B //电源管理寄存器1 //#define MPU_PWR_MGMT2_REG 0X6C //电源管理寄存器2 //#define MPU_FIFO_CNTH_REG 0X72 //FIFO计数寄存器高八位 //#define MPU_FIFO_CNTL_REG 0X73 //FIFO计数寄存器低八位 //#define MPU_FIFO_RW_REG 0X74 //FIFO读写寄存器 //#define MPU_DEVICE_ID_REG 0X75 //器件ID寄存器 // ////如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位). ////如果接V3.3,则IIC地址为0X69(不包含最低位). //#define MPU_ADDR 0X69 //#define MPU_WHO_AM_I_ADDR 0X12 // //////因为模块AD0默认接GND,所以转为读写地址后,为0XD1和0XD0(如果接VCC,则为0XD3和0XD2) ////#define MPU_READ 0XD1 ////#define MPU_WRITE 0XD0 // //SP_BSP_MPU6050 *MPU_Angle; // // // //typedef uint8_t u8; //typedef uint16_t u16; // //float Kalman_filter_pitch(float newAngle, float newRate, float dt); // //float Kalman_BM_pitch(float newAngle_pitch, float newRate_pitch, float dt, float Tol_Acc); // //float Kalman_BM_roll(float newAngle_roll, float newRate_roll, float dt, float Tol_Acc); // //float FirstOrder_pitch(float newAngle, float newRate, float dt); //float SecondOrder_pitch(float newAngle, float newRate, float dt); // //float Kalman_filter_roll(float newAngle, float newRate, float dt); // //float FirstOrder_roll(float newAngle, float newRate, float dt); //float SecondOrder_roll(float newAngle, float newRate, float dt); // // ///* Kalman filter variables */ //float Q_angle_pitch = 0.001; // Process noise variance for the accelerometer //float Q_bias_pitch = 0.003; // Process noise variance for the gyro bias //float R_measure_pitch = 0.03; // Measurement noise variance - this is actually the variance of the measurement noise // //float angle_pitch = 0.0; // The angle calculated by the Kalman filter - part of the 2x1 state vector //float angle_roll = 0.0; //float bias_pitch = 0.0; // The gyro bias calculated by the Kalman filter - part of the 2x1 state vector //float rate_pitch; // Unbiased rate calculated from the rate and the calculated bias - you have to call getAngle to update the rate // //float P_pitch[2][2]={{0.0,0.0},{0.0,0.0}}; // Error covariance matrix - This is a 2x2 matrix ///////////////////////////////////////////////////////////////////////////////////// //float K1_pitch =0.1; // 对加速度计取值的权重 //float FirstOrder_angle_pitch; // //float K2_pitch =0.2; // 对加速度计取值的权重 //float kx1_pitch,kx2_pitch,ky1_pitch; //float SecondOrder_angle_pitch; // // //float FirstOrder_angle_roll; //float SecondOrder_angle_roll; // //初始化MPU6050 //u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);//IIC连续写 //u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf); //IIC连续读 //u8 MPU_Write_Byte(u8 devaddr,u8 reg,u8 data); //u8 MPU_Read_Byte(u8 devaddr,u8 reg); // //u8 MPU_Set_Gyro_Fsr(u8 fsr); //u8 MPU_Set_Accel_Fsr(u8 fsr); //u8 MPU_Set_LPF(u16 lpf); //u8 MPU_Set_Rate(u16 rate); //u8 MPU_Set_Fifo(u8 sens); // //double MPU_Get_Temperature(void); //u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz); //u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az); //void Mean_filtering(double G_XX, double G_YY, double G_ZZ,double A_XX, double A_YY, double A_ZZ,double *XYZ_Val); //void Mean_filtering_1(double G_XX_1, double G_YY_1, double G_ZZ_1,double A_XX_1, double A_YY_1, double A_ZZ_1,double *XYZ_Val_1); //void Mean_filter_Angle(double G_XX_1, int Conversion_Flag,double *XY_Angle) ;//double G_YY_1, //void GetAngle(); //void GetPitch(); ////void Judging_Symbols(double x,double y,double z,int *Symbol_Val); // // // //// The angle should be in degrees and the rate should be in degrees per second and the delta time in seconds //float Kalman_filter_pitch(float newAngle_pitch, float newRate_pitch, float dt) { // //Pitch_Kalman = Kalman_filter(Pitch, GyroX, dt); // // KasBot V2 - Kalman filter module - http://www.x-firm.com/?page_id=145 // // Modified by Kristian Lauszus // // See my blog post for more information: http://blog.tkjelectronics.dk/2012/09/a-practical-approach-to-kalman-filter-and-how-to-implement-it // // // Discrete Kalman filter time update equations - Time Update ("Predict") // // Update xhat - Project the state ahead // /* Step 1 */ // rate_pitch = newRate_pitch - bias_pitch; // angle_pitch += dt * rate_pitch; // // // Update estimation error covariance - Project the error covariance ahead // /* Step 2 */ // P_pitch[0][0] += dt * (dt*P_pitch[1][1] - P_pitch[0][1] - P_pitch[1][0] + Q_angle_pitch); // P_pitch[0][1] -= dt * P_pitch[1][1]; // P_pitch[1][0] -= dt * P_pitch[1][1]; // P_pitch[1][1] += Q_bias_pitch * dt; // // // Discrete Kalman filter measurement update equations - Measurement Update ("Correct") // // Calculate Kalman gain - Compute the Kalman gain // /* Step 4 */ // float S_pitch = P_pitch[0][0] + R_measure_pitch; // Estimate error // /* Step 5 */ // float K_pitch[2]; // Kalman gain - This is a 2x1 vector // K_pitch[0] = P_pitch[0][0] / S_pitch; // K_pitch[1] = P_pitch[1][0] / S_pitch; // // // Calculate angle and bias - Update estimate with measurement zk (newAngle) // /* Step 3 */ // float y_pitch = newAngle_pitch - angle_pitch; // Angle difference // /* Step 6 */ // angle_pitch += K_pitch[0] * y_pitch; // bias_pitch += K_pitch[1] * y_pitch; // // // Calculate estimation error covariance - Update the error covariance // /* Step 7 */ // float P00_temp_pitch = P_pitch[0][0]; // float P01_temp_pitch = P_pitch[0][1]; // // P_pitch[0][0] -= K_pitch[0] * P00_temp_pitch; // P_pitch[0][1] -= K_pitch[0] * P01_temp_pitch; // P_pitch[1][0] -= K_pitch[1] * P00_temp_pitch; // P_pitch[1][1] -= K_pitch[1] * P01_temp_pitch; // return angle_pitch; //}; //float angle_pitch_BM = 0.0; //float bias_pitch_BM =0.0; //float Q_angle_pitch_BM = 0.001; // Process noise variance for the accelerometer //float PP_pitch_BM[2][2]={{1.0,0.0},{0.0,1.0}}; // Error covariance matrix - This is a 2x2 matrix //float R_angle_Pit_mea_BM= 0.1; //float Pitch_kal_BM = 0.0; // ////【算法】基于STM32的MPU6050卡尔曼滤波算法(入门级) // ////在该算法中对角度噪声进行处理,根据加速度的值,重新调整角度计算权值 //float Kalman_BM_pitch(float newAngle_pitch, float newRate_pitch, float dt, float Tol_Acc) { // // Pitch_kal_BM += dt * (newRate_pitch-bias_pitch_BM); //过程计算值 // //设置权重 //// if((Tol_Acc>1.001)&&(Tol_Acc<0.999)) //// { //// Factor_G=1; //// } //// else //// { //// //Factor_G= 1/(fabs((Tol_Acc-1)+0.02)) +0.1 ; //// Factor_G= 20 ; //// } // // Factor_G=1; // //预测协方差矩阵 // PP_pitch_BM[0][0] = Factor_G*(PP_pitch_BM[0][0] - (PP_pitch_BM[0][1] + PP_pitch_BM[1][0]-PP_pitch_BM[1][1]*dt)*dt)+ Q_angle_pitch_BM; // PP_pitch_BM[0][1] = Factor_G*(PP_pitch_BM[0][1] - PP_pitch_BM[1][1]*dt); // PP_pitch_BM[1][0] = Factor_G*(PP_pitch_BM[1][0] - PP_pitch_BM[1][1]*dt); // PP_pitch_BM[1][1] = Factor_G*(PP_pitch_BM[1][1] )+Q_bias_pitch; // // float K_deno_Pitch=PP_pitch_BM[0][0]+R_angle_Pit_mea_BM; // // //卡尔曼增益计算0 // float K_pitch_BM[2]; // Kalman gain - This is a 2x1 vector // K_pitch_BM[0] = PP_pitch_BM[0][0] / K_deno_Pitch; // K_pitch_BM[1] = PP_pitch_BM[1][0] / K_deno_Pitch; // // bias_pitch_BM= bias_pitch_BM+ K_pitch_BM[1] * (newAngle_pitch - Pitch_kal_BM); // Pitch_kal_BM = Pitch_kal_BM + K_pitch_BM[0] * (newAngle_pitch - Pitch_kal_BM); //// float PP_pitch_BM // float PP_pitch_BM_L[2][2]; // PP_pitch_BM_L[0][0]=PP_pitch_BM[0][0];PP_pitch_BM_L[0][1]=PP_pitch_BM[0][1];PP_pitch_BM_L[1][0]=PP_pitch_BM[1][0];PP_pitch_BM_L[1][1]=PP_pitch_BM[1][1]; // // PP_pitch_BM[0][0] = PP_pitch_BM_L[0][0] -K_pitch_BM[0] * PP_pitch_BM_L[0][0]; // PP_pitch_BM[0][1] = PP_pitch_BM_L[0][1] -K_pitch_BM[0] * PP_pitch_BM_L[0][1]; // PP_pitch_BM[1][0] = PP_pitch_BM_L[1][0] -K_pitch_BM[1] * PP_pitch_BM_L[0][0]; // PP_pitch_BM[1][1] = PP_pitch_BM_L[1][1] -K_pitch_BM[1] * PP_pitch_BM_L[0][1]; // return Pitch_kal_BM; //} // //float PP_roll_BM[2][2]={{1.0,0.0},{0.0,1.0}}; //float bias_roll_BM =0.0; //float Q_bias_roll = 0.003; // Process noise variance for the gyro bias //float Q_angle_roll_BM = 0.001; // Process noise variance for the accelerometer //float Roll_kal_BM = 0.0; //float R_angle_Roll_mea_BM= 0.1; //float Factor_G; // //float Kalman_BM_roll(float newAngle_roll, float newRate_roll, float dt, float Tol_Acc) { // // Roll_kal_BM += dt * (newRate_roll-bias_roll_BM); //过程计算值 // //设置权重 // // float Factor_G= 1/fabs((Tol_Acc-1+0.01)) +0.1 ; // // if((Tol_Acc>1.001)&&(Tol_Acc<0.999)) // { // Factor_G=1; // } // else // { // //Factor_G= 1/(fabs((Tol_Acc-1)+0.02)) +0.1 ; // Factor_G= 20 ; // } // // Factor_G=1; // // //预测协方差矩阵 // PP_roll_BM[0][0] = Factor_G*(PP_roll_BM[0][0] - (PP_roll_BM[0][1] + PP_roll_BM[1][0]-PP_roll_BM[1][1]*dt)*dt)+ Q_angle_roll_BM; // PP_roll_BM[0][1] = Factor_G*(PP_roll_BM[0][1] - PP_roll_BM[1][1]*dt); // PP_roll_BM[1][0] = Factor_G*(PP_roll_BM[1][0] - PP_roll_BM[1][1]*dt); // PP_roll_BM[1][1] = Factor_G*(PP_roll_BM[1][1] )+Q_bias_roll; // // float K_deno_Roll=PP_roll_BM[0][0]+R_angle_Roll_mea_BM; // // //卡尔曼增益计算0 // float K_roll_BM[2]; // Kalman gain - This is a 2x1 vector // K_roll_BM[0] = PP_roll_BM[0][0] / K_deno_Roll; // K_roll_BM[1] = PP_roll_BM[1][0] / K_deno_Roll; // // bias_roll_BM= bias_roll_BM+ K_roll_BM[1] * (newAngle_roll - Roll_kal_BM); // Roll_kal_BM = Roll_kal_BM + K_roll_BM[0] * (newAngle_roll - Roll_kal_BM); //// float PP_roll_BM // float PP_roll_BM_L[2][2]; // PP_roll_BM_L[0][0]=PP_roll_BM[0][0];PP_roll_BM_L[0][1]=PP_roll_BM[0][1];PP_roll_BM_L[1][0]=PP_roll_BM[1][0];PP_roll_BM_L[1][1]=PP_roll_BM[1][1]; // // PP_roll_BM[0][0] = PP_roll_BM_L[0][0] -K_roll_BM[0] * PP_roll_BM_L[0][0]; // PP_roll_BM[0][1] = PP_roll_BM_L[0][1] -K_roll_BM[0] * PP_roll_BM_L[0][1]; // PP_roll_BM[1][0] = PP_roll_BM_L[1][0] -K_roll_BM[1] * PP_roll_BM_L[0][0]; // PP_roll_BM[1][1] = PP_roll_BM_L[1][1] -K_roll_BM[1] * PP_roll_BM_L[0][1]; // return Roll_kal_BM; //} // //uint8_t GF_MSP_IMU_6050_Init(SP_BSP_MPU6050 *_IMU6050_Angle) //{ // MPU_Angle = _IMU6050_Angle; // GF_BSP_Interrupt_Add_CallBack( // DF_BSP_InterCall_TIM1_100ms_PeriodElapsedCallback, // GF_BSP_GetAngle); // return 1; //} // ////void GF_BSP_GetAngle();//如,数据有问题,请分开调用 // // //float FirstOrder_pitch(float newAngle_pitch, float newRate_pitch, float dt)//采集后计算的角度和角加速度 //{ // FirstOrder_angle_pitch = K1_pitch * newAngle_pitch + (1-K1_pitch) * (angle_pitch + newRate_pitch * dt); // return FirstOrder_angle_pitch; //} // //float SecondOrder_pitch(float newAngle_pitch, float newRate_pitch, float dt)//采集后计算的角度和角加速度 //{ // kx1_pitch=(newAngle_pitch-SecondOrder_angle_pitch)*(1-K2_pitch)*(1-K2_pitch); // ky1_pitch=ky1_pitch+kx1_pitch*dt; // kx2_pitch=ky1_pitch+2*(1-K2_pitch)*(newAngle_pitch-SecondOrder_angle_pitch)+newRate_pitch; // SecondOrder_angle_pitch=SecondOrder_angle_pitch+ kx2_pitch*dt; // return SecondOrder_angle_pitch; //} // //float Pitch_A,Roll_A,Pitch_A_1,Roll_A_1,Yaw_A,Pitch_A_2,Roll_A_2; //滤波前 // //float ROLL_END,ROLL_END_1,PITCH_END,PITCH_END_1; ////float ROll_KAL_END, PITCH_KAL_END; // // //float Pitch_Kalman,Pitch_first,Pitch_second; //float Roll_Kalman,Roll_first,Roll_second; // //u8 bufG[6],bufA[6]; //角速度、加速度数据缓冲区 //int16_t GyroX,GyroY,GyroZ; //角速度 // //float GyroX_D,GyroY_D,GyroZ_D; //角速度 // //int16_t AccX,AccY,AccZ; //加速度 //double AccX_D,AccY_D,AccZ_D; //加速度 //uint32_t tem0,tem1; //存放系统时间,us // ////获取系统时间,用于卡尔曼滤波 //__STATIC_INLINE uint32_t GXT_SYSTICK_IsActiveCounterFlag(void) //{ // return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk)); //} //static uint32_t getCurrentMicros(void) //{ // /* Ensure COUNTFLAG is reset by reading SysTick control and status register */ // GXT_SYSTICK_IsActiveCounterFlag(); // uint32_t m = HAL_GetTick(); // const uint32_t tms = SysTick->LOAD + 1; // __IO uint32_t u = tms - SysTick->VAL; // if (GXT_SYSTICK_IsActiveCounterFlag()) { // m = HAL_GetTick(); // u = tms - SysTick->VAL; // } // return (m * 1000 + (u * 1000) / tms); //} ////获取系统时间,单位us //uint32_t micros(void) //{ // return getCurrentMicros(); //} // ////初始化MPU6050 ////返回值:1,成功 //// 其他,错误代码 //uint8_t GF_BSP_MPU_Init(void) //{ // u8 res; // MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT1_REG, 0X80); //复位MPU6050 // HAL_Delay(500); //延时500ms // MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT1_REG, 0X00); //唤醒MPU6050 // HAL_Delay(500); // // tem1 = micros(); // // MPU_Set_LPF(50); //设置MPU6050的数字低通滤波器 // MPU_Set_Gyro_Fsr(2); //陀螺仪传感器,±1000dps // MPU_Set_Accel_Fsr(2); //加速度传感器,±8g // MPU_Set_Rate(1000); //设置采样率1000Hz // // MPU_Write_Byte(MPU_ADDR, MPU_INT_EN_REG, 0X00); //关闭所有中断 // MPU_Write_Byte(MPU_ADDR, MPU_USER_CTRL_REG, 0X00); //I2C主模式关闭 // MPU_Write_Byte(MPU_ADDR, MPU_FIFO_EN_REG, 0X00); //关闭FIFO // MPU_Write_Byte(MPU_ADDR, MPU_INTBP_CFG_REG, 0X80); //INT引脚低电平有效 // res = MPU_Read_Byte(MPU_ADDR, MPU_DEVICE_ID_REG); // if (res == MPU_WHO_AM_I_ADDR) //器件ID正确 // { // MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT1_REG, 0X01); //设置CLKSEL,PLL 1:X,2:Y,3:Z轴为参考 // MPU_Write_Byte(MPU_ADDR, MPU_PWR_MGMT2_REG, 0X00); //加速度与陀螺仪都工作 // MPU_Set_Rate(1000); //设置采样率为1000Hz // return 1; // } // else // return 0; //} // ////设置MPU6050陀螺仪传感器满量程范围 ////fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps ////返回值:0,设置成功 //// 其他,设置失败 //u8 MPU_Set_Gyro_Fsr(u8 fsr) //{ // return MPU_Write_Byte(MPU_ADDR, MPU_GYRO_CFG_REG, fsr << 3); //设置陀螺仪满量程范围 //} // // ////设置MPU6050加速度传感器满量程范围 ////fsr:0,±2g;1,±4g;2,±8g;3,±16g ////返回值:0,设置成功 //// 其他,设置失败 //u8 MPU_Set_Accel_Fsr(u8 fsr) //{ // return MPU_Write_Byte(MPU_ADDR, MPU_ACCEL_CFG_REG, fsr << 3); //设置加速度传感器满量程范围 //} // // ////设置MPU6050的数字低通滤波器 ////lpf:数字低通滤波频率(Hz) ////返回值:0,设置成功 //// 其他,设置失败 //u8 MPU_Set_LPF(u16 lpf) //{ // u8 data = 0; // if (lpf >= 188) data = 1; // else if (lpf >= 98) data = 2; // else if (lpf >= 42) data = 3; // else if (lpf >= 20) data = 4; // else if (lpf >= 10) data = 5; // else data = 6; // return MPU_Write_Byte(MPU_ADDR, MPU_CFG_REG, data); //设置数字低通滤波器 //} ////设置MPU6050的采样率(假定Fs=1KHz) ////rate:4~1000(Hz) ////返回值:0,设置成功 //// 其他,设置失败 //u8 MPU_Set_Rate(u16 rate) //{ // u8 data; // if (rate > 1000) rate = 1000; // if (rate < 4) rate = 4; // data = 1000 / rate - 1; // data = MPU_Write_Byte(MPU_ADDR, MPU_SAMPLE_RATE_REG, data); //设置数字低通滤波器 // return MPU_Set_LPF(rate / 2); //自动设置LPF为采样率的一半 //} // ////得到温度值 ////返回值:温度值(扩大了100倍) //double MPU_Get_Temperature(void) //{ // u8 buf[2]; // short raw; // double temp; // MPU_Read_Len(MPU_ADDR, MPU_TEMP_OUTH_REG, 2, buf); // raw = ((u16)buf[0] << 8) | buf[1]; // temp = 25 + ((double)raw) / 326.8; // return temp; //} ////得到陀螺仪值(原始值) ////gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号) ////返回值:0,成功 //// 其他,错误代码 //u8 MPU_Get_Gyroscope(short *gx, short *gy, short *gz) //{ // u8 buf[6], res; // res = MPU_Read_Len(MPU_ADDR, MPU_GYRO_XOUTH_REG, 6, buf); // if (res == 0) // { // *gx = ((u16)buf[0] << 8) | buf[1]; // *gy = ((u16)buf[2] << 8) | buf[3]; // *gz = ((u16)buf[4] << 8) | buf[5]; // } // return res; //} ////得到加速度值(原始值) ////gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号) ////返回值:0,成功 //// 其他,错误代码 //u8 MPU_Get_Accelerometer(short *ax, short *ay, short *az) //{ // u8 buf[6], res; // res = MPU_Read_Len(MPU_ADDR, MPU_ACCEL_XOUTH_REG, 6, buf); // if (res == 0) // { // *ax = ((u16)buf[0] << 8) | buf[1]; // *ay = ((u16)buf[2] << 8) | buf[3]; // *az = ((u16)buf[4] << 8) | buf[5]; // } // return res; //} // ////IIC连续写 ////addr:器件地址 ////reg:寄存器地址 ////len:写入长度 ////buf:数据区 ////返回值:0,正常 //// 其他,错误代码 //u8 MPU_Write_Len(u8 addr, u8 reg, u8 len, u8 *buf) //{ // u8 res; // res = HAL_I2C_Mem_Write(&hi2c4, (addr << 1), reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff); // return res; //} // ////IIC连续读 ////addr:器件地址 ////reg:要读取的寄存器地址 ////len:要读取的长度 ////buf:读取到的数据存储区 ////返回值:0,正常 //// 其他,错误代码 //u8 MPU_Read_Len(u8 addr, u8 reg, u8 len, u8 *buf) //{ // u8 res; // res = HAL_I2C_Mem_Read(&hi2c4, (addr << 1), reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff); // return res; //} // ////IIC写一个字节 ////devaddr:器件IIC地址 ////reg:寄存器地址 ////data:数据 ////返回值:0,正常 //// 其他,错误代码 //u8 MPU_Write_Byte(u8 addr, u8 reg, u8 data) //{ // u8 res; // res = HAL_I2C_Mem_Write(&hi2c4, (addr << 1), reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 0xfff); // return res; //} // ////IIC读一个字节 ////reg:寄存器地址 ////返回值:读到的数据 //double Angle_End[2];float dt; //u8 MPU_Read_Byte(u8 addr, u8 reg) //{ // u8 res; // HAL_I2C_Mem_Read(&hi2c4, (addr << 1), reg, I2C_MEMADD_SIZE_8BIT, &res, 1, 0xfff); // return res; //} // //float Angle_X_G, Angle_Y_G; //double ACC_TOTAL; // //double XYZ_ACC[6];double XYZ_ACC_1[6]; // //void GF_BSP_GetAngle() //{ // int GyroX_bias=29; int GyroY_bias=10;int GyroZ_bias=13; // tem0 = micros(); // MPU_Read_Len(MPU_ADDR, MPU_GYRO_XOUTH_REG, 6, bufG); // GyroX = (int16_t)(((int16_t)bufG[0] << 8) + bufG[1]); // GyroY = (int16_t)(((int16_t)bufG[2] << 8) + bufG[3]); // GyroZ = (int16_t)(((int16_t)bufG[4] << 8) + bufG[5]); // // GyroX=GyroX-GyroX_bias; // GyroY=GyroY-GyroY_bias; // GyroZ=GyroZ-GyroZ_bias; // GyroX_D=(float)GyroX*0.030487804878049; // GyroY_D=(float)GyroY*0.030487804878049; // GyroZ_D=(float)GyroZ*0.030487804878049; //// GyroX = GyroX / 32.7 - 0 ;//gyroZ_OFF; // Convert to deg/s // // MPU_Read_Len(MPU_ADDR, MPU_ACCEL_XOUTH_REG, 6, bufA); // AccX = (int16_t)(((int16_t)bufA[0] << 8) | bufA[1]); // AccY = (int16_t)(((int16_t)bufA[2] << 8) | bufA[3]); // AccZ = (int16_t)(((int16_t)bufA[4] << 8) | bufA[5]); // int AccX_Bis=-40; int AccY_Bis=-22; int AccZ_Bis=29; // AccX=AccX-AccX_Bis; // AccY=AccY-AccY_Bis; // AccZ=AccZ-AccZ_Bis; // // AccX_D =1.0*(double)AccX *0.000244140625; // AccY_D =1.0*(double)AccY *0.000244140625; // AccZ_D =(double)AccZ *0.000244140625; // // // dt = (tem0-tem1)/1000000.0; // // Roll_A_1=atan2(-AccY_D,AccX_D)*180/3.1415926; // ACC_TOTAL=sqrt(AccX_D*AccX_D+AccY_D*AccY_D+AccZ_D*AccZ_D); // // // Mean_filtering(GyroX_D,GyroY_D,GyroZ_D,AccX_D, AccY_D, AccZ_D,XYZ_ACC); //// Mean_filtering_1(GyroX_D,GyroY_D,GyroZ_D,AccX_D, AccY_D, AccZ_D,XYZ_ACC_1); // double GyroX_D_F,GyroY_D_F,GyroZ_D_F,AccX_D_F,AccY_D_F,AccZ_D_F; //角速度 // GyroX_D_F=XYZ_ACC[0]; // GyroY_D_F=XYZ_ACC[1]; // GyroZ_D_F=XYZ_ACC[2]; // // AccX_D_F=XYZ_ACC[3]; // AccY_D_F=XYZ_ACC[4]; // AccZ_D_F=XYZ_ACC[5]; // //// 基于加速度计算欧拉角 // // Roll_A_2=atan2(-AccY_D_F,AccX_D_F)*180/3.1415926;//正确//正确//正确//正确//正确//正确//正确//正确//壁面安装计算方法,已和瑞芬对比 // Pitch_A_2=-atan(AccZ_D_F/sqrt(AccY_D_F*AccY_D_F+AccX_D_F*AccX_D_F))*180/3.14159;//正确//正确//正确//正确//正确//壁面放置计算方法 // //基于陀螺仪计算欧拉角 // // // // Kalman_BM_roll(Roll_A_2, GyroZ_D_F, dt, ACC_TOTAL);//修正后 // //Kalman_BM_pitch(Pitch_A_2, GyroY_D, dt, ACC_TOTAL);//修正后 // // Mean_filter_Angle(Roll_kal_BM, 0,Angle_End);//,Pitch_kal_BM*100 // Angle_End[0]=Angle_End[0]-1*0; // if(Angle_End[0]>180) // { // Angle_End[0]=Angle_End[0]-360; // } // else if(Angle_End[0]<=-180) // { // Angle_End[0]=Angle_End[0]+360; // } // // Angle_End[0]=Angle_End[0]*100; // //MPU_Angle->MPU_Roll=(int32_t)(fabs(Roll_kal_BM*100)); // // // MPU_Angle->MPU_Pitch=(int32_t)(Angle_End[0]); // // //MPU_Angle->MPU_Pitch=(int32_t)(fabs(Pitch_kal_BM*100)); // tem1= tem0; //} // // //void GetPitch(){ //// pitch = &Pitch; //// pitch_kalman = &Pitch_Kalman; //// pitch_first = &Pitch_first; //// pitch_second = &Pitch_second; // // //printf("%f,%f,%f,%f\r\n",Pitch,Pitch_Kalman,Pitch_first,Pitch_second); //} //void Judging_Symbols(double x,double y,double z,int *Symbol_Val) //{ // if(x>0) // { // Symbol_Val[0]=1; // } // else // { // Symbol_Val[0]=-1; // } // if(y>0) // { // Symbol_Val[1]=1; // } // else // { // Symbol_Val[1]=-1; // } // if(z>0) // { // Symbol_Val[2]=1; // } // else // { // Symbol_Val[2]=-1; // } // //} // //float bias_roll = 0.0; //float rate_roll; //float P_roll[2][2]={{0.0,0.0},{0.0,0.0}}; //float Q_angle_roll = 0.001; // //float R_measure_roll = 0.03; // //float Kalman_filter_roll(float newAngle_roll, float newRate_roll, float dt) { // //Pitch_Kalman = Kalman_filter(Pitch, GyroX, dt); // // KasBot V2 - Kalman filter module - http://www.x-firm.com/?page_id=145 // // Modified by Kristian Lauszus // // See my blog post for more information: http://blog.tkjelectronics.dk/2012/09/a-practical-approach-to-kalman-filter-and-how-to-implement-it // // // Discrete Kalman filter time update equations - Time Update ("Predict") // // Update xhat - Project the state ahead // /* Step 1 */ // rate_roll = newRate_roll - bias_roll; // angle_roll += dt * rate_roll; // // // Update estimation error covariance - Project the error covariance ahead // /* Step 2 */ // P_roll[0][0] += dt * (dt*P_roll[1][1] - P_roll[0][1] - P_roll[1][0] + Q_angle_roll); // P_roll[0][1] -= dt * P_roll[1][1]; // P_roll[1][0] -= dt * P_roll[1][1]; // P_roll[1][1] += Q_bias_roll * dt; // // // Discrete Kalman filter measurement update equations - Measurement Update ("Correct") // // Calculate Kalman gain - Compute the Kalman gain // /* Step 4 */ // float S_roll = P_roll[0][0] + R_measure_roll; // Estimate error // /* Step 5 */ // float K_roll[2]; // Kalman gain - This is a 2x1 vector // K_roll[0] = P_roll[0][0] / S_roll; // K_roll[1] = P_roll[1][0] / S_roll; // // // Calculate angle and bias - Update estimate with measurement zk (newAngle) // /* Step 3 */ // float y_roll = newAngle_roll - angle_roll; // Angle difference // /* Step 6 */ // angle_roll += K_roll[0] * y_roll; // bias_roll += K_roll[1] * y_roll; // // // Calculate estimation error covariance - Update the error covariance // /* Step 7 */ // float P00_temp_roll = P_roll[0][0]; // float P01_temp_roll = P_roll[0][1]; // // P_roll[0][0] -= K_roll[0] * P00_temp_roll; // P_roll[0][1] -= K_roll[0] * P01_temp_roll; // P_roll[1][0] -= K_roll[1] * P00_temp_roll; // P_roll[1][1] -= K_roll[1] * P01_temp_roll; // // return angle_roll; //}; //float K1_roll =0.1; //float FirstOrder_roll(float newAngle_roll, float newRate_roll, float dt)//采集后计算的角度和角加速度 //{ // FirstOrder_angle_roll = K1_roll * newAngle_roll + (1-K1_roll) * (angle_roll + newRate_roll * dt); // return FirstOrder_angle_roll; //} // //float K2_roll =0.2; // 对加速度计取值的权重 //float kx1_roll,kx2_roll,ky1_roll; //float SecondOrder_roll(float newAngle_roll, float newRate_roll, float dt)//采集后计算的角度和角加速度 //{ // kx1_roll=(newAngle_roll-SecondOrder_angle_roll)*(1-K2_roll)*(1-K2_roll); // ky1_roll=ky1_roll+kx1_roll*dt; // kx2_roll=ky1_roll+2*(1-K2_roll)*(newAngle_roll-SecondOrder_angle_roll)+newRate_roll; // SecondOrder_angle_roll=SecondOrder_angle_roll+ kx2_roll*dt; // return SecondOrder_angle_roll; //} // //double GG_XX[NNN]; //double GG_YY[NNN]; //double GG_ZZ[NNN]; // //double AA_XX[NNN]; //double AA_YY[NNN]; //double AA_ZZ[NNN]; // //int Mean_Index=0; //void Mean_filtering(double G_XX, double G_YY, double G_ZZ,double A_XX, double A_YY, double A_ZZ,double *XYZ_Val) //{ // GG_XX[Mean_Index]=G_XX; // GG_YY[Mean_Index]=G_YY; // GG_ZZ[Mean_Index]=G_ZZ; // // // AA_XX[Mean_Index]=A_XX; // AA_YY[Mean_Index]=A_YY; // AA_ZZ[Mean_Index]=A_ZZ; // // double Sum_XYZ[7]; // // for (int i = 0; i < NNN; i++) // { // Sum_XYZ[0] += GG_XX[i]; // Sum_XYZ[1] += GG_YY[i]; // Sum_XYZ[2] += GG_ZZ[i]; // // Sum_XYZ[3] += AA_XX[i]; // Sum_XYZ[4] += AA_YY[i]; // Sum_XYZ[5] += AA_ZZ[i]; // } // // XYZ_Val[0]=Sum_XYZ[0]/NNN; // XYZ_Val[1]=Sum_XYZ[1]/NNN; // XYZ_Val[2]=Sum_XYZ[2]/NNN; // XYZ_Val[3]=Sum_XYZ[3]/NNN; // XYZ_Val[4]=Sum_XYZ[4]/NNN; // XYZ_Val[5]=Sum_XYZ[5]/NNN; // // Mean_Index++; // // if(Mean_Index>=NNN) // { // Mean_Index=0; // } //} // //double Angle_RROOLL[NNN_1]={0}; //double Angle_PITCH[NNN_1]; //int Angle_Index=0; //double Sum_Angle[2]={0,0}; // //void Mean_filter_Angle(double G_XX_1, int Conversion_Flag,double *XY_Angle) //double G_YY_1, //{ // double Old_GG_X= Angle_RROOLL[Angle_Index]; // Angle_RROOLL[Angle_Index]=G_XX_1; // if(Sum_Angle[0]>135*NNN_1) // { // if(Angle_RROOLL[Angle_Index]<-160) // { // Angle_RROOLL[Angle_Index]=Angle_RROOLL[Angle_Index]+360; // } // } // else if(Sum_Angle[0]<-135*NNN_1) // { // if(Angle_RROOLL[Angle_Index]>160) // { // Angle_RROOLL[Angle_Index]=Angle_RROOLL[Angle_Index]-360; // } // }//角度转换完成 // // Sum_Angle[0]=Sum_Angle[0]+Angle_RROOLL[Angle_Index]- Old_GG_X; // XY_Angle[0]=Sum_Angle[0]/NNN_1; // if(XY_Angle[0]>180) // { // XY_Angle[0]=XY_Angle[0]-360; // for(int i=0;i=NNN_1) // { // Angle_Index=0; // } //} // // // //double Sum_GX=0; //double Sum_GY=0; //double Sum_GZ=0; // //double Sum_AX=0; //double Sum_AY=0; //double Sum_AZ=0; //int Mean_Index_0=0; // //double GG_XX_X[NNN]; //double GG_YY_X[NNN]; //double GG_ZZ_X[NNN]; // //double AA_XX_X[NNN]; //double AA_YY_X[NNN]; //double AA_ZZ_X[NNN]; // //void Mean_filtering_1(double G_XX_1, double G_YY_1, double G_ZZ_1,double A_XX_1, double A_YY_1, double A_ZZ_1,double *XYZ_Val_1) //{ // double Old_GG_X= GG_XX_X[Mean_Index_0]; // double Old_GG_Y= GG_YY_X[Mean_Index_0]; // double Old_GG_Z= GG_ZZ_X[Mean_Index_0]; // // double Old_AA_X= AA_XX_X[Mean_Index_0]; // double Old_AA_Y= AA_YY_X[Mean_Index_0]; // double Old_AA_Z= AA_ZZ_X[Mean_Index_0]; // // // GG_XX_X[Mean_Index_0]=G_XX_1; // GG_YY_X[Mean_Index_0]=G_YY_1; // GG_ZZ_X[Mean_Index_0]=G_ZZ_1; // // AA_XX_X[Mean_Index_0]=A_XX_1; // AA_YY_X[Mean_Index_0]=A_YY_1; // AA_ZZ_X[Mean_Index_0]=A_ZZ_1; // //数据已更新 // // Sum_GX=Sum_GX+GG_XX_X[Mean_Index_0]-Old_GG_X;//Sum Update // Sum_GY=Sum_GY+GG_YY_X[Mean_Index_0]-Old_GG_Y;//Sum Update // Sum_GZ=Sum_GZ+GG_ZZ_X[Mean_Index_0]-Old_GG_Z;//Sum Update // // Sum_AX=Sum_AX+AA_XX_X[Mean_Index_0]-Old_AA_X;//Sum Update // Sum_AY=Sum_AY+AA_YY_X[Mean_Index_0]-Old_AA_Y;//Sum Update // Sum_AZ=Sum_AZ+AA_ZZ_X[Mean_Index_0]-Old_AA_Z;//Sum Update // // XYZ_Val_1[0]=Sum_GX/NNN; // XYZ_Val_1[1]=Sum_GY/NNN; // XYZ_Val_1[2]=Sum_GZ/NNN; // // XYZ_Val_1[3]=Sum_AX/NNN; // XYZ_Val_1[4]=Sum_AY/NNN; // XYZ_Val_1[5]=Sum_AZ/NNN; // // Mean_Index_0++; // if(Mean_Index_0>=NNN) // { // Mean_Index_0=0; // } // //} // //