当前位置: 首页 > news >正文

ICM20948 DMP代码详解(11)

接前一篇文章:ICM20948 DMP代码详解(10)

上一回讲解完了icm20948_sensor_setup函数的第1段代码,本回继续往下解析。为了便于理解和回顾,再次贴出icm20948_sensor_setup函数源码,在EMD-App\src\ICM20948\sensor.c中,如下:

int icm20948_sensor_setup(void){int rc;uint8_t i, whoami = 0xff;/** Just get the whoami*/rc = inv_icm20948_get_whoami(&icm_device, &whoami);if (interface_is_SPI() == 0)	{		// If we're using I2Cif (whoami == 0xff) {				// if whoami fails try the other I2C Addressswitch_I2C_to_revA();rc = inv_icm20948_get_whoami(&icm_device, &whoami);}}INV_MSG(INV_MSG_LEVEL_INFO, "ICM20948 WHOAMI value=0x%02x", whoami);/** Check if WHOAMI value corresponds to any value from EXPECTED_WHOAMI array*/for(i = 0; i < sizeof(EXPECTED_WHOAMI)/sizeof(EXPECTED_WHOAMI[0]); ++i) {if(whoami == EXPECTED_WHOAMI[i]) {break;}}if(i == sizeof(EXPECTED_WHOAMI)/sizeof(EXPECTED_WHOAMI[0])) {INV_MSG(INV_MSG_LEVEL_ERROR, "Bad WHOAMI value. Got 0x%02x.", whoami);return rc;}/* Setup accel and gyro mounting matrix and associated angle for current board */inv_icm20948_init_matrix(&icm_device);/* set default power mode */INV_MSG(INV_MSG_LEVEL_VERBOSE, "Putting Icm20948 in sleep mode...");rc = inv_icm20948_initialize(&icm_device, dmp3_image, sizeof(dmp3_image));if (rc != 0) {INV_MSG(INV_MSG_LEVEL_ERROR, "Initialization failed. Error loading DMP3...");return rc;}/** Configure and initialize the ICM20948 for normal use*/INV_MSG(INV_MSG_LEVEL_INFO, "Booting up icm20948...");/* Initialize auxiliary sensors */inv_icm20948_register_aux_compass(&icm_device, INV_ICM20948_COMPASS_ID_AK09916, AK0991x_DEFAULT_I2C_ADDR);rc = inv_icm20948_initialize_auxiliary(&icm_device);if (rc == -1) {INV_MSG(INV_MSG_LEVEL_ERROR, "Compass not detected...");}icm20948_apply_mounting_matrix();icm20948_set_fsr();/* re-initialize base state structure */inv_icm20948_init_structure(&icm_device);/* we should be good to go ! */INV_MSG(INV_MSG_LEVEL_VERBOSE, "We're good to go !");return 0;
}

接下来是第2段代码,代码片段如下:

	/* Setup accel and gyro mounting matrix and associated angle for current board */inv_icm20948_init_matrix(&icm_device);

这段代码根据说明,功能是为当前电路板设置加速度和陀螺仪安装(悬挂)矩阵以及相关角度。

inv_icm20948_init_matrix函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Setup.c中,代码如下:

void inv_icm20948_init_matrix(struct inv_icm20948 *s)
{// initialize chip to bodys->s_quat_chip_to_body[0] = (1L<<30);s->s_quat_chip_to_body[1] = 0;s->s_quat_chip_to_body[2] = 0;s->s_quat_chip_to_body[3] = 0;//initialize mounting matrixmemset(s->mounting_matrix, 0, sizeof(s->mounting_matrix));s->mounting_matrix[0] = 1;s->mounting_matrix[4] = 1;s->mounting_matrix[8] = 1;//initialize soft iron matrixs->soft_iron_matrix[0] = (1L<<30);s->soft_iron_matrix[4] = (1L<<30);s->soft_iron_matrix[8] = (1L<<30);inv_icm20948_set_chip_to_body_axis_quaternion(s, s->mounting_matrix, 0.0);
}

函数参数struct inv_icm20948 *s对应的实参为&icm_device。icm_device前文已讲过,为EMD-App\src\ICM20948\sensor.c中的全局变量,之前已在inv_icm20948_reset_states函数中做过初始化。

参数类型struct inv_icm20948前文也讲到过,当时说后续使用的时候再针对于具体成员进行讲解。之前在inv_icm20948_register_aux_compass函数中用到了该结构中的struct inv_icm20948_secondary_states secondary_state成员和signed char mounting_matrix_secondary_compass[9]成员,这里用到的是signed char mounting_matrix[9]成员、long soft_iron_matrix[9]成员、以及long s_quat_chip_to_body[4]成员。

typedef struct inv_icm20948 {struct inv_icm20948_serif serif;……/* data converter */long s_quat_chip_to_body[4];……/* Icm20948Fifo usage */signed char mounting_matrix[9];signed char mounting_matrix_secondary_compass[9];long soft_iron_matrix[9];……
} inv_icm20948_t;

inv_icm20948_set_chip_to_body_axis_quaternion函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataConverter.c中,代码如下:

void inv_icm20948_set_chip_to_body_axis_quaternion(struct inv_icm20948 *s, signed char *accel_gyro_matrix, float angle)
{int i;float rot[9];long qcb[4];long q_all[4];long q_adjust[4];for (i=0; i<9; i++)rot[i] = (float)accel_gyro_matrix[i];//convert Chip to Body transformation matrix to quaternion//inv_icm20948_convert_matrix_to_quat_fxp(rot, qcb);inv_rotation_to_quaternion(rot, qcb);//The quaterion generated is the inverse, take the inverse again.qcb[1] = -qcb[1];qcb[2] = -qcb[2];qcb[3] = -qcb[3];//now rotate by angle, negate angle to rotate other wayq_adjust[0] = (long)((1L<<30) * cosf(-angle*(float)M_PI/180.f/2.f));q_adjust[1] = 0;q_adjust[2] = (long)((1L<<30) * sinf(-angle*(float)M_PI/180.f/2.f));q_adjust[3] = 0;invn_convert_quat_mult_fxp(q_adjust, qcb, q_all);inv_icm20948_set_chip_to_body(s, q_all);
}

对于该函数的解析,放在下一回中。


http://www.mrgr.cn/news/23411.html

相关文章:

  • 在 ArkTS 中,如何有效地进行内存管理和避免内存泄漏?
  • Spring Boot 自动配置
  • TCP 三次握手和四次挥手
  • HalconDotNet的图像模式识别详解
  • Pycharm Remote Development 报错解决
  • 在IDEA中如何创建web项目?——不使用Archetype
  • Edge-Triggered模式:反应堆
  • 人人都想转行的AI产品经理到底是啥?看完这一篇你就知道了
  • 如何理解API与数据源?
  • 摩洛哥的预扣税及企业所得税
  • Find My皮套|苹果Find My技术与皮套结合,智能防丢,全球定位
  • 酷柚易汛ERP全新APP端上线啦!
  • 油耳朵耳屎怎么清理?可视耳勺使用方法
  • SmartNews如何赋能日本市场解锁购买力强劲广告营销新篇章
  • 价值流架构指南:构建业务创新与竞争优势的全面方法论
  • 教师节重磅福利!《动手学强化学习》作者亲自带你学强化学习
  • VUCA时代与传统企业数字化转型
  • 一分钟了解小程序的等保测评
  • 信息系统运行维护制度(Word原件)
  • 单例模式解析