TinyRobotics
Loading...
Searching...
No Matches
CarAckerman.h
1#pragma once
2
3#include "TinyRobotics/motors/Motors.h"
4#include "Vehicle.h"
5
6namespace tinyrobotics {
7
8/**
9 * @class CarAckerman
10 * @ingroup vehicles
11 * @brief Car with Ackerman steering and single drive motor.
12 *
13 * This class abstracts a simple car:
14 * - 1 drive motor (HBridge)
15 * - 1 steering servo (ServoMotor)
16 *
17 * Usage Example:
18 * @code
19 * CarAckerman car;
20 * car.setPins(5, 6, 9); // in1, in2, steeringPin
21 * car.setSpeed(60); // 60% forward
22 * car.setSteering(30); // 30 degrees left
23 * car.end(); // brake
24 * @endcode
25 */
26
27template <typename T=float, typename MotorMT = BrushedMotor<T>,
28 typename ServoMT = ServoMotor<T>>
29class CarAckerman : public Vehicle<T> {
30 public:
31 CarAckerman() = default;
32
33 /**
34 * @brief Set the pins for the drive motor and steering servo.
35 * @param in1 HBridge IN1
36 * @param in2 HBridge IN2
37 * @param pwm HBridge PWM
38 * @param steeringPin Servo pin for steering
39 */
40 void setPins(int in1, int in2, int steeringPin) {
41 motor_.setPins(in1, in2);
42 steering_.setPin(steeringPin);
43 }
44
45 /**
46 * @brief Set drive speed (percent, -100 to 100). Positive = forward.
47 */
48 void setSpeed(float percent) {
49 speed_ = constrain(percent * Vehicle<T>::getSpeedFactor(), -100.0f, 100.0f);
50 motor_.setValuePercent(speed_);
51 // publish speed as message for telemetry
52 Message<float> msg(MessageContent::MotorSpeed, percent, Unit::Percent);
53 msg.origin = MessageOrigin::Vehicle;
54 Vehicle<T>::sendMessage(msg);
55 }
56
57 /**
58 * @brief Set steering angle (degrees, left positive, right negative).
59 */
60 void setSteeringAngle(float angle) {
61 angleDeg_ = angle;
62 steering_.setAngle(angle);
63 // publish steering angle as message for telemetry
64 Message<float> msg(MessageContent::SteeringAngle, angle, Unit::AngleDegree);
65 msg.origin = MessageOrigin::Vehicle;
66 Vehicle<T>::sendMessage(msg);
67 }
68
69 void setSteeringAngle(Angle angle) {
70 setSteeringAngle(static_cast<int>(angle.getValue(AngleUnit::DEG)));
71 }
72
73 Angle getSteeringAngle() const { return Angle(angleDeg_, AngleUnit::DEG); }
74
75 float getSpeed() const { return speed_; }
76
77 /** Stop the car (brake motor) */
78 void end() override {
80 setSteeringAngle(0);
81 // stop all motors
82 for (auto* motor : getMotors()) {
83 if (motor) motor->end();
84 }
85 }
86
87 bool isPinsSet() const { return motor_.isPinsSet() && steering_.isPinsSet(); }
88
89 bool onMessage(const Message<float>& msg) override {
90 float angle;
91 switch (msg.content) {
92 case MessageContent::Throttle:
93 if (msg.unit != Unit::Percent) return false;
94 setSpeed(static_cast<int>(msg.value));
95 return true;
96 case MessageContent::SteeringAngle:
97 angle = msg.value;
98 if (!toAngleDegree(angle, msg.unit, angle))
99 return false; // Invalid unit
100 setSteeringAngle(angle);
101 return true;
102 case MessageContent::Obstacle:
103 Vehicle<T>::setSpeedFactor(0);
104 return true;
105 default:
106 return false; // Unhandled message content
107 }
108 }
109
110 std::vector<MessageContent> getControls() const override {
111 return {MessageContent::Throttle, MessageContent::SteeringAngle};
112 }
113
114 MotorMT& getMotor() { return motor_; }
115 ServoMT& getServo() { return steering_; }
116
117 std::vector<IMotor<T>*> getMotors() override {
118 std::vector<IMotor<T>*> motors;
119 motors.push_back(&motor_);
120 motors.push_back(&steering_);
121 return motors;
122 }
123
124
125 protected:
126 MotorMT motor_;
127 ServoMT steering_;
128 float speed_ = 0;
129 float angleDeg_ = 0;
130};
131
132} // namespace tinyrobotics
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 with Ackerman steering and single drive motor.
Definition: CarAckerman.h:29
void setSpeed(float percent)
Set drive speed (percent, -100 to 100). Positive = forward.
Definition: CarAckerman.h:48
void setSteeringAngle(float angle)
Set steering angle (degrees, left positive, right negative).
Definition: CarAckerman.h:60
void setPins(int in1, int in2, int steeringPin)
Set the pins for the drive motor and steering servo.
Definition: CarAckerman.h:40
void end() override
Definition: CarAckerman.h:78
bool isPinsSet() const
Check if the necessary pins for the vehicle's actuators have been set (pure virtual).
Definition: CarAckerman.h:87
bool onMessage(const Message< float > &msg) override
Handle an incoming message (pure virtual).
Definition: CarAckerman.h:89
High-level wrapper for Arduino Servo control (RC servo motors).
Definition: ServoMotor.h:40
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