77#include " sfeQwiicOtos.h"
88
99sfeQwiicOtos::sfeQwiicOtos ()
10+ : _commBus{nullptr }, _linearUnit{kOtosLinearUnitInches }, _angularUnit{kOtosAngularUnitDegrees },
11+ _meterToUnit{kMeterToInch }, _radToUnit{kRadianToDegree }
1012{
11- // Set communication bus to nullptr
12- _commBus = nullptr ;
13-
14- // Set default units to inches and degrees
15- _linearUnit = kOtosLinearUnitInches ;
16- _angularUnit = kOtosAngularUnitDegrees ;
17-
18- // Set conversion factors to default units
19- _meterToUnit = kMeterToInch ;
20- _radToUnit = kRadianToDegree ;
13+ // Nothing to do here!
2114}
2215
2316sfeTkError_t sfeQwiicOtos::begin (sfeTkII2C *commBus)
@@ -27,7 +20,7 @@ sfeTkError_t sfeQwiicOtos::begin(sfeTkII2C *commBus)
2720 return kSTkErrFail ;
2821
2922 // Check the device address
30- if (commBus->address () < 0x08 || commBus-> address () > 0x77 )
23+ if (commBus->address () != kOtosDefaultAddress )
3124 return kSTkErrFail ;
3225
3326 // Set bus pointer
@@ -45,7 +38,7 @@ sfeTkError_t sfeQwiicOtos::isConnected()
4538 return err;
4639
4740 // Read the product ID
48- uint8_t prodId = 0 ;
41+ uint8_t prodId;
4942 err = _commBus->readRegisterByte (kOtosRegProductId , prodId);
5043 if (err != kSTkErrOk )
5144 return err;
@@ -62,7 +55,7 @@ sfeTkError_t sfeQwiicOtos::getVersionInfo(otos_version_t &hwVersion, otos_versio
6255{
6356 // Read hardware and firmware version registers
6457 uint8_t rawData[2 ];
65- size_t readBytes = 0 ;
58+ size_t readBytes;
6659 sfeTkError_t err = _commBus->readRegisterRegion (kOtosRegHwVersion , rawData, 2 , readBytes);
6760 if (err != kSTkErrOk )
6861 return err;
@@ -121,22 +114,29 @@ sfeTkError_t sfeQwiicOtos::calibrateImu(uint8_t numSamples, bool waitUntilDone)
121114 if (!waitUntilDone)
122115 return kSTkErrOk ;
123116
124- // Wait for the calibration to finish, which is indicated by the gyro
125- // calibration register reading zero
126- uint8_t calibrationValue = numSamples;
127- while (calibrationValue != 0 )
117+ // Wait for the calibration to finish, which is indicated by the IMU
118+ // calibration register reading zero, or until we reach the maximum number
119+ // of read attempts
120+ for ( uint8_t numAttempts = numSamples; numAttempts > 0 ; numAttempts-- )
128121 {
129- // Give a short delay between reads
130- delayMs (2 );
122+ // Give a short delay between reads. As of firmware v1.0, samples take
123+ // 2.4ms each, so 3ms should guarantee the next sample is done. This
124+ // also ensures the max attempts is not exceeded in normal operation
125+ delayMs (3 );
131126
132127 // Read the gryo calibration register value
128+ uint8_t calibrationValue;
133129 err = _commBus->readRegisterByte (kOtosRegImuCalib , calibrationValue);
134130 if (err != kSTkErrOk )
135131 return err;
132+
133+ // Check if calibration is done
134+ if (calibrationValue == 0 )
135+ return kSTkErrOk ;
136136 }
137137
138- // Done!
139- return kSTkErrOk ;
138+ // Max number of attempts reached, calibration failed
139+ return kSTkErrFail ;
140140}
141141
142142otos_linear_unit_t sfeQwiicOtos::getLinearUnit ()
@@ -178,8 +178,8 @@ void sfeQwiicOtos::setAngularUnit(otos_angular_unit_t unit)
178178sfeTkError_t sfeQwiicOtos::getLinearScalar (float &scalar)
179179{
180180 // Read the linear scalar from the device
181- uint8_t rawScalar = 0 ;
182- sfeTkError_t err = _commBus->readRegisterByte (kOtosRegScalarXY , rawScalar);
181+ uint8_t rawScalar;
182+ sfeTkError_t err = _commBus->readRegisterByte (kOtosRegScalarLinear , rawScalar);
183183 if (err != kSTkErrOk )
184184 return kSTkErrFail ;
185185
@@ -192,22 +192,22 @@ sfeTkError_t sfeQwiicOtos::getLinearScalar(float &scalar)
192192
193193sfeTkError_t sfeQwiicOtos::setLinearScalar (float scalar)
194194{
195- // Check if the scalar is out of bounds, can only be 0.872 to 1.127
196- if (scalar < 0 . 872f || scalar > 1 . 127f )
195+ // Check if the scalar is out of bounds
196+ if (scalar < kSfeOtosMinScalar || scalar > kSfeOtosMaxScalar )
197197 return kSTkErrFail ;
198198
199- // Convert to raw integer, multiples of 0.1%
200- uint8_t rawScalar = (int8_t )((scalar - 1 .0f ) * 1000 );
199+ // Convert to integer, multiples of 0.1% (+0.5 to round instead of truncate)
200+ uint8_t rawScalar = (int8_t )((scalar - 1 .0f ) * 1000 + 0 . 5f );
201201
202202 // Write the scalar to the device
203- return _commBus->writeRegisterByte (kOtosRegScalarXY , rawScalar);
203+ return _commBus->writeRegisterByte (kOtosRegScalarLinear , rawScalar);
204204}
205205
206206sfeTkError_t sfeQwiicOtos::getAngularScalar (float &scalar)
207207{
208208 // Read the angular scalar from the device
209- uint8_t rawScalar = 0 ;
210- sfeTkError_t err = _commBus->readRegisterByte (kOtosRegScalarH , rawScalar);
209+ uint8_t rawScalar;
210+ sfeTkError_t err = _commBus->readRegisterByte (kOtosRegScalarAngular , rawScalar);
211211 if (err != kSTkErrOk )
212212 return kSTkErrFail ;
213213
@@ -220,15 +220,15 @@ sfeTkError_t sfeQwiicOtos::getAngularScalar(float &scalar)
220220
221221sfeTkError_t sfeQwiicOtos::setAngularScalar (float scalar)
222222{
223- // Check if the scalar is out of bounds, can only be 0.872 to 1.127
224- if (scalar < 0 . 872f || scalar > 1 . 127f )
223+ // Check if the scalar is out of bounds
224+ if (scalar < kSfeOtosMinScalar || scalar > kSfeOtosMaxScalar )
225225 return kSTkErrFail ;
226226
227- // Convert to raw integer, multiples of 0.1%
228- uint8_t rawScalar = (int8_t )((scalar - 1 .0f ) * 1000 );
227+ // Convert to integer, multiples of 0.1% (+0.5 to round instead of truncate)
228+ uint8_t rawScalar = (int8_t )((scalar - 1 .0f ) * 1000 + 0 . 5f );
229229
230230 // Write the scalar to the device
231- return _commBus->writeRegisterByte (kOtosRegScalarH , rawScalar);
231+ return _commBus->writeRegisterByte (kOtosRegScalarAngular , rawScalar);
232232}
233233
234234sfeTkError_t sfeQwiicOtos::resetTracking ()
@@ -276,12 +276,12 @@ sfeTkError_t sfeQwiicOtos::setPosition(otos_pose2d_t &pose)
276276
277277sfeTkError_t sfeQwiicOtos::getVelocity (otos_pose2d_t &pose)
278278{
279- return readPoseRegs (kOtosRegVelXL , pose, kInt16ToMeter , kInt16ToRps );
279+ return readPoseRegs (kOtosRegVelXL , pose, kInt16ToMps , kInt16ToRps );
280280}
281281
282282sfeTkError_t sfeQwiicOtos::getAcceleration (otos_pose2d_t &pose)
283283{
284- return readPoseRegs (kOtosRegAccXL , pose, kInt16ToMeter , kInt16ToRpss );
284+ return readPoseRegs (kOtosRegAccXL , pose, kInt16ToMpss , kInt16ToRpss );
285285}
286286
287287sfeTkError_t sfeQwiicOtos::getPositionStdDev (otos_pose2d_t &pose)
@@ -291,19 +291,19 @@ sfeTkError_t sfeQwiicOtos::getPositionStdDev(otos_pose2d_t &pose)
291291
292292sfeTkError_t sfeQwiicOtos::getVelocityStdDev (otos_pose2d_t &pose)
293293{
294- return readPoseRegs (kOtosRegVelStdXL , pose, kInt16ToMeter , kInt16ToRps );
294+ return readPoseRegs (kOtosRegVelStdXL , pose, kInt16ToMps , kInt16ToRps );
295295}
296296
297297sfeTkError_t sfeQwiicOtos::getAccelerationStdDev (otos_pose2d_t &pose)
298298{
299- return readPoseRegs (kOtosRegAccStdXL , pose, kInt16ToMeter , kInt16ToRpss );
299+ return readPoseRegs (kOtosRegAccStdXL , pose, kInt16ToMpss , kInt16ToRpss );
300300}
301301
302302sfeTkError_t sfeQwiicOtos::getPosVelAcc (otos_pose2d_t &pos, otos_pose2d_t &vel, otos_pose2d_t &acc)
303303{
304304 // Read all pose registers
305305 uint8_t rawData[18 ];
306- size_t bytesRead = 0 ;
306+ size_t bytesRead;
307307 sfeTkError_t err = _commBus->readRegisterRegion (kOtosRegPosXL , rawData, 18 , bytesRead);
308308 if (err != kSTkErrOk )
309309 return err;
@@ -314,8 +314,8 @@ sfeTkError_t sfeQwiicOtos::getPosVelAcc(otos_pose2d_t &pos, otos_pose2d_t &vel,
314314
315315 // Convert raw data to pose units
316316 regsToPose (rawData, pos, kInt16ToMeter , kInt16ToRad );
317- regsToPose (rawData + 6 , vel, kInt16ToMeter , kInt16ToRps );
318- regsToPose (rawData + 12 , acc, kInt16ToMeter , kInt16ToRpss );
317+ regsToPose (rawData + 6 , vel, kInt16ToMps , kInt16ToRps );
318+ regsToPose (rawData + 12 , acc, kInt16ToMpss , kInt16ToRpss );
319319
320320 // Done!
321321 return kSTkErrOk ;
@@ -325,7 +325,7 @@ sfeTkError_t sfeQwiicOtos::getPosVelAccStdDev(otos_pose2d_t &pos, otos_pose2d_t
325325{
326326 // Read all pose registers
327327 uint8_t rawData[18 ];
328- size_t bytesRead = 0 ;
328+ size_t bytesRead;
329329 sfeTkError_t err = _commBus->readRegisterRegion (kOtosRegPosStdXL , rawData, 18 , bytesRead);
330330 if (err != kSTkErrOk )
331331 return err;
@@ -336,8 +336,8 @@ sfeTkError_t sfeQwiicOtos::getPosVelAccStdDev(otos_pose2d_t &pos, otos_pose2d_t
336336
337337 // Convert raw data to pose units
338338 regsToPose (rawData, pos, kInt16ToMeter , kInt16ToRad );
339- regsToPose (rawData + 6 , vel, kInt16ToMeter , kInt16ToRps );
340- regsToPose (rawData + 12 , acc, kInt16ToMeter , kInt16ToRpss );
339+ regsToPose (rawData + 6 , vel, kInt16ToMps , kInt16ToRps );
340+ regsToPose (rawData + 12 , acc, kInt16ToMpss , kInt16ToRpss );
341341
342342 // Done!
343343 return kSTkErrOk ;
@@ -347,7 +347,7 @@ sfeTkError_t sfeQwiicOtos::getPosVelAccAndStdDev(otos_pose2d_t &pos, otos_pose2d
347347{
348348 // Read all pose registers
349349 uint8_t rawData[36 ];
350- size_t bytesRead = 0 ;
350+ size_t bytesRead;
351351 sfeTkError_t err = _commBus->readRegisterRegion (kOtosRegPosXL , rawData, 36 , bytesRead);
352352 if (err != kSTkErrOk )
353353 return err;
@@ -358,19 +358,19 @@ sfeTkError_t sfeQwiicOtos::getPosVelAccAndStdDev(otos_pose2d_t &pos, otos_pose2d
358358
359359 // Convert raw data to pose units
360360 regsToPose (rawData, pos, kInt16ToMeter , kInt16ToRad );
361- regsToPose (rawData + 6 , vel, kInt16ToMeter , kInt16ToRps );
362- regsToPose (rawData + 12 , acc, kInt16ToMeter , kInt16ToRpss );
361+ regsToPose (rawData + 6 , vel, kInt16ToMps , kInt16ToRps );
362+ regsToPose (rawData + 12 , acc, kInt16ToMpss , kInt16ToRpss );
363363 regsToPose (rawData + 18 , posStdDev, kInt16ToMeter , kInt16ToRad );
364- regsToPose (rawData + 24 , velStdDev, kInt16ToMeter , kInt16ToRps );
365- regsToPose (rawData + 30 , accStdDev, kInt16ToMeter , kInt16ToRpss );
364+ regsToPose (rawData + 24 , velStdDev, kInt16ToMps , kInt16ToRps );
365+ regsToPose (rawData + 30 , accStdDev, kInt16ToMpss , kInt16ToRpss );
366366
367367 // Done!
368368 return kSTkErrOk ;
369369}
370370
371371sfeTkError_t sfeQwiicOtos::readPoseRegs (uint8_t reg, otos_pose2d_t &pose, float rawToXY, float rawToH)
372372{
373- size_t bytesRead = 0 ;
373+ size_t bytesRead;
374374 uint8_t rawData[6 ];
375375
376376 // Attempt to read the raw pose data
0 commit comments