TinyRobotics
Loading...
Searching...
No Matches
Odometry3D.h
1#pragma once
2#include <cmath>
3#include <vector>
4
5#include "Arduino.h" // for millis()
6#include "TinyRobotics/coordinates/Coordinate.h"
7#include "TinyRobotics/coordinates/Orientation3D.h"
8#include "TinyRobotics/units/Units.h"
9#include "TinyRobotics/odometry/IOdometryModel3D.h"
10
11namespace tinyrobotics {
12
13/**
14 * @class Odometry3D
15 * @ingroup odometry
16 * @brief Tracks 3D position and orientation of a robot using velocity and
17 * angular rates.
18 *
19 * This class provides simple 3D odometry for mobile robots, such as drones or
20 * underwater vehicles. It integrates linear velocity and angular velocity over
21 * time to estimate the robot's position (x, y, z) and orientation (yaw, pitch,
22 * roll) in meters and radians.
23 *
24 * ## Inputs
25 * - Linear velocity (vx, vy, vz) in m/s (robot frame)
26 * - Angular velocity (wx, wy, wz) in rad/s (robot frame)
27 * - Time delta (in milliseconds, or uses millis() if not provided)
28 *
29 * ## Outputs
30 * - 3D position (x, y, z) in meters
31 * - 3D orientation (yaw, pitch, roll) in radians
32 *
33 * ## Limitations
34 * - Assumes no slip or drift
35 * - Subject to integration drift over time
36 *
37 * @author TinyRobotics contributors
38 * @date 2026-03-31
39 */
40
41class Odometry3D {
42public:
43 Odometry3D(MessageSource& vehicle, IOdometryModel3D& model)
44 : vehicle(vehicle), model(model) {
45 vehicle.subscribe(model); // Subscribe to model messages if needed
46 model.registerCallback([](void* userData) {
47 Odometry3D* odometry = static_cast<Odometry3D*>(userData);
48 odometry->update();
49 }, this);
50 }
51
52 /**
53 * @brief Initialize the odometry state.
54 * @param initialPosition The starting position (x, y, z) in meters.
55 * @param initialOrientation The starting orientation (yaw, pitch, roll) in
56 * radians.
57 * @return true on success
58 */
59 bool begin(Coordinate<float> initialPosition = {0, 0, 0},
60 Orientation3D initialOrientation = Orientation3D()) {
61 position = initialPosition;
62 orientation = initialOrientation;
63 totalDistance = 0.0f;
64 lastUpdateTimeMs = 0;
65 return true;
66 }
67
68 /**
69 * @brief Update the odometry state with new velocities and angular rates.
70 */
71 void update() {
72 uint32_t now = millis();
73 uint32_t deltaTimeMs = now - lastUpdateTimeMs;
74 if (lastUpdateTimeMs > 0) {
75 float vx, vy, vz, wx, wy, wz;
76 model.getLinearVelocity(vx, vy, vz);
77 model.getAngularVelocity(wx, wy, wz);
78 float dt = static_cast<float>(deltaTimeMs) / 1000.0f;
79 // Integrate orientation (Euler angles, simple integration)
80 orientation.roll += wx * dt;
81 orientation.pitch += wy * dt;
82 orientation.yaw += wz * dt;
83 orientation.wrap();
84 // Rotate velocity to world frame (using current orientation)
85 float cr = std::cos(orientation.roll), sr = std::sin(orientation.roll);
86 float cp = std::cos(orientation.pitch), sp = std::sin(orientation.pitch);
87 float cy = std::cos(orientation.yaw), sy = std::sin(orientation.yaw);
88 // Rotation matrix (ZYX convention)
89 float vx_world = cy * cp * vx + (cy * sp * sr - sy * cr) * vy +
90 (cy * sp * cr + sy * sr) * vz;
91 float vy_world = sy * cp * vx + (sy * sp * sr + cy * cr) * vy +
92 (sy * sp * cr - cy * sr) * vz;
93 float vz_world = -sp * vx + cp * sr * vy + cp * cr * vz;
94 // Integrate velocity for position
95 float dx = vx_world * dt;
96 float dy = vy_world * dt;
97 float dz = vz_world * dt;
98 position.x += dx;
99 position.y += dy;
100 position.z += dz;
101 totalDistance += std::sqrt(dx * dx + dy * dy + dz * dz);
102 lastDelta = Distance3D(dx, dy, dz, DistanceUnit::M);
103 }
104 lastUpdateTimeMs = now;
105 }
106
107
108 // Remove all parameterized update methods for clarity and consistency
109
110 /// @brief Get the current 3D position (meters)
111 Coordinate<float> getPosition() const { return position; }
112 /// @brief Get the current orientation as Orientation3D (yaw, pitch, roll in
113 /// radians)
114 Orientation3D getOrientation() const { return orientation; }
115 /// @brief Get the total distance traveled
116 Distance getTotalDistance() const {
117 return Distance(totalDistance, DistanceUnit::M);
118 }
119 /// @brief Get the last delta update (dx, dy, dz)
120 Distance3D getLastDelta() const { return lastDelta; }
121
122protected:
123 MessageSource& vehicle;
124 IOdometryModel3D& model;
125 Coordinate<float> position;
126 Orientation3D orientation;
127 float totalDistance = 0.0f;
128 Distance3D lastDelta = Distance3D(0.0f, 0.0f, 0.0f, DistanceUnit::M);
129 uint32_t lastUpdateTimeMs = 0;
130};
131
132} // namespace tinyrobotics
A generic 3D coordinate class for robotics, navigation, and spatial calculations.
Definition: Coordinate.h:57
Represents a 3D distance or position vector with unit support.
Definition: Distance.h:164
Represents a distance measurement with unit conversion support.
Definition: Distance.h:40
Abstract interface for 3D odometry models. Provides access to current linear and angular velocities f...
Definition: IOdometryModel3D.h:14
virtual void getAngularVelocity(float &wx, float &wy, float &wz) const =0
Get the current angular velocity (wx, wy, wz) in rad/s (robot frame).
virtual void getLinearVelocity(float &vx, float &vy, float &vz) const =0
Get the current linear velocity (vx, vy, vz) in m/s (robot frame).
virtual void registerCallback(void(*callback)(void *), void *userData)
Register a callback to be invoked on relevant events (e.g., input change, update).
Definition: IOdometryModel3D.h:22
Tracks 3D position and orientation of a robot using velocity and angular rates.
Definition: Odometry3D.h:41
bool begin(Coordinate< float > initialPosition={0, 0, 0}, Orientation3D initialOrientation=Orientation3D())
Initialize the odometry state.
Definition: Odometry3D.h:59
Distance3D getLastDelta() const
Get the last delta update (dx, dy, dz)
Definition: Odometry3D.h:120
Coordinate< float > getPosition() const
Get the current 3D position (meters)
Definition: Odometry3D.h:111
Orientation3D getOrientation() const
Get the current orientation as Orientation3D (yaw, pitch, roll in radians)
Definition: Odometry3D.h:114
Distance getTotalDistance() const
Get the total distance traveled.
Definition: Odometry3D.h:116
void update()
Update the odometry state with new velocities and angular rates.
Definition: Odometry3D.h:71
Simple 3D orientation class (yaw, pitch, roll in radians)
Definition: Orientation3D.h:13
float roll
Roll angle (radians)
Definition: Orientation3D.h:22
float pitch
Pitch angle (radians)
Definition: Orientation3D.h:21
float yaw
Yaw angle (radians)
Definition: Orientation3D.h:20
DistanceUnit
Supported distance units for conversion and representation.
Definition: Distance.h:10