@@ -26,7 +26,8 @@ using namespace OnixSourcePlugin;
2626
2727PolledBno055::PolledBno055 (std::string name, std::string hubName, const oni_dev_idx_t deviceIdx_, std::shared_ptr<Onix1> ctx)
2828 : OnixDevice(name, hubName, PolledBno055::getDeviceType(), deviceIdx_, ctx, true),
29- I2CRegisterContext(Bno055Address, deviceIdx_, ctx)
29+ I2CRegisterContext(Bno055Address, deviceIdx_, ctx),
30+ Thread(" Polled BNO: " + name)
3031{
3132 auto streamIdentifier = getStreamIdentifier ();
3233
@@ -36,10 +37,10 @@ PolledBno055::PolledBno055(std::string name, std::string hubName, const oni_dev_
3637 " Bosch Bno055 9-axis inertial measurement unit (IMU) Euler angle" ,
3738 streamIdentifier,
3839 3 ,
39- sampleRate ,
40+ SampleRate ,
4041 " Eul" ,
4142 ContinuousChannel::Type::AUX,
42- eulerAngleScale ,
43+ EulerAngleScale ,
4344 " Degrees" ,
4445 { " Y" , " R" , " P" },
4546 " euler" ,
@@ -52,10 +53,10 @@ PolledBno055::PolledBno055(std::string name, std::string hubName, const oni_dev_
5253 " Bosch Bno055 9-axis inertial measurement unit (IMU) Quaternion" ,
5354 streamIdentifier,
5455 4 ,
55- sampleRate ,
56+ SampleRate ,
5657 " Quat" ,
5758 ContinuousChannel::Type::AUX,
58- quaternionScale ,
59+ QuaternionScale ,
5960 " " ,
6061 { " W" , " X" , " Y" , " Z" },
6162 " quaternion" ,
@@ -68,10 +69,10 @@ PolledBno055::PolledBno055(std::string name, std::string hubName, const oni_dev_
6869 " Bosch Bno055 9-axis inertial measurement unit (IMU) Acceleration" ,
6970 streamIdentifier,
7071 3 ,
71- sampleRate ,
72+ SampleRate ,
7273 " Acc" ,
7374 ContinuousChannel::Type::AUX,
74- accelerationScale ,
75+ AccelerationScale ,
7576 " m / s ^ 2" ,
7677 { " X" , " Y" , " Z" },
7778 " acceleration" ,
@@ -84,10 +85,10 @@ PolledBno055::PolledBno055(std::string name, std::string hubName, const oni_dev_
8485 " Bosch Bno055 9-axis inertial measurement unit (IMU) Gravity" ,
8586 streamIdentifier,
8687 3 ,
87- sampleRate ,
88+ SampleRate ,
8889 " Grav" ,
8990 ContinuousChannel::Type::AUX,
90- accelerationScale ,
91+ AccelerationScale ,
9192 " m/s^2" ,
9293 { " X" , " Y" , " Z" },
9394 " gravity" ,
@@ -100,7 +101,7 @@ PolledBno055::PolledBno055(std::string name, std::string hubName, const oni_dev_
100101 " Bosch Bno055 9-axis inertial measurement unit (IMU) Temperature" ,
101102 streamIdentifier,
102103 1 ,
103- sampleRate ,
104+ SampleRate ,
104105 " Temp" ,
105106 ContinuousChannel::Type::AUX,
106107 1 .0f ,
@@ -115,7 +116,7 @@ PolledBno055::PolledBno055(std::string name, std::string hubName, const oni_dev_
115116 " Bosch Bno055 9-axis inertial measurement unit (IMU) Calibration status" ,
116117 streamIdentifier,
117118 4 ,
118- sampleRate ,
119+ SampleRate ,
119120 " Cal" ,
120121 ContinuousChannel::Type::AUX,
121122 1 .0f ,
@@ -126,10 +127,15 @@ PolledBno055::PolledBno055(std::string name, std::string hubName, const oni_dev_
126127 );
127128 streamInfos.add (calibrationStatusStream);
128129
129- for (int i = 0 ; i < numFrames ; i++)
130+ for (int i = 0 ; i < NumFrames ; i++)
130131 eventCodes[i] = 0 ;
131132}
132133
134+ PolledBno055::~PolledBno055 ()
135+ {
136+ stopThread (500 );
137+ }
138+
133139OnixDeviceType PolledBno055::getDeviceType ()
134140{
135141 return OnixDeviceType::POLLEDBNO;
@@ -174,7 +180,7 @@ bool PolledBno055::updateSettings()
174180 rc = WriteByte (0x3D , 0x0C ); // Operation mode is NDOF
175181 if (rc != ONI_ESUCCESS) return false ;
176182
177- rc = set933I2cRate (i2cRate );
183+ rc = set933I2cRate (I2cRate );
178184
179185 return rc == ONI_ESUCCESS;
180186}
@@ -184,16 +190,36 @@ void PolledBno055::startAcquisition()
184190 sampleNumber = 0 ;
185191 currentFrame = 0 ;
186192
193+ previousTime = std::chrono::steady_clock::now ();
194+
187195 if (isEnabled ())
188- startTimer (timerIntervalInMilliseconds );
196+ startThread ( );
189197}
190198
191- void PolledBno055::stopAcquisition ()
199+ void PolledBno055::run ()
192200{
193- stopTimer ();
201+ while (!threadShouldExit ())
202+ {
203+ time_point now = std::chrono::steady_clock::now ();
194204
195- while (isTimerRunning ())
196- std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
205+ std::chrono::milliseconds dur = std::chrono::duration_cast<std::chrono::milliseconds>(now - previousTime);
206+
207+ // NB: If the interval has not passed yet, wait for the remaining duration
208+ if (dur < TimerIntervalInMilliseconds)
209+ {
210+ std::this_thread::sleep_for (TimerIntervalInMilliseconds - dur);
211+ }
212+
213+ pollFrame ();
214+
215+ previousTime += TimerIntervalInMilliseconds;
216+ }
217+ }
218+
219+ void PolledBno055::stopAcquisition ()
220+ {
221+ if (isThreadRunning ())
222+ stopThread (500 );
197223}
198224
199225void PolledBno055::addFrame (oni_frame_t * frame)
@@ -203,63 +229,75 @@ void PolledBno055::addFrame(oni_frame_t* frame)
203229
204230void PolledBno055::addSourceBuffers (OwnedArray<DataBuffer>& sourceBuffers)
205231{
206- sourceBuffers.add (new DataBuffer (numberOfChannels , (int )sampleRate * bufferSizeInSeconds));
232+ sourceBuffers.add (new DataBuffer (NumberOfChannels , (int )SampleRate * bufferSizeInSeconds));
207233 bnoBuffer = sourceBuffers.getLast ();
208234}
209235
210- int16_t PolledBno055::readInt16 ( uint32_t startAddress )
236+ void PolledBno055::processFrames ( )
211237{
212- uint32_t value = 0 ;
213- int rc = ReadWord (startAddress, 2 , &value);
214-
215- if (rc != ONI_ESUCCESS)
216- return 0 ;
238+ }
217239
218- return static_cast <int16_t >(value);
240+ int16_t PolledBno055::getInt16FromUint32 (uint32_t value, bool getLowerValue)
241+ {
242+ return getLowerValue ?
243+ static_cast <int16_t >(value & 0xFFFFu ) :
244+ static_cast <int16_t >((value & 0xFFFF0000u ) >> 16 );
219245}
220246
221- void PolledBno055::hiResTimerCallback ()
247+ void PolledBno055::pollFrame ()
222248{
223249 size_t offset = 0 ;
250+ uint32_t value;
251+
224252
225253 // Euler
226- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress) * eulerAngleScale;
227- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 2 ) * eulerAngleScale;
228- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 4 ) * eulerAngleScale;
254+ ReadWord (EulerHeadingLsbAddress, 4 , &value);
255+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, true ) * EulerAngleScale;
256+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, false ) * EulerAngleScale;
257+
258+ ReadWord (EulerHeadingLsbAddress + 4 , 4 , &value);
259+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, true ) * EulerAngleScale;
229260
230261 // Quaternion
231- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 6 ) * quaternionScale;
232- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 8 ) * quaternionScale;
233- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 10 ) * quaternionScale;
234- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 12 ) * quaternionScale;
262+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, false ) * QuaternionScale;
263+
264+ ReadWord (EulerHeadingLsbAddress + 8 , 4 , &value);
265+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, true ) * QuaternionScale;
266+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, false ) * QuaternionScale;
267+
268+ ReadWord (EulerHeadingLsbAddress + 12 , 4 , &value);
269+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, true ) * QuaternionScale;
235270
236271 // Acceleration
237272
238- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 14 ) * accelerationScale;
239- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 16 ) * accelerationScale;
240- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 18 ) * accelerationScale;
273+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, false ) * AccelerationScale;
274+
275+ ReadWord (EulerHeadingLsbAddress + 16 , 4 , &value);
276+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, true ) * AccelerationScale;
277+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, false ) * AccelerationScale;
241278
242279 // Gravity
243280
244- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 20 ) * accelerationScale;
245- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 22 ) * accelerationScale;
246- bnoSamples[offset++ * numFrames + currentFrame] = readInt16 (EulerHeadingLsbAddress + 24 ) * accelerationScale;
281+ ReadWord (EulerHeadingLsbAddress + 20 , 4 , &value);
282+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, true ) * AccelerationScale;
283+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, false ) * AccelerationScale;
284+
285+ ReadWord (EulerHeadingLsbAddress + 24 , 4 , &value);
286+ bnoSamples[offset++ * NumFrames + currentFrame] = getInt16FromUint32 (value, true ) * AccelerationScale;
247287
248288 // Temperature
249289
250- oni_reg_val_t byte;
251- ReadByte (EulerHeadingLsbAddress + 26 , &byte);
252- bnoSamples[offset++ * numFrames + currentFrame] = static_cast <uint8_t >(byte);
290+ bnoSamples[offset++ * NumFrames + currentFrame] = static_cast <uint8_t >((value & 0xFF0000u ) >> 16 );
253291
254292 // Calibration Status
255293
256- ReadByte (EulerHeadingLsbAddress + 27 , &byte );
257-
294+ oni_reg_val_t byte = static_cast < uint8_t >((value & 0xFF000000u ) >> 24 );
295+
258296 constexpr uint8_t statusMask = 0b11 ;
259297
260298 for (int i = 0 ; i < 4 ; i++)
261299 {
262- bnoSamples[currentFrame + (offset + i) * numFrames ] = (byte & (statusMask << (2 * i))) >> (2 * i);
300+ bnoSamples[currentFrame + (offset + i) * NumFrames ] = (byte & (statusMask << (2 * i))) >> (2 * i);
263301 }
264302
265303 oni_reg_val_t timestampL = 0 , timestampH = 0 ;
@@ -274,13 +312,24 @@ void PolledBno055::hiResTimerCallback()
274312
275313 currentFrame++;
276314
277- if (currentFrame >= numFrames )
315+ if (currentFrame >= NumFrames )
278316 {
279- bnoBuffer->addToBuffer (bnoSamples.data (), sampleNumbers, bnoTimestamps, eventCodes, numFrames );
317+ bnoBuffer->addToBuffer (bnoSamples.data (), sampleNumbers, bnoTimestamps, eventCodes, NumFrames );
280318 currentFrame = 0 ;
281319 }
282320}
283321
322+ int16_t PolledBno055::readInt16 (uint32_t startAddress)
323+ {
324+ uint32_t value = 0 ;
325+ int rc = ReadWord (startAddress, 2 , &value);
326+
327+ if (rc != ONI_ESUCCESS)
328+ return 0 ;
329+
330+ return static_cast <int16_t >(value);
331+ }
332+
284333void PolledBno055::setBnoAxisMap (Bno055AxisMap map)
285334{
286335 axisMap = map;
0 commit comments