4#include "TinyRobotics/motors/Motors.h"
7namespace tinyrobotics {
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
34template <size_t N = 4,
typename T=
float,
typename MotorMT =
BrushedMotor<T>>
37 CarDifferential() : speed_(0), turn_(0) {}
40
41
42
43 void setPins(
int motor,
int in1,
int in2) {
44 if (motor >= 0 && motor < 4) {
45 motors_[motor].setPins(in1, in2);
46 motors_[motor].setID((uint8_t)motor);
51
52
53
55 speed_ = constrain(percent *
Vehicle<T>::getSpeedFactor(), -100, 100);
60
61
62
64 float percent = map(angle, -45.0f, 45.0f, -100.0f, 100.0f);
65 turn_ = constrain(percent, -100.0f, 100.0f);
69 void setSteeringAngle(
Angle angle) {
70 setSteeringAngle(
static_cast<
int>(angle.getValue(
AngleUnit::DEG)));
74
75
80 for (
int i = 0; i < 4; ++i) {
86
87
88
89
90
92 if (motor >= 0 && motor < 4) {
93 motorGain_[motor] = gain;
98 for (
int i = 0; i < 4; ++i) {
99 if (!motors_[i].isPinsSet())
return false;
105 switch (msg.content) {
106 case MessageContent::Throttle:
107 if (msg.unit != Unit::Percent)
return false;
108 setSpeed(
static_cast<
int>(msg.value));
110 case MessageContent::SteeringAngle:
111 float angle = msg.value;
112 if (!toAngleDegree(angle, msg.unit, angle))
114 this->setSteeringAgle(angle);
116 case MessageContent::Obstacle:
117 Vehicle<T>::setSpeedFactor(0);
124 std::vector<MessageContent> getControls()
const override {
125 return {MessageContent::Throttle, MessageContent::SteeringAngle};
128 MotorMT& getMotor(size_t index) {
return motors_[index % N]; }
130 std::vector<IMotor<T>*> getMotors()
override {
131 std::vector<IMotor<T>*> motors;
132 for (
int i = 0; i < N; ++i) {
133 motors.push_back(&motors_[i]);
140 float motorGain_[N] = {1.0f, 1.0f, 1.0f, 1.0f};
144
145
146
147
148
149
150
151
152
153
155 int left = speed_ - turn_;
156 int right = speed_ + turn_;
158 for (
int i = 0; i < 4; ++i) {
159 speed[i] = (i % 2 == 0) ? left * motorGain_[i] : right * motorGain_[i];
160 speed[i] = constrain(speed[i], -100, 100);
164 for (
int i = 0; i < 4; ++i) {
165 motors_[i].setSpeedPercent(speed[i]);
169 for (
int i = 0; i < 4; ++i) {
170 Message<
float> msg(MessageContent::MotorSpeed, speed[i], Unit::Percent);
171 msg.origin = MessageOrigin::Vehicle;
173 Vehicle<T>::sendMessage(msg);
Represents an angle with unit conversion and wrap-around support.
Definition: Angle.h:42
High-level H-Bridge motor driver class for bidirectional DC motor control.
Definition: BrushedMotor.h:36
Car model with differential drive. The direction is controlled by adjusting the speed of the motors....
Definition: CarDifferential.h:35
void setSpeed(float percent)
Set forward/reverse speed for all motors (percent, -100 to 100). Positive = forward,...
Definition: CarDifferential.h:54
void setMotorGain(int motor, float gain)
Set a calibration gain for a specific motor (default 1.0).
Definition: CarDifferential.h:91
void end() override
Stop all motors and reset speed and turn state.
Definition: CarDifferential.h:76
void setSteeringAgle(float angle)
Set turn (percent, -100 to 100). Positive = right, negative = left. This slows down the motors on one...
Definition: CarDifferential.h:63
void updateMotors()
Update all motors based on speed and turn.
Definition: CarDifferential.h:154
bool isPinsSet() const
Check if the necessary pins for the vehicle's actuators have been set (pure virtual).
Definition: CarDifferential.h:97
bool onMessage(const Message< float > &msg) override
Handle an incoming message (pure virtual).
Definition: CarDifferential.h:104
void setPins(int motor, int in1, int in2)
Set the pins for a specific motor (0=front left, 1=front right, 2=rear left, 3=rear right)
Definition: CarDifferential.h:43
Abstract base class for all vehicle types.
Definition: Vehicle.h:26
AngleUnit
Supported angle units for conversion and representation.
Definition: Angle.h:11
Generic message structure for communication, parameterized by value type.
Definition: Message.h:72