1
+ #include " imu.h"
2
+
3
+ namespace xrp {
4
+
5
+ unsigned long _imuUpdatePeriod = 1000 / IMU_UPDATE_RATE_HZ;
6
+ Adafruit_LSM6DSOX _lsm6;
7
+ bool _imuReady = false ;
8
+ bool _imuEnabled = false ;
9
+
10
+ unsigned long _lastIMUUpdateTime = 0 ;
11
+ bool _imuOnePassComplete = false ;
12
+
13
+ float _gyroOffsetsDegPerSec[3 ] = {0 , 0 , 0 };
14
+ float _gyroRatesDegPerSec[3 ] = {0 , 0 , 0 };
15
+ float _gyroAnglesDeg[3 ] = {0 , 0 , 0 };
16
+
17
+ float _radToDeg (float angleRad) {
18
+ return angleRad * 180.0 / PI;
19
+ }
20
+
21
+ bool imuIsReady () {
22
+ return _imuReady;
23
+ }
24
+
25
+ void imuSetEnabled (bool enabled) {
26
+ _imuEnabled = enabled;
27
+ Serial.printf (" [IMU] %s\n " , enabled ? " Enabling" : " Disabling" );
28
+ }
29
+
30
+ bool imuIsEnabled () {
31
+ return _imuEnabled;
32
+ }
33
+
34
+ void imuInit (uint8_t addr, TwoWire *theWire) {
35
+ if (!_lsm6.begin_I2C (addr, theWire, 0 )) {
36
+ Serial.println (" Failed to find LSM6DSOX" );
37
+ _imuReady = false ;
38
+ }
39
+ else {
40
+ _imuReady = true ;
41
+ Serial.println (" --- IMU ---" );
42
+ Serial.println (" LSM6DSOX detected" );
43
+ Serial.print (" Accel Range: " );
44
+ switch (_lsm6.getAccelRange ()) {
45
+ case LSM6DS_ACCEL_RANGE_2_G:
46
+ Serial.println (" +-2G" );
47
+ break ;
48
+ case LSM6DS_ACCEL_RANGE_4_G:
49
+ Serial.println (" +-4G" );
50
+ break ;
51
+ case LSM6DS_ACCEL_RANGE_8_G:
52
+ Serial.println (" +-8G" );
53
+ break ;
54
+ case LSM6DS_ACCEL_RANGE_16_G:
55
+ Serial.println (" +-16G" );
56
+ break ;
57
+ }
58
+
59
+ Serial.print (" Gyro Range: " );
60
+ switch (_lsm6.getGyroRange ()) {
61
+ case LSM6DS_GYRO_RANGE_125_DPS:
62
+ Serial.println (" 125 DPS" );
63
+ break ;
64
+ case LSM6DS_GYRO_RANGE_250_DPS:
65
+ Serial.println (" 250 DPS" );
66
+ break ;
67
+ case LSM6DS_GYRO_RANGE_500_DPS:
68
+ Serial.println (" 500 DPS" );
69
+ break ;
70
+ case LSM6DS_GYRO_RANGE_1000_DPS:
71
+ Serial.println (" 1000 DPS" );
72
+ break ;
73
+ case LSM6DS_GYRO_RANGE_2000_DPS:
74
+ Serial.println (" 2000 DPS" );
75
+ break ;
76
+ case ISM330DHCX_GYRO_RANGE_4000_DPS:
77
+ break ;
78
+ }
79
+ }
80
+ }
81
+
82
+ bool imuPeriodic () {
83
+ if (!_imuReady) return false ;
84
+ if (!_imuEnabled) return false ;
85
+
86
+ unsigned long currTime = millis ();
87
+ unsigned long dt = currTime - _lastIMUUpdateTime;
88
+
89
+ // Send the IMU data at the specified IMU_UPDATE_RATE_HZ
90
+ if (dt < _imuUpdatePeriod) return false ;
91
+
92
+ // Get IMU data
93
+ sensors_event_t accel;
94
+ sensors_event_t gyro;
95
+ sensors_event_t temp;
96
+
97
+ _lsm6.getEvent (&accel, &gyro, &temp);
98
+
99
+ float rateX = _radToDeg (gyro.gyro .x );
100
+ float rateY = _radToDeg (gyro.gyro .y );
101
+ float rateZ = _radToDeg (gyro.gyro .z );
102
+ _gyroRatesDegPerSec[0 ] = rateX - _gyroOffsetsDegPerSec[0 ];
103
+ _gyroRatesDegPerSec[1 ] = rateY - _gyroOffsetsDegPerSec[1 ];
104
+ _gyroRatesDegPerSec[2 ] = rateZ - _gyroOffsetsDegPerSec[2 ];
105
+
106
+ // We can't integrate with only a single value, so bail out
107
+ if (!_imuOnePassComplete) {
108
+ _imuOnePassComplete = true ;
109
+ _lastIMUUpdateTime = currTime;
110
+ return false ;
111
+ }
112
+
113
+ float dtInSeconds = dt / 1000.0 ;
114
+
115
+ for (int i = 0 ; i < 3 ; i++) {
116
+ _gyroAnglesDeg[i] = _gyroAnglesDeg[i] + (_gyroRatesDegPerSec[i] * dtInSeconds);
117
+ }
118
+
119
+ _lastIMUUpdateTime = currTime;
120
+ return true ;
121
+ }
122
+
123
+ float gyroGetAngleX () {
124
+ return _gyroAnglesDeg[0 ];
125
+ }
126
+
127
+ float gyroGetRateX () {
128
+ return _gyroRatesDegPerSec[0 ];
129
+ }
130
+
131
+ float gyroGetAngleY () {
132
+ return _gyroAnglesDeg[1 ];
133
+ }
134
+
135
+ float gyroGetRateY () {
136
+ return _gyroRatesDegPerSec[1 ];
137
+ }
138
+
139
+ float gyroGetAngleZ () {
140
+ return _gyroAnglesDeg[2 ];
141
+ }
142
+
143
+ float gyroGetRateZ () {
144
+ return _gyroRatesDegPerSec[2 ];
145
+ }
146
+
147
+ void gyroReset () {
148
+ for (int i = 0 ; i < 3 ; i++) {
149
+ _gyroRatesDegPerSec[i] = 0 ;
150
+ _gyroAnglesDeg[i] = 0 ;
151
+ }
152
+
153
+ _imuOnePassComplete = false ;
154
+ }
155
+
156
+ } // namespace xrp
0 commit comments