Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 28 additions & 5 deletions lib/bno080/BNO080.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,18 @@ uint16_t BNO080::parseInputReport(void)

timeStamp = ((uint32_t)shtpData[4] << (8 * 3)) | ((uint32_t)shtpData[3] << (8 * 2)) | ((uint32_t)shtpData[2] << (8 * 1)) | ((uint32_t)shtpData[1] << (8 * 0));

// The gyro-integrated input reports are sent via the special gyro channel and do no include the usual ID, sequence, and status fields
// The gyro-integrated input reports are sent via the special gyro channel and do not include the usual ID, sequence, and status fields
if(shtpHeader[2] == CHANNEL_GYRO) {
rawQuatI = (uint16_t)shtpData[1] << 8 | shtpData[0];
rawQuatJ = (uint16_t)shtpData[3] << 8 | shtpData[2];
rawQuatK = (uint16_t)shtpData[5] << 8 | shtpData[4];
rawQuatReal = (uint16_t)shtpData[7] << 8 | shtpData[6];
rawGyroIntegratedQuatI = (uint16_t)shtpData[1] << 8 | shtpData[0];
rawGyroIntegratedQuatJ = (uint16_t)shtpData[3] << 8 | shtpData[2];
rawGyroIntegratedQuatK = (uint16_t)shtpData[5] << 8 | shtpData[4];
rawGyroIntegratedQuatReal = (uint16_t)shtpData[7] << 8 | shtpData[6];

rawFastGyroX = (uint16_t)shtpData[9] << 8 | shtpData[8];
rawFastGyroY = (uint16_t)shtpData[11] << 8 | shtpData[10];
rawFastGyroZ = (uint16_t)shtpData[13] << 8 | shtpData[12];

hasNewGyroIntegratedQuaternion = true;
hasNewFastGyro_ = true;
return SENSOR_REPORTID_GYRO_INTEGRATED_ROTATION_VECTOR;
}
Expand Down Expand Up @@ -598,6 +601,26 @@ bool BNO080::getNewGameQuat(float &i, float &j, float &k, float &real, uint8_t &
return false;
}

void BNO080::getGyroIntegratedQuat(
float &i,
float &j,
float &k,
float &real
)
{
i = qToFloat(rawGyroIntegratedQuatI, rotationVector_Q1);
j = qToFloat(rawGyroIntegratedQuatJ, rotationVector_Q1);
k = qToFloat(rawGyroIntegratedQuatK, rotationVector_Q1);
real = qToFloat(rawGyroIntegratedQuatReal, rotationVector_Q1);

hasNewGyroIntegratedQuaternion = false;
}

bool BNO080::hasNewGyroIntegratedQuat()
{
return hasNewGyroIntegratedQuaternion;
}

void BNO080::getMagQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy)
{
i = qToFloat(rawMagQuatI, rotationVector_Q1);
Expand Down
4 changes: 4 additions & 0 deletions lib/bno080/BNO080.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ class BNO080
bool getNewQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy);
void getGameQuat(float &i, float &j, float &k, float &real, uint8_t &accuracy);
bool getNewGameQuat(float &i, float &j, float &k, float &real, uint8_t &accuracy);
bool hasNewGyroIntegratedQuat();
void getGyroIntegratedQuat(float &i, float &j, float &k, float &real);
void getMagQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy);
bool getNewMagQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy);
float getQuatI();
Expand Down Expand Up @@ -345,6 +347,8 @@ class BNO080
uint16_t rawMagX, rawMagY, rawMagZ, magAccuracy;
uint16_t rawQuatI, rawQuatJ, rawQuatK, rawQuatReal, rawQuatRadianAccuracy, quatAccuracy;
uint16_t rawGameQuatI, rawGameQuatJ, rawGameQuatK, rawGameQuatReal, quatGameAccuracy;
uint16_t rawGyroIntegratedQuatI, rawGyroIntegratedQuatJ, rawGyroIntegratedQuatK, rawGyroIntegratedQuatReal;
bool hasNewGyroIntegratedQuaternion = false;
uint16_t rawMagQuatI, rawMagQuatJ, rawMagQuatK, rawMagQuatReal, rawMagQuatRadianAccuracy, quatMagAccuracy;
bool hasNewQuaternion, hasNewGameQuaternion, hasNewMagQuaternion, hasNewAccel_, hasNewLinAccel_, hasNewFastGyro_;
bool hasNewMag_, hasNewGyro_;
Expand Down
5 changes: 5 additions & 0 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
#define EXPERIMENTAL_BNO_DISABLE_ACCEL_CALIBRATION true
#endif

#ifndef EXPERIMENTAL_BNO_USE_GIRV
#define EXPERIMENTAL_BNO_USE_GIRV false
// Use GIRV on BNO to report at 333Hz, stabilization still happens at 100Hz
#endif

#ifndef IMU_USE_EXTERNAL_CLOCK
#define IMU_USE_EXTERNAL_CLOCK true // Use external clock for IMU (ICM-45686 only)
#endif
Expand Down
23 changes: 23 additions & 0 deletions src/sensors/bno080sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ void BNO080Sensor::motionSetup() {

toggles = configuration.getSensorToggles(sensorId);

#if EXPERIMENTAL_BNO_USE_GIRV
imu.enableGyroIntegratedRotationVector(3);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All of this PR can be just this line. Everything else is you renamed one gyro members to another? Also gyro intergrated rotation vector is not better than game rotation vector, it should drift significantly more.

@poprox24 poprox24 Sep 24, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

GIRV does not drift more because it still does the correction on the IMU at the 100Hz, it sends more data, up to 1000Hz(it got too hot so I set it to 333), but it still does the correction at 100Hz, just as it does now

I renamed stuff because I feel it is more readable this way, if you wish you can return it

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The only difference here is faster tracking and more battery usage, also to add to the renaming, it was only to make the GIRV path clearer so it doesn't share the same variables as the regular rotation vector, feel free to return it if it doesn't make sense to you

@poprox24 poprox24 Sep 24, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@Eirenliel I have tested it tonight for a few hours and had zero issues with it, works perfectly fine, no drift issues, and surprisingly barely any more battery usage.

Works especially well with no filtering set in slimevr settings

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

By adding new members (even though they're actually same use as rawQuat* before), you broke some other readings. Just read rawQuat instead?

#else

if (!toggles.getToggle(SensorToggles::MagEnabled)) {
if ((sensorType == SensorTypeID::BNO085 || sensorType == SensorTypeID::BNO086)
&& BNO_USE_ARVR_STABILIZATION) {
Expand All @@ -75,6 +79,7 @@ void BNO080Sensor::motionSetup() {
imu.enableRotationVector(10);
}
}
#endif

#if ENABLE_INSPECTION
imu.enableRawGyro(10);
Expand Down Expand Up @@ -190,6 +195,24 @@ void BNO080Sensor::motionLoop() {
imu.resetNewRawGyro();
}

#if EXPERIMENTAL_BNO_USE_GIRV

if (imu.hasNewGyroIntegratedQuat()) {
Quat nRotation;

imu.getGyroIntegratedQuat(
nRotation.x,
nRotation.y,
nRotation.z,
nRotation.w
);

setFusedRotation(nRotation);
continue;
}

#endif

if (!toggles.getToggle(SensorToggles::MagEnabled)) {
if (imu.hasNewGameQuat()) // New quaternion if context
{
Expand Down
Loading