Skip to content

Commit e96647d

Browse files
committed
Add examples 2, 3, and 4
Units, calibration, and offset
1 parent 0b6f6f3 commit e96647d

File tree

6 files changed

+385
-77
lines changed

6 files changed

+385
-77
lines changed
Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "SparkFun_Qwiic_OTOS_Arduino_Library.h"
22
#include "Wire.h"
33

4-
// Create an OTOS object
4+
// Create an Optical Tracking Odometry Sensor object
55
QwiicOTOS myOtos;
66

77
void setup()
@@ -21,47 +21,36 @@ void setup()
2121

2222
Serial.println("OTOS connected!");
2323

24-
// The IMU on the OTOS includes a gyroscope and accelerometer, which could
25-
// have an offset. This needs to be calibrated out in order to get accurate
26-
// tracking, which must be done while the OTOS is stationary and flat!
27-
Serial.println("Calibrating IMU...");
28-
myOtos.calibrateImu();
29-
30-
// We'll also reset the tracking to start at the origin
31-
Serial.println("Resetting pose...");
32-
otos_pose2d_t currentPose = {0, 0, 0};
33-
myOtos.setPosition(currentPose);
34-
35-
myOtos.setLinearUnit(kOtosLinearUnitInches);
36-
myOtos.setAngularUnit(kOtosAngularUnitDegrees);
24+
// Reset the tracking algorithm, making the sensor report it's at the origin
25+
myOtos.resetTracking();
3726
}
3827

