IMU and GPS¶
This section describes the functions for using the built-in Inertial Motion Unit (IMU) and the external GPS sensor.
Inertial Motion Unit (IMU)¶
RoverWing contains a built-in Inertial Motion Unit (IMU), which is based on ICM42605 chip from Invensense. This chip combines a 3-axis accelerometer and a 3-axis gyro sensor, which provide information about acceleration and rotational speed. RoverWing firmware combines the sensor data to provide information about rover orientation in space, in the form of Yaw, Pitch, and Roll angles. (RoverWing’s firmware is based on the work of Kris Winer and uses data fusion algorithm invented by Sebastian Madgwick.)
Note
Current version of RoverWing firmware requires that the RoverWing be mounted horizontally.
Below is the description of functions related to IMU. You can also check sample code in IMU example sketch included with RoverWing library.
Initialization¶
By default, the IMU is inactive. To start/stop it, use the functions below.
-
void
IMUbegin
()¶ Activate IMU
-
void
IMUend
()¶ Stop the IMU
-
bool
IMUisActive
()¶ Returns true if IMU is active. This function can be used to verify that IMU activation was successful.
Calibration¶
Before use, the IMU needs to be calibrated. The calibration process determines and then applies corrections (offsets) to the raw data; without these corrections, the data returned by the sensor is very inaccurate.
If you haven’t calibrated the sensor before (or want to recalibrate it), use the following function:
-
void
IMUcalibrate
()¶ This function will determine and apply the corrections; it will also save these corrections in the flash storage of the RoverWing microcontroller, where they will be stored for future use. This data is preserved even after you disconnect power from your RoverWing board (much like the usual USB flash drive).
This function will take about 10 seconds to execute; during this time, the robot must be completely stationary on a flat horizontal surface.
If you had previously calibrated the sensor, you do not need to repeat the calibration process - by default, upon initialization the IMU loads previously saved calibration values.
Note that the IMU is somewhat sensitive to temperature changes, so if the temperature changes (e.g., you moved your robot from indoors to the street for testing), it is advised that you recalibrate the IMU.
Reading Values¶
RoverWing allows you to read both the raw data (accelerometer and gyro readings) and computed orientation, using the following functions:
-
void
getAccel
()¶ Fetches from the RoverWing raw acceleration data and saves it using member variables
ax
,ay
,az
, which give the acceleration in x-, y-, and z- directions respectively in in units of 1g (9.81 m/) as floats.
-
void
getGyro
()¶ Fetches from the RoverWing raw gyro data and saves it using member variables
gx
,gy
,gz
, which give the angular rotation velocity around x-, y-, and z- axes respectively, in degree/s (as floats).
-
float
getYaw
()¶
-
float
getPitch
()¶
-
float
getRoll
()¶ These functions return yaw, pitch, and roll angles for the robot. These three angles describe the robot orientation as described below (this assumes that RoverWing is mounted horizontally on the robot, with power supply connector facing the back of the robot and the USB port on the right).
- yaw is the rotation around the vertical axis (positive angle corresponds to clockwise rotation, i.e. right turns), relative to the starting position of the robot
- pitch is the rotation around the horizontal line, running from left to right. Positive pitch angle corresponds to raising the front of the robot and lowering the back
- roll is the rotation around the horizontal line running from front to back. Positive roll angle corresponds to raising the left side of the robot and lowering the right.
For more information about yaw, pitch, and roll angles, please visit https://en.wikipedia.org/wiki/Aircraft_principal_axes
-
void
getOrientationQuat
()¶ - Gets robot orientation as a unit quaternion (see https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation). The result can be accessed using member variable
float quat[4]
, which contains the four components of the quaternion:q=quat[0]+i*quat[1]+j*quat[2]+k*quat[3]
GPS¶
If you have connected a GPS sensor to RoverWing as described in RoverWing User Guide, you can use the functions below to access it.
Initialization¶
-
void
GPSbegin
()¶ Start the GPS. Note that after starting, it can take the sensor a while to get GPS location fix: the time ranges from several seconds if the sensor had recently been used in a nearby location to several minutes if the sensor has been moved to a completely new location.
-
void
GPSend
()¶ Stops the GPS sensor.
-
uint8_t
GPSstatus
()¶ Gets current GPS status. Possible values are
GPS_OFF
: GPS is inactiveGPS_OK
: GPS is active and has a valid location fixGPS_WAITING
: GPS is active, but is waiting to receive a location fix. The sensor switches to this status if it hasn’t received a valid GPS signal for more than 3 seconds.
Usage¶
After the GPS has been initialized and received location fix, you can use the following functions to access the GPS coordinates.
-
void
getGPSlocation
()¶ Gets from RoverWing and saves the latest GPS location data, which can later be accessed using the functions below.
-
double
latitude
()¶
-
double
longitude
()¶ Return the robot latitude and longitude in degrees, following the usual conventions: latitude ranges from -90 (South Pole) to 90 (North Pole); longitude ranges from -180 (west of Greenwich) to 180 (east of Greenwich). Note that these coordinates refer to the location fetched at last call of
getGPSlocation()
.
-
int32_t
latitudeL
()¶
-
int32_t
longitudeL
()¶ Return longitude and latitude of the robot, in units of degree (about 10 cm).
-
uint32_t
GPStimestamp
()¶ Returns time when the last GPS location fix was received, in milliseconds since reboot of the RoverWing board.
Location Data¶
RoverWing library provides a type for storing GPS location and timestamp. It is
defined in RoverWing.h
as follows:
struct location_t {
int32_t latitude; //latitude, in units of 10^{-7} degree
int32_t longitude;
uint32_t timestamp; //in ms, as reported by millis()
};
The functions below provide some tools for working with location data:
-
void
saveGPSlocation
(location_t & loc)¶ Saves current robot location to variable
loc
ot typelocation_t
.
-
float
distanceTo
(const location_t & loc)¶ Returns distance from current robot location to location
loc
, in meters.
-
float
bearingTo
(const location_t & loc)¶ Returns bearing from current robot location to
loc
. The bearing is measured in degrees and ranges from -180 to 180, with North being 0.
Note
Functions distanceTo()
, bearingTo()
use flat map model. The
results are accurate enough for distances up to 10 km, but if you want to
find the distance between your robot and Mount Everest, you need to write
your own code or google for existing solutions (unless you are within 10
km of Mount Everest).