Files
SpotMicroESP32-Leika/include/servo.h
T
2023-08-07 22:17:08 +02:00

115 lines
2.9 KiB
C++

#pragma once
#include <memory>
#include <Adafruit_PWMServoDriver.h>
#include <globals.h>
#include <webserver.h>
#if USE_WIFI && USE_WEBSERVER
extern DRAM_ATTR CWebServer g_WebServer;
#endif
typedef struct {
float omega;
float phi;
float psi;
float xm;
float ym;
float zm;
bool set;
} position_t;
class Servo : public Adafruit_PWMServoDriver {
public:
Servo() : Adafruit_PWMServoDriver() {}
void SetAngles(int16_t* angle) {
for(size_t i = 0; i < 12; i++)
servo_angles[i] = angle[i];
updateServos();
}
void SetAngle(uint8_t id, int8_t angle) {
servo_angles[id] = angle;
updateServos();
}
void updateServos() {
for(uint8_t i = 0; i < 12; i++){
int8_t angle = servo_angles[i];
uint16_t pulse = (uint16_t) (0.5 + servo_min[i] + (((angle * servo_invert[i]) + 90) * servo_conversion[i]));
setPWM(i, 0, pulse);
}
broadcastAngles();
}
void setBody(float phi, float theta, float psi, float x, float y, float z) {
goal_position.phi = (phi - 128) / 2;
goal_position.omega = (theta - 128) / 2;
goal_position.psi = (psi - 128) / 2;
goal_position.xm = (x - 128) / 2;
goal_position.ym = (y - 128) / 2;
goal_position.zm = (z - 128) / 2;
updateAngles();
}
void setBodyAngle(float phi, float theta, float psi) {
goal_position.phi = phi;
goal_position.omega = theta;
goal_position.psi = psi;
updateAngles();
}
void setBodyPosition(float x, float y, float z) {
goal_position.xm = x;
goal_position.ym = y;
goal_position.zm = z;
updateAngles();
}
void updateAngles() {
servo_angles[0] = goal_position.phi;
servo_angles[1] = goal_position.omega;
servo_angles[2] = goal_position.psi;
servo_angles[3] = goal_position.xm;
servo_angles[4] = goal_position.ym;
servo_angles[5] = goal_position.zm;
updateServos();
broadcastAngles();
}
void deactivate() {
isActive = false;
sleep();
}
void activate() {
isActive = true;
sleep();
}
void toggleState() {
isActive ? sleep() : wakeup();
isActive = !isActive;
}
bool isActive {true};
private:
void broadcastAngles() {
uint8_t* buf = (uint8_t*)&servo_angles;
g_WebServer.broadcast(buf, 12);
}
const int16_t servo_min[12] {92,101,129,92,118,125,110,101,125,92,101,125};
const int8_t servo_invert[12] = {-1,1,1, -1,-1,-1, 1,1,1, 1,-1,-1};
const float servo_conversion[12] {2.2,2.1055555,1.96923,2.2,2.1055555,1.96923,2.2,2.1055555,1.96923,2.2,2.1055555,1.96923};
position_t spot_position = {.omega=0,.phi=0,.psi=0,.xm=-40,.ym=-170, .zm=0, .set=1};
position_t goal_position = {0,};
int16_t servo_angles[12]{0,};
};
extern DRAM_ATTR std::unique_ptr<Servo> g_ptrServo;