Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3895d95
Added ICM20984
atinm Jun 29, 2025
e896acf
Added Sparkfun ICM20948 breakout board (SPI only, I2C TBD)
atinm Jun 29, 2025
527d8b1
Merge branch 'main-upstream' into atinm/icm20948-imu
atinm Jul 2, 2025
8bd66ff
Copied files to top level from Sparkfun's subdirectory and updated RE…
atinm Jul 2, 2025
1ded436
Added back the config for imu_int_mode for ICM20948
atinm Jul 2, 2025
c258480
Use uint8_t for interrupt_mode
atinm Jul 2, 2025
42736b0
Handle when we aren't using MBED or RP2040
atinm Jul 2, 2025
176314e
Moved interrupt_mode from config to gizmo
atinm Jul 2, 2025
9fa51c6
Use bool to pass interrupt mode to _imu_ll_interrupt_setup
atinm Jul 2, 2025
af6d8bf
Added some comments about the quaternion math and fixed yaw radian ca…
atinm Jul 3, 2025
b04db65
Make the IMU interrupt check a loop rather than a die for IMUs that t…
atinm Jul 3, 2025
860abb5
Added mf_IMU for AHR and fixed sign
atinm Jul 4, 2025
86d07e9
Removed extra comment
atinm Jul 4, 2025
21d4588
Moved ImuGizmoICM20948.cpp to src/imu
atinm Jul 4, 2025
726d540
Add src/imu/ImuGizmoICM20948.cpp since move
atinm Jul 4, 2025
c6ed36a
Allow imu_has_mag config option
atinm Jul 4, 2025
0088470
Fix config->has_mag - it is a bool
atinm Jul 4, 2025
7b99f7e
Move AHR setup after IMU setup, and separate interrupt setup
atinm Jul 4, 2025
af09253
Die if using mf_IMU on AHR with an IMU that does not have sensor fusion
atinm Jul 4, 2025
fa4f032
Moved imu_use_mag to bottom and pass it along to the IMUs
atinm Jul 4, 2025
73232a7
Set sample rate to 225 Hz which is the best ICM20948 can do
atinm Jul 5, 2025
bec9795
Do bias correction on the quaternions as well
atinm Jul 5, 2025
f77ef9a
Fix more Quaternion calculations and calibration
atinm Jul 5, 2025
1a3495d
Fix quaternion align and remove hack for flipYaw()
atinm Jul 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/ahr/AhrGizmoImu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include "ahr.h"

class AhrGizmoImu : public AhrGizmo {
private:
AhrConfig *config;
AhrState *state;

//NED reference frame
//gyro in rad/sec
//acc in g
//mag any unit of measurement

// quaternion of sensor frame relative to auxiliary frame
float q0 = 1.0f; //Initialize quaternion
float q1 = 0.0f;
float q2 = 0.0f;
float q3 = 0.0f;

public:
AhrGizmoImu(Ahr *ahr) {
this->config = &(ahr->config);
this->state = (AhrState*)ahr;
}

void setInitalOrientation(float *qnew) {
q0 = qnew[0];
q1 = qnew[1];
q2 = qnew[2];
q3 = qnew[3];
}

bool update() {
// nothing to do - the imu update already updated state->q quaternions
return true;
}
};
2 changes: 1 addition & 1 deletion src/ahr/ahr.cpp
Comment thread
atinm marked this conversation as resolved.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put this in a new PR - I think this will need some additional considerations...

Some (random) thoughts:

Rather add a new imu_gizmo mf_ICM20948_6DOF than a new parameter. (I try to keep number of parameters as low as possible)

If adding a parameter:

New config params should be added at the end of the array - this allows users to upgrade without eeprom corruption.

I would use value 0 or 1 (not <=0 or 1)

Default value 1 makes more sense to me - use mag if we have it.

Rather name the param and related vars imu_use_mag, and reserve the "has" properties for driver capabilities.

Not consistent with current 9dof drivers...

@atinm atinm Jul 4, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, not consistent with existing drivers - made it use_mag and moved to bottom. Only really used by ICM20948 for now, could be used by MPU9250 if it supports 6DOF. But left others alone to have minimal code changes.

@atinm atinm Jul 4, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the meantime, my quadcopter crashed and burned badly - need to debug it, it stopped listening to IBUS and didn't automatically disarm itself when it lost contact!

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my quadcopter crashed and burned badly

