Skip to content

Commit

Permalink
Add a way to toggle magnetometer in runtime (SlimeVR#341)
Browse files Browse the repository at this point in the history
* Untested magnetometer toggle feature for BNO08X and overal packet structure for setting flags from the server

* Some build fixes

* refactor(configuration): rename `CalibrationConfig` to `SensorConfig`

* fix network package order

* typo found

* ignore clion files

* finish feature

* remove ota config that i used

* C skill issue on defines

* i have personal issues with C

* do a reset before

* reinit sensor

* Fix remaining merge errors

* remove BNO_USE_MAGNETOMETER_CORRECTION

* Update src/sensors/sensor.h

Co-authored-by: Lena <[email protected]>

* who loves tabs

* send sensorconfig instead of magdata on sensorinfo

* Bump protocol and firmware version

---------

Co-authored-by: Eiren Rain <[email protected]>
Co-authored-by: DevMiner <[email protected]>
Co-authored-by: Lena <[email protected]>
  • Loading branch information
4 people authored and gorbit99 committed Nov 12, 2024
1 parent f71a483 commit 3ad8ba2
Show file tree
Hide file tree
Showing 28 changed files with 591 additions and 489 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
build/
venv/
cache/
.idea/
78 changes: 42 additions & 36 deletions src/configuration/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void Configuration::setup() {
save();
}

loadCalibrations();
loadSensors();

m_Loaded = true;

Expand All @@ -103,19 +103,19 @@ void Configuration::setup() {
}

void Configuration::save() {
for (size_t i = 0; i < m_Calibrations.size(); i++) {
CalibrationConfig config = m_Calibrations[i];
if (config.type == CalibrationConfigType::NONE) {
for (size_t i = 0; i < m_Sensors.size(); i++) {
SensorConfig config = m_Sensors[i];
if (config.type == SensorConfigType::NONE) {
continue;
}

char path[17];
sprintf(path, DIR_CALIBRATIONS "/%d", i);

m_Logger.trace("Saving calibration data for %d", i);
m_Logger.trace("Saving sensor config data for %d", i);

File file = LittleFS.open(path, "w");
file.write((uint8_t*)&config, sizeof(CalibrationConfig));
file.write((uint8_t*)&config, sizeof(SensorConfig));
file.close();
}

Expand All @@ -131,7 +131,7 @@ void Configuration::save() {
void Configuration::reset() {
LittleFS.format();

m_Calibrations.clear();
m_Sensors.clear();
m_Config.version = 1;
save();

Expand All @@ -140,28 +140,28 @@ void Configuration::reset() {

int32_t Configuration::getVersion() const { return m_Config.version; }

size_t Configuration::getCalibrationCount() const { return m_Calibrations.size(); }
size_t Configuration::getSensorCount() const { return m_Sensors.size(); }

CalibrationConfig Configuration::getCalibration(size_t sensorID) const {
if (sensorID >= m_Calibrations.size()) {
SensorConfig Configuration::getSensor(size_t sensorID) const {
if (sensorID >= m_Sensors.size()) {
return {};
}

return m_Calibrations.at(sensorID);
return m_Sensors.at(sensorID);
}

void Configuration::setCalibration(size_t sensorID, const CalibrationConfig& config) {
size_t currentCalibrations = m_Calibrations.size();
void Configuration::setSensor(size_t sensorID, const SensorConfig& config) {
size_t currentSensors = m_Sensors.size();

if (sensorID >= currentCalibrations) {
m_Calibrations.resize(sensorID + 1);
if (sensorID >= currentSensors) {
m_Sensors.resize(sensorID + 1);
}

m_Calibrations[sensorID] = config;
m_Sensors[sensorID] = config;
}

void Configuration::eraseCalibration() {
m_Calibrations.clear();
void Configuration::eraseSensors() {
m_Sensors.clear();

SlimeVR::Utils::forEachFile(DIR_CALIBRATIONS, [&](SlimeVR::Utils::File f) {
char path[17];
Expand All @@ -175,19 +175,19 @@ void Configuration::eraseCalibration() {
save();
}

void Configuration::loadCalibrations() {
void Configuration::loadSensors() {
SlimeVR::Utils::forEachFile(DIR_CALIBRATIONS, [&](SlimeVR::Utils::File f) {
CalibrationConfig calibrationConfig;
f.read((uint8_t*)&calibrationConfig, sizeof(CalibrationConfig));
SensorConfig sensorConfig;
f.read((uint8_t*)&sensorConfig, sizeof(SensorConfig));

uint8_t sensorId = strtoul(f.name(), nullptr, 10);
m_Logger.debug(
"Found sensor calibration for %s at index %d",
calibrationConfigTypeToString(calibrationConfig.type),
calibrationConfigTypeToString(sensorConfig.type),
sensorId
);

setCalibration(sensorId, calibrationConfig);
setSensor(sensorId, sensorConfig);
});
}

Expand Down Expand Up @@ -220,8 +220,8 @@ bool Configuration::loadTemperatureCalibration(
return false;
}

CalibrationConfigType storedConfigType;
f.read((uint8_t*)&storedConfigType, sizeof(CalibrationConfigType));
SensorConfigType storedConfigType;
f.read((uint8_t*)&storedConfigType, sizeof(SensorConfigType));

if (storedConfigType != config.type) {
m_Logger.debug(
Expand All @@ -248,7 +248,7 @@ bool Configuration::saveTemperatureCalibration(
uint8_t sensorId,
const GyroTemperatureCalibrationConfig& config
) {
if (config.type == CalibrationConfigType::NONE) {
if (config.type == SensorConfigType::NONE) {
return false;
}

Expand All @@ -270,17 +270,17 @@ bool Configuration::runMigrations(int32_t version) { return true; }
void Configuration::print() {
m_Logger.info("Configuration:");
m_Logger.info(" Version: %d", m_Config.version);
m_Logger.info(" %d Calibrations:", m_Calibrations.size());
m_Logger.info(" %d Sensors:", m_Sensors.size());

for (size_t i = 0; i < m_Calibrations.size(); i++) {
const CalibrationConfig& c = m_Calibrations[i];
for (size_t i = 0; i < m_Sensors.size(); i++) {
const SensorConfig& c = m_Sensors[i];
m_Logger.info(" - [%3d] %s", i, calibrationConfigTypeToString(c.type));

switch (c.type) {
case CalibrationConfigType::NONE:
case SensorConfigType::NONE:
break;

case CalibrationConfigType::BMI160:
case SensorConfigType::BMI160:
m_Logger.info(
" A_B : %f, %f, %f",
UNPACK_VECTOR_ARRAY(c.data.bmi160.A_B)
Expand All @@ -302,7 +302,7 @@ void Configuration::print() {

break;

case CalibrationConfigType::SFUSION:
case SensorConfigType::SFUSION:
m_Logger.info(
" A_B : %f, %f, %f",
UNPACK_VECTOR_ARRAY(c.data.sfusion.A_B)
Expand All @@ -326,7 +326,7 @@ void Configuration::print() {
);
break;

case CalibrationConfigType::ICM20948:
case SensorConfigType::ICM20948:
m_Logger.info(
" G: %d, %d, %d",
UNPACK_VECTOR_ARRAY(c.data.icm20948.G)
Expand All @@ -342,7 +342,7 @@ void Configuration::print() {

break;

case CalibrationConfigType::MPU9250:
case SensorConfigType::MPU9250:
m_Logger.info(
" A_B : %f, %f, %f",
UNPACK_VECTOR_ARRAY(c.data.mpu9250.A_B)
Expand Down Expand Up @@ -376,7 +376,7 @@ void Configuration::print() {

break;

case CalibrationConfigType::MPU6050:
case SensorConfigType::MPU6050:
m_Logger.info(
" A_B : %f, %f, %f",
UNPACK_VECTOR_ARRAY(c.data.mpu6050.A_B)
Expand All @@ -387,7 +387,13 @@ void Configuration::print() {
);

break;
case CalibrationConfigType::NONBLOCKING:

case SensorConfigType::BNO0XX:
m_Logger.info(" magEnabled: %d", c.data.bno0XX.magEnabled);

break;

case SensorConfigType::NONBLOCKING:
if (c.data.nonblocking.sensorTimestepsCalibrated) {
m_Logger.info(
" Calibrated timesteps: Accel %f, Gyro %f, "
Expand Down
12 changes: 6 additions & 6 deletions src/configuration/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ class Configuration {

int32_t getVersion() const;

size_t getCalibrationCount() const;
CalibrationConfig getCalibration(size_t sensorID) const;
void setCalibration(size_t sensorID, const CalibrationConfig& config);
void eraseCalibration();
size_t getSensorCount() const;
SensorConfig getSensor(size_t sensorID) const;
void setSensor(size_t sensorID, const SensorConfig& config);
void eraseSensors();

bool loadTemperatureCalibration(
uint8_t sensorId,
Expand All @@ -58,13 +58,13 @@ class Configuration {
);

private:
void loadCalibrations();
void loadSensors();
bool runMigrations(int32_t version);

bool m_Loaded = false;

DeviceConfig m_Config{};
std::vector<CalibrationConfig> m_Calibrations;
std::vector<SensorConfig> m_Sensors;

Logging::Logger m_Logger = Logging::Logger("Configuration");
};
Expand Down
48 changes: 22 additions & 26 deletions src/configuration/DeviceConfig.h
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
/*
SlimeVR Code is placed under the MIT license
Copyright (c) 2022 TheDevMinerTV
SlimeVR Code is placed under the MIT license
Copyright (c) 2022 TheDevMinerTV
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef SLIMEVR_CONFIGURATION_DEVICECONFIG_H
#define SLIMEVR_CONFIGURATION_DEVICECONFIG_H

#include "CalibrationConfig.h"

namespace SlimeVR {
namespace Configuration {
struct DeviceConfig {
int32_t version;
};
}
}
namespace SlimeVR::Configuration {
struct DeviceConfig {
int32_t version;
};
} // namespace SlimeVR::Configuration

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,46 @@
THE SOFTWARE.
*/

#include "CalibrationConfig.h"
#include "SensorConfig.h"

namespace SlimeVR {
namespace Configuration {
const char* calibrationConfigTypeToString(CalibrationConfigType type) {
const char* calibrationConfigTypeToString(SensorConfigType type) {
switch (type) {
case NONE:
case SensorConfigType::NONE:
return "NONE";
case BMI160:
case SensorConfigType::BMI160:
return "BMI160";
case MPU6050:
case SensorConfigType::MPU6050:
return "MPU6050";
case MPU9250:
case SensorConfigType::MPU9250:
return "MPU9250";
case ICM20948:
case SensorConfigType::ICM20948:
return "ICM20948";
case SFUSION:
case SensorConfigType::SFUSION:
return "SoftFusion (common)";
case NONBLOCKING:
case SensorConfigType::BNO0XX:
return "BNO0XX";
case SensorConfigType::NONBLOCKING:
return "Non Blocking (common)";
default:
return "UNKNOWN";
}
}

uint16_t configDataToNumber(SensorConfig sensorConfig) {
uint16_t data = 0;
switch (sensorConfig.type) {
case SensorConfigType::BNO0XX: {
auto config = &sensorConfig.data.bno0XX;
data += config->magEnabled;
break;
}
case SensorConfigType::NONE:
default:
break;
}
return data;
}
} // namespace Configuration
} // namespace SlimeVR
Loading

0 comments on commit 3ad8ba2

Please sign in to comment.