mirror of
https://github.com/BotChain-Robots/firmware.git
synced 2026-07-08 17:47:21 +02:00
movement set read write to nvs working
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
idf_component_register(SRCS "MovementManager.cpp" "MovementManager.cpp" "TopologyManager.cpp"
|
||||
idf_component_register(SRCS "MovementManager.cpp" "MovementSetManager.cpp" "TopologyManager.cpp"
|
||||
PRIV_REQUIRES esp_event nvs_flash rmt dataLink flatbuffers
|
||||
# REQUIRES esp_timer
|
||||
INCLUDE_DIRS "include")
|
||||
|
||||
@@ -10,11 +10,6 @@ MovementSetManager::MovementSetManager(){
|
||||
return;
|
||||
}
|
||||
|
||||
if (!topology_manager->is_ready()){
|
||||
ESP_LOGE(MOVEMENTS_DEBUG_TAG, "Topology Manager is not ready!");
|
||||
return;
|
||||
}
|
||||
|
||||
ready = true;
|
||||
};
|
||||
|
||||
@@ -22,28 +17,51 @@ MovementSetManager::~MovementSetManager(){
|
||||
nvs_close(handle);
|
||||
}
|
||||
|
||||
esp_err_t MovementSetManager::add_movement(Movement::MovementEntry& entry, uint8_t& index){
|
||||
/**
|
||||
* @brief Adds a movement entry into the movements map
|
||||
*
|
||||
* @param entry Movement entry information
|
||||
* @param index Sequence number of the movements
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t MovementSetManager::add_movement(MovementEntryData& entry, uint8_t index){
|
||||
if (!ready){
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (entry.board_id() == PC_ADDR || entry.board_id() == BROADCAST_ADDR){
|
||||
if (entry.board_id == PC_ADDR || entry.board_id == BROADCAST_ADDR){
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (movements.find(index) != movements.end()){
|
||||
for (Movement::MovementEntry& e : movements[index]){
|
||||
if (e.board_id() == entry.board_id()){
|
||||
for (MovementEntryData& e : movements[index]){
|
||||
if (e.board_id == entry.board_id){
|
||||
return ESP_ERR_INVALID_ARG; //only unique board ids per index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.post_delay_ms == 0){
|
||||
//we don't want 0ms delay in between the movements, so we will add the default delay
|
||||
entry.post_delay_ms = DEFAULT_DELAY_MS;
|
||||
}
|
||||
|
||||
if (entry.ack != static_cast<uint8_t>(ACK_VALUES::NO_ACK) && entry.ack_ttl_ms == 0){
|
||||
entry.ack_ttl_ms = DEFAULT_ACK_TTL_MS;
|
||||
}
|
||||
|
||||
movements[index].push_back(entry);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a movement entry from the sequence, given the board id
|
||||
*
|
||||
* @param index Sequence number
|
||||
* @param board_id
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t MovementSetManager::remove_movement(uint8_t index, uint8_t board_id){
|
||||
if (board_id == PC_ADDR || board_id == BROADCAST_ADDR){
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -53,10 +71,14 @@ esp_err_t MovementSetManager::remove_movement(uint8_t index, uint8_t board_id){
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!ready){
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
for (auto it = movements[index].begin(); it != movements[index].end(); ++it) {
|
||||
if (it->board_id() == board_id){
|
||||
if (it->board_id == board_id){
|
||||
movements[index].erase(it);
|
||||
found = true;
|
||||
break;
|
||||
@@ -70,23 +92,116 @@ esp_err_t MovementSetManager::remove_movement(uint8_t index, uint8_t board_id){
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t MovementSetManager::update_movement(Movement::MovementEntry& entry, uint8_t index){
|
||||
esp_err_t MovementSetManager::get_curr_movement_set(std::unordered_map<uint8_t, std::vector<MovementEntryData>>& set){
|
||||
if (!ready){
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
set = movements;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t MovementSetManager::get_curr_movement_set(Movement::MovementSet& set){
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t MovementSetManager::get_nvs_movement_set(std::unordered_map<uint8_t, std::vector<MovementEntryData>>& set){
|
||||
if (!ready){
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t MovementSetManager::verify_movement_set(){
|
||||
return ESP_OK;
|
||||
}
|
||||
size_t size = 0;
|
||||
esp_err_t res = nvs_get_u32(handle, MOVEMENTS_NVS_SET_SIZE_KEY, reinterpret_cast<uint32_t*>(&size));
|
||||
|
||||
esp_err_t MovementSetManager::get_nvs_movement_set(Movement::MovementSet& set){
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(MOVEMENTS_DEBUG_TAG, "Failed to read data size");
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> buffer(size);
|
||||
|
||||
res = nvs_get_blob(handle, MOVEMENTS_NVS_SET_KEY, buffer.data(), &size);
|
||||
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(MOVEMENTS_DEBUG_TAG, "Failed to read blob");
|
||||
return res;
|
||||
}
|
||||
|
||||
// Verify the FlatBuffer
|
||||
flatbuffers::Verifier verifier(buffer.data(), buffer.size());
|
||||
if (!Movement::VerifyMovementSetBuffer(verifier)) {
|
||||
ESP_LOGE(MOVEMENTS_DEBUG_TAG, "FlatBuffer verification failed");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Parse root
|
||||
const Movement::MovementSet* movement_set = Movement::GetMovementSet(buffer.data());
|
||||
|
||||
movements.clear();
|
||||
|
||||
const auto* map = movement_set->movement_map();
|
||||
if (!map) {
|
||||
return ESP_OK; // empty set
|
||||
}
|
||||
|
||||
// Iterate map entries
|
||||
for (const Movement::MovementVector* mv : *map) {
|
||||
uint8_t key = mv->key();
|
||||
|
||||
auto& vec = movements[key];
|
||||
vec.clear();
|
||||
|
||||
const auto* entries = mv->movements();
|
||||
if (!entries) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vec.reserve(entries->size());
|
||||
|
||||
// Must iterate over Movement::MovementEntry* (FlatBuffers table)
|
||||
for (const Movement::MovementEntry* e : *entries) {
|
||||
vec.push_back({
|
||||
e->board_id(),
|
||||
e->module_type(),
|
||||
e->value_action(),
|
||||
*e->condition(), // copy struct
|
||||
e->ack(),
|
||||
e->ack_ttl_ms(),
|
||||
e->post_delay_ms()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
set = movements;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t MovementSetManager::write_nvs_movement_set(){
|
||||
if (!ready){
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
Flatbuffers::SerializedMessage m = builder.build_movement_set(movements);
|
||||
|
||||
esp_err_t res = nvs_set_u32(handle, MOVEMENTS_NVS_SET_SIZE_KEY, static_cast<uint32_t>(m.size));
|
||||
|
||||
res = nvs_commit(handle);
|
||||
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(MOVEMENTS_DEBUG_TAG, "Failed to commit data size");
|
||||
return res;
|
||||
}
|
||||
|
||||
res = nvs_set_blob(handle, MOVEMENTS_NVS_SET_KEY, m.data, m.size);
|
||||
|
||||
if (res != ESP_OK){
|
||||
ESP_LOGE(MOVEMENTS_DEBUG_TAG, "Failed to write to nvs");
|
||||
return res;
|
||||
}
|
||||
|
||||
res = nvs_commit(handle);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(MOVEMENTS_DEBUG_TAG, "Failed to commit topology");
|
||||
return res;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#define MOVEMENTS_NVS_KEY "key"
|
||||
#define MOVEMENTS_NVS_TOPOLOGY_KEY "topology"
|
||||
#define MOVEMENTS_NVS_TOPOLOGY_DATA_SIZE_KEY "data_size"
|
||||
#define MOVEMENTS_NVS_SET_KEY "mvt_set"
|
||||
#define MOVEMENTS_NVS_SET_SIZE_KEY "mvt_data_size"
|
||||
#define MOVEMENTS_DEBUG_TAG "movements"
|
||||
|
||||
class MovementManager {
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
#include "MovementManager.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "TopologyManager.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "MovementSetBuilder.h"
|
||||
#include "unordered_map"
|
||||
#include "constants/rmt.h"
|
||||
#include "constants/datalink.h"
|
||||
|
||||
#ifdef MOVEMENTS
|
||||
#pragma once
|
||||
|
||||
#define DEFAULT_DELAY_MS 50 //some random value that i am using to default to for the delay after a movement has been completed
|
||||
#define DEFAULT_ACK_TTL_MS 100
|
||||
#define CONDITION_BLOB_NOT_IN_USE 0
|
||||
#define CONDITION_BLOB_IN_USE 1
|
||||
|
||||
enum class ACK_VALUES : uint8_t {
|
||||
NO_ACK, //no acks required
|
||||
ACK, //acks required to be sent and received properly within ttl
|
||||
ACK_NO_FAIL, //acks required to be send but not necessarily required to be received properly within ttl
|
||||
};
|
||||
|
||||
enum class CONDITION_VALUES : uint8_t {
|
||||
LT,
|
||||
LEQ,
|
||||
GT,
|
||||
GEQ,
|
||||
EQ,
|
||||
NE,
|
||||
};
|
||||
|
||||
class MovementSetManager {
|
||||
public:
|
||||
MovementSetManager();
|
||||
~MovementSetManager();
|
||||
esp_err_t add_movement(Movement::MovementEntry& entry, uint8_t& index);
|
||||
esp_err_t add_movement(MovementEntryData& entry, uint8_t index);
|
||||
esp_err_t remove_movement(uint8_t index, uint8_t board_id);
|
||||
esp_err_t update_movement(Movement::MovementEntry& entry, uint8_t index);
|
||||
esp_err_t get_curr_movement_set(Movement::MovementSet& set);
|
||||
esp_err_t verify_movement_set();
|
||||
esp_err_t get_nvs_movement_set(Movement::MovementSet& set);
|
||||
esp_err_t get_curr_movement_set(std::unordered_map<uint8_t, std::vector<MovementEntryData>>& set);
|
||||
esp_err_t get_nvs_movement_set(std::unordered_map<uint8_t, std::vector<MovementEntryData>>& set);
|
||||
esp_err_t write_nvs_movement_set();
|
||||
|
||||
private:
|
||||
std::unique_ptr<TopologyManager> topology_manager = std::make_unique<TopologyManager>();
|
||||
std::unordered_map<uint8_t, std::vector<Movement::MovementEntry>> movements;
|
||||
std::unordered_map<uint8_t, std::vector<MovementEntryData>> movements;
|
||||
nvs_handle_t handle;
|
||||
bool ready = false;
|
||||
Flatbuffers::MovementSetBuilder builder;
|
||||
|
||||
Reference in New Issue
Block a user