Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

impl: basic magnetometer toggling #315

Closed
wants to merge 3 commits into from
Closed
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
2 changes: 2 additions & 0 deletions lib/bno055_adafruit/Adafruit_BNO055.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ class Adafruit_BNO055 {
void enterSuspendMode();
void enterNormalMode();

adafruit_bno055_opmode_t getMode() { return _mode; }

private:
byte read8(adafruit_bno055_reg_t);
bool readLen(adafruit_bno055_reg_t, byte *buffer, uint8_t len);
Expand Down
51 changes: 51 additions & 0 deletions src/network/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,15 @@ void Connection::sendSensorInfo(Sensor* sensor) {
MUST(sendByte((uint8_t)sensor->getSensorState()));
MUST(sendByte(sensor->getSensorType()));

// 0b00000000
// ^^
// |`- supportsMagToggle
// `-- hasMagEnabled
const bool supportsMagToggle = sensor->supportsTogglingMagnetometer();
const bool hasMagEnabled = sensor->hasMagnetometerEnabled();
const uint8_t magInfo = (supportsMagToggle << 1) | hasMagEnabled;
MUST(sendByte(magInfo));

MUST(endPacket());
}

Expand Down Expand Up @@ -409,6 +418,19 @@ void Connection::sendTrackerDiscovery() {
MUST(endPacket());
}

void Connection::sendToggleMagnetometerResult(uint8_t sensorId, bool result) {
MUST(m_Connected);

MUST(beginPacket());

MUST(sendPacketType(PACKET_TOGGLE_MAGNETOMETER));
MUST(sendPacketNumber());
MUST(sendByte(sensorId));
MUST(sendByte(result));

MUST(endPacket());
}

#if ENABLE_INSPECTION
void Connection::sendInspectionRawIMUData(
uint8_t sensorId,
Expand Down Expand Up @@ -709,6 +731,35 @@ void Connection::update() {
#endif
}

break;

case PACKET_TOGGLE_MAGNETOMETER:
constexpr size_t PACKET_TOGGLE_MAGNETOMETER_SIZE = 4 + 8 + 1 + 1;

// Packet type (4) + Packet number (8) + sensor ID (1) + enabled (1)
if (len < PACKET_TOGGLE_MAGNETOMETER_SIZE) {
m_Logger.warn("Invalid toggle magnetometer packet: too short");
break;
}

const auto sensorId = m_Packet[12];
const auto enabled = m_Packet[13];

const auto sensor = sensorManager.getSensors().at(sensorId);
if (sensor == nullptr) {
m_Logger.warn("Invalid sensor ID in toggle magnetometer packet");
break;
}

bool result = false;
if (sensor->supportsTogglingMagnetometer()) {
result = sensor->toggleMagnetometer(enabled);
} else {
m_Logger.warn("Received toggle magnetometer packet for sensor that doesn't support it");
}

sendToggleMagnetometerResult(sensorId, result);

break;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/network/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ class Connection {
// PACKET_SENSOR_INFO 15
void sendSensorInfo(Sensor* sensor);

// PACKET_TOGGLE_MAGNETOMETER 21
void sendToggleMagnetometerResult(uint8_t sensorId, bool result);

bool m_Connected = false;
SlimeVR::Logging::Logger m_Logger = SlimeVR::Logging::Logger("UDPConnection");

Expand Down
1 change: 1 addition & 0 deletions src/network/packets.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#define PACKET_TEMPERATURE 20
// #define PACKET_USER_ACTION 21 // Joycon buttons only currently
#define PACKET_FEATURE_FLAGS 22
#define PACKET_TOGGLE_MAGNETOMETER 23

#define PACKET_BUNDLE 100

Expand Down
31 changes: 31 additions & 0 deletions src/sensors/bno055sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@
#include "globals.h"
#include "GlobalVars.h"

/*
Info:

Check the datasheet for the BNO055 for more information on the different
operation modes.

OPERATION_MODE_IMUPLUS = OPR_MODE 0x08
In the IMU mode the relative orientation of the BNO055 in space is
calculated from the accelerometer and gyroscope data. The calculation
is fast.

OPERATION_MODE_NDOF = OPR_MODE 0x0C
This is a fusion mode with 9 degrees of freedom where the fused
absolute orientation data is calculated from accelerometer, gyroscope
and the magnetometer. The advantages of combining all three sensors are
a fast calculation, resulting in high output data rate, and high
robustness from magnetic field distortions. In this mode the
Fast Magnetometer calibration is turned ON and thereby resulting in
quick calibration of the magnetometer and higher output data accuracy.
*/

void BNO055Sensor::motionSetup() {
imu = Adafruit_BNO055(sensorId, addr);
delay(3000);
Expand Down Expand Up @@ -76,3 +97,13 @@ void BNO055Sensor::motionLoop() {
void BNO055Sensor::startCalibration(int calibrationType) {

}

bool BNO055Sensor::hasMagnetometerEnabled() {
return imu.getMode() == Adafruit_BNO055::OPERATION_MODE_NDOF;
}

bool BNO055Sensor::toggleMagnetometer(bool enabled) {
imu.setMode(enabled ? Adafruit_BNO055::OPERATION_MODE_NDOF : Adafruit_BNO055::OPERATION_MODE_IMUPLUS);

return true;
}
4 changes: 4 additions & 0 deletions src/sensors/bno055sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class BNO055Sensor : public Sensor
void motionLoop() override final;
void startCalibration(int calibrationType) override final;

bool supportsTogglingMagnetometer() { return true; };
bool hasMagnetometerEnabled() override final;
bool toggleMagnetometer(bool enabled) override final;

private:
Adafruit_BNO055 imu;
};
Expand Down
6 changes: 6 additions & 0 deletions src/sensors/sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ void Sensor::printDebugTemperatureCalibrationState() { printTemperatureCalibrati
void Sensor::saveTemperatureCalibration() { printTemperatureCalibrationUnsupported(); };
void Sensor::resetTemperatureCalibrationState() { printTemperatureCalibrationUnsupported(); };

bool Sensor::toggleMagnetometer(bool enabled) {
m_Logger.error("Toggling the magnetometer is not supported or implemented for IMU %s", getIMUNameByType(sensorType));

return false;
};

const char * getIMUNameByType(int imuType) {
switch(imuType) {
case IMU_MPU9250:
Expand Down
8 changes: 7 additions & 1 deletion src/sensors/sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ class Sensor
virtual void printDebugTemperatureCalibrationState();
virtual void resetTemperatureCalibrationState();
virtual void saveTemperatureCalibration();

// TODO: Replace with feature flags
virtual bool supportsTogglingMagnetometer() { return false; };
virtual bool hasMagnetometerEnabled() { return false; };
virtual bool toggleMagnetometer(bool enabled);

bool isWorking() {
return working;
};
Expand Down Expand Up @@ -106,7 +112,7 @@ class Sensor
Vector3 acceleration{};

SlimeVR::Logging::Logger m_Logger;

public:
uint8_t sclPin = 0;
uint8_t sdaPin = 0;
Expand Down
Loading