-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathBraccio++.h
198 lines (151 loc) · 6.54 KB
/
Braccio++.h
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
/*
* Board support library for the Arduino Braccio++ 6-DOF robot arm.
* Copyright (C) 2022 Arduino (http://www.arduino.cc/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA.
*/
#ifndef __BRACCIO_PLUSPLUS_H__
#define __BRACCIO_PLUSPLUS_H__
/**************************************************************************************
* INCLUDE
**************************************************************************************/
#include "Arduino.h"
#include "lib/powerdelivery/PD_UFP.h"
#include "lib/ioexpander/TCA6424A.h"
#include "lib/display/Backlight.h"
#include "lib/motors/SmartServo.h"
#include "drivers/Ticker.h"
#include "lib/TFT_eSPI/TFT_eSPI.h" // Hardware-specific library
#include "lib/lvgl/lvgl.h"
#include <chrono>
using namespace std::chrono;
/**************************************************************************************
* FORWARD DECLARATION
**************************************************************************************/
class Servo;
/**************************************************************************************
* CLASS DECLARATION
**************************************************************************************/
class BraccioClass
{
public:
BraccioClass();
inline bool begin() { return begin(nullptr); }
inline bool begin(voidFuncPtr custom_menu) { return begin(custom_menu, true); }
bool begin(voidFuncPtr custom_menu, bool const wait_for_all_motor_connected);
void pingOn();
void pingOff();
bool connected(int const id);
Servo move(int const id);
Servo get (int const id);
void moveTo(float const a1, float const a2, float const a3, float const a4, float const a5, float const a6);
void positions(float * buffer);
void positions(float & a1, float & a2, float & a3, float & a4, float & a5, float & a6);
inline void setMaxTorque(uint16_t const max_torque) { _servos.setMaxTorque(max_torque); }
inline void setMaxTorque(int const id, uint16_t const max_torque) { _servos.setMaxTorque(id, max_torque); }
inline void setAngularVelocity(float const angular_velocity_deg_per_sec) { _servos.setAngularVelocity(angular_velocity_deg_per_sec); }
inline float getAngularVelocity() const { return _servos.getAngularVelocity(); }
inline void disengage(int const id = SmartServoClass::BROADCAST) { _servos.disengage(id); }
inline void engage (int const id = SmartServoClass::BROADCAST) { _servos.engage(id); }
int getKey();
void connectJoystickTo(lv_obj_t* obj);
inline bool isJoystickPressed_LEFT() { return (digitalRead(BTN_LEFT) == LOW); }
inline bool isJoystickPressed_RIGHT() { return (digitalRead(BTN_RIGHT) == LOW); }
inline bool isJoystickPressed_SELECT() { return (digitalRead(BTN_SEL) == LOW); }
inline bool isJoystickPressed_UP() { return (digitalRead(BTN_UP) == LOW); }
inline bool isJoystickPressed_DOWN() { return (digitalRead(BTN_DOWN) == LOW); }
inline bool isButtonPressed_ENTER() { return (digitalRead(BTN_ENTER) == LOW); }
inline void lvgl_lock () { _display_mtx.lock(); }
inline void lvgl_unlock() { _display_mtx.unlock(); }
static BraccioClass& get_default_instance() {
static BraccioClass dev;
return dev;
}
/* Those functions MUST NOT be used by the user. */
void lvgl_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
void onPowerIrqEvent();
void onPowerTimerEvent();
protected:
inline void setID(int const id) { _servos.setID(id); }
private:
void button_init();
rtos::Mutex _i2c_mtx;
RS485Class _serial485;
SmartServoClass _servos;
PD_UFP_log_c _PD_UFP;
TCA6424A _expander;
bool expander_init();
void expander_setGreen(int const i);
void expander_setRed(int const i);
bool _is_ping_allowed;
bool _is_motor_connected[SmartServoClass::NUM_MOTORS];
rtos::Mutex _motors_connected_mtx;
rtos::Thread _motors_connected_thd;
bool isPingAllowed();
void setMotorConnectionStatus(int const id, bool const is_connected);
void motorConnectedThreadFunc();
static int constexpr BTN_LEFT = 3;
static int constexpr BTN_RIGHT = 4;
static int constexpr BTN_UP = 5;
static int constexpr BTN_DOWN = 2;
static int constexpr BTN_SEL = A0;
static int constexpr BTN_ENTER = A1;
static size_t constexpr LVGL_DRAW_BUFFER_SIZE = 240 * 240 / 10;
Backlight _bl;
TFT_eSPI _gfx;
lv_disp_drv_t _lvgl_disp_drv;
lv_indev_drv_t _lvgl_indev_drv;
lv_disp_draw_buf_t _lvgl_disp_buf;
lv_color_t _lvgl_draw_buf[LVGL_DRAW_BUFFER_SIZE];
lv_group_t * _lvgl_p_obj_group;
lv_indev_t * _lvgl_kb_indev;
lv_style_t _lv_style;
rtos::Mutex _display_mtx;
rtos::Thread _display_thd;
bool backlight_init();
void display_init();
void lvgl_init();
void display_thread_func();
void lvgl_splashScreen(unsigned long const duration_ms);
void lvgl_pleaseConnectPower();
void lvgl_defaultMenu();
static uint32_t constexpr PD_IRQ_EVENT_FLAG = 1;
static uint32_t constexpr PD_TIMER_EVENT_FLAG = 2;
rtos::EventFlags _pd_events;
mbed::Ticker _pd_timer;
rtos::Thread _pd_thd;
void pd_thread_func();
};
#define Braccio BraccioClass::get_default_instance()
class Servo
{
public:
Servo(SmartServoClass & servos, int const id) : _servos(servos), _id(id) { }
inline void disengage() { _servos.disengage(_id); }
inline void engage() { _servos.engage(_id); }
inline bool engaged() { return _servos.isEngaged(_id); }
inline void setMaxTorque(uint16_t const max_torque) { _servos.setMaxTorque(_id, max_torque); }
inline Servo & move() { return *this; }
inline Servo & to (float const angle) { _servos.setPosition(_id, angle); return *this; }
inline float position() { return _servos.getPosition(_id); }
inline bool connected() { return Braccio.connected(_id); }
inline void info(Stream & stream) { _servos.getInfo(stream, _id); }
operator bool() { return connected(); }
private:
SmartServoClass & _servos;
int const _id;
};
#endif //__BRACCIO_PLUSPLUS_H__