ouch!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seemed to have lost some code when I split Icm20948 and ibus code so putting it back - related to calibration and quaternions

Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void Ahr::getQFromMag(float *q) {
q[3] = 0;
Serial.println("AHR: No Magnetometer, yaw:0.00");
}else{
float yaw_rad = -atan2(my, mx);
float yaw_rad = atan2(my, mx);
yaw = yaw_rad * rad_to_deg;
pitch = 0;
roll = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/cfg/cfg.h
Comment thread
atinm marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ SOFTWARE.
MF_PARAM( gps_baud, 0, int32_t, 'i') \
\
/*IMU - Inertial Measurement Unit (acc/gyro)*/ \
MF_PARAM( imu_gizmo, 0, int32_t, 'e', mf_NONE,mf_BMI270,mf_MPU6000,mf_MPU6050,mf_MPU6500,mf_MPU9150,mf_MPU9250,mf_ICM45686,mf_ICM42688) \
MF_PARAM( imu_gizmo, 0, int32_t, 'e', mf_NONE,mf_BMI270,mf_MPU6000,mf_MPU6050,mf_MPU6500,mf_MPU9150,mf_MPU9250,mf_ICM45686,mf_ICM42688,mf_ICM20948) \
MF_PARAM( imu_spi_bus, -1, int32_t, 'i') \
MF_PARAM( imu_i2c_bus, -1, int32_t, 'i') \
MF_PARAM( imu_i2c_adr, 0, int32_t, 'i') \
Expand Down
15 changes: 15 additions & 0 deletions src/imu/ICM20948/AK09916_ENUMERATIONS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef _AK09916_ENUMERATIONS_H_
#define _AK09916_ENUMERATIONS_H_

typedef enum
{
AK09916_mode_power_down = 0x00,
AK09916_mode_single = (0x01 << 0),
AK09916_mode_cont_10hz = (0x01 << 1),
AK09916_mode_cont_20hz = (0x02 << 1),
AK09916_mode_cont_50hz = (0x03 << 1),
AK09916_mode_cont_100hz = (0x04 << 1),
AK09916_mode_self_test = (0x01 << 4),
} AK09916_mode_e;

#endif // _AK09916_ENUMERATIONS_H_
83 changes: 83 additions & 0 deletions src/imu/ICM20948/AK09916_REGISTERS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#ifndef _AK09916_REGISTERS_H_
#define _AK09916_REGISTERS_H_

#include <stdint.h>

typedef enum
{
AK09916_REG_WIA1 = 0x00,
AK09916_REG_WIA2,
AK09916_REG_RSV1,
AK09916_REG_RSV2, // Reserved register. We start reading here when using the DMP. Secret sauce...
// discontinuity - containing another nine reserved registers? Secret sauce...
AK09916_REG_ST1 = 0x10,
AK09916_REG_HXL,
AK09916_REG_HXH,
AK09916_REG_HYL,
AK09916_REG_HYH,
AK09916_REG_HZL,
AK09916_REG_HZH,
// discontinuity
AK09916_REG_ST2 = 0x18,
// discontinuity
AK09916_REG_CNTL2 = 0x31,
AK09916_REG_CNTL3,
} AK09916_Reg_Addr_e;

typedef struct
{
uint8_t WIA1;
} AK09916_WIA1_Reg_t;

typedef struct
{
uint8_t WIA2;
} AK09916_WIA2_Reg_t;

typedef struct
{
uint8_t DRDY : 1;
uint8_t DOR : 1;
uint8_t reserved_0 : 6;
} AK09916_ST1_Reg_t;

// typedef struct{

// }AK09916_HXL_Reg_t;

// typedef struct{

// }AK09916_HXH_Reg_t;
// typedef struct{

// }AK09916_HYL_Reg_t;
// typedef struct{

// }AK09916_HYH_Reg_t;
// typedef struct{

// }AK09916_HZL_Reg_t;
// typedef struct{

// }AK09916_HZH_Reg_t;

typedef struct
{
uint8_t reserved_0 : 3;
uint8_t HOFL : 1;
uint8_t reserved_1 : 4;
} AK09916_ST2_Reg_t;

typedef struct
{
uint8_t MODE : 5;
uint8_t reserved_0 : 3;
} AK09916_CNTL2_Reg_t;

typedef struct
{
uint8_t SRST : 1;
uint8_t reserved_0 : 7;
} AK09916_CNTL3_Reg_t;

#endif // _AK09916_REGISTERS_H_
Loading