Skyward boardcore
Loading...
Searching...
No Matches
BMX160WithCorrection.cpp
Go to the documentation of this file.
1/* Copyright (c) 2021 Skyward Experimental Rocketry
2 * Authors: Riccardo Musso, Luca Conterio, Alberto Nidasio
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
24
25#include <miosix.h>
26
27#include <fstream>
28
29using namespace miosix;
30using namespace Eigen;
31
32namespace Boardcore
33{
34
36 AxisOrthoOrientation rotation)
37 : bmx160(bmx160), rotation(rotation)
38{
39 accelerometerCorrector.fromFile("/sd/bmx160_accelerometer_correction.csv");
40 magnetometerCorrector.fromFile("/sd/bmx160_magnetometer_correction.csv");
41
42 // TODO: Remove
43 // magnetometerCorrector.setA(Vector3f{0.73726, 0.59599, 2.27584});
44 // magnetometerCorrector.setb(Vector3f{39.22325, -17.47903, -13.81505});
45
46 gyroscopeBias = Vector3f{0, 0, 0};
47}
48
49bool BMX160WithCorrection::init() { return true; }
50
51bool BMX160WithCorrection::selfTest() { return true; }
52
54{
55 gyroscopeBias = Vector3f{0, 0, 0};
56 calibrating = true;
57}
58
60{
61 calibrating = false;
62 calibrationPoints = 0;
63}
64
66{
67 if (!bmx160)
68 {
69 LOG_ERR(logger, "Driver doesn't point to valid sensor");
71 }
72
73 Eigen::Vector3f avgAccel{0, 0, 0}, avgMag{0, 0, 0}, avgGyro{0, 0, 0}, vec;
75 BMX160Data fifoElement;
76 uint16_t lastFifoSize;
77 const auto lastFifo = bmx160->getLastFifo(
78 lastFifoSize); // get last fifo and save last fifo size in fifoSize
79
80 // Read all data in the fifo
81 for (int i = 0; i < lastFifoSize; i++)
82 {
83 fifoElement = lastFifo[i];
84 // Read acceleration data
85 static_cast<AccelerometerData>(fifoElement) >> vec;
86 avgAccel += vec;
87
88 // Read magnetometer data
89 static_cast<MagnetometerData>(fifoElement) >> vec;
90 avgMag += vec;
91
92 // Read gyroscope data
93 static_cast<GyroscopeData>(fifoElement) >> vec;
94 avgGyro += vec;
95 }
96
97 // Average the samples
98 if (lastFifoSize == 0)
99 {
100 static_cast<AccelerometerData>(bmx160->getLastSample()) >> avgAccel;
101 static_cast<MagnetometerData>(bmx160->getLastSample()) >> avgMag;
102 static_cast<GyroscopeData>(bmx160->getLastSample()) >> avgGyro;
103 fifoElement = bmx160->getLastSample();
104 }
105 else
106 {
107 avgAccel /= lastFifoSize;
108 avgMag /= lastFifoSize;
109 avgGyro /= lastFifoSize;
110 }
111
112 // Correct the measurements
113 avgAccel = accelerometerCorrector.correct(avgAccel);
114 avgMag = magnetometerCorrector.correct(avgMag);
115
116 result.accelerationTimestamp = fifoElement.accelerationTimestamp;
117 static_cast<AccelerometerData&>(result) << avgAccel;
118 result.magneticFieldTimestamp = fifoElement.accelerationTimestamp;
119 static_cast<MagnetometerData&>(result) << avgMag;
120 result.angularSpeedTimestamp = fifoElement.accelerationTimestamp;
121 static_cast<GyroscopeData&>(result) << (avgGyro - gyroscopeBias);
122
123 if (calibrating)
124 {
125 gyroscopeBias = (gyroscopeBias * calibrationPoints + avgGyro) /
126 (calibrationPoints + 1);
127 calibrationPoints++;
128 }
129
130 return rotateAxis(result);
131}
132
133BMX160WithCorrectionData BMX160WithCorrection::rotateAxis(
135{
136 // Accelerometer
137 AccelerometerData accData = data;
138 Eigen::Vector3f accDataVector;
139 accData >> accDataVector;
140 accDataVector = rotation.getMatrix() * accDataVector;
141 accData << accDataVector;
142
143 // Gyroscope
144 GyroscopeData gyrData = data;
145 Eigen::Vector3f gyrDataVector;
146 gyrData >> gyrDataVector;
147 gyrDataVector = rotation.getMatrix() * gyrDataVector;
148 gyrData << gyrDataVector;
149
150 // Magnetometer
151 MagnetometerData magData = data;
152 Eigen::Vector3f magDataVector;
153 magData >> magDataVector;
154 magDataVector = rotation.getMatrix() * magDataVector;
155 magData << magDataVector;
156
157 data = accData;
158 data = gyrData;
159 data = magData;
160
161 return data;
162}
163
164} // namespace Boardcore
#define LOG_ERR(logger,...)
BMX160 Driver.
Definition BMX160.h:45
BMX160WithCorrectionData sampleImpl() override
Read a data sample from the sensor. In case of errors, the method should return the last available co...
bool selfTest() override
Check if the sensor is working.
BMX160WithCorrection(BMX160 *bmx160, AxisOrthoOrientation rotation={ Direction::POSITIVE_X, Direction::POSITIVE_Y})
bool init() override
Initialize the sensor.
const std::array< Data, FifoSize > getLastFifo(uint16_t &lastFifoSize)
Definition Sensor.h:175
virtual Data getLastSample()
Definition Sensor.h:131
bool fromFile(const std::string &fileName) override
Eigen::Vector3f correct(const Eigen::Vector3f &input) const override
This file includes all the types the logdecoder script will decode.
Structure to handle accelerometer data.
Definition SensorData.h:121
This struct represents orthogonal rotations.
Eigen::Matrix3f getMatrix() const override
Returns a rotation matrix.
Structure to handle gyroscope data.
Definition SensorData.h:207
Structure to handle magnetometer data.
Definition SensorData.h:249