TinyRobotics
Loading...
Searching...
No Matches
GenericMotor.h
1#pragma once
2#include "IMotor.h"
3#include "stdint.h"
4#include "assert.h"
5
6namespace tinyrobotics {
7
8/**
9 * @class GenericMotor
10 * @ingroup motors
11 * @brief Motor abstraction for integrating external/custom motor drivers using
12 * callbacks.
13 *
14 * This class provides a flexible interface for controlling motors that do not
15 * fit the standard interface. The user supplies an external motor object (as a
16 * void pointer) and callback functions for starting/stopping the motor and for
17 * setting the speed or angle. This allows integration of custom motor drivers
18 * or hardware with the TinyRobotics framework.
19 *
20 * - The @c valueCB callback is mandatory and is called with the desired speed
21 * or angle value.
22 * - The @c beginCB and @c endCB callbacks are optional and can be used to
23 * define custom start/stop logic.
24 * - The user motor object can be accessed via @c getMotor<T>().
25 *
26 * Example usage:
27 * @code
28 * MyMotorDriver driver;
29 * GenericMotor motor(0, &driver);
30 * motor.setValueCallback([](int8_t value, GenericMotor& m) {
31 * MyMotorDriver* drv = m.getMotor<MyMotorDriver>();
32 * drv->setPWM(value);
33 * });
34 * motor.setBeginCallback([](GenericMotor& m) {
35 * // Custom start logic
36 * return true;
37 * });
38 * motor.setEndCallback([](GenericMotor& m) {
39 * // Custom stop logic
40 * });
41 * @endcode
42 */
43
44template <typename T = float>
45class GenericMotor : public IMotor<T> {
46 public:
47 GenericMotor() = default;
48 GenericMotor(uint8_t id, void* driver = nullptr) {
49 this->setID(id);
50 this->driver = driver;
51 }
52
53 /// Start the motor using the optional begin callback
54 bool begin() override {
55 if (valueCB == nullptr) {
56 return false; // Callbacks not defined, cannot start
57 }
58 bool result = true;
59 // Call optional callback to start the motor
60 if (beginCB) result = beginCB(*this);
61 return result;
62 }
63
64 /// Set value as percentage (-100 to 100)
65 bool setValuePercent(T percent) override {
66 value = constrain(percent, -100.0f, 100.0f);
67 if (valueCB) {
68 valueCB(percent, *this);
69 }
70 return true;
71 }
72
73 /// Get current value percentage
74 T getValuePercent() const override { return value; }
75
76 /// For Servo: Set angle in degrees (-90 to 90) by mapping it to percentage
77 void setAngle(T angle) {
78 float valuePercent =
79 map(angle, -90.0f, 90.0f, -100.0f, 100.0f); // Map angle to percentage
81 valuePercent); // For simplicity, treat angle as a percentage value
82 }
83
84 /// For Servo: Get angle in degrees by mapping percentage back to angle
85 T getAngle() {
86 return map(value, -100.0f, 100.0f, -90.0f,
87 90.0f); // Map percentage back to angle
88 }
89
90 /// Stop the motor using the optional end callback
91 void end() override {
92 if (endCB) {
93 endCB(*this); // Call callback to stop the motor
94 }
95 }
96
97 /// Mandatory callback to define speed/angle control behavior
98 void setValueCallback(void (*valueCB)(T value, GenericMotor& motor)) {
99 this->valueCB = valueCB;
100 }
101
102 /// Optional callback to define begin behavior
103 void setBeginCallback(bool (*beginCB)(GenericMotor& motor)) {
104 this->beginCB = beginCB;
105 }
106
107 /// Optional callback to define end behavior
108 void setEndCallback(void (*endCB)(GenericMotor& motor)) {
109 this->endCB = endCB;
110 }
111
112 /// Provides the user motor object
113 template <typename DriverT>
114 DriverT& getDriver() {
115 assert(driver != nullptr);
116 return *static_cast<DriverT*>(driver);
117 }
118
119 /// Not supported
120 bool isPinsSet() const override { return true; }
121 /// Not supported
122 void setPin(int pin) { notSupported("setPin"); }
123 /// Not supported
124 void setPins(int, int, int na = -1) { notSupported("setPins"); }
125
126 protected:
127 void* driver = nullptr; // Optional pointer to user motor object for callbacks
128 T value = 0.0f; // Current value percentage
129 bool (*beginCB)(GenericMotor& motor) = nullptr;
130 void (*endCB)(GenericMotor& motor) = defaultEnd;
131 void (*valueCB)(T value, GenericMotor& motor) =
132 nullptr; // Callback function pointer for speed/angle control
133
134 /// Default logic for end processing: just stop the motor!
135 static void defaultEnd(GenericMotor& motor) {
136 motor.setValuePercent(
137 0); // Default behavior: stop the motor by setting speed to 0
138 }
139
140 /// Log an error for unsupported methods
141 void notSupported(const char* method) {
142 TRLogger.error("'%s' is not supported for GenericMotor", method);
143 }
144};
145
146} // namespace tinyrobotics
Motor abstraction for integrating external/custom motor drivers using callbacks.
Definition: GenericMotor.h:45
void setAngle(T angle)
For Servo: Set angle in degrees (-90 to 90) by mapping it to percentage.
Definition: GenericMotor.h:77
void setPins(int, int, int na=-1)
Not supported.
Definition: GenericMotor.h:124
void setPin(int pin)
Not supported.
Definition: GenericMotor.h:122
bool setValuePercent(T percent) override
Set value as percentage (-100 to 100)
Definition: GenericMotor.h:65
void setBeginCallback(bool(*beginCB)(GenericMotor &motor))
Optional callback to define begin behavior.
Definition: GenericMotor.h:103
void setValueCallback(void(*valueCB)(T value, GenericMotor &motor))
Mandatory callback to define speed/angle control behavior.
Definition: GenericMotor.h:98
void notSupported(const char *method)
Log an error for unsupported methods.
Definition: GenericMotor.h:141
void end() override
Stop the motor using the optional end callback.
Definition: GenericMotor.h:91
static void defaultEnd(GenericMotor &motor)
Default logic for end processing: just stop the motor!
Definition: GenericMotor.h:135
bool isPinsSet() const override
Not supported.
Definition: GenericMotor.h:120
T getAngle()
For Servo: Get angle in degrees by mapping percentage back to angle.
Definition: GenericMotor.h:85
bool begin() override
Start the motor using the optional begin callback.
Definition: GenericMotor.h:54
void setEndCallback(void(*endCB)(GenericMotor &motor))
Optional callback to define end behavior.
Definition: GenericMotor.h:108
T getValuePercent() const override
Get current value percentage.
Definition: GenericMotor.h:74
DriverT & getDriver()
Provides the user motor object.
Definition: GenericMotor.h:114
Abstract base class for all motor driver types.
Definition: IMotor.h:21