Skip to content

Cleanup/Refactor SmartServo #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5007a37
Deleting superfluous file ArduinoRS485.h.
aentinger Jan 11, 2022
20e1d00
Turning SmartServo from a template class in a normal C++ class since …
aentinger Jan 11, 2022
f6e6be7
Moving member variable initialisation from class body to constructor.
aentinger Jan 11, 2022
f1f6f77
There's no need to create an instance of SmartServoClass on the heap,…
aentinger Jan 11, 2022
8bccedd
Replacing enum 'positionMode' with enum class 'PositionMode' for incr…
aentinger Jan 11, 2022
d555e32
Inline short functions.
aentinger Jan 11, 2022
7dcae14
Applying const-correctness is a first step towards detecting programm…
aentinger Jan 12, 2022
0be3119
Extracting enum SERVO_REG into separate file 'SmartServoConst.h'.
aentinger Jan 12, 2022
7e4fd4c
Turning SmartServoConstants into an enum class prevents misusage, as …
aentinger Jan 12, 2022
2b39743
Extract servo operation commands into enum class.
aentinger Jan 12, 2022
49263cb
Replacing uint8_t with enum class SmartServoOperation ensures that th…
aentinger Jan 12, 2022
0771846
Extract PositionMode into header file 'SmartServoConst.h'.
aentinger Jan 12, 2022
02a4559
Turning const MAX_MOTORS private, replacing const with constexpr to e…
aentinger Jan 12, 2022
8f5f632
Add separators for better readability.
aentinger Jan 12, 2022
4dde2a6
Initialize private member 'errors' within constructor, prefix with '_'.
aentinger Jan 12, 2022
2232b99
Prefix private member 'onError' with '_', initialise within constructor.
aentinger Jan 12, 2022
acbe869
Deleting superfluous variable 'timestamps'.
aentinger Jan 12, 2022
ef93888
The struct needs to be packed, otherwise the little trick with conver…
aentinger Jan 12, 2022
7f7378c
Replace tabs with spaces (why does anyone still uses tabs in their ed…
aentinger Jan 12, 2022
f564e9f
Remove superfluous inclusion of 'Arduino.h' in .cpp file (already inc…
aentinger Jan 12, 2022
6a000cb
Provide REG/CMD macros to hide 'ugly' conversion function 'toVal'.
aentinger Jan 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
342 changes: 172 additions & 170 deletions src/Braccio++.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,208 +23,210 @@
extern const lv_img_dsc_t img_bulb_gif;

extern "C" {
void braccio_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
void read_keypad(lv_indev_drv_t * indev, lv_indev_data_t * data);
void braccio_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
void read_keypad(lv_indev_drv_t * indev, lv_indev_data_t * data);
};

enum speed_grade_t {
FAST = 10,
MEDIUM = 100,
SLOW = 1000,
FAST = 10,
MEDIUM = 100,
SLOW = 1000,
};

#include <chrono>
using namespace std::chrono;

class MotorsWrapper {
public:
MotorsWrapper(SmartServoClass<7>* servos, int idx) : _servos(servos), _idx(idx) {}
MotorsWrapper& to(float angle) {
_servos->setPosition(_idx, angle, _speed);
return *this;
}
MotorsWrapper& in(std::chrono::milliseconds len) {
_servos->setTime(_idx, len.count());
return *this;
}
MotorsWrapper& move() {
return *this;
}
float position() {
return _servos->getPosition(_idx);
}
bool connected() {
return _servos->ping(_idx) == 0;
}
operator bool() {
return connected();
}
void info(Stream& stream) {
_servos->getInfo(stream, _idx);
}
void disengage() {
_servos->disengage(_idx);
}
void engage() {
_servos->engage(_idx);
}
bool engaged() {
return _servos->isEngaged(_idx);
}
MotorsWrapper(SmartServoClass & servos, int idx) : _servos(servos), _idx(idx) {}
MotorsWrapper& to(float angle) {
_servos.setPosition(_idx, angle, _speed);
return *this;
}
MotorsWrapper& in(std::chrono::milliseconds len) {
_servos.setTime(_idx, len.count());
return *this;
}
MotorsWrapper& move() {
return *this;
}
float position() {
return _servos.getPosition(_idx);
}
bool connected() {
return _servos.ping(_idx) == 0;
}
operator bool() {
return connected();
}
void info(Stream& stream) {
_servos.getInfo(stream, _idx);
}
void disengage() {
_servos.disengage(_idx);
}
void engage() {
_servos.engage(_idx);
}
bool engaged() {
return _servos.isEngaged(_idx);
}

private:
SmartServoClass<7>* _servos;
int _idx;
int _speed = 100;
SmartServoClass & _servos;
int _idx;
int _speed = 100;
};

class BraccioClass {
class BraccioClass
{
public:
BraccioClass() {}
bool begin(voidFuncPtr customMenu = nullptr);

// setters
MotorsWrapper move(int joint_index) {
MotorsWrapper wrapper(servos, joint_index);
return wrapper;
}
MotorsWrapper get(int joint_index) {
return move(joint_index);
}
void moveTo(int joint_index, int position) {
//servos->setPosition(joint_index, position, 100);
}
void moveTo(int joint_index, float angle) {
servos->setPosition(joint_index, angle, 100);
}
void moveTo(float a1, float a2, float a3, float a4, float a5, float a6) {
servos->setPositionMode(pmSYNC);
servos->setPosition(1, a1, runTime);
servos->setPosition(2, a2, runTime);
servos->setPosition(3, a3, runTime);
servos->setPosition(4, a4, runTime);
servos->setPosition(5, a5, runTime);
servos->setPosition(6, a6, runTime);
servos->synchronize();
servos->setPositionMode(pmIMMEDIATE);
}
// getters
void positions(float* buffer) {
for (int i = 1; i < 7; i++) {
*buffer++ = servos->getPosition(i);
}
}
void positions(float& a1, float& a2, float& a3, float& a4, float& a5, float& a6) {
// TODO: add check if motors are actually connected
a1 = servos->getPosition(1);
a2 = servos->getPosition(2);
a3 = servos->getPosition(3);
a4 = servos->getPosition(4);
a5 = servos->getPosition(5);
a6 = servos->getPosition(6);
}
float position(int joint_index);
bool connected(int joint_index) {
return _connected[joint_index];
}

void speed(speed_grade_t speed_grade) {
runTime = speed_grade;
}

void disengage(int id = SmartServoClass<7>::BROADCAST) {
servos->disengage(id);
}

void engage(int id = SmartServoClass<7>::BROADCAST) {
servos->engage(id);
}

int getKey();
void connectJoystickTo(lv_obj_t* obj);

TFT_eSPI gfx = TFT_eSPI();

bool ping_allowed = true;

static BraccioClass& get_default_instance() {
static BraccioClass dev;
return dev;
}

BraccioClass();

bool begin(voidFuncPtr customMenu = nullptr);

// setters
MotorsWrapper move(int joint_index) {
MotorsWrapper wrapper(servos, joint_index);
return wrapper;
}
MotorsWrapper get(int joint_index) {
return move(joint_index);
}
void moveTo(int joint_index, int position) {
//servos.setPosition(joint_index, position, 100);
}
void moveTo(int joint_index, float angle) {
servos.setPosition(joint_index, angle, 100);
}
void moveTo(float a1, float a2, float a3, float a4, float a5, float a6) {
servos.setPositionMode(PositionMode::SYNC);
servos.setPosition(1, a1, runTime);
servos.setPosition(2, a2, runTime);
servos.setPosition(3, a3, runTime);
servos.setPosition(4, a4, runTime);
servos.setPosition(5, a5, runTime);
servos.setPosition(6, a6, runTime);
servos.synchronize();
servos.setPositionMode(PositionMode::IMMEDIATE);
}
// getters
void positions(float* buffer) {
for (int i = 1; i < 7; i++) {
*buffer++ = servos.getPosition(i);
}
}
void positions(float& a1, float& a2, float& a3, float& a4, float& a5, float& a6) {
// TODO: add check if motors are actually connected
a1 = servos.getPosition(1);
a2 = servos.getPosition(2);
a3 = servos.getPosition(3);
a4 = servos.getPosition(4);
a5 = servos.getPosition(5);
a6 = servos.getPosition(6);
}
float position(int joint_index);
bool connected(int joint_index) {
return _connected[joint_index];
}

void speed(speed_grade_t speed_grade) {
runTime = speed_grade;
}

void disengage(int id = SmartServoClass::BROADCAST) {
servos.disengage(id);
}

void engage(int id = SmartServoClass::BROADCAST) {
servos.engage(id);
}

int getKey();
void connectJoystickTo(lv_obj_t* obj);

TFT_eSPI gfx = TFT_eSPI();

bool ping_allowed = true;

static BraccioClass& get_default_instance() {
static BraccioClass dev;
return dev;
}

protected:
// ioexpander APIs
void digitalWrite(int pin, uint8_t value);
// ioexpander APIs
void digitalWrite(int pin, uint8_t value);

// default display APIs
void drawMenu();
void splashScreen(int duration = 1000);
void hideMenu();
void drawImage(char* image);
void defaultMenu();
// default display APIs
void drawMenu();
void splashScreen(int duration = 1000);
void hideMenu();
void drawImage(char* image);
void defaultMenu();

void setID(int id) {
servos->setID(id);
}
void setID(int id) {
servos.setID(id);
}

private:

RS485Class serial485 = RS485Class(Serial1, 0, 7, 8); // TX, DE, RE
SmartServoClass<7>* servos = new SmartServoClass<7>(serial485);

PD_UFP_log_c PD_UFP = PD_UFP_log_c(PD_LOG_LEVEL_VERBOSE);
TCA6424A expander = TCA6424A(TCA6424A_ADDRESS_ADDR_HIGH);
Backlight bl;
RS485Class serial485;
SmartServoClass servos;
PD_UFP_log_c PD_UFP;
TCA6424A expander;
Backlight bl;

speed_grade_t runTime = SLOW; //ms
speed_grade_t runTime; //ms

voidFuncPtr _customMenu = nullptr;
voidFuncPtr _customMenu;

const int BTN_LEFT = 3;
const int BTN_RIGHT = 4;
const int BTN_UP = 5;
const int BTN_DOWN = 2;
const int BTN_SEL = A0;
const int BTN_ENTER = A1;
const int BTN_LEFT = 3;
const int BTN_RIGHT = 4;
const int BTN_UP = 5;
const int BTN_DOWN = 2;
const int BTN_SEL = A0;
const int BTN_ENTER = A1;

lv_disp_drv_t disp_drv;
lv_indev_drv_t indev_drv;
lv_disp_draw_buf_t disp_buf;
lv_color_t buf[240 * 240 / 10];
lv_group_t* p_objGroup;
lv_indev_t *kb_indev;
lv_disp_draw_buf_t disp_buf;
lv_color_t buf[240 * 240 / 10];
lv_group_t* p_objGroup;
lv_indev_t *kb_indev;

bool _connected[8];

#ifdef __MBED__
rtos::EventFlags pd_events;
rtos::Mutex i2c_mutex;
mbed::Ticker pd_timer;

unsigned int start_pd_burst = 0xFFFFFFFF;

void unlock_pd_semaphore_irq() {
start_pd_burst = millis();
pd_events.set(2);
}

void unlock_pd_semaphore() {
pd_events.set(1);
}

void setGreen(int i) {
expander.writePin(i * 2 - 1, 0);
expander.writePin(i * 2 - 2, 1);
}

void setRed(int i) {
expander.writePin(i * 2 - 1, 1);
expander.writePin(i * 2 - 2, 0);
}

void pd_thread();
void display_thread();
void motors_connected_thread();
rtos::EventFlags pd_events;
rtos::Mutex i2c_mutex;
mbed::Ticker pd_timer;

unsigned int start_pd_burst = 0xFFFFFFFF;

void unlock_pd_semaphore_irq() {
start_pd_burst = millis();
pd_events.set(2);
}

void unlock_pd_semaphore() {
pd_events.set(1);
}

void setGreen(int i) {
expander.writePin(i * 2 - 1, 0);
expander.writePin(i * 2 - 2, 1);
}

void setRed(int i) {
expander.writePin(i * 2 - 1, 1);
expander.writePin(i * 2 - 2, 0);
}

void pd_thread();
void display_thread();
void motors_connected_thread();
#endif

};
Expand Down
Loading