TinyRobotics
Loading...
Searching...
No Matches
ServoMotor.h
1#pragma once
2#include <Arduino.h>
3#ifdef ESP32
4#include <ESP32Servo.h>
5#else
6#include <Servo.h>
7#endif
8
9#include "IMotor.h"
10
11namespace tinyrobotics {
12
13/**
14 * @class ServoMotor
15 * @ingroup motors
16 * @brief High-level wrapper for Arduino Servo control (RC servo motors).
17 *
18 * This class provides an easy interface for controlling standard RC servo
19 * motors using the Arduino Servo library. It allows you to:
20 * - Attach/detach a servo to a digital pin
21 * - Set the servo angle in degrees (using ROS right-handed convention: 0 is
22 * forward, +left, -right)
23 * - Set the servo position by pulse width (microseconds)
24 * - Read back the last set angle (in degrees)
25 * - Constrain the allowed angle range for safety or mechanical limits
26 *
27 * Usage Example:
28 * @code
29 * ServoMotor servo;
30 * servo.attach(9); // Attach to pin 9
31 * servo.setConstraints(-45, 45); // Limit range to -45..45 degrees
32 * servo.setAngle(45); // Set to 45 degrees left
33 * int angle = servo.getAngle(); // Read last angle
34 * servo.detach(); // Detach when done
35 * @endcode
36 *
37 * @note Requires the Arduino Servo library.
38 */
39template <typename T = float>
40class ServoMotor : public IMotor<T> {
41 public:
42 ServoMotor(uint8_t id = 0) { this->setID(id); }
43
44 /** Attach the servo to a pin */
45 void setPin(int pin) { this->pin = pin; }
46
47 bool begin() {
48 if (pin == -1) return false;
49 servo.attach(pin);
50 return true;
51 }
52
53 /** Set servo angle (degrees, 90 .. -90): 0 is forward */
54 void setAngle(int8_t rosAngleDegrees) {
55 // potentially constrain the angles
56 if (rosAngleDegrees < minAngle) rosAngleDegrees = minAngle;
57 if (rosAngleDegrees > maxAngle) rosAngleDegrees = maxAngle;
58 int8_t angle = map(rosAngleDegrees, -90, 90, 0, 180);
59 servo.write(constrain(angle, 0, 180));
60 }
61
62 /** Get the last written angle (degrees) */
64 int angle = servo.read();
65 return map(angle, 0, 180, -90, 90);
66 }
67
68 /**
69 * Set servo position as a percentage (-100 to 100).
70 * -100 = minAngle, 0 = center, 100 = maxAngle
71 */
72 bool setValuePercent(T percent) override {
73 lastValuePercent = constrain(percent, -100.0f, 100.0f);
74 // Map percent to angle in allowed range
75 int8_t angle = map(lastValuePercent, -100.0f, 100.0f, minAngle, maxAngle);
76 setAngle(angle);
77 return true;
78 }
79
80 T getValuePercent() const override { return lastValuePercent; }
81
82 /// Set constraints on the allowed angle range (degrees). This can be used to
83 /// prevent the servo from moving beyond physical limits or to limit the range
84 /// of motion for safety: by default, the full range of -90 to 90 degrees is
85 /// allowed.
86 void setConstraints(int minAngle, int maxAngle) {
87 minAngle = max(minAngle, -90);
88 maxAngle = min(maxAngle, 90);
89 }
90
91 void end() override {
92 setAngle(0);
93 servo.detach();
94 }
95
96 bool isPinsSet() const { return is_pin_asssigned; }
97
98 protected:
99 ::Servo servo;
100 int pin = -1;
101 int minAngle = -90;
102 int maxAngle = 90;
103 bool is_pin_asssigned = false;
104 T lastValuePercent = 0.0f;
105};
106
107} // namespace tinyrobotics
Abstract base class for all motor driver types.
Definition: IMotor.h:21
High-level wrapper for Arduino Servo control (RC servo motors).
Definition: ServoMotor.h:40
void setPin(int pin)
Definition: ServoMotor.h:45
bool setValuePercent(T percent) override
Definition: ServoMotor.h:72
int8_t getAngle()
Definition: ServoMotor.h:63
void setConstraints(int minAngle, int maxAngle)
Definition: ServoMotor.h:86
void setAngle(int8_t rosAngleDegrees)
Definition: ServoMotor.h:54