♻️ Major clean up of project structure
This commit is contained in:
@@ -14,9 +14,9 @@ typedef std::function<void(const String &originId, bool sync)> SubscribeCallback
|
||||
|
||||
class EventSocket {
|
||||
public:
|
||||
EventSocket();
|
||||
EventSocket(PsychicHttpServer &server, const char *route = "/api/ws");
|
||||
|
||||
PsychicWebSocketHandler *getHandler() { return &_socket; }
|
||||
void begin();
|
||||
|
||||
bool hasSubscribers(const char *event);
|
||||
|
||||
@@ -28,6 +28,8 @@ class EventSocket {
|
||||
|
||||
private:
|
||||
PsychicWebSocketHandler _socket;
|
||||
PsychicHttpServer &_server;
|
||||
const char *_route;
|
||||
|
||||
std::map<String, std::list<int>> client_subscriptions;
|
||||
std::map<String, std::list<EventCallback>> event_callbacks;
|
||||
@@ -41,6 +43,4 @@ class EventSocket {
|
||||
esp_err_t onFrame(PsychicWebSocketRequest *request, httpd_ws_frame *frame);
|
||||
};
|
||||
|
||||
extern EventSocket socket;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <LittleFS.h>
|
||||
|
||||
#define ESPFS LittleFS
|
||||
#define ESP_FS LittleFS
|
||||
|
||||
#define AP_SETTINGS_FILE "/config/apSettings.json"
|
||||
#define CAMERA_SETTINGS_FILE "/config/cameraSettings.json"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <event_socket.h>
|
||||
#include <PsychicHttp.h>
|
||||
|
||||
#include <HTTPClient.h>
|
||||
#include <HTTPUpdate.h>
|
||||
#include <task_manager.h>
|
||||
|
||||
#define EVENT_DOWNLOAD_OTA "otastatus"
|
||||
#define OTA_TASK_STACK_SIZE 9216
|
||||
|
||||
class DownloadFirmwareService {
|
||||
public:
|
||||
DownloadFirmwareService();
|
||||
|
||||
esp_err_t handleDownloadUpdate(PsychicRequest *request, JsonVariant &json);
|
||||
|
||||
private:
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef FirmwareUploadService_h
|
||||
#define FirmwareUploadService_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <Update.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include <PsychicHttp.h>
|
||||
#include <system_service.h>
|
||||
#include <event_socket.h>
|
||||
|
||||
enum FileType { ft_none = 0, ft_firmware = 1, ft_md5 = 2 };
|
||||
|
||||
class FirmwareUploadService {
|
||||
public:
|
||||
FirmwareUploadService();
|
||||
|
||||
void begin();
|
||||
|
||||
PsychicUploadHandler *getHandler() { return &uploadHandler; }
|
||||
|
||||
private:
|
||||
PsychicUploadHandler uploadHandler;
|
||||
esp_err_t handleUpload(PsychicRequest *request, const String &filename, uint64_t index, uint8_t *data, size_t len,
|
||||
bool final);
|
||||
esp_err_t uploadComplete(PsychicRequest *request);
|
||||
esp_err_t handleError(PsychicRequest *request, int code);
|
||||
esp_err_t handleEarlyDisconnect();
|
||||
};
|
||||
|
||||
#endif // end FirmwareUploadService_h
|
||||
+14
-32
@@ -13,33 +13,13 @@
|
||||
#include <motion_states/rest_state.h>
|
||||
#include <message_types.h>
|
||||
|
||||
#define DEFAULT_STATE false
|
||||
#define ANGLES_EVENT "angles"
|
||||
#define INPUT_EVENT "input"
|
||||
#define MODE_EVENT "mode"
|
||||
#define WALK_GAIT_EVENT "walk_gait"
|
||||
|
||||
enum class MOTION_STATE { DEACTIVATED, IDLE, CALIBRATION, REST, STAND, WALK };
|
||||
|
||||
class MotionService {
|
||||
public:
|
||||
MotionService(ServoController *servoController, Peripherals *peripherals)
|
||||
: _servoController(servoController), _peripherals(peripherals) {}
|
||||
MotionService() {}
|
||||
|
||||
void begin() {
|
||||
socket.onEvent(INPUT_EVENT, [&](JsonVariant &root, int originId) { handleInput(root, originId); });
|
||||
|
||||
socket.onEvent(MODE_EVENT, [&](JsonVariant &root, int originId) { handleMode(root, originId); });
|
||||
|
||||
socket.onEvent(WALK_GAIT_EVENT, [&](JsonVariant &root, int originId) { handleWalkGait(root, originId); });
|
||||
|
||||
socket.onEvent(ANGLES_EVENT, [&](JsonVariant &root, int originId) { anglesEvent(root, originId); });
|
||||
|
||||
socket.onSubscribe(ANGLES_EVENT,
|
||||
std::bind(&MotionService::syncAngles, this, std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
body_state.updateFeet(KinConfig::default_feet_positions);
|
||||
}
|
||||
void begin() { body_state.updateFeet(KinConfig::default_feet_positions); }
|
||||
|
||||
void anglesEvent(JsonVariant &root, int originId) {
|
||||
JsonArray array = root.as<JsonArray>();
|
||||
@@ -50,12 +30,14 @@ class MotionService {
|
||||
}
|
||||
|
||||
void setState(MotionState *newState) {
|
||||
_servoController->activate();
|
||||
if (state) {
|
||||
state->end();
|
||||
}
|
||||
state = newState;
|
||||
if (state) state->begin();
|
||||
if (state) {
|
||||
_servoController->activate();
|
||||
state->begin();
|
||||
}
|
||||
}
|
||||
|
||||
void handleInput(JsonVariant &root, int originId) {
|
||||
@@ -89,7 +71,7 @@ class MotionService {
|
||||
JsonDocument doc;
|
||||
doc.set(static_cast<int>(mode));
|
||||
JsonVariant data = doc.as<JsonVariant>();
|
||||
socket.emit(MODE_EVENT, data, String(originId).c_str());
|
||||
// socket.emit(MODE_EVENT, data, String(originId).c_str());
|
||||
}
|
||||
|
||||
void emitAngles(const String &originId = "", bool sync = false) {
|
||||
@@ -97,7 +79,7 @@ class MotionService {
|
||||
auto arr = doc.to<JsonArray>();
|
||||
for (int i = 0; i < 12; i++) arr.add(angles[i]);
|
||||
JsonVariant data = doc.as<JsonVariant>();
|
||||
socket.emit(ANGLES_EVENT, data, originId.c_str());
|
||||
// socket.emit(ANGLES_EVENT, data, originId.c_str());
|
||||
}
|
||||
|
||||
void syncAngles(const String &originId = "", bool sync = false) {
|
||||
@@ -105,8 +87,7 @@ class MotionService {
|
||||
_servoController->setAngles(angles);
|
||||
}
|
||||
|
||||
void handleGestures() {
|
||||
const gesture_t ges = _peripherals->takeGesture();
|
||||
void handleGestures(const gesture_t ges) {
|
||||
if (ges != gesture_t::eGestureNone) {
|
||||
ESP_LOGI("Motion", "Gesture: %d", ges);
|
||||
switch (ges) {
|
||||
@@ -120,13 +101,13 @@ class MotionService {
|
||||
}
|
||||
}
|
||||
|
||||
bool updateMotion() {
|
||||
handleGestures();
|
||||
bool update(Peripherals *peripherals) {
|
||||
handleGestures(peripherals->takeGesture());
|
||||
if (!state) return false;
|
||||
unsigned long now = millis();
|
||||
float dt = (now - lastUpdate) / 1000.0f;
|
||||
lastUpdate = now;
|
||||
state->updateImuOffsets(_peripherals->angleY(), _peripherals->angleX());
|
||||
state->updateImuOffsets(peripherals->angleY(), peripherals->angleX());
|
||||
state->step(body_state, dt);
|
||||
kinematics.calculate_inverse_kinematics(body_state, new_angles);
|
||||
|
||||
@@ -147,9 +128,10 @@ class MotionService {
|
||||
|
||||
float *getAngles() { return angles; }
|
||||
|
||||
inline bool isActive() { return state != nullptr; }
|
||||
|
||||
private:
|
||||
ServoController *_servoController;
|
||||
Peripherals *_peripherals;
|
||||
Kinematics kinematics;
|
||||
|
||||
CommandMsg command = {0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
@@ -161,7 +161,7 @@ class GestureSensor {
|
||||
|
||||
gesture_t getGesture() { return msg.gesture; }
|
||||
|
||||
gesture_t takeGesture() {
|
||||
gesture_t const takeGesture() {
|
||||
const auto g = msg.gesture;
|
||||
msg.gesture = eGestureNone;
|
||||
return g;
|
||||
|
||||
@@ -49,15 +49,15 @@ class Peripherals : public StatefulService<PeripheralsConfiguration> {
|
||||
_eventEndpoint.begin();
|
||||
_persistence.readFromFS();
|
||||
|
||||
socket.onEvent(EVENT_I2C_SCAN, [&](JsonVariant &root, int originId) {
|
||||
scanI2C();
|
||||
emitI2C();
|
||||
});
|
||||
// socket.onEvent(EVENT_I2C_SCAN, [&](JsonVariant &root, int originId) {
|
||||
// scanI2C();
|
||||
// emitI2C();
|
||||
// });
|
||||
|
||||
socket.onSubscribe(EVENT_I2C_SCAN, [&](const String &originId, bool sync) {
|
||||
scanI2C();
|
||||
emitI2C(originId, sync);
|
||||
});
|
||||
// socket.onSubscribe(EVENT_I2C_SCAN, [&](const String &originId, bool sync) {
|
||||
// scanI2C();
|
||||
// emitI2C(originId, sync);
|
||||
// });
|
||||
|
||||
updatePins();
|
||||
|
||||
@@ -79,6 +79,13 @@ class Peripherals : public StatefulService<PeripheralsConfiguration> {
|
||||
#endif
|
||||
};
|
||||
|
||||
void update() {
|
||||
readIMU();
|
||||
readMag();
|
||||
// _peripherals.readBMP();
|
||||
EXECUTE_EVERY_N_MS(100, { readGesture(); });
|
||||
}
|
||||
|
||||
void loop() {
|
||||
EXECUTE_EVERY_N_MS(_updateInterval, {
|
||||
beginTransaction();
|
||||
@@ -112,7 +119,7 @@ class Peripherals : public StatefulService<PeripheralsConfiguration> {
|
||||
}
|
||||
ESP_LOGI("Peripherals", "Emitting I2C scan results, %s %d", originId.c_str(), sync);
|
||||
JsonVariant data = doc.as<JsonVariant>();
|
||||
socket.emit(EVENT_I2C_SCAN, data, originId.c_str(), sync);
|
||||
// socket.emit(EVENT_I2C_SCAN, data, originId.c_str(), sync);
|
||||
}
|
||||
|
||||
void scanI2C(uint8_t lower = 1, uint8_t higher = 127) {
|
||||
@@ -197,7 +204,7 @@ class Peripherals : public StatefulService<PeripheralsConfiguration> {
|
||||
|
||||
// float angleZ() { return _imu.getAngleZ(); }
|
||||
|
||||
gesture_t takeGesture() {
|
||||
gesture_t const takeGesture() {
|
||||
return
|
||||
#if FT_ENABLED(USE_PAJ7620U2)
|
||||
_gesture.takeGesture();
|
||||
@@ -225,7 +232,7 @@ class Peripherals : public StatefulService<PeripheralsConfiguration> {
|
||||
#endif
|
||||
#if FT_ENABLED(USE_MPU6050 || USE_BNO055) || FT_ENABLED(USE_HMC5883)
|
||||
JsonVariant data = doc.as<JsonVariant>();
|
||||
socket.emit(EVENT_IMU, data);
|
||||
// socket.emit(EVENT_IMU, data);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -235,7 +242,7 @@ class Peripherals : public StatefulService<PeripheralsConfiguration> {
|
||||
JsonArray root = doc.to<JsonArray>();
|
||||
root[0] = _left_distance, root[1] = _right_distance;
|
||||
JsonVariant data = doc.as<JsonVariant>();
|
||||
socket.emit("sonar", data);
|
||||
// socket.emit("sonar", data);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -32,16 +32,16 @@ class ServoController : public StatefulService<ServoSettings> {
|
||||
_persistence(ServoSettings::read, ServoSettings::update, this, SERVO_SETTINGS_FILE) {}
|
||||
|
||||
void begin() {
|
||||
socket.onEvent(EVENT_SERVO_CONFIGURATION_SETTINGS,
|
||||
[&](JsonVariant &root, int originId) { servoEvent(root, originId); });
|
||||
socket.onEvent(EVENT_SERVO_STATE, [&](JsonVariant &root, int originId) { stateUpdate(root, originId); });
|
||||
// socket.onEvent(EVENT_SERVO_CONFIGURATION_SETTINGS,
|
||||
// [&](JsonVariant &root, int originId) { servoEvent(root, originId); });
|
||||
// socket.onEvent(EVENT_SERVO_STATE, [&](JsonVariant &root, int originId) { stateUpdate(root, originId); });
|
||||
_persistence.readFromFS();
|
||||
|
||||
initializePCA();
|
||||
socket.onEvent(EVENT_SERVO_STATE, [&](JsonVariant &root, int originId) {
|
||||
is_active = root["active"] | false;
|
||||
is_active ? activate() : deactivate();
|
||||
});
|
||||
// socket.onEvent(EVENT_SERVO_STATE, [&](JsonVariant &root, int originId) {
|
||||
// is_active = root["active"] | false;
|
||||
// is_active ? activate() : deactivate();
|
||||
// });
|
||||
}
|
||||
|
||||
void pcaWrite(int index, int value) {
|
||||
@@ -110,7 +110,7 @@ class ServoController : public StatefulService<ServoSettings> {
|
||||
_pca.setMultiplePWM(pwms, 12);
|
||||
}
|
||||
|
||||
void updateServoState() {
|
||||
void update() {
|
||||
if (control_state == SERVO_CONTROL_STATE::ANGLE) calculatePWM();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
#ifndef Spot_h
|
||||
#define Spot_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <PsychicHttp.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <WiFi.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#include <filesystem.h>
|
||||
#include <firmware_download_service.h>
|
||||
#include <firmware_upload_service.h>
|
||||
#include <peripherals/peripherals.h>
|
||||
#include <peripherals/servo_controller.h>
|
||||
#include <peripherals/led_service.h>
|
||||
#include <peripherals/camera_service.h>
|
||||
#include <event_socket.h>
|
||||
#include <features.h>
|
||||
#include <motion.h>
|
||||
#include <task_manager.h>
|
||||
#include <wifi_service.h>
|
||||
#include <ap_service.h>
|
||||
#include <mdns_service.h>
|
||||
|
||||
#ifdef EMBED_WWW
|
||||
#include <WWWData.h>
|
||||
#endif
|
||||
|
||||
#ifndef APP_VERSION
|
||||
#define APP_VERSION "v1"
|
||||
#endif
|
||||
|
||||
#ifndef APP_NAME
|
||||
#define APP_NAME "SpotMicro"
|
||||
#endif
|
||||
|
||||
#ifndef APPLICATION_CORE
|
||||
#define APPLICATION_CORE -1
|
||||
#endif
|
||||
|
||||
class Spot {
|
||||
public:
|
||||
Spot();
|
||||
|
||||
void initialize();
|
||||
|
||||
// sense
|
||||
void readSensors() {
|
||||
_peripherals.readIMU();
|
||||
_peripherals.readMag();
|
||||
_peripherals.readBMP();
|
||||
EXECUTE_EVERY_N_MS(100, { _peripherals.readGesture(); });
|
||||
}
|
||||
|
||||
// plan
|
||||
void planMotion() { updatedMotion = _motionService.updateMotion(); }
|
||||
|
||||
// act
|
||||
void updateActuators() {
|
||||
if (updatedMotion) _servoController.setAngles(_motionService.getAngles());
|
||||
updatedMotion = false;
|
||||
|
||||
_servoController.updateServoState();
|
||||
#if FT_ENABLED(USE_WS2812)
|
||||
_ledService.loop();
|
||||
#endif
|
||||
}
|
||||
|
||||
// communicate
|
||||
void emitTelemetry() {
|
||||
if (updatedMotion) EXECUTE_EVERY_N_MS(100, { _motionService.emitAngles(); });
|
||||
EXECUTE_EVERY_N_MS(250, { _peripherals.emitIMU(); });
|
||||
// _peripherals.emitSonar();
|
||||
}
|
||||
|
||||
private:
|
||||
PsychicHttpServer _server;
|
||||
WiFiService _wifiService;
|
||||
APService _apService;
|
||||
EventSocket _socket;
|
||||
MDNSService _mdnsService;
|
||||
#if FT_ENABLED(USE_UPLOAD_FIRMWARE)
|
||||
FirmwareUploadService _uploadFirmwareService;
|
||||
#endif
|
||||
#if FT_ENABLED(USE_DOWNLOAD_FIRMWARE)
|
||||
DownloadFirmwareService _downloadFirmwareService;
|
||||
#endif
|
||||
#if FT_ENABLED(USE_MOTION)
|
||||
MotionService _motionService;
|
||||
#endif
|
||||
#if FT_ENABLED(USE_CAMERA)
|
||||
Camera::CameraService _cameraService;
|
||||
#endif
|
||||
Peripherals _peripherals;
|
||||
ServoController _servoController;
|
||||
#if FT_ENABLED(USE_WS2812)
|
||||
LEDService _ledService;
|
||||
#endif
|
||||
|
||||
bool updatedMotion = false;
|
||||
|
||||
const char *_appName = APP_NAME;
|
||||
const u_int16_t _numberEndpoints = 137 + 36;
|
||||
const u_int32_t _maxFileUpload = 2300000; // 2.3 MB
|
||||
const uint16_t _port = 80;
|
||||
|
||||
protected:
|
||||
void loop();
|
||||
static void _loopImpl(void *_this) { static_cast<Spot *>(_this)->loop(); }
|
||||
void setupServer();
|
||||
void startServices();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <PsychicHttp.h>
|
||||
#include <WiFi.h>
|
||||
#include <task_manager.h>
|
||||
#include <event_socket.h>
|
||||
// #include <event_socket.h>
|
||||
#include <filesystem.h>
|
||||
#include <global.h>
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ class FSPersistence {
|
||||
JsonStateReader<T> _stateReader;
|
||||
JsonStateUpdater<T> _stateUpdater;
|
||||
StatefulService<T> *_statefulService;
|
||||
FS *_fs {&ESPFS};
|
||||
FS *_fs {&ESP_FS};
|
||||
const char *_filePath;
|
||||
size_t _bufferSize;
|
||||
HandlerId _updateHandlerId;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <PsychicHttp.h>
|
||||
|
||||
#include <event_socket.h>
|
||||
// #include <event_socket.h>
|
||||
#include <template/stateful_service.h>
|
||||
|
||||
template <class T>
|
||||
@@ -15,10 +15,10 @@ class EventEndpoint {
|
||||
}
|
||||
|
||||
void begin() {
|
||||
socket.onEvent(_event,
|
||||
std::bind(&EventEndpoint::updateState, this, std::placeholders::_1, std::placeholders::_2));
|
||||
socket.onSubscribe(_event,
|
||||
std::bind(&EventEndpoint::syncState, this, std::placeholders::_1, std::placeholders::_2));
|
||||
// socket.onEvent(_event,
|
||||
// std::bind(&EventEndpoint::updateState, this, std::placeholders::_1, std::placeholders::_2));
|
||||
// socket.onSubscribe(_event,
|
||||
// std::bind(&EventEndpoint::syncState, this, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -35,6 +35,6 @@ class EventEndpoint {
|
||||
JsonDocument jsonDocument;
|
||||
JsonVariant root = jsonDocument.to<JsonVariant>();
|
||||
_statefulService->read(root, _stateReader);
|
||||
socket.emit(_event, root, originId.c_str(), sync);
|
||||
// socket.emit(_event, root, originId.c_str(), sync);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include <PsychicHttp.h>
|
||||
#include "WWWData.h"
|
||||
|
||||
void mountStaticAssets(PsychicHttpServer& s);
|
||||
Reference in New Issue
Block a user