3928
void loop()
4029
{
41-
// Get latest pose from sensor, which includes the x and y coordinates, plus
30+
// Get the latest sensor pose, which includes the x and y coordinates, plus
4231
// the heading angle
4332
otos_pose2d_t otosPose;
4433
myOtos.getPosition(otosPose);
4534

4635
// Print measurement
4736
Serial.println();
48-
Serial.println("Current pose:");
49-
Serial.print("X (Meters): ");
50-
Serial.println(otosPose.x, 3);
51-
Serial.print("Y (Meters): ");
52-
Serial.println(otosPose.y, 3);
53-
Serial.print("Heading (Radians): ");
54-
Serial.println(otosPose.h, 3);
37+
Serial.println("Sensor pose:");
38+
Serial.print("X (Inches): ");
39+
Serial.println(otosPose.x);
40+
Serial.print("Y (Inches): ");
41+
Serial.println(otosPose.y);
42+
Serial.print("Heading (Degrees): ");
43+
Serial.println(otosPose.h);
5544

5645
// Wait a bit so we don't spam the serial port
5746
delay(500);
5847

5948
// Alternatively, you can comment out the print and delay code above, and
60-
// instead use the following code to refresh the data more quickly
61-
// Serial.print(otosPose.x, 3);
62-
// Serial.print(", ");
63-
// Serial.print(otosPose.y, 3);
64-
// Serial.print(", ");
65-
// Serial.println(otosPose.h, 3);
49+
// instead use the following code to rapidly refresh the data
50+
// Serial.print(otosPose.x);
51+
// Serial.print("\t");
52+
// Serial.print(otosPose.y);
53+
// Serial.print("\t");
54+
// Serial.println(otosPose.h);
6655
// delay(10);
6756
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "SparkFun_Qwiic_OTOS_Arduino_Library.h"
2+
#include "Wire.h"
3+
4+
// Create an Optical Tracking Odometry Sensor object
5+
QwiicOTOS myOtos;
6+
7+
void setup()
8+
{
9+
// Start serial
10+
Serial.begin(115200);
11+
Serial.println("Qwiic OTOS Example 2 - Set Units");
12+
13+
Wire.begin();
14+
15+
// Attempt to begin the sensor
16+
while (myOtos.begin() == false)
17+
{
18+
Serial.println("OTOS not connected, check your wiring and I2C address!");
19+
delay(1000);
20+
}
21+
22+
Serial.println("OTOS connected!");
23+
24+
// Set the desired units for linear and angular measurements. Can be either
25+
// meters or inches for linear, and radians or degrees for angular. If not
26+
// set, the default is inches and degrees.
27+
myOtos.setLinearUnit(kOtosLinearUnitMeters);
28+
// myOtos.setLinearUnit(kOtosLinearUnitInches);
29+
myOtos.setAngularUnit(kOtosAngularUnitRadians);
30+
// myOtos.setAngularUnit(kOtosAngularUnitDegrees);
31+
32+
// Reset the tracking algorithm, making the sensor report it's at the origin
33+
myOtos.resetTracking();
34+
}
35+
36+
void loop()
37+
{
38+
// Get the latest sensor pose, which includes the x and y coordinates, plus
39+
// the heading angle
40+
otos_pose2d_t otosPose;
41+
myOtos.getPosition(otosPose);
42+
43+
// Print measurement
44+
Serial.println();
45+
Serial.println("Sensor pose:");
46+
Serial.print("X (Meters): ");
47+
Serial.println(otosPose.x, 4);
48+
Serial.print("Y (Meters): ");
49+
Serial.println(otosPose.y, 4);
50+
Serial.print("Heading (Radians): ");
51+
Serial.println(otosPose.h, 4);
52+
53+
// Wait a bit so we don't spam the serial port
54+
delay(500);
55+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "SparkFun_Qwiic_OTOS_Arduino_Library.h"
2+
#include "Wire.h"
3+
4+
// Create an Optical Tracking Odometry Sensor object
5+
QwiicOTOS myOtos;
6+
7+
void setup()
8+
{
9+
// Start serial
10+
Serial.begin(115200);
11+
Serial.println("Qwiic OTOS Example 3 - Calibration");
12+
13+
Wire.begin();
14+
15+
// Attempt to begin the sensor
16+
while (myOtos.begin() == false)
17+
{
18+
Serial.println("OTOS not connected, check your wiring and I2C address!");
19+
delay(1000);
20+
}
21+
22+
Serial.println("OTOS connected!");
23+
24+
// The IMU on the OTOS includes a gyroscope and accelerometer, which could
25+
// have an offset. The OTOS performs a quick calibration when it powers up,
26+
// but it is recommended to perform a more thorough calibration at the start
27+
// of your programs. Note that the sensor must be completely stationary and
28+
// flat during calibration! When calling calibrateImu(), you can specify the
29+
// number of samples to take and whether to wait until the calibration is
30+
// complete. If no parameters are provided, it will take 255 samples and
31+
// wait until done; each sample takes about 1.2ms, so about 306ms total
32+
myOtos.calibrateImu();
33+
// myOtos.calibrateImu(255, true);
34+
35+
// Here we can set the linear and angular scalars, which can compensate for
36+
// scaling issues with the sensor measurements. Note that as of firmware
37+
// version 1.0, these values will be lost after a power cycle, so you will
38+
// need to set them each time you power up the sensor. They can be any value
39+
// from 0.872 to 1.127 in increments of 0.001 (0.1%). It is recommended to
40+
// first set both scalars to 1.0, then calibrate the angular scalar, then
41+
// the linear scalar. To calibrate the angular scalar, spin the robot by
42+
// multiple rotations (eg. 10) to get a precise error, then set the scalar
43+
// to the inverse of the error. Remember that the angle wraps from -180 to
44+
// 180 degrees, so for example, if after 10 rotations counterclockwise
45+
// (positive rotation), the sensor reports -15 degrees, the required scalar
46+
// would be 3600/3585 = 1.004. To calibrate the linear scalar, move the
47+
// robot a known distance and measure the error; do this multiple times at
48+
// multiple speeds to get an average, then set the linear scalar to the
49+
// inverse of the error. For example, if you move the robot 100 inches and
50+
// the sensor reports 103 inches, set the linear scalar to 100/103 = 0.971
51+
myOtos.setLinearScalar(1.0);
52+
myOtos.setAngularScalar(1.0);
53+
54+
// Reset the tracking algorithm, making the sensor report it's at the origin
55+
myOtos.resetTracking();
56+
}
57+
58+
void loop()
59+
{
60+
// Get the latest sensor pose, which includes the x and y coordinates, plus
61+
// the heading angle
62+
otos_pose2d_t otosPose;
63+
myOtos.getPosition(otosPose);
64+
65+
// Print measurement
66+
Serial.println();
67+
Serial.println("Sensor pose:");
68+
Serial.print("X (Inches): ");
69+
Serial.println(otosPose.x);
70+
Serial.print("Y (Inches): ");
71+
Serial.println(otosPose.y);
72+
Serial.print("Heading (Degrees): ");
73+
Serial.println(otosPose.h);
74+
75+
// Wait a bit so we don't spam the serial port
76+
delay(500);
77+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "SparkFun_Qwiic_OTOS_Arduino_Library.h"
2+
#include "Wire.h"
3+
4+
// Create an Optical Tracking Odometry Sensor object
5+
QwiicOTOS myOtos;
6+
7+
void setup()
8+
{
9+
// Start serial
10+
Serial.begin(115200);
11+
Serial.println("Qwiic OTOS Example 4 - Set Offset and Position");
12+
13+
Wire.begin();
14+
15+
// Attempt to begin the sensor
16+
while (myOtos.begin() == false)
17+
{
18+
Serial.println("OTOS not connected, check your wiring and I2C address!");
19+
delay(1000);
20+
}
21+
22+
Serial.println("OTOS connected!");
23+
24+
// Here you can set the offset for the sensor relative to the center of the
25+
// robot. The units default to inches and degrees, but if you want to use
26+
// different units, specify them before setting the offset! For example, if
27+
// the sensor is mounted 5 inches to the left (negative X) and 10 inches
28+
// forward (positive Y) of the center of the robot, and mounted 90 degrees
29+
// clockwise (negative rotation) from the robot's orientation, the offset
30+
// would be {-5, 10, -90}. These can be any value, even the angle can be
31+
// tweaked slightly to compensate for imperfect mounting (eg. 1.3 degrees).
32+
otos_pose2d_t offset = {-5, 10, -90};
33+
myOtos.setOffset(offset);
34+
35+
// Reset the tracking algorithm, making the sensor report it's at the origin
36+
myOtos.resetTracking();
37+
38+
// The OTOS sensor itself does not know about the offset defined above, it
39+
// only tracks its own location; the offset is applied by the library when
40+
// getPosition() is called. After resetting the tracking, the sensor will
41+
// report that it's at the origin, but getPosition() will return the inverse
42+
// of the offset pose. This can be resolved by calling setPosition(), which
43+
// take into account the offset and set the sensor's location accordingly.
44+
// Here we set the location to the origin, but any location is valid within
45+
// the sensor's tracking range.
46+
otos_pose2d_t newPose = {0, 0, 0};
47+
myOtos.setPosition(newPose);
48+
}
49+
50+
void loop()
51+
{
52+
// Get the latest robot pose, which includes the x and y coordinates, plus
53+
// the heading angle
54+
otos_pose2d_t robotPose;
55+
myOtos.getPosition(robotPose);
56+
57+
// Print measurement
58+
Serial.println();
59+
Serial.println("Robot pose:");
60+
Serial.print("X (Inches): ");
61+
Serial.println(robotPose.x);
62+
Serial.print("Y (Inches): ");
63+
Serial.println(robotPose.y);
64+
Serial.print("Heading (Degrees): ");
65+
Serial.println(robotPose.h);
66+
67+
// Wait a bit so we don't spam the serial port
68+
delay(500);
69+
}

0 commit comments

Comments
 (0)