-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRBCXManager.h
More file actions
267 lines (217 loc) · 8.35 KB
/
RBCXManager.h
File metadata and controls
267 lines (217 loc) · 8.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#pragma once
// clang-format off
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include "freertos/semphr.h"
// clang-format on
#include <functional>
#include <list>
#include <memory>
#include <mutex>
#include <vector>
#include "RBCXBattery.h"
#include "RBCXButtons.h"
#include "RBCXLeds.h"
#include "RBCXMotor.h"
#include "RBCXMpu.h"
#include "RBCXOled.h"
#include "RBCXPiezo.h"
#include "RBCXStupidServo.h"
#include "RBCXTimers.h"
#include "RBCXUltrasound.h"
#include "RBCXSmartServoBusBackend.h"
#include "RBCXStupidServo.h"
#include "coproc_link_parser.h"
#include "rbcx.pb.h"
namespace rb {
class MotorChangeBuilder;
//! This enum contains flags for the Manager's install() method.
enum ManagerInstallFlags {
MAN_NONE = 0,
//!< Disables automatic motor failsafe, which stops the motors
//!< after 300ms of no set motor power calls.
MAN_DISABLE_MOTOR_FAILSAFE = (1 << 0),
//!< Disables the watchdog on STM32 coprocessor, which resets the
//!< ESP32 and stops all peripherials if ESP32 does not respond in time.
//!< The watchdog is disabled by default, but this library enables it on start
//!< (unless this flag is used) and it stays on through ESP32 restarts.
MAN_DISABLE_ESP_WATCHDOG = (1 << 1),
};
inline ManagerInstallFlags operator|(
ManagerInstallFlags a, ManagerInstallFlags b) {
return static_cast<ManagerInstallFlags>(
static_cast<int>(a) | static_cast<int>(b));
}
// Periodically print info about all RBCX tasks to the console
// #define RB_DEBUG_MONITOR_TASKS 1
/**
* \brief The main library class for working with the RBCX board.
* Call the install() method at the start of your program.
*/
class Manager {
friend class MotorChangeBuilder;
friend class Encoder;
friend class PcntInterruptHandler;
friend class Motor;
public:
Manager(Manager const&) = delete;
void operator=(Manager const&) = delete;
/**
* \brief Get manager instance.
*
* Always returns the same instance and is thread-safe. Don't forget to call install() to initialize
* the manager at the start of your program, when you first get the instance.
*/
static Manager& get() {
static Manager instance;
return instance;
}
/**
* \brief Initialize the manager - must be called once at the start of the program.
*
* \param flags modify the manager's behavior or toggle some features. See @{ManagerInstallFlags} enum.
*/
void install(ManagerInstallFlags flags = MAN_NONE,
BaseType_t managerLoopStackSize = 3072);
/**
* \brief Initialize the UART servo bus for intelligent servos LX-16. TODO: smart servos not implemented!
* \return Instance of the class {@link SmartServoBus} which manage the intelligent servos.
*/
//SmartServoBus& initSmartServoBus(uint8_t servo_count);
/**
* \brief Get the {@link SmartServoBus} for working with intelligent servos LX-16..
* \return Instance of the class {@link SmartServoBus} which manage the intelligent servos.
*/
//SmartServoBus& servoBus() { return m_servos; };
Ultrasound& ultrasound(uint8_t index) { return m_ultrasounds[index]; }
StupidServo& stupidServo(uint8_t index);
Oled& oled() { return m_oled; } //!< Get the {@link Piezo} controller
Mpu& mpu() { return m_mpu; } //!< Get the {@link Piezo} controller
// Pass to Esp32-lx16a library's begin()
SmartServoBusBackend &smartServoBusBackend();
Piezo& piezo() { return m_piezo; } //!< Get the {@link Piezo} controller
Battery& battery() {
return m_battery;
} //!< Get the {@link Battery} interface
Leds& leds() { return m_leds; } //!< Get the {@link Leds} helper
Buttons& buttons() { return m_buttons; }
Motor& motor(MotorId id) {
return m_motors[static_cast<int>(id)];
}; //!< Get a motor instance
MotorChangeBuilder
setMotors(); //!< Create motor power change builder: {@link MotorChangeBuilder}.
/**
* \brief Schedule callback to fire after period (in millisecond).
*
* Return true from the callback to schedule periodically, false to not (singleshot timer).
*
* \param period_ms is period in which will be the schedule callback fired
* \param callback is a function which will be schedule with the set period.
*/
void schedule(uint32_t period_ms, std::function<bool()> callback) {
timers().schedule(period_ms, callback);
}
inline Timers& timers() { return rb::Timers::get(); }
// internal api to monitor RBCX tasks
void monitorTask(TaskHandle_t task);
void sendToCoproc(const CoprocReq& msg);
const CoprocStat_VersionStat& coprocFwVersion() const {
return m_coprocFwVersion;
}
void coprocFwVersionAssert(uint32_t minVersion, const char* name);
bool coprocFwAtLeastVersion(uint32_t minVersion);
private:
Manager();
~Manager();
static void consumerRoutineTrampoline(void* cookie);
void consumerRoutine();
static void keepaliveRoutine(void* cookie);
void resetMotorsFailSafe();
bool motorsFailSafe();
#ifdef RB_DEBUG_MONITOR_TASKS
bool printTasksDebugInfo();
std::vector<TaskHandle_t> m_tasks;
std::mutex m_tasks_mutex;
#endif
void fault(CoprocStat_FaultStat faultStat);
TaskHandle_t m_keepaliveTask;
CoprocCodec m_codec;
uint8_t m_txBuf[CoprocCodec::MaxFrameSize];
std::mutex m_codecTxMutex;
uint16_t m_coprocWatchdogTimer;
CoprocStat_VersionStat m_coprocFwVersion;
SemaphoreHandle_t m_coprocSemaphore;
TickType_t m_motors_last_set;
Motor m_motors[size_t(MotorId::MAX)];
rb::Oled m_oled;
rb::Mpu m_mpu;
rb::Piezo m_piezo;
rb::Leds m_leds;
rb::Buttons m_buttons;
rb::Battery m_battery;
rb::Ultrasound m_ultrasounds[UltrasoundsCount];
rb::SmartServoBusBackend m_smartServoBusBackend;
};
/**
* \brief Helper class for building the motor change event
*/
class MotorChangeBuilder {
public:
MotorChangeBuilder();
MotorChangeBuilder(const MotorChangeBuilder& o) = delete;
MotorChangeBuilder(MotorChangeBuilder&& o);
~MotorChangeBuilder();
/**
* \brief Set single motor power.
* \param id of the motor (e.g. rb:MotorId::M1)
* \param power of the motor <-32768; 32767>
**/
MotorChangeBuilder& power(MotorId id, int16_t value);
/**
* \brief Set single motor power.
* \param id of the motor (e.g. rb:MotorId::M1)
* \param speed of the motor in encoder ticks <-32768; 32767>
**/
MotorChangeBuilder& speed(MotorId id, int16_t ticksPerSecond);
/**
* \brief Start braking.
* \param id of the motor (e.g. rb:MotorId::M1)
* \param brakingPower power of the braking, <0, 32767>
**/
MotorChangeBuilder& brake(MotorId id, uint16_t brakingPower);
/**
* \brief Limit motor index's power to percent.
* \param id of the motor (e.g. rb:MotorId::M1)
* \param percent of the maximal power of the motor <0 - 100>
**/
MotorChangeBuilder& pwmMaxPercent(MotorId id, int8_t percent);
/**
* \brief Drive motor to relative position.
* \param id of the motor (e.g. rb:MotorId::M1)
* \param positionRelative relative position of the motor in encoder ticks
* \param speedTicksPerSecond speed of the motor in encoder ticks <-32768; 32767>
* \param callback is a function which will be called when the motor reach the position
* \return MotorChangeBuilder
**/
MotorChangeBuilder& drive(MotorId id, int32_t positionRelative,
int16_t speedTicksPerSecond, Motor::callback_t callback = nullptr);
/**
* \brief Drive motor to absolute position.
* \param id of the motor (e.g. rb:MotorId::M1)
* \param positionAbsolute absolute position of the motor in encoder ticks
* \param speedTicksPerSecond speed of the motor in encoder ticks <-32768; 32767>
* \param callback is a function which will be called when the motor reach the position
* \return MotorChangeBuilder
**/
MotorChangeBuilder& driveToValue(MotorId id, int32_t positionAbsolute,
int16_t speedTicksPerSecond, Motor::callback_t callback = nullptr);
/**
* \brief Finish the changes and submit the events.
* This method must be called at the end of the motor change event.
* If the method is not called, the motor change event will not be submitted.
**/
void set();
private:
std::vector<std::function<void()>> m_calls;
};
} // namespace rb