/* Task_atti_esti Task */ /* Includes ----------------------------------------------------------------- */ #include "task\user_task.h" #include "device\bmi088.h" #include "component\ahrs.h" #include "device\ist8310.h" #include "component/pid.h" #include "bsp/pwm.h" /* Private typedef ---------------------------------------------------------- */ /* Private define ----------------------------------------------------------- */ /* Private macro ------------------------------------------------------------ */ /* Private variables -------------------------------------------------------- */ BMI088_t bmi088; IST8310_t ist8310; AHRS_t gimbal_ahrs; AHRS_Eulr_t eulr_to_send; KPID_t imu_temp_ctrl_pid; uint16_t N=0; float sum_x = 0, sum_y = 0, sum_z = 0; static const KPID_Params_t imu_temp_ctrl_pid_param = { .k = 0.5f, .p = 1.0f, .i = 0.0f, .d = 0.0f, .i_limit = 1.0f, .out_limit = 1.0f, }; BMI088_Cali_t bmi_cali={0.00176034111f,0.000634364958f,0.000980574405f};//////暂时使用,学习flash后更改添加初始化代码 IST8310_Cali_t ist_cali = { .magn_offset = {0,0,0}, // 零偏,初始设为0 .magn_scale = {0,0,0} // 比例因子,初始设为1 }; /* Private function --------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */ /** * \brief Task_atti_esti Task * * \param argument 未使用 */ void Task_atti_esti(void *argument) { (void)argument; /* 未使用argument,消除警告 */ BMI088_Init(&bmi088, &bmi_cali/*(task_runtime.cfg.cali.bmi088)*/);//校准数据,学习flash或直接传入 // IST8310_Init(&ist8310, &ist_cali/*(task_runtime.cfg.cali.ist8310)*/); AHRS_Init(&gimbal_ahrs, &ist8310.magn, BMI088_GetUpdateFreq(&bmi088)); PID_Init(&imu_temp_ctrl_pid, KPID_MODE_NO_D, 1.0f / BMI088_GetUpdateFreq(&bmi088), &imu_temp_ctrl_pid_param); BSP_PWM_Start(BSP_PWM_IMU_HEAT); /* 计算任务运行到指定频率需要等待的tick数 */ const uint32_t delay_tick = osKernelGetTickFreq() / TASK_FREQ_ATTI_ESTI; osDelay(TASK_INIT_DELAY_ATTI_ESTI); /* 延时一段时间再开启任务 */ uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */ while (1) { tick += delay_tick; /* 计算下一个唤醒时刻 */ /*User code begin*/ /* 记录任务所使用的的栈空间 */ task_runtime.stack_water_mark.atti_esti = osThreadGetStackSpace(osThreadGetId()); /* 等待IMU新数据 */ BMI088_WaitNew(); /* 开始数据接收DMA,加速度计和陀螺仪共用同一个SPI接口, * 一次只能开启一个DMA */ BMI088_AcclStartDmaRecv(); BMI088_AcclWaitDmaCplt(); BMI088_GyroStartDmaRecv(); BMI088_GyroWaitDmaCplt(); // IST8310_WaitNew(999); // IST8310_StartDmaRecv(); // IST8310_WaitDmaCplt(); /* 锁住RTOS内核防止数据解析过程中断,造成错误 */ osKernelLock(); /* 接收完所有数据后,把数据从原始字节加工成方便计算的数据 */ BMI088_ParseAccl(&bmi088); BMI088_ParseGyro(&bmi088); // IST8310_Parse(&ist8310); // if(N<1000){ // // sum_x += bmi088.gyro.x; // sum_y += bmi088.gyro.y; // sum_z += bmi088.gyro.z; // // N++; // }else{ // bmi_cali.gyro_offset.x = sum_x / 1000; // bmi_cali.gyro_offset.y = sum_y / 1000; // bmi_cali.gyro_offset.z = sum_z / 1000; // } /* 根据设备接收到的数据进行姿态解析 */ AHRS_Update(&gimbal_ahrs, &bmi088.accl, &bmi088.gyro, &ist8310.magn); /* 根据解析出来的四元数计算欧拉角 */ AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs); osKernelUnlock(); osMessageQueueReset(task_runtime.msgq.accl); osMessageQueuePut(task_runtime.msgq.accl, &bmi088.accl, 0, 0); osMessageQueuePut(task_runtime.msgq.accl, &bmi088.accl, 0, 0); osMessageQueueReset(task_runtime.msgq.gyro); osMessageQueuePut(task_runtime.msgq.gyro, &bmi088.gyro, 0, 0); osMessageQueuePut(task_runtime.msgq.gyro, &bmi088.gyro, 0, 0); osMessageQueueReset(task_runtime.msgq.eulr_imu); osMessageQueuePut(task_runtime.msgq.eulr_imu, &eulr_to_send, 0, 0); BSP_PWM_Set(BSP_PWM_IMU_HEAT, PID_Calc(&imu_temp_ctrl_pid, 40.0f, bmi088.temp, 0.0f, 0.0f)); /*User code end*/ osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */ } }