TinyRobotics
Loading...
Searching...
No Matches
OdometryDifferentialDriveModel.h
1#pragma once
2#include <cmath>
3
4#include "ISpeedSource.h"
5#include "TinyRobotics/communication/Message.h"
6#include "TinyRobotics/odometry/IOdometryModel2D.h"
7#include "TinyRobotics/units/Units.h"
8#include "stdint.h"
9
10namespace tinyrobotics {
11
12/**
13 * @class OdometryDifferentialDriveModel
14 * @ingroup odometry
15 * @brief Odometry model for differential drive robots.
16 *
17 * Computes heading change (deltaTheta) using left and right wheel speeds.
18 */
20 public:
21 OdometryDifferentialDriveModel(Distance wheelBase) : wheelBase(wheelBase) {}
22
23 virtual void updateSpeed(uint32_t deltaTimeMs) {
24 leftSpeed = p_speedSource->updateSpeed(deltaTimeMs, 0);
25 rightSpeed = p_speedSource->updateSpeed(deltaTimeMs, 1);
26 }
27
28 /**
29 * @brief Compute heading change (deltaTheta) for differential drive.
30 * @param deltaTimeMs Time interval (milliseconds)
31 * @return Change in heading (radians)
32 */
33 float computeDeltaTheta(uint16_t deltaTimeMs) const override {
34 float wb = wheelBase.getValue(DistanceUnit::M);
35 float vLeft = leftSpeed.getValue(SpeedUnit::MPS);
36 float vRight = rightSpeed.getValue(SpeedUnit::MPS);
37 float omega = (vRight - vLeft) / wb;
38 return omega * static_cast<float>(deltaTimeMs) / 1000.0f;
39 }
40
41 void computeDeltaXY(float theta, uint32_t deltaTimeMs, float& deltaX,
42 float& deltaY) const override {
43 // Differential drive: use average wheel speed for linear velocity
44 float vLeft = leftSpeed.getValue(SpeedUnit::MPS);
45 float vRight = rightSpeed.getValue(SpeedUnit::MPS);
46 float v = 0.5f * (vLeft + vRight);
47 float dt = deltaTimeMs / 1000.0f;
48 deltaX = v * std::cos(theta) * dt;
49 deltaY = v * std::sin(theta) * dt;
50 }
51 bool onMessage(const Message<float>& msg) {
52 if (msg.origin != MessageOrigin::Vehicle &&
53 msg.origin != MessageOrigin::Motor)
54 return false;
55 //  update speed and steering angle from messages
56 switch (msg.content) {
57 case MessageContent::SteeringAngle:
58 if (msg.unit != Unit::AngleRadian) return false;
59 steeringAngle = Angle(msg.value, AngleUnit::RAD);
60 return true;
61 case MessageContent::MotorSpeed:
62 if (msg.unit != Unit::Percent) return false;
63 // differential motor with left = 0 and right = 1
64 switch (msg.origin_id) {
65 case 0:
66 p_speedSource->setThrottlePercent(msg.value, 0);
67 leftSpeed = p_speedSource->getSpeed(0);
68 break;
69 case 1:
70 p_speedSource->setThrottlePercent(msg.value, 1);
71 rightSpeed = p_speedSource->getSpeed(1);
72 if (callback) {
73 callback(userData);
74 }
75 break;
76 default:
77 // ignore other motors
78 break;
79 }
80 return true;
81 default:
82 return false; // Unhandled message content
83 }
84 }
85
86 void setCallback(void (*callback)(void*), void* userData) {
87 this->callback = callback;
88 this->userData = userData;
89 }
90
91 void setSpeedSource(ISpeedSource& speedSource) {
92 p_speedSource = &speedSource;
93 }
94
95 Speed getSpeed() const override { return (leftSpeed + rightSpeed) / 2; }
96 Angle getSteeringAngle() const override { return steeringAngle; }
97
98 private:
99 Distance wheelBase;
100 ISpeedSource* p_speedSource = nullptr;
101 Speed leftSpeed;
102 Speed rightSpeed;
103 Angle steeringAngle;
104 void (*callback)(void*) = nullptr;
105 void* userData = nullptr;
106};
107
108} // namespace tinyrobotics
Represents an angle with unit conversion and wrap-around support.
Definition: Angle.h:42
Represents a distance measurement with unit conversion support.
Definition: Distance.h:40
Abstract interface for 2D odometry models.
Definition: IOdometryModel2D.h:9
Interface for speed sources.
Definition: ISpeedSource.h:9
Odometry model for differential drive robots.
Definition: OdometryDifferentialDriveModel.h:19
void computeDeltaXY(float theta, uint32_t deltaTimeMs, float &deltaX, float &deltaY) const override
Compute position change (deltaX, deltaY) for odometry kinematics.
Definition: OdometryDifferentialDriveModel.h:41
Speed getSpeed() const override
Get the current speed of the vehicle.
Definition: OdometryDifferentialDriveModel.h:95
bool onMessage(const Message< float > &msg)
Handle an incoming message (pure virtual).
Definition: OdometryDifferentialDriveModel.h:51
void setSpeedSource(ISpeedSource &speedSource)
Set the speed source (e.g., encoder, estimator) for this model.
Definition: OdometryDifferentialDriveModel.h:91
float computeDeltaTheta(uint16_t deltaTimeMs) const override
Compute heading change (deltaTheta) for differential drive.
Definition: OdometryDifferentialDriveModel.h:33
Angle getSteeringAngle() const override
Get the current steering angle of the vehicle.
Definition: OdometryDifferentialDriveModel.h:96
virtual void updateSpeed(uint32_t deltaTimeMs)
Update the speed estimate based on elapsed time.
Definition: OdometryDifferentialDriveModel.h:23
Represents a speed measurement with unit conversion support.
Definition: Speed.h:40
DistanceUnit
Supported distance units for conversion and representation.
Definition: Distance.h:10
SpeedUnit
Supported speed units for conversion and representation.
Definition: Speed.h:10
Generic message structure for communication, parameterized by value type.
Definition: Message.h:72