Oled implementation (#1)

This commit is contained in:
2026-02-07 15:05:45 -05:00
committed by GitHub
parent 048e39016a
commit 33c3ebad53
46 changed files with 1790 additions and 1260 deletions

4
.gitignore vendored
View File

@@ -45,3 +45,7 @@
/cmake-build-debug /cmake-build-debug
/.cache /.cache
**/.DS_Store **/.DS_Store
CMakeCache.txt
/CMakeFiles
/examples/display/build
*.log

View File

@@ -39,10 +39,11 @@ endif()
target_include_directories(c_control PUBLIC include) target_include_directories(c_control PUBLIC include)
target_link_libraries(c_control target_link_libraries(c_control
PUBLIC
spdlog::spdlog
PRIVATE PRIVATE
librpc::librpc librpc::librpc
Eigen3::Eigen Eigen3::Eigen
spdlog::spdlog
sentry-native::sentry-native sentry-native::sentry-native
sentry-crashpad::sentry-crashpad sentry-crashpad::sentry-crashpad
) )
@@ -63,10 +64,11 @@ add_library(control SHARED
target_include_directories(control PUBLIC include) target_include_directories(control PUBLIC include)
target_link_libraries(control target_link_libraries(control
PUBLIC
spdlog::spdlog
PRIVATE PRIVATE
librpc::librpc librpc::librpc
Eigen3::Eigen Eigen3::Eigen
spdlog::spdlog
sentry-native::sentry-native sentry-native::sentry-native
sentry-crashpad::sentry-crashpad sentry-crashpad::sentry-crashpad
) )

View File

@@ -4,6 +4,6 @@
"conan": {} "conan": {}
}, },
"include": [ "include": [
"build/RelWithDebInfo/generators/CMakePresets.json" "build/Release/generators/CMakePresets.json"
] ]
} }

View File

@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.15)
project(DisplayExample)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(libcontrol REQUIRED)
find_package(spdlog REQUIRED)
find_package(librpc REQUIRED)
add_executable(DisplayExample main.cpp)
target_link_libraries(DisplayExample
PRIVATE
libcontrol::libcontrol
spdlog::spdlog
librpc::librpc
)

View File

@@ -0,0 +1,9 @@
{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
"build/CMakePresets.json"
]
}

View File

@@ -0,0 +1,10 @@
# Display Example
## Compiling
```
conan install . --build=missing --output-folder=build -s build_type=Release
cmake -S . -B "build" -DCMAKE_TOOLCHAIN_FILE="build/conan_toolchain.cmake" -DCMAKE_BUILD_TYPE="Release"
cmake --build "./build" --config "Release"
./build/DisplayExample
```

View File

@@ -0,0 +1,9 @@
[requires]
libcontrol/1.0.0
flatbuffers/24.12.23
spdlog/1.16.0
librpc/1.1.6
[generators]
CMakeDeps
CMakeToolchain

31
examples/display/main.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include <chrono>
#include <iostream>
#include <format>
#include <thread>
#include "libcontrol.h"
int main() {
const auto controller = std::make_unique<RobotController>();
controller->fetchDirectlyConnectedModules(true);
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Found " << controller->getModules().size() << " modules" << std::endl;
for (const auto& maybe_module : controller->getModules()) {
if (const auto& module = maybe_module.lock()) {
std::cout << "Found module " << (int)module->get_device_id();
if (module->get_type() == ModuleType_DISPLAY) {
module->actuate(std::format("BotChain \n\n\nModule ID: {}", module->get_device_id()));
}
}
}
return 0;
}

View File

@@ -10,20 +10,23 @@
class Hub final : public Module { class Hub final : public Module {
public: public:
explicit Hub(uint8_t device_id) : Module(device_id) {}; explicit Hub(uint8_t device_id) : Module(device_id) {};
Hub(uint8_t device_id, ModuleType module_type) : Module(device_id, module_type) {}; Hub(uint8_t device_id, ModuleType module_type)
: Module(device_id, module_type) {};
Hub(uint8_t device_id, ModuleType module_type, Messaging::ConnectionType connection_type, Hub(uint8_t device_id, ModuleType module_type,
uint8_t leader) Messaging::ConnectionType connection_type, uint8_t leader)
: Module(device_id, module_type, connection_type, leader) {}; : Module(device_id, module_type, connection_type, leader) {};
double get_position() override; double get_position() override;
void actuate(double position) override; std::string get_text() override;
void actuate(double x, double y) override; void actuate(double position) override;
std::vector<uint8_t> get_actuation_message() override; void actuate(double x, double y) override;
void update_sensor_data(const Flatbuffers::sensor_value &value) override; void actuate(const std::string &t) override;
std::vector<uint8_t> get_actuation_message() override;
void update_sensor_data(const Flatbuffers::sensor_value &value) override;
}; };
#endif // CONTROL_HUB_H #endif // CONTROL_HUB_H

View File

@@ -7,6 +7,7 @@
#include <chrono> #include <chrono>
#include <cstdint> #include <cstdint>
#include <string>
#include "flatbuffers/SensorMessageBuilder.h" #include "flatbuffers/SensorMessageBuilder.h"
#include "flatbuffers_generated/RobotModule_generated.h" #include "flatbuffers_generated/RobotModule_generated.h"
@@ -14,53 +15,54 @@
#include "librpc.h" #include "librpc.h"
struct neighbour { struct neighbour {
uint8_t device_id; uint8_t device_id;
Orientation orientation; Orientation orientation;
}; };
class Module { class Module {
public: public:
explicit Module(uint8_t device_id) : m_device_id(device_id) {}; explicit Module(uint8_t device_id) : m_device_id(device_id) {};
Module(uint8_t device_id, ModuleType module_type) Module(uint8_t device_id, ModuleType module_type)
: m_device_id(device_id), m_module_type(module_type) {}; : m_device_id(device_id), m_module_type(module_type) {};
Module(uint8_t device_id, ModuleType module_type, Messaging::ConnectionType connection_type, Module(uint8_t device_id, ModuleType module_type,
uint8_t leader) Messaging::ConnectionType connection_type, uint8_t leader)
: m_device_id(device_id), m_module_type(module_type), m_connection_type(connection_type), : m_device_id(device_id), m_module_type(module_type),
m_leader(leader) {}; m_connection_type(connection_type), m_leader(leader) {};
std::vector<neighbour> get_neighbours(); std::vector<neighbour> get_neighbours();
uint8_t get_device_id(); uint8_t get_device_id();
ModuleType get_type(); ModuleType get_type();
Messaging::ConnectionType get_connection_type(); Messaging::ConnectionType get_connection_type();
uint8_t get_leader(); uint8_t get_leader();
std::chrono::time_point<std::chrono::system_clock> get_last_updated_time(); std::chrono::time_point<std::chrono::system_clock> get_last_updated_time();
virtual double get_position() = 0; // Not all modules implement all actuation/sensor values, some are no-ops
virtual void actuate(double x) = 0; virtual double get_position() = 0;
virtual std::string get_text() = 0;
virtual void actuate(double x) = 0;
virtual void actuate(const std::string &text) = 0;
virtual void actuate(double x, double y) = 0;
// There are no modules with 2D actuation support, this is an example of how to implement it. void update_module_metadata(const Messaging::TopologyMessage &message);
virtual void actuate(double x, double y) = 0;
void update_module_metadata(const Messaging::TopologyMessage &message); virtual std::vector<uint8_t> get_actuation_message() = 0;
virtual void update_sensor_data(const Flatbuffers::sensor_value &value) = 0;
virtual std::vector<uint8_t> get_actuation_message() = 0; private:
virtual void update_sensor_data(const Flatbuffers::sensor_value &value) = 0; uint8_t m_device_id;
ModuleType m_module_type;
private: Messaging::ConnectionType m_connection_type;
uint8_t m_device_id; uint8_t m_leader;
ModuleType m_module_type; std::chrono::time_point<std::chrono::system_clock> m_last_updated;
Messaging::ConnectionType m_connection_type; std::vector<neighbour> m_neighbours;
uint8_t m_leader; std::shared_ptr<MessagingInterface> m_messaging_interface;
std::chrono::time_point<std::chrono::system_clock> m_last_updated;
std::vector<neighbour> m_neighbours;
std::shared_ptr<MessagingInterface> m_messaging_interface;
}; };
#endif // CONTROL_MODULE_H #endif // CONTROL_MODULE_H

View File

@@ -5,10 +5,10 @@
#include "flatbuffers_generated/RobotModule_generated.h" #include "flatbuffers_generated/RobotModule_generated.h"
class ModuleFactory { class ModuleFactory {
public: public:
static std::shared_ptr<Module> static std::shared_ptr<Module>
createModule(uint8_t device_id, ModuleType type, createModule(uint8_t device_id, ModuleType type,
std::shared_ptr<MessagingInterface> &messaging_interface); std::shared_ptr<MessagingInterface> &messaging_interface);
}; };
#endif // CONTROL_MODULEFACTORY_H #endif // CONTROL_MODULEFACTORY_H

View File

@@ -9,20 +9,21 @@
#include "flatbuffers_generated/TopologyMessage_generated.h" #include "flatbuffers_generated/TopologyMessage_generated.h"
class Actuator : public Module { class Actuator : public Module {
public: public:
explicit Actuator(uint8_t device_id) : Module(device_id) {}; explicit Actuator(uint8_t device_id) : Module(device_id) {};
Actuator(uint8_t device_id, ModuleType module_type) : Module(device_id, module_type) {}; Actuator(uint8_t device_id, ModuleType module_type)
: Module(device_id, module_type) {};
Actuator(uint8_t device_id, ModuleType module_type, Messaging::ConnectionType connection_type, Actuator(uint8_t device_id, ModuleType module_type,
uint8_t leader) Messaging::ConnectionType connection_type, uint8_t leader)
: Module(device_id, module_type, connection_type, leader) {}; : Module(device_id, module_type, connection_type, leader) {};
protected: protected:
virtual std::vector<uint8_t> get_actuation_message() = 0; virtual std::vector<uint8_t> get_actuation_message() = 0;
private: private:
[[noreturn]] void actuator_tx_loop(); [[noreturn]] void actuator_tx_loop();
}; };
#endif // CONTROL_MODULE_H #endif // CONTROL_MODULE_H

View File

@@ -5,33 +5,38 @@
#ifndef CONTROL_BOUNDED1DPOSITIONALACTUATOR_H #ifndef CONTROL_BOUNDED1DPOSITIONALACTUATOR_H
#define CONTROL_BOUNDED1DPOSITIONALACTUATOR_H #define CONTROL_BOUNDED1DPOSITIONALACTUATOR_H
#include <string>
#include "actuators/Actuator.h" #include "actuators/Actuator.h"
#include "flatbuffers/AngleControlMessageBuilder.h" #include "flatbuffers/AngleControlMessageBuilder.h"
#include "flatbuffers/SensorMessageBuilder.h" #include "flatbuffers/SensorMessageBuilder.h"
class BoundedPositionalActuator1D : public Actuator { class BoundedPositionalActuator1D : public Actuator {
public: public:
BoundedPositionalActuator1D(uint8_t device_id, ModuleType type, double max_value, BoundedPositionalActuator1D(uint8_t device_id, ModuleType type,
double min_value, double initial_position) double max_value, double min_value,
: Actuator(device_id, type), m_target_position(initial_position), m_max_value(max_value), double initial_position)
m_min_value(min_value), : Actuator(device_id, type), m_target_position(initial_position),
acm_builder(std::make_unique<Flatbuffers::AngleControlMessageBuilder>()) { m_max_value(max_value), m_min_value(min_value),
} acm_builder(
std::make_unique<Flatbuffers::AngleControlMessageBuilder>()) {}
double get_position() override; double get_position() override;
void actuate(double position) override; std::string get_text() override; // no-op
void actuate(double x, double y) override; // no-op void actuate(double position) override;
void actuate(const std::string &text) override; // no-op
void actuate(double x, double y) override; // no-op
std::vector<uint8_t> get_actuation_message() override; std::vector<uint8_t> get_actuation_message() override;
void update_sensor_data(const Flatbuffers::sensor_value &value) override; void update_sensor_data(const Flatbuffers::sensor_value &value) override;
private: private:
double m_current_position = 0; double m_current_position = 0;
double m_target_position; double m_target_position;
double m_max_value; double m_max_value;
double m_min_value; double m_min_value;
std::unique_ptr<Flatbuffers::AngleControlMessageBuilder> acm_builder; std::unique_ptr<Flatbuffers::AngleControlMessageBuilder> acm_builder;
}; };
#endif // CONTROL_1DPOSITIONALACTUATOR_H #endif // CONTROL_1DPOSITIONALACTUATOR_H

View File

@@ -0,0 +1,38 @@
//
// Created by Johnathon Slightham on 2025-11-13.
//
#ifndef CONTROL_OLEDACTUATOR_H
#define CONTROL_OLEDACTUATOR_H
#include <string>
#include "actuators/Actuator.h"
#include "flatbuffers/SensorMessageBuilder.h"
#include "flatbuffers/TextControlMessageBuilder.h"
class OledActuator : public Actuator {
public:
OledActuator(uint8_t device_id, ModuleType type)
: Actuator(device_id, type),
m_text_message_builder(
std::make_unique<Flatbuffers::TextControlMessageBuilder>()) {}
double get_position() override;
std::string get_text() override;
void actuate(double position) override;
void actuate(double x, double y) override; // no-op
void actuate(const std::string &text) override;
std::vector<uint8_t> get_actuation_message() override;
void update_sensor_data(const Flatbuffers::sensor_value &value) override;
private:
std::string m_current_text = "";
std::string m_target_text = "";
std::unique_ptr<Flatbuffers::TextControlMessageBuilder>
m_text_message_builder;
};
#endif // CONTROL_OLEDACTUATOR_H

View File

@@ -5,30 +5,35 @@
#ifndef CONTROL_1DPOSITIONALACTUATOR_H #ifndef CONTROL_1DPOSITIONALACTUATOR_H
#define CONTROL_1DPOSITIONALACTUATOR_H #define CONTROL_1DPOSITIONALACTUATOR_H
#include <string>
#include "actuators/Actuator.h" #include "actuators/Actuator.h"
#include "flatbuffers/AngleControlMessageBuilder.h" #include "flatbuffers/AngleControlMessageBuilder.h"
#include "flatbuffers/SensorMessageBuilder.h" #include "flatbuffers/SensorMessageBuilder.h"
class PositionalActuator1D final : public Actuator { class PositionalActuator1D final : public Actuator {
public: public:
PositionalActuator1D(uint8_t device_id, ModuleType type) PositionalActuator1D(uint8_t device_id, ModuleType type)
: Actuator(device_id, type), : Actuator(device_id, type),
m_acm_builder(std::make_unique<Flatbuffers::AngleControlMessageBuilder>()) {}; m_acm_builder(
std::make_unique<Flatbuffers::AngleControlMessageBuilder>()) {};
double get_position() override; double get_position() override;
void actuate(double position) override; std::string get_text() override; // no-op
void actuate(double x, double y) override; // no-op void actuate(double position) override;
void actuate(const std::string &text) override; // no-op
void actuate(double x, double y) override; // no-op
std::vector<uint8_t> get_actuation_message() override; std::vector<uint8_t> get_actuation_message() override;
void update_sensor_data(const Flatbuffers::sensor_value &value) override; void update_sensor_data(const Flatbuffers::sensor_value &value) override;
private: private:
void update_loop(); void update_loop();
double m_target_position = 0; double m_target_position = 0;
double m_current_position = 0; double m_current_position = 0;
double m_board_target_position = 0; double m_board_target_position = 0;
std::unique_ptr<Flatbuffers::AngleControlMessageBuilder> m_acm_builder; std::unique_ptr<Flatbuffers::AngleControlMessageBuilder> m_acm_builder;
}; };
#endif // CONTROL_1DPOSITIONALACTUATOR_H #endif // CONTROL_1DPOSITIONALACTUATOR_H

View File

@@ -14,15 +14,15 @@
namespace Flatbuffers { namespace Flatbuffers {
class AngleControlMessageBuilder { class AngleControlMessageBuilder {
public: public:
AngleControlMessageBuilder() : builder_(256) { AngleControlMessageBuilder() : builder_(256) {}
}
SerializedMessage build_angle_control_message(int16_t angle); SerializedMessage build_angle_control_message(int16_t angle);
static const Messaging::AngleControlMessage *parse_angle_control_message(const uint8_t *buffer); static const Messaging::AngleControlMessage *
parse_angle_control_message(const uint8_t *buffer);
private: private:
flatbuffers::FlatBufferBuilder builder_; flatbuffers::FlatBufferBuilder builder_;
}; };
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -12,33 +12,32 @@
namespace Flatbuffers { namespace Flatbuffers {
struct ModuleInstance { struct ModuleInstance {
uint8_t id; uint8_t id;
ModuleType type; ModuleType type;
int angle; int angle;
}; };
struct ModuleConnectionInstance { struct ModuleConnectionInstance {
uint8_t from_module_id; uint8_t from_module_id;
uint8_t to_module_id; uint8_t to_module_id;
uint8_t from_socket; uint8_t from_socket;
uint8_t to_socket; uint8_t to_socket;
Orientation orientation; Orientation orientation;
}; };
class RobotConfigurationBuilder { class RobotConfigurationBuilder {
public: public:
RobotConfigurationBuilder() : builder_(1024) { RobotConfigurationBuilder() : builder_(1024) {}
}
SerializedMessage SerializedMessage build_robot_configuration(
build_robot_configuration(const std::vector<ModuleInstance> &modules, const std::vector<ModuleInstance> &modules,
const std::vector<ModuleConnectionInstance> &connections); const std::vector<ModuleConnectionInstance> &connections);
static const Frontend::RobotConfiguration * static const Frontend::RobotConfiguration *
parse_robot_configuration(const std::uint8_t *buffer); parse_robot_configuration(const std::uint8_t *buffer);
private: private:
flatbuffers::FlatBufferBuilder builder_; flatbuffers::FlatBufferBuilder builder_;
}; };
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -5,6 +5,7 @@
#ifndef SENSORMESSAGEBUILDER_H #ifndef SENSORMESSAGEBUILDER_H
#define SENSORMESSAGEBUILDER_H #define SENSORMESSAGEBUILDER_H
#include <string>
#include <variant> #include <variant>
#include "flatbuffers_generated/SensorMessage_generated.h" #include "flatbuffers_generated/SensorMessage_generated.h"
@@ -12,42 +13,52 @@
namespace Flatbuffers { namespace Flatbuffers {
struct target_angle { struct target_angle {
int16_t angle; int16_t angle;
}; };
struct current_angle { struct current_angle {
int16_t angle; int16_t angle;
}; };
typedef std::variant<target_angle, current_angle> sensor_value; struct current_text {
std::string text;
};
typedef std::variant<target_angle, current_angle, current_text> sensor_value;
class SensorMessageBuilder { class SensorMessageBuilder {
public: public:
SensorMessageBuilder() : builder_(1024) { SensorMessageBuilder() : builder_(1024) {}
static const Messaging::SensorMessage *
parse_sensor_message(const std::uint8_t *buffer);
template <typename T>
static std::optional<sensor_value>
build_sensor_value(Messaging::SensorValue type, T value) {
switch (type) {
case Messaging::SensorValue_TargetAngle: {
const Messaging::TargetAngle *target =
static_cast<const Messaging::TargetAngle *>(value);
return target_angle{target->value()};
} }
case Messaging::SensorValue_CurrentAngle: {
static const Messaging::SensorMessage *parse_sensor_message(const std::uint8_t *buffer); const Messaging::CurrentAngle *current =
static_cast<const Messaging::CurrentAngle *>(value);
template <typename T> return current_angle{current->value()};
static std::optional<sensor_value> build_sensor_value(Messaging::SensorValue type, T value) {
switch (type) {
case Messaging::SensorValue_TargetAngle: {
const Messaging::TargetAngle *target =
static_cast<const Messaging::TargetAngle *>(value);
return target_angle{target->value()};
}
case Messaging::SensorValue_CurrentAngle: {
const Messaging::CurrentAngle *current =
static_cast<const Messaging::CurrentAngle *>(value);
return current_angle{current->value()};
}
default:
return std::nullopt;
}
} }
case Messaging::SensorValue_CurrentText: {
const Messaging::CurrentText *current =
static_cast<const Messaging::CurrentText *>(value);
return current_text{current->value()->str()};
}
default:
return std::nullopt;
}
}
private: private:
flatbuffers::FlatBufferBuilder builder_; flatbuffers::FlatBufferBuilder builder_;
}; };
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -9,8 +9,8 @@
namespace Flatbuffers { namespace Flatbuffers {
struct SerializedMessage { struct SerializedMessage {
void *data; void *data;
size_t size; size_t size;
}; };
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -0,0 +1,27 @@
//
// Created by Johnathon Slightham on 2025-06-30.
//
#ifndef TEXTCONTROLMESSAGEBUILDER_H_
#define TEXTCONTROLMESSAGEBUILDER_H_
#include <string>
#include <vector>
#include "SerializedMessage.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers_generated/TextControlMessage_generated.h"
namespace Flatbuffers {
class TextControlMessageBuilder {
public:
TextControlMessageBuilder() : builder_(256) {}
SerializedMessage build_text_control_message(std::string &t);
private:
flatbuffers::FlatBufferBuilder builder_;
};
} // namespace Flatbuffers
#endif

View File

@@ -12,20 +12,21 @@
namespace Flatbuffers { namespace Flatbuffers {
class TopologyMessageBuilder { class TopologyMessageBuilder {
public: public:
TopologyMessageBuilder() : builder_(1024) { TopologyMessageBuilder() : builder_(1024) {}
}
SerializedMessage build_topology_message(uint8_t module_id, ModuleType module_type, SerializedMessage
const std::vector<uint8_t> &channel_to_module, build_topology_message(uint8_t module_id, ModuleType module_type,
const std::vector<int8_t> &orientation_to_module); const std::vector<uint8_t> &channel_to_module,
const std::vector<int8_t> &orientation_to_module);
static const Messaging::TopologyMessage *parse_topology_message(const uint8_t *buffer); static const Messaging::TopologyMessage *
parse_topology_message(const uint8_t *buffer);
static bool is_valid_topology_message(const uint8_t *buffer, size_t size); static bool is_valid_topology_message(const uint8_t *buffer, size_t size);
private: private:
flatbuffers::FlatBufferBuilder builder_; flatbuffers::FlatBufferBuilder builder_;
}; };
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -17,68 +17,76 @@ namespace Messaging {
struct AngleControlMessage; struct AngleControlMessage;
struct AngleControlMessageBuilder; struct AngleControlMessageBuilder;
struct AngleControlMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct AngleControlMessage FLATBUFFERS_FINAL_CLASS
typedef AngleControlMessageBuilder Builder; : private ::flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ANGLE = 4 }; typedef AngleControlMessageBuilder Builder;
int16_t angle() const { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
return GetField<int16_t>(VT_ANGLE, 0); VT_ANGLE = 4
} };
bool Verify(::flatbuffers::Verifier &verifier) const { int16_t angle() const { return GetField<int16_t>(VT_ANGLE, 0); }
return VerifyTableStart(verifier) && VerifyField<int16_t>(verifier, VT_ANGLE, 2) && bool Verify(::flatbuffers::Verifier &verifier) const {
verifier.EndTable(); return VerifyTableStart(verifier) &&
} VerifyField<int16_t>(verifier, VT_ANGLE, 2) && verifier.EndTable();
}
}; };
struct AngleControlMessageBuilder { struct AngleControlMessageBuilder {
typedef AngleControlMessage Table; typedef AngleControlMessage Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_angle(int16_t angle) { void add_angle(int16_t angle) {
fbb_.AddElement<int16_t>(AngleControlMessage::VT_ANGLE, angle, 0); fbb_.AddElement<int16_t>(AngleControlMessage::VT_ANGLE, angle, 0);
} }
explicit AngleControlMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { explicit AngleControlMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
start_ = fbb_.StartTable(); : fbb_(_fbb) {
} start_ = fbb_.StartTable();
::flatbuffers::Offset<AngleControlMessage> Finish() { }
const auto end = fbb_.EndTable(start_); ::flatbuffers::Offset<AngleControlMessage> Finish() {
auto o = ::flatbuffers::Offset<AngleControlMessage>(end); const auto end = fbb_.EndTable(start_);
return o; auto o = ::flatbuffers::Offset<AngleControlMessage>(end);
} return o;
}
}; };
inline ::flatbuffers::Offset<AngleControlMessage> inline ::flatbuffers::Offset<AngleControlMessage>
CreateAngleControlMessage(::flatbuffers::FlatBufferBuilder &_fbb, int16_t angle = 0) { CreateAngleControlMessage(::flatbuffers::FlatBufferBuilder &_fbb,
AngleControlMessageBuilder builder_(_fbb); int16_t angle = 0) {
builder_.add_angle(angle); AngleControlMessageBuilder builder_(_fbb);
return builder_.Finish(); builder_.add_angle(angle);
return builder_.Finish();
} }
inline const Messaging::AngleControlMessage *GetAngleControlMessage(const void *buf) { inline const Messaging::AngleControlMessage *
return ::flatbuffers::GetRoot<Messaging::AngleControlMessage>(buf); GetAngleControlMessage(const void *buf) {
return ::flatbuffers::GetRoot<Messaging::AngleControlMessage>(buf);
} }
inline const Messaging::AngleControlMessage *GetSizePrefixedAngleControlMessage(const void *buf) { inline const Messaging::AngleControlMessage *
return ::flatbuffers::GetSizePrefixedRoot<Messaging::AngleControlMessage>(buf); GetSizePrefixedAngleControlMessage(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Messaging::AngleControlMessage>(
buf);
} }
inline bool VerifyAngleControlMessageBuffer(::flatbuffers::Verifier &verifier) { inline bool VerifyAngleControlMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<Messaging::AngleControlMessage>(nullptr); return verifier.VerifyBuffer<Messaging::AngleControlMessage>(nullptr);
} }
inline bool VerifySizePrefixedAngleControlMessageBuffer(::flatbuffers::Verifier &verifier) { inline bool
return verifier.VerifySizePrefixedBuffer<Messaging::AngleControlMessage>(nullptr); VerifySizePrefixedAngleControlMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<Messaging::AngleControlMessage>(
nullptr);
} }
inline void inline void FinishAngleControlMessageBuffer(
FinishAngleControlMessageBuffer(::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Messaging::AngleControlMessage> root) { ::flatbuffers::Offset<Messaging::AngleControlMessage> root) {
fbb.Finish(root); fbb.Finish(root);
} }
inline void FinishSizePrefixedAngleControlMessageBuffer( inline void FinishSizePrefixedAngleControlMessageBuffer(
::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Messaging::AngleControlMessage> root) { ::flatbuffers::Offset<Messaging::AngleControlMessage> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }
} // namespace Messaging } // namespace Messaging

View File

@@ -23,177 +23,195 @@ struct RobotConfiguration;
struct RobotConfigurationBuilder; struct RobotConfigurationBuilder;
struct ModuleConnection FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct ModuleConnection FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef ModuleConnectionBuilder Builder; typedef ModuleConnectionBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_FROM_MODULE_ID = 4, VT_FROM_MODULE_ID = 4,
VT_TO_MODULE_ID = 6, VT_TO_MODULE_ID = 6,
VT_FROM_SOCKET = 8, VT_FROM_SOCKET = 8,
VT_TO_SOCKET = 10, VT_TO_SOCKET = 10,
VT_ORIENTATION = 12 VT_ORIENTATION = 12
}; };
uint8_t from_module_id() const { uint8_t from_module_id() const {
return GetField<uint8_t>(VT_FROM_MODULE_ID, 0); return GetField<uint8_t>(VT_FROM_MODULE_ID, 0);
} }
uint8_t to_module_id() const { uint8_t to_module_id() const { return GetField<uint8_t>(VT_TO_MODULE_ID, 0); }
return GetField<uint8_t>(VT_TO_MODULE_ID, 0); uint8_t from_socket() const { return GetField<uint8_t>(VT_FROM_SOCKET, 0); }
} uint8_t to_socket() const { return GetField<uint8_t>(VT_TO_SOCKET, 0); }
uint8_t from_socket() const { Orientation orientation() const {
return GetField<uint8_t>(VT_FROM_SOCKET, 0); return static_cast<Orientation>(GetField<int8_t>(VT_ORIENTATION, 0));
} }
uint8_t to_socket() const { bool Verify(::flatbuffers::Verifier &verifier) const {
return GetField<uint8_t>(VT_TO_SOCKET, 0); return VerifyTableStart(verifier) &&
} VerifyField<uint8_t>(verifier, VT_FROM_MODULE_ID, 1) &&
Orientation orientation() const { VerifyField<uint8_t>(verifier, VT_TO_MODULE_ID, 1) &&
return static_cast<Orientation>(GetField<int8_t>(VT_ORIENTATION, 0)); VerifyField<uint8_t>(verifier, VT_FROM_SOCKET, 1) &&
} VerifyField<uint8_t>(verifier, VT_TO_SOCKET, 1) &&
bool Verify(::flatbuffers::Verifier &verifier) const { VerifyField<int8_t>(verifier, VT_ORIENTATION, 1) &&
return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_FROM_MODULE_ID, 1) && verifier.EndTable();
VerifyField<uint8_t>(verifier, VT_TO_MODULE_ID, 1) && }
VerifyField<uint8_t>(verifier, VT_FROM_SOCKET, 1) &&
VerifyField<uint8_t>(verifier, VT_TO_SOCKET, 1) &&
VerifyField<int8_t>(verifier, VT_ORIENTATION, 1) && verifier.EndTable();
}
}; };
struct ModuleConnectionBuilder { struct ModuleConnectionBuilder {
typedef ModuleConnection Table; typedef ModuleConnection Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_from_module_id(uint8_t from_module_id) { void add_from_module_id(uint8_t from_module_id) {
fbb_.AddElement<uint8_t>(ModuleConnection::VT_FROM_MODULE_ID, from_module_id, 0); fbb_.AddElement<uint8_t>(ModuleConnection::VT_FROM_MODULE_ID,
} from_module_id, 0);
void add_to_module_id(uint8_t to_module_id) { }
fbb_.AddElement<uint8_t>(ModuleConnection::VT_TO_MODULE_ID, to_module_id, 0); void add_to_module_id(uint8_t to_module_id) {
} fbb_.AddElement<uint8_t>(ModuleConnection::VT_TO_MODULE_ID, to_module_id,
void add_from_socket(uint8_t from_socket) { 0);
fbb_.AddElement<uint8_t>(ModuleConnection::VT_FROM_SOCKET, from_socket, 0); }
} void add_from_socket(uint8_t from_socket) {
void add_to_socket(uint8_t to_socket) { fbb_.AddElement<uint8_t>(ModuleConnection::VT_FROM_SOCKET, from_socket, 0);
fbb_.AddElement<uint8_t>(ModuleConnection::VT_TO_SOCKET, to_socket, 0); }
} void add_to_socket(uint8_t to_socket) {
void add_orientation(Orientation orientation) { fbb_.AddElement<uint8_t>(ModuleConnection::VT_TO_SOCKET, to_socket, 0);
fbb_.AddElement<int8_t>(ModuleConnection::VT_ORIENTATION, static_cast<int8_t>(orientation), }
0); void add_orientation(Orientation orientation) {
} fbb_.AddElement<int8_t>(ModuleConnection::VT_ORIENTATION,
explicit ModuleConnectionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { static_cast<int8_t>(orientation), 0);
start_ = fbb_.StartTable(); }
} explicit ModuleConnectionBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
::flatbuffers::Offset<ModuleConnection> Finish() { : fbb_(_fbb) {
const auto end = fbb_.EndTable(start_); start_ = fbb_.StartTable();
auto o = ::flatbuffers::Offset<ModuleConnection>(end); }
return o; ::flatbuffers::Offset<ModuleConnection> Finish() {
} const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<ModuleConnection>(end);
return o;
}
}; };
inline ::flatbuffers::Offset<ModuleConnection> inline ::flatbuffers::Offset<ModuleConnection>
CreateModuleConnection(::flatbuffers::FlatBufferBuilder &_fbb, uint8_t from_module_id = 0, CreateModuleConnection(::flatbuffers::FlatBufferBuilder &_fbb,
uint8_t to_module_id = 0, uint8_t from_socket = 0, uint8_t to_socket = 0, uint8_t from_module_id = 0, uint8_t to_module_id = 0,
uint8_t from_socket = 0, uint8_t to_socket = 0,
Orientation orientation = Orientation_Deg0) { Orientation orientation = Orientation_Deg0) {
ModuleConnectionBuilder builder_(_fbb); ModuleConnectionBuilder builder_(_fbb);
builder_.add_orientation(orientation); builder_.add_orientation(orientation);
builder_.add_to_socket(to_socket); builder_.add_to_socket(to_socket);
builder_.add_from_socket(from_socket); builder_.add_from_socket(from_socket);
builder_.add_to_module_id(to_module_id); builder_.add_to_module_id(to_module_id);
builder_.add_from_module_id(from_module_id); builder_.add_from_module_id(from_module_id);
return builder_.Finish(); return builder_.Finish();
} }
struct RobotConfiguration FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct RobotConfiguration FLATBUFFERS_FINAL_CLASS
typedef RobotConfigurationBuilder Builder; : private ::flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { typedef RobotConfigurationBuilder Builder;
VT_MODULES = 4, enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_CONNECTIONS = 6 VT_MODULES = 4,
}; VT_CONNECTIONS = 6
const ::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>> *modules() const { };
return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>> *>( const ::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>> *
VT_MODULES); modules() const {
} return GetPointer<
const ::flatbuffers::Vector<::flatbuffers::Offset<Frontend::ModuleConnection>> * const ::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>> *>(
connections() const { VT_MODULES);
return GetPointer< }
const ::flatbuffers::Vector<::flatbuffers::Offset<Frontend::ModuleConnection>> *>( const ::flatbuffers::Vector<
VT_CONNECTIONS); ::flatbuffers::Offset<Frontend::ModuleConnection>> *
} connections() const {
bool Verify(::flatbuffers::Verifier &verifier) const { return GetPointer<const ::flatbuffers::Vector<
return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_MODULES) && ::flatbuffers::Offset<Frontend::ModuleConnection>> *>(VT_CONNECTIONS);
verifier.VerifyVector(modules()) && verifier.VerifyVectorOfTables(modules()) && }
VerifyOffset(verifier, VT_CONNECTIONS) && verifier.VerifyVector(connections()) && bool Verify(::flatbuffers::Verifier &verifier) const {
verifier.VerifyVectorOfTables(connections()) && verifier.EndTable(); return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_MODULES) &&
} verifier.VerifyVector(modules()) &&
verifier.VerifyVectorOfTables(modules()) &&
VerifyOffset(verifier, VT_CONNECTIONS) &&
verifier.VerifyVector(connections()) &&
verifier.VerifyVectorOfTables(connections()) && verifier.EndTable();
}
}; };
struct RobotConfigurationBuilder { struct RobotConfigurationBuilder {
typedef RobotConfiguration Table; typedef RobotConfiguration Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_modules( void add_modules(::flatbuffers::Offset<
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>>> modules) { ::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>>>
fbb_.AddOffset(RobotConfiguration::VT_MODULES, modules); modules) {
} fbb_.AddOffset(RobotConfiguration::VT_MODULES, modules);
void add_connections(::flatbuffers::Offset< }
::flatbuffers::Vector<::flatbuffers::Offset<Frontend::ModuleConnection>>> void add_connections(::flatbuffers::Offset<::flatbuffers::Vector<
connections) { ::flatbuffers::Offset<Frontend::ModuleConnection>>>
fbb_.AddOffset(RobotConfiguration::VT_CONNECTIONS, connections); connections) {
} fbb_.AddOffset(RobotConfiguration::VT_CONNECTIONS, connections);
explicit RobotConfigurationBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { }
start_ = fbb_.StartTable(); explicit RobotConfigurationBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
} : fbb_(_fbb) {
::flatbuffers::Offset<RobotConfiguration> Finish() { start_ = fbb_.StartTable();
const auto end = fbb_.EndTable(start_); }
auto o = ::flatbuffers::Offset<RobotConfiguration>(end); ::flatbuffers::Offset<RobotConfiguration> Finish() {
return o; const auto end = fbb_.EndTable(start_);
} auto o = ::flatbuffers::Offset<RobotConfiguration>(end);
return o;
}
}; };
inline ::flatbuffers::Offset<RobotConfiguration> CreateRobotConfiguration( inline ::flatbuffers::Offset<RobotConfiguration> CreateRobotConfiguration(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>>> modules = 0, ::flatbuffers::Offset<
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<Frontend::ModuleConnection>>> ::flatbuffers::Vector<::flatbuffers::Offset<RobotModule>>>
modules = 0,
::flatbuffers::Offset<::flatbuffers::Vector<
::flatbuffers::Offset<Frontend::ModuleConnection>>>
connections = 0) { connections = 0) {
RobotConfigurationBuilder builder_(_fbb); RobotConfigurationBuilder builder_(_fbb);
builder_.add_connections(connections); builder_.add_connections(connections);
builder_.add_modules(modules); builder_.add_modules(modules);
return builder_.Finish(); return builder_.Finish();
} }
inline ::flatbuffers::Offset<RobotConfiguration> CreateRobotConfigurationDirect( inline ::flatbuffers::Offset<RobotConfiguration> CreateRobotConfigurationDirect(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder &_fbb,
const std::vector<::flatbuffers::Offset<RobotModule>> *modules = nullptr, const std::vector<::flatbuffers::Offset<RobotModule>> *modules = nullptr,
const std::vector<::flatbuffers::Offset<Frontend::ModuleConnection>> *connections = nullptr) { const std::vector<::flatbuffers::Offset<Frontend::ModuleConnection>>
auto modules__ = modules ? _fbb.CreateVector<::flatbuffers::Offset<RobotModule>>(*modules) : 0; *connections = nullptr) {
auto connections__ = auto modules__ =
connections modules ? _fbb.CreateVector<::flatbuffers::Offset<RobotModule>>(*modules)
? _fbb.CreateVector<::flatbuffers::Offset<Frontend::ModuleConnection>>(*connections) : 0;
: 0; auto connections__ =
return Frontend::CreateRobotConfiguration(_fbb, modules__, connections__); connections
? _fbb.CreateVector<
::flatbuffers::Offset<Frontend::ModuleConnection>>(*connections)
: 0;
return Frontend::CreateRobotConfiguration(_fbb, modules__, connections__);
} }
inline const Frontend::RobotConfiguration *GetRobotConfiguration(const void *buf) { inline const Frontend::RobotConfiguration *
return ::flatbuffers::GetRoot<Frontend::RobotConfiguration>(buf); GetRobotConfiguration(const void *buf) {
return ::flatbuffers::GetRoot<Frontend::RobotConfiguration>(buf);
} }
inline const Frontend::RobotConfiguration *GetSizePrefixedRobotConfiguration(const void *buf) { inline const Frontend::RobotConfiguration *
return ::flatbuffers::GetSizePrefixedRoot<Frontend::RobotConfiguration>(buf); GetSizePrefixedRobotConfiguration(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Frontend::RobotConfiguration>(buf);
} }
inline bool VerifyRobotConfigurationBuffer(::flatbuffers::Verifier &verifier) { inline bool VerifyRobotConfigurationBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<Frontend::RobotConfiguration>(nullptr); return verifier.VerifyBuffer<Frontend::RobotConfiguration>(nullptr);
} }
inline bool VerifySizePrefixedRobotConfigurationBuffer(::flatbuffers::Verifier &verifier) { inline bool
return verifier.VerifySizePrefixedBuffer<Frontend::RobotConfiguration>(nullptr); VerifySizePrefixedRobotConfigurationBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<Frontend::RobotConfiguration>(
nullptr);
} }
inline void inline void FinishRobotConfigurationBuffer(
FinishRobotConfigurationBuffer(::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Frontend::RobotConfiguration> root) { ::flatbuffers::Offset<Frontend::RobotConfiguration> root) {
fbb.Finish(root); fbb.Finish(root);
} }
inline void FinishSizePrefixedRobotConfigurationBuffer( inline void FinishSizePrefixedRobotConfigurationBuffer(
::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Frontend::RobotConfiguration> root) { ::flatbuffers::Offset<Frontend::RobotConfiguration> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }
} // namespace Frontend } // namespace Frontend

View File

@@ -19,200 +19,227 @@ struct RobotModule;
struct RobotModuleBuilder; struct RobotModuleBuilder;
enum ModuleType : int8_t { enum ModuleType : int8_t {
ModuleType_SPLITTER = 0, ModuleType_SPLITTER = 0,
ModuleType_SERVO_1 = 1, ModuleType_SERVO_1 = 1,
ModuleType_DC_MOTOR = 2, ModuleType_DC_MOTOR = 2,
ModuleType_BATTERY = 3, ModuleType_BATTERY = 3,
ModuleType_SERVO_2 = 4, ModuleType_SERVO_2 = 4,
ModuleType_MIN = ModuleType_SPLITTER, ModuleType_DISPLAY = 5,
ModuleType_MAX = ModuleType_SERVO_2 ModuleType_GRIPPER = 6,
ModuleType_SPEAKER = 7,
ModuleType_IMU = 8,
ModuleType_DISTANCE_SENSOR = 9,
ModuleType_SPLITTER_2 = 10,
ModuleType_SPLITTER_3 = 11,
ModuleType_SPLITTER_4 = 12,
ModuleType_SPLITTER_5 = 13,
ModuleType_SPLITTER_6 = 14,
ModuleType_SPLITTER_7 = 15,
ModuleType_SPLITTER_8 = 16,
ModuleType_MIN = ModuleType_SPLITTER,
ModuleType_MAX = ModuleType_SPLITTER_8
}; };
inline const ModuleType (&EnumValuesModuleType())[5] { inline const ModuleType (&EnumValuesModuleType())[17] {
static const ModuleType values[] = {ModuleType_SPLITTER, ModuleType_SERVO_1, static const ModuleType values[] = {
ModuleType_DC_MOTOR, ModuleType_BATTERY, ModuleType_SPLITTER, ModuleType_SERVO_1, ModuleType_DC_MOTOR,
ModuleType_SERVO_2}; ModuleType_BATTERY, ModuleType_SERVO_2, ModuleType_DISPLAY,
return values; ModuleType_GRIPPER, ModuleType_SPEAKER, ModuleType_IMU,
ModuleType_DISTANCE_SENSOR, ModuleType_SPLITTER_2, ModuleType_SPLITTER_3,
ModuleType_SPLITTER_4, ModuleType_SPLITTER_5, ModuleType_SPLITTER_6,
ModuleType_SPLITTER_7, ModuleType_SPLITTER_8};
return values;
} }
inline const char *const *EnumNamesModuleType() { inline const char *const *EnumNamesModuleType() {
static const char *const names[6] = {"SPLITTER", "SERVO_1", "DC_MOTOR", static const char *const names[18] = {
"BATTERY", "SERVO_2", nullptr}; "SPLITTER", "SERVO_1", "DC_MOTOR", "BATTERY", "SERVO_2",
return names; "DISPLAY", "GRIPPER", "SPEAKER", "IMU", "DISTANCE_SENSOR",
"SPLITTER_2", "SPLITTER_3", "SPLITTER_4", "SPLITTER_5", "SPLITTER_6",
"SPLITTER_7", "SPLITTER_8", nullptr};
return names;
} }
inline const char *EnumNameModuleType(ModuleType e) { inline const char *EnumNameModuleType(ModuleType e) {
if (::flatbuffers::IsOutRange(e, ModuleType_SPLITTER, ModuleType_SERVO_2)) if (::flatbuffers::IsOutRange(e, ModuleType_SPLITTER, ModuleType_SPLITTER_8))
return ""; return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesModuleType()[index]; return EnumNamesModuleType()[index];
} }
enum Orientation : int8_t { enum Orientation : int8_t {
Orientation_Deg0 = 0, Orientation_Deg0 = 0,
Orientation_Deg90 = 1, Orientation_Deg90 = 1,
Orientation_Deg180 = 2, Orientation_Deg180 = 2,
Orientation_Deg270 = 3, Orientation_Deg270 = 3,
Orientation_MIN = Orientation_Deg0, Orientation_MIN = Orientation_Deg0,
Orientation_MAX = Orientation_Deg270 Orientation_MAX = Orientation_Deg270
}; };
inline const Orientation (&EnumValuesOrientation())[4] { inline const Orientation (&EnumValuesOrientation())[4] {
static const Orientation values[] = {Orientation_Deg0, Orientation_Deg90, Orientation_Deg180, static const Orientation values[] = {Orientation_Deg0, Orientation_Deg90,
Orientation_Deg270}; Orientation_Deg180, Orientation_Deg270};
return values; return values;
} }
inline const char *const *EnumNamesOrientation() { inline const char *const *EnumNamesOrientation() {
static const char *const names[5] = {"Deg0", "Deg90", "Deg180", "Deg270", nullptr}; static const char *const names[5] = {"Deg0", "Deg90", "Deg180", "Deg270",
return names; nullptr};
return names;
} }
inline const char *EnumNameOrientation(Orientation e) { inline const char *EnumNameOrientation(Orientation e) {
if (::flatbuffers::IsOutRange(e, Orientation_Deg0, Orientation_Deg270)) if (::flatbuffers::IsOutRange(e, Orientation_Deg0, Orientation_Deg270))
return ""; return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesOrientation()[index]; return EnumNamesOrientation()[index];
} }
enum ModuleState : uint8_t { enum ModuleState : uint8_t {
ModuleState_NONE = 0, ModuleState_NONE = 0,
ModuleState_MotorState = 1, ModuleState_MotorState = 1,
ModuleState_MIN = ModuleState_NONE, ModuleState_MIN = ModuleState_NONE,
ModuleState_MAX = ModuleState_MotorState ModuleState_MAX = ModuleState_MotorState
}; };
inline const ModuleState (&EnumValuesModuleState())[2] { inline const ModuleState (&EnumValuesModuleState())[2] {
static const ModuleState values[] = {ModuleState_NONE, ModuleState_MotorState}; static const ModuleState values[] = {ModuleState_NONE,
return values; ModuleState_MotorState};
return values;
} }
inline const char *const *EnumNamesModuleState() { inline const char *const *EnumNamesModuleState() {
static const char *const names[3] = {"NONE", "MotorState", nullptr}; static const char *const names[3] = {"NONE", "MotorState", nullptr};
return names; return names;
} }
inline const char *EnumNameModuleState(ModuleState e) { inline const char *EnumNameModuleState(ModuleState e) {
if (::flatbuffers::IsOutRange(e, ModuleState_NONE, ModuleState_MotorState)) if (::flatbuffers::IsOutRange(e, ModuleState_NONE, ModuleState_MotorState))
return ""; return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesModuleState()[index]; return EnumNamesModuleState()[index];
} }
template <typename T> struct ModuleStateTraits { template <typename T> struct ModuleStateTraits {
static const ModuleState enum_value = ModuleState_NONE; static const ModuleState enum_value = ModuleState_NONE;
}; };
template <> struct ModuleStateTraits<MotorState> { template <> struct ModuleStateTraits<MotorState> {
static const ModuleState enum_value = ModuleState_MotorState; static const ModuleState enum_value = ModuleState_MotorState;
}; };
bool VerifyModuleState(::flatbuffers::Verifier &verifier, const void *obj, ModuleState type); bool VerifyModuleState(::flatbuffers::Verifier &verifier, const void *obj,
bool VerifyModuleStateVector(::flatbuffers::Verifier &verifier, ModuleState type);
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values, bool VerifyModuleStateVector(
const ::flatbuffers::Vector<uint8_t> *types); ::flatbuffers::Verifier &verifier,
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
const ::flatbuffers::Vector<uint8_t> *types);
struct MotorState FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct MotorState FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef MotorStateBuilder Builder; typedef MotorStateBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ANGLE = 4 }; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
int32_t angle() const { VT_ANGLE = 4
return GetField<int32_t>(VT_ANGLE, 0); };
} int32_t angle() const { return GetField<int32_t>(VT_ANGLE, 0); }
bool Verify(::flatbuffers::Verifier &verifier) const { bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && VerifyField<int32_t>(verifier, VT_ANGLE, 4) && return VerifyTableStart(verifier) &&
verifier.EndTable(); VerifyField<int32_t>(verifier, VT_ANGLE, 4) && verifier.EndTable();
} }
}; };
struct MotorStateBuilder { struct MotorStateBuilder {
typedef MotorState Table; typedef MotorState Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_angle(int32_t angle) { void add_angle(int32_t angle) {
fbb_.AddElement<int32_t>(MotorState::VT_ANGLE, angle, 0); fbb_.AddElement<int32_t>(MotorState::VT_ANGLE, angle, 0);
} }
explicit MotorStateBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { explicit MotorStateBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
start_ = fbb_.StartTable(); : fbb_(_fbb) {
} start_ = fbb_.StartTable();
::flatbuffers::Offset<MotorState> Finish() { }
const auto end = fbb_.EndTable(start_); ::flatbuffers::Offset<MotorState> Finish() {
auto o = ::flatbuffers::Offset<MotorState>(end); const auto end = fbb_.EndTable(start_);
return o; auto o = ::flatbuffers::Offset<MotorState>(end);
} return o;
}
}; };
inline ::flatbuffers::Offset<MotorState> CreateMotorState(::flatbuffers::FlatBufferBuilder &_fbb, inline ::flatbuffers::Offset<MotorState>
int32_t angle = 0) { CreateMotorState(::flatbuffers::FlatBufferBuilder &_fbb, int32_t angle = 0) {
MotorStateBuilder builder_(_fbb); MotorStateBuilder builder_(_fbb);
builder_.add_angle(angle); builder_.add_angle(angle);
return builder_.Finish(); return builder_.Finish();
} }
struct RobotModule FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct RobotModule FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef RobotModuleBuilder Builder; typedef RobotModuleBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_ID = 4, VT_ID = 4,
VT_MODULE_TYPE = 6, VT_MODULE_TYPE = 6,
VT_CONFIGURATION_TYPE = 8, VT_CONFIGURATION_TYPE = 8,
VT_CONFIGURATION = 10 VT_CONFIGURATION = 10
}; };
uint8_t id() const { uint8_t id() const { return GetField<uint8_t>(VT_ID, 0); }
return GetField<uint8_t>(VT_ID, 0); ModuleType module_type() const {
} return static_cast<ModuleType>(GetField<int8_t>(VT_MODULE_TYPE, 0));
ModuleType module_type() const { }
return static_cast<ModuleType>(GetField<int8_t>(VT_MODULE_TYPE, 0)); ModuleState configuration_type() const {
} return static_cast<ModuleState>(
ModuleState configuration_type() const { GetField<uint8_t>(VT_CONFIGURATION_TYPE, 0));
return static_cast<ModuleState>(GetField<uint8_t>(VT_CONFIGURATION_TYPE, 0)); }
} const void *configuration() const {
const void *configuration() const { return GetPointer<const void *>(VT_CONFIGURATION);
return GetPointer<const void *>(VT_CONFIGURATION); }
} template <typename T> const T *configuration_as() const;
template <typename T> const T *configuration_as() const; const MotorState *configuration_as_MotorState() const {
const MotorState *configuration_as_MotorState() const { return configuration_type() == ModuleState_MotorState
return configuration_type() == ModuleState_MotorState ? static_cast<const MotorState *>(configuration())
? static_cast<const MotorState *>(configuration()) : nullptr;
: nullptr; }
} bool Verify(::flatbuffers::Verifier &verifier) const {
bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) &&
return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_ID, 1) && VerifyField<uint8_t>(verifier, VT_ID, 1) &&
VerifyField<int8_t>(verifier, VT_MODULE_TYPE, 1) && VerifyField<int8_t>(verifier, VT_MODULE_TYPE, 1) &&
VerifyField<uint8_t>(verifier, VT_CONFIGURATION_TYPE, 1) && VerifyField<uint8_t>(verifier, VT_CONFIGURATION_TYPE, 1) &&
VerifyOffset(verifier, VT_CONFIGURATION) && VerifyOffset(verifier, VT_CONFIGURATION) &&
VerifyModuleState(verifier, configuration(), configuration_type()) && VerifyModuleState(verifier, configuration(), configuration_type()) &&
verifier.EndTable(); verifier.EndTable();
} }
}; };
template <> inline const MotorState *RobotModule::configuration_as<MotorState>() const { template <>
return configuration_as_MotorState(); inline const MotorState *RobotModule::configuration_as<MotorState>() const {
return configuration_as_MotorState();
} }
struct RobotModuleBuilder { struct RobotModuleBuilder {
typedef RobotModule Table; typedef RobotModule Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_id(uint8_t id) { void add_id(uint8_t id) {
fbb_.AddElement<uint8_t>(RobotModule::VT_ID, id, 0); fbb_.AddElement<uint8_t>(RobotModule::VT_ID, id, 0);
} }
void add_module_type(ModuleType module_type) { void add_module_type(ModuleType module_type) {
fbb_.AddElement<int8_t>(RobotModule::VT_MODULE_TYPE, static_cast<int8_t>(module_type), 0); fbb_.AddElement<int8_t>(RobotModule::VT_MODULE_TYPE,
} static_cast<int8_t>(module_type), 0);
void add_configuration_type(ModuleState configuration_type) { }
fbb_.AddElement<uint8_t>(RobotModule::VT_CONFIGURATION_TYPE, void add_configuration_type(ModuleState configuration_type) {
static_cast<uint8_t>(configuration_type), 0); fbb_.AddElement<uint8_t>(RobotModule::VT_CONFIGURATION_TYPE,
} static_cast<uint8_t>(configuration_type), 0);
void add_configuration(::flatbuffers::Offset<void> configuration) { }
fbb_.AddOffset(RobotModule::VT_CONFIGURATION, configuration); void add_configuration(::flatbuffers::Offset<void> configuration) {
} fbb_.AddOffset(RobotModule::VT_CONFIGURATION, configuration);
explicit RobotModuleBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { }
start_ = fbb_.StartTable(); explicit RobotModuleBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
} : fbb_(_fbb) {
::flatbuffers::Offset<RobotModule> Finish() { start_ = fbb_.StartTable();
const auto end = fbb_.EndTable(start_); }
auto o = ::flatbuffers::Offset<RobotModule>(end); ::flatbuffers::Offset<RobotModule> Finish() {
return o; const auto end = fbb_.EndTable(start_);
} auto o = ::flatbuffers::Offset<RobotModule>(end);
return o;
}
}; };
inline ::flatbuffers::Offset<RobotModule> inline ::flatbuffers::Offset<RobotModule>
@@ -220,69 +247,72 @@ CreateRobotModule(::flatbuffers::FlatBufferBuilder &_fbb, uint8_t id = 0,
ModuleType module_type = ModuleType_SPLITTER, ModuleType module_type = ModuleType_SPLITTER,
ModuleState configuration_type = ModuleState_NONE, ModuleState configuration_type = ModuleState_NONE,
::flatbuffers::Offset<void> configuration = 0) { ::flatbuffers::Offset<void> configuration = 0) {
RobotModuleBuilder builder_(_fbb); RobotModuleBuilder builder_(_fbb);
builder_.add_configuration(configuration); builder_.add_configuration(configuration);
builder_.add_configuration_type(configuration_type); builder_.add_configuration_type(configuration_type);
builder_.add_module_type(module_type); builder_.add_module_type(module_type);
builder_.add_id(id); builder_.add_id(id);
return builder_.Finish(); return builder_.Finish();
} }
inline bool VerifyModuleState(::flatbuffers::Verifier &verifier, const void *obj, inline bool VerifyModuleState(::flatbuffers::Verifier &verifier,
ModuleState type) { const void *obj, ModuleState type) {
switch (type) { switch (type) {
case ModuleState_NONE: { case ModuleState_NONE: {
return true;
}
case ModuleState_MotorState: {
auto ptr = reinterpret_cast<const MotorState *>(obj);
return verifier.VerifyTable(ptr);
}
default:
return true;
}
}
inline bool
VerifyModuleStateVector(::flatbuffers::Verifier &verifier,
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
const ::flatbuffers::Vector<uint8_t> *types) {
if (!values || !types)
return !values && !types;
if (values->size() != types->size())
return false;
for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifyModuleState(verifier, values->Get(i), types->GetEnum<ModuleState>(i))) {
return false;
}
}
return true; return true;
}
case ModuleState_MotorState: {
auto ptr = reinterpret_cast<const MotorState *>(obj);
return verifier.VerifyTable(ptr);
}
default:
return true;
}
}
inline bool VerifyModuleStateVector(
::flatbuffers::Verifier &verifier,
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
const ::flatbuffers::Vector<uint8_t> *types) {
if (!values || !types)
return !values && !types;
if (values->size() != types->size())
return false;
for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifyModuleState(verifier, values->Get(i),
types->GetEnum<ModuleState>(i))) {
return false;
}
}
return true;
} }
inline const RobotModule *GetRobotModule(const void *buf) { inline const RobotModule *GetRobotModule(const void *buf) {
return ::flatbuffers::GetRoot<RobotModule>(buf); return ::flatbuffers::GetRoot<RobotModule>(buf);
} }
inline const RobotModule *GetSizePrefixedRobotModule(const void *buf) { inline const RobotModule *GetSizePrefixedRobotModule(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<RobotModule>(buf); return ::flatbuffers::GetSizePrefixedRoot<RobotModule>(buf);
} }
inline bool VerifyRobotModuleBuffer(::flatbuffers::Verifier &verifier) { inline bool VerifyRobotModuleBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<RobotModule>(nullptr); return verifier.VerifyBuffer<RobotModule>(nullptr);
} }
inline bool VerifySizePrefixedRobotModuleBuffer(::flatbuffers::Verifier &verifier) { inline bool
return verifier.VerifySizePrefixedBuffer<RobotModule>(nullptr); VerifySizePrefixedRobotModuleBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<RobotModule>(nullptr);
} }
inline void FinishRobotModuleBuffer(::flatbuffers::FlatBufferBuilder &fbb, inline void FinishRobotModuleBuffer(::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<RobotModule> root) { ::flatbuffers::Offset<RobotModule> root) {
fbb.Finish(root); fbb.Finish(root);
} }
inline void FinishSizePrefixedRobotModuleBuffer(::flatbuffers::FlatBufferBuilder &fbb, inline void
::flatbuffers::Offset<RobotModule> root) { FinishSizePrefixedRobotModuleBuffer(::flatbuffers::FlatBufferBuilder &fbb,
fbb.FinishSizePrefixed(root); ::flatbuffers::Offset<RobotModule> root) {
fbb.FinishSizePrefixed(root);
} }
#endif // FLATBUFFERS_GENERATED_ROBOTMODULE_H_ #endif // FLATBUFFERS_GENERATED_ROBOTMODULE_H_

View File

@@ -8,15 +8,18 @@
// Ensure the included flatbuffers.h is the same version as when this file was // Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible. // generated, otherwise it may not be compatible.
// static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && // static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
// FLATBUFFERS_VERSION_MINOR == 2 && // FLATBUFFERS_VERSION_MINOR == 2 &&
// FLATBUFFERS_VERSION_REVISION == 10, // FLATBUFFERS_VERSION_REVISION == 10,
// "Non-compatible flatbuffers version included"); // "Non-compatible flatbuffers version included");
namespace Messaging { namespace Messaging {
struct TargetAngle; struct TargetAngle;
struct TargetAngleBuilder; struct TargetAngleBuilder;
struct CurrentText;
struct CurrentTextBuilder;
struct CurrentAngle; struct CurrentAngle;
struct CurrentAngleBuilder; struct CurrentAngleBuilder;
@@ -24,240 +27,316 @@ struct SensorMessage;
struct SensorMessageBuilder; struct SensorMessageBuilder;
enum SensorValue : uint8_t { enum SensorValue : uint8_t {
SensorValue_NONE = 0, SensorValue_NONE = 0,
SensorValue_TargetAngle = 1, SensorValue_TargetAngle = 1,
SensorValue_CurrentAngle = 2, SensorValue_CurrentAngle = 2,
SensorValue_MIN = SensorValue_NONE, SensorValue_CurrentText = 3,
SensorValue_MAX = SensorValue_CurrentAngle SensorValue_MIN = SensorValue_NONE,
SensorValue_MAX = SensorValue_CurrentText
}; };
inline const SensorValue (&EnumValuesSensorValue())[3] { inline const SensorValue (&EnumValuesSensorValue())[4] {
static const SensorValue values[] = {SensorValue_NONE, SensorValue_TargetAngle, static const SensorValue values[] = {
SensorValue_CurrentAngle}; SensorValue_NONE, SensorValue_TargetAngle, SensorValue_CurrentAngle,
return values; SensorValue_CurrentText};
return values;
} }
inline const char *const *EnumNamesSensorValue() { inline const char *const *EnumNamesSensorValue() {
static const char *const names[4] = {"NONE", "TargetAngle", "CurrentAngle", nullptr}; static const char *const names[5] = {"NONE", "TargetAngle", "CurrentAngle",
return names; "CurrentText", nullptr};
return names;
} }
inline const char *EnumNameSensorValue(SensorValue e) { inline const char *EnumNameSensorValue(SensorValue e) {
if (::flatbuffers::IsOutRange(e, SensorValue_NONE, SensorValue_CurrentAngle)) if (::flatbuffers::IsOutRange(e, SensorValue_NONE, SensorValue_CurrentText))
return ""; return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesSensorValue()[index]; return EnumNamesSensorValue()[index];
} }
template <typename T> struct SensorValueTraits { template <typename T> struct SensorValueTraits {
static const SensorValue enum_value = SensorValue_NONE; static const SensorValue enum_value = SensorValue_NONE;
}; };
template <> struct SensorValueTraits<Messaging::TargetAngle> { template <> struct SensorValueTraits<Messaging::TargetAngle> {
static const SensorValue enum_value = SensorValue_TargetAngle; static const SensorValue enum_value = SensorValue_TargetAngle;
}; };
template <> struct SensorValueTraits<Messaging::CurrentAngle> { template <> struct SensorValueTraits<Messaging::CurrentAngle> {
static const SensorValue enum_value = SensorValue_CurrentAngle; static const SensorValue enum_value = SensorValue_CurrentAngle;
}; };
bool VerifySensorValue(::flatbuffers::Verifier &verifier, const void *obj, SensorValue type); template <> struct SensorValueTraits<Messaging::CurrentText> {
bool VerifySensorValueVector(::flatbuffers::Verifier &verifier, static const SensorValue enum_value = SensorValue_CurrentText;
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values, };
const ::flatbuffers::Vector<uint8_t> *types);
bool VerifySensorValue(::flatbuffers::Verifier &verifier, const void *obj,
SensorValue type);
bool VerifySensorValueVector(
::flatbuffers::Verifier &verifier,
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
const ::flatbuffers::Vector<uint8_t> *types);
struct TargetAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct TargetAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef TargetAngleBuilder Builder; typedef TargetAngleBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_VALUE = 4 }; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
int16_t value() const { VT_VALUE = 4
return GetField<int16_t>(VT_VALUE, 0); };
} int16_t value() const { return GetField<int16_t>(VT_VALUE, 0); }
bool Verify(::flatbuffers::Verifier &verifier) const { bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && VerifyField<int16_t>(verifier, VT_VALUE, 2) && return VerifyTableStart(verifier) &&
verifier.EndTable(); VerifyField<int16_t>(verifier, VT_VALUE, 2) && verifier.EndTable();
} }
}; };
struct TargetAngleBuilder { struct TargetAngleBuilder {
typedef TargetAngle Table; typedef TargetAngle Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_value(int16_t value) { void add_value(int16_t value) {
fbb_.AddElement<int16_t>(TargetAngle::VT_VALUE, value, 0); fbb_.AddElement<int16_t>(TargetAngle::VT_VALUE, value, 0);
} }
explicit TargetAngleBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { explicit TargetAngleBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
start_ = fbb_.StartTable(); : fbb_(_fbb) {
} start_ = fbb_.StartTable();
::flatbuffers::Offset<TargetAngle> Finish() { }
const auto end = fbb_.EndTable(start_); ::flatbuffers::Offset<TargetAngle> Finish() {
auto o = ::flatbuffers::Offset<TargetAngle>(end); const auto end = fbb_.EndTable(start_);
return o; auto o = ::flatbuffers::Offset<TargetAngle>(end);
} return o;
}
}; };
inline ::flatbuffers::Offset<TargetAngle> CreateTargetAngle(::flatbuffers::FlatBufferBuilder &_fbb, inline ::flatbuffers::Offset<TargetAngle>
int16_t value = 0) { CreateTargetAngle(::flatbuffers::FlatBufferBuilder &_fbb, int16_t value = 0) {
TargetAngleBuilder builder_(_fbb); TargetAngleBuilder builder_(_fbb);
builder_.add_value(value); builder_.add_value(value);
return builder_.Finish(); return builder_.Finish();
}
struct CurrentText FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef CurrentTextBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_VALUE = 4
};
const ::flatbuffers::String *value() const {
return GetPointer<const ::flatbuffers::String *>(VT_VALUE);
}
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_VALUE) &&
verifier.VerifyString(value()) && verifier.EndTable();
}
};
struct CurrentTextBuilder {
typedef CurrentText Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_value(::flatbuffers::Offset<::flatbuffers::String> value) {
fbb_.AddOffset(CurrentText::VT_VALUE, value);
}
explicit CurrentTextBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<CurrentText> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<CurrentText>(end);
return o;
}
};
inline ::flatbuffers::Offset<CurrentText>
CreateCurrentText(::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<::flatbuffers::String> value = 0) {
CurrentTextBuilder builder_(_fbb);
builder_.add_value(value);
return builder_.Finish();
}
inline ::flatbuffers::Offset<CurrentText>
CreateCurrentTextDirect(::flatbuffers::FlatBufferBuilder &_fbb,
const char *value = nullptr) {
auto value__ = value ? _fbb.CreateString(value) : 0;
return Messaging::CreateCurrentText(_fbb, value__);
} }
struct CurrentAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct CurrentAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef CurrentAngleBuilder Builder; typedef CurrentAngleBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_VALUE = 4 }; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
int16_t value() const { VT_VALUE = 4
return GetField<int16_t>(VT_VALUE, 0); };
} int16_t value() const { return GetField<int16_t>(VT_VALUE, 0); }
bool Verify(::flatbuffers::Verifier &verifier) const { bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && VerifyField<int16_t>(verifier, VT_VALUE, 2) && return VerifyTableStart(verifier) &&
verifier.EndTable(); VerifyField<int16_t>(verifier, VT_VALUE, 2) && verifier.EndTable();
} }
}; };
struct CurrentAngleBuilder { struct CurrentAngleBuilder {
typedef CurrentAngle Table; typedef CurrentAngle Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_value(int16_t value) { void add_value(int16_t value) {
fbb_.AddElement<int16_t>(CurrentAngle::VT_VALUE, value, 0); fbb_.AddElement<int16_t>(CurrentAngle::VT_VALUE, value, 0);
} }
explicit CurrentAngleBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { explicit CurrentAngleBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
start_ = fbb_.StartTable(); : fbb_(_fbb) {
} start_ = fbb_.StartTable();
::flatbuffers::Offset<CurrentAngle> Finish() { }
const auto end = fbb_.EndTable(start_); ::flatbuffers::Offset<CurrentAngle> Finish() {
auto o = ::flatbuffers::Offset<CurrentAngle>(end); const auto end = fbb_.EndTable(start_);
return o; auto o = ::flatbuffers::Offset<CurrentAngle>(end);
} return o;
}
}; };
inline ::flatbuffers::Offset<CurrentAngle> inline ::flatbuffers::Offset<CurrentAngle>
CreateCurrentAngle(::flatbuffers::FlatBufferBuilder &_fbb, int16_t value = 0) { CreateCurrentAngle(::flatbuffers::FlatBufferBuilder &_fbb, int16_t value = 0) {
CurrentAngleBuilder builder_(_fbb); CurrentAngleBuilder builder_(_fbb);
builder_.add_value(value); builder_.add_value(value);
return builder_.Finish(); return builder_.Finish();
} }
struct SensorMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct SensorMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef SensorMessageBuilder Builder; typedef SensorMessageBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_VALUES_TYPE = 4, VT_VALUES_TYPE = 4,
VT_VALUES = 6 VT_VALUES = 6
}; };
const ::flatbuffers::Vector<uint8_t> *values_type() const { const ::flatbuffers::Vector<uint8_t> *values_type() const {
return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_VALUES_TYPE); return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_VALUES_TYPE);
} }
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values() const { const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values() const {
return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_VALUES); return GetPointer<
} const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_VALUES);
bool Verify(::flatbuffers::Verifier &verifier) const { }
return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_VALUES_TYPE) && bool Verify(::flatbuffers::Verifier &verifier) const {
verifier.VerifyVector(values_type()) && VerifyOffset(verifier, VT_VALUES) && return VerifyTableStart(verifier) &&
verifier.VerifyVector(values()) && VerifyOffset(verifier, VT_VALUES_TYPE) &&
VerifySensorValueVector(verifier, values(), values_type()) && verifier.EndTable(); verifier.VerifyVector(values_type()) &&
} VerifyOffset(verifier, VT_VALUES) &&
verifier.VerifyVector(values()) &&
VerifySensorValueVector(verifier, values(), values_type()) &&
verifier.EndTable();
}
}; };
struct SensorMessageBuilder { struct SensorMessageBuilder {
typedef SensorMessage Table; typedef SensorMessage Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_values_type(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type) { void add_values_type(
fbb_.AddOffset(SensorMessage::VT_VALUES_TYPE, values_type); ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type) {
} fbb_.AddOffset(SensorMessage::VT_VALUES_TYPE, values_type);
void }
add_values(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> values) { void add_values(
fbb_.AddOffset(SensorMessage::VT_VALUES, values); ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>>
} values) {
explicit SensorMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { fbb_.AddOffset(SensorMessage::VT_VALUES, values);
start_ = fbb_.StartTable(); }
} explicit SensorMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
::flatbuffers::Offset<SensorMessage> Finish() { : fbb_(_fbb) {
const auto end = fbb_.EndTable(start_); start_ = fbb_.StartTable();
auto o = ::flatbuffers::Offset<SensorMessage>(end); }
return o; ::flatbuffers::Offset<SensorMessage> Finish() {
} const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<SensorMessage>(end);
return o;
}
}; };
inline ::flatbuffers::Offset<SensorMessage> CreateSensorMessage( inline ::flatbuffers::Offset<SensorMessage> CreateSensorMessage(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type = 0, ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type = 0,
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> values = 0) { ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>>
SensorMessageBuilder builder_(_fbb); values = 0) {
builder_.add_values(values); SensorMessageBuilder builder_(_fbb);
builder_.add_values_type(values_type); builder_.add_values(values);
return builder_.Finish(); builder_.add_values_type(values_type);
return builder_.Finish();
} }
inline ::flatbuffers::Offset<SensorMessage> inline ::flatbuffers::Offset<SensorMessage> CreateSensorMessageDirect(
CreateSensorMessageDirect(::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder &_fbb,
const std::vector<uint8_t> *values_type = nullptr, const std::vector<uint8_t> *values_type = nullptr,
const std::vector<::flatbuffers::Offset<void>> *values = nullptr) { const std::vector<::flatbuffers::Offset<void>> *values = nullptr) {
auto values_type__ = values_type ? _fbb.CreateVector<uint8_t>(*values_type) : 0; auto values_type__ =
auto values__ = values ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*values) : 0; values_type ? _fbb.CreateVector<uint8_t>(*values_type) : 0;
return Messaging::CreateSensorMessage(_fbb, values_type__, values__); auto values__ =
values ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*values) : 0;
return Messaging::CreateSensorMessage(_fbb, values_type__, values__);
} }
inline bool VerifySensorValue(::flatbuffers::Verifier &verifier, const void *obj, inline bool VerifySensorValue(::flatbuffers::Verifier &verifier,
SensorValue type) { const void *obj, SensorValue type) {
switch (type) { switch (type) {
case SensorValue_NONE: { case SensorValue_NONE: {
return true;
}
case SensorValue_TargetAngle: {
auto ptr = reinterpret_cast<const Messaging::TargetAngle *>(obj);
return verifier.VerifyTable(ptr);
}
case SensorValue_CurrentAngle: {
auto ptr = reinterpret_cast<const Messaging::CurrentAngle *>(obj);
return verifier.VerifyTable(ptr);
}
default:
return true;
}
}
inline bool
VerifySensorValueVector(::flatbuffers::Verifier &verifier,
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
const ::flatbuffers::Vector<uint8_t> *types) {
if (!values || !types)
return !values && !types;
if (values->size() != types->size())
return false;
for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifySensorValue(verifier, values->Get(i), types->GetEnum<SensorValue>(i))) {
return false;
}
}
return true; return true;
}
case SensorValue_TargetAngle: {
auto ptr = reinterpret_cast<const Messaging::TargetAngle *>(obj);
return verifier.VerifyTable(ptr);
}
case SensorValue_CurrentAngle: {
auto ptr = reinterpret_cast<const Messaging::CurrentAngle *>(obj);
return verifier.VerifyTable(ptr);
}
case SensorValue_CurrentText: {
auto ptr = reinterpret_cast<const Messaging::CurrentText *>(obj);
return verifier.VerifyTable(ptr);
}
default:
return true;
}
}
inline bool VerifySensorValueVector(
::flatbuffers::Verifier &verifier,
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
const ::flatbuffers::Vector<uint8_t> *types) {
if (!values || !types)
return !values && !types;
if (values->size() != types->size())
return false;
for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifySensorValue(verifier, values->Get(i),
types->GetEnum<SensorValue>(i))) {
return false;
}
}
return true;
} }
inline const Messaging::SensorMessage *GetSensorMessage(const void *buf) { inline const Messaging::SensorMessage *GetSensorMessage(const void *buf) {
return ::flatbuffers::GetRoot<Messaging::SensorMessage>(buf); return ::flatbuffers::GetRoot<Messaging::SensorMessage>(buf);
} }
inline const Messaging::SensorMessage *GetSizePrefixedSensorMessage(const void *buf) { inline const Messaging::SensorMessage *
return ::flatbuffers::GetSizePrefixedRoot<Messaging::SensorMessage>(buf); GetSizePrefixedSensorMessage(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Messaging::SensorMessage>(buf);
} }
inline bool VerifySensorMessageBuffer(::flatbuffers::Verifier &verifier) { inline bool VerifySensorMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<Messaging::SensorMessage>(nullptr); return verifier.VerifyBuffer<Messaging::SensorMessage>(nullptr);
} }
inline bool VerifySizePrefixedSensorMessageBuffer(::flatbuffers::Verifier &verifier) { inline bool
return verifier.VerifySizePrefixedBuffer<Messaging::SensorMessage>(nullptr); VerifySizePrefixedSensorMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<Messaging::SensorMessage>(nullptr);
} }
inline void FinishSensorMessageBuffer(::flatbuffers::FlatBufferBuilder &fbb, inline void FinishSensorMessageBuffer(
::flatbuffers::Offset<Messaging::SensorMessage> root) { ::flatbuffers::FlatBufferBuilder &fbb,
fbb.Finish(root); ::flatbuffers::Offset<Messaging::SensorMessage> root) {
fbb.Finish(root);
} }
inline void inline void FinishSizePrefixedSensorMessageBuffer(
FinishSizePrefixedSensorMessageBuffer(::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Messaging::SensorMessage> root) { ::flatbuffers::Offset<Messaging::SensorMessage> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }
} // namespace Messaging } // namespace Messaging

View File

@@ -0,0 +1,102 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_TEXTCONTROLMESSAGE_MESSAGING_H_
#define FLATBUFFERS_GENERATED_TEXTCONTROLMESSAGE_MESSAGING_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
// static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
// FLATBUFFERS_VERSION_MINOR == 2 &&
// FLATBUFFERS_VERSION_REVISION == 10,
// "Non-compatible flatbuffers version included");
namespace Messaging {
struct TextControlMessage;
struct TextControlMessageBuilder;
struct TextControlMessage FLATBUFFERS_FINAL_CLASS
: private ::flatbuffers::Table {
typedef TextControlMessageBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_MESSAGE = 4
};
const ::flatbuffers::String *message() const {
return GetPointer<const ::flatbuffers::String *>(VT_MESSAGE);
}
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_MESSAGE) &&
verifier.VerifyString(message()) && verifier.EndTable();
}
};
struct TextControlMessageBuilder {
typedef TextControlMessage Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_message(::flatbuffers::Offset<::flatbuffers::String> message) {
fbb_.AddOffset(TextControlMessage::VT_MESSAGE, message);
}
explicit TextControlMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<TextControlMessage> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<TextControlMessage>(end);
return o;
}
};
inline ::flatbuffers::Offset<TextControlMessage> CreateTextControlMessage(
::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<::flatbuffers::String> message = 0) {
TextControlMessageBuilder builder_(_fbb);
builder_.add_message(message);
return builder_.Finish();
}
inline ::flatbuffers::Offset<TextControlMessage>
CreateTextControlMessageDirect(::flatbuffers::FlatBufferBuilder &_fbb,
const char *message = nullptr) {
auto message__ = message ? _fbb.CreateString(message) : 0;
return Messaging::CreateTextControlMessage(_fbb, message__);
}
inline const Messaging::TextControlMessage *
GetTextControlMessage(const void *buf) {
return ::flatbuffers::GetRoot<Messaging::TextControlMessage>(buf);
}
inline const Messaging::TextControlMessage *
GetSizePrefixedTextControlMessage(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Messaging::TextControlMessage>(buf);
}
inline bool VerifyTextControlMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<Messaging::TextControlMessage>(nullptr);
}
inline bool
VerifySizePrefixedTextControlMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<Messaging::TextControlMessage>(
nullptr);
}
inline void FinishTextControlMessageBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Messaging::TextControlMessage> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedTextControlMessageBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Messaging::TextControlMessage> root) {
fbb.FinishSizePrefixed(root);
}
} // namespace Messaging
#endif // FLATBUFFERS_GENERATED_TEXTCONTROLMESSAGE_MESSAGING_H_

View File

@@ -20,182 +20,192 @@ struct TopologyMessage;
struct TopologyMessageBuilder; struct TopologyMessageBuilder;
enum ConnectionType : int8_t { enum ConnectionType : int8_t {
ConnectionType_DIRECT = 0, ConnectionType_DIRECT = 0,
ConnectionType_HOP = 1, ConnectionType_HOP = 1,
ConnectionType_MIN = ConnectionType_DIRECT, ConnectionType_MIN = ConnectionType_DIRECT,
ConnectionType_MAX = ConnectionType_HOP ConnectionType_MAX = ConnectionType_HOP
}; };
inline const ConnectionType (&EnumValuesConnectionType())[2] { inline const ConnectionType (&EnumValuesConnectionType())[2] {
static const ConnectionType values[] = {ConnectionType_DIRECT, ConnectionType_HOP}; static const ConnectionType values[] = {ConnectionType_DIRECT,
return values; ConnectionType_HOP};
return values;
} }
inline const char *const *EnumNamesConnectionType() { inline const char *const *EnumNamesConnectionType() {
static const char *const names[3] = {"DIRECT", "HOP", nullptr}; static const char *const names[3] = {"DIRECT", "HOP", nullptr};
return names; return names;
} }
inline const char *EnumNameConnectionType(ConnectionType e) { inline const char *EnumNameConnectionType(ConnectionType e) {
if (::flatbuffers::IsOutRange(e, ConnectionType_DIRECT, ConnectionType_HOP)) if (::flatbuffers::IsOutRange(e, ConnectionType_DIRECT, ConnectionType_HOP))
return ""; return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesConnectionType()[index]; return EnumNamesConnectionType()[index];
} }
struct TopologyMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct TopologyMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef TopologyMessageBuilder Builder; typedef TopologyMessageBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_MODULE_ID = 4, VT_MODULE_ID = 4,
VT_MODULE_TYPE = 6, VT_MODULE_TYPE = 6,
VT_NUM_CHANNELS = 8, VT_NUM_CHANNELS = 8,
VT_CHANNEL_TO_MODULE = 10, VT_CHANNEL_TO_MODULE = 10,
VT_CHANNEL_TO_ORIENTATION = 12, VT_CHANNEL_TO_ORIENTATION = 12,
VT_CONNECTION = 14, VT_CONNECTION = 14,
VT_LEADER = 16, VT_LEADER = 16,
VT_FIRMWARE = 18 VT_FIRMWARE = 18
}; };
uint8_t module_id() const { uint8_t module_id() const { return GetField<uint8_t>(VT_MODULE_ID, 0); }
return GetField<uint8_t>(VT_MODULE_ID, 0); ModuleType module_type() const {
} return static_cast<ModuleType>(GetField<int8_t>(VT_MODULE_TYPE, 0));
ModuleType module_type() const { }
return static_cast<ModuleType>(GetField<int8_t>(VT_MODULE_TYPE, 0)); uint8_t num_channels() const { return GetField<uint8_t>(VT_NUM_CHANNELS, 0); }
} const ::flatbuffers::Vector<uint8_t> *channel_to_module() const {
uint8_t num_channels() const { return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(
return GetField<uint8_t>(VT_NUM_CHANNELS, 0); VT_CHANNEL_TO_MODULE);
} }
const ::flatbuffers::Vector<uint8_t> *channel_to_module() const { const ::flatbuffers::Vector<int8_t> *channel_to_orientation() const {
return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_CHANNEL_TO_MODULE); return GetPointer<const ::flatbuffers::Vector<int8_t> *>(
} VT_CHANNEL_TO_ORIENTATION);
const ::flatbuffers::Vector<int8_t> *channel_to_orientation() const { }
return GetPointer<const ::flatbuffers::Vector<int8_t> *>(VT_CHANNEL_TO_ORIENTATION); Messaging::ConnectionType connection() const {
} return static_cast<Messaging::ConnectionType>(
Messaging::ConnectionType connection() const { GetField<int8_t>(VT_CONNECTION, 0));
return static_cast<Messaging::ConnectionType>(GetField<int8_t>(VT_CONNECTION, 0)); }
} uint8_t leader() const { return GetField<uint8_t>(VT_LEADER, 0); }
uint8_t leader() const { const ::flatbuffers::String *firmware() const {
return GetField<uint8_t>(VT_LEADER, 0); return GetPointer<const ::flatbuffers::String *>(VT_FIRMWARE);
} }
const ::flatbuffers::String *firmware() const { bool Verify(::flatbuffers::Verifier &verifier) const {
return GetPointer<const ::flatbuffers::String *>(VT_FIRMWARE); return VerifyTableStart(verifier) &&
} VerifyField<uint8_t>(verifier, VT_MODULE_ID, 1) &&
bool Verify(::flatbuffers::Verifier &verifier) const { VerifyField<int8_t>(verifier, VT_MODULE_TYPE, 1) &&
return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_MODULE_ID, 1) && VerifyField<uint8_t>(verifier, VT_NUM_CHANNELS, 1) &&
VerifyField<int8_t>(verifier, VT_MODULE_TYPE, 1) && VerifyOffset(verifier, VT_CHANNEL_TO_MODULE) &&
VerifyField<uint8_t>(verifier, VT_NUM_CHANNELS, 1) && verifier.VerifyVector(channel_to_module()) &&
VerifyOffset(verifier, VT_CHANNEL_TO_MODULE) && VerifyOffset(verifier, VT_CHANNEL_TO_ORIENTATION) &&
verifier.VerifyVector(channel_to_module()) && verifier.VerifyVector(channel_to_orientation()) &&
VerifyOffset(verifier, VT_CHANNEL_TO_ORIENTATION) && VerifyField<int8_t>(verifier, VT_CONNECTION, 1) &&
verifier.VerifyVector(channel_to_orientation()) && VerifyField<uint8_t>(verifier, VT_LEADER, 1) &&
VerifyField<int8_t>(verifier, VT_CONNECTION, 1) && VerifyOffset(verifier, VT_FIRMWARE) &&
VerifyField<uint8_t>(verifier, VT_LEADER, 1) && verifier.VerifyString(firmware()) && verifier.EndTable();
VerifyOffset(verifier, VT_FIRMWARE) && verifier.VerifyString(firmware()) && }
verifier.EndTable();
}
}; };
struct TopologyMessageBuilder { struct TopologyMessageBuilder {
typedef TopologyMessage Table; typedef TopologyMessage Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_module_id(uint8_t module_id) { void add_module_id(uint8_t module_id) {
fbb_.AddElement<uint8_t>(TopologyMessage::VT_MODULE_ID, module_id, 0); fbb_.AddElement<uint8_t>(TopologyMessage::VT_MODULE_ID, module_id, 0);
} }
void add_module_type(ModuleType module_type) { void add_module_type(ModuleType module_type) {
fbb_.AddElement<int8_t>(TopologyMessage::VT_MODULE_TYPE, static_cast<int8_t>(module_type), fbb_.AddElement<int8_t>(TopologyMessage::VT_MODULE_TYPE,
0); static_cast<int8_t>(module_type), 0);
} }
void add_num_channels(uint8_t num_channels) { void add_num_channels(uint8_t num_channels) {
fbb_.AddElement<uint8_t>(TopologyMessage::VT_NUM_CHANNELS, num_channels, 0); fbb_.AddElement<uint8_t>(TopologyMessage::VT_NUM_CHANNELS, num_channels, 0);
} }
void void add_channel_to_module(
add_channel_to_module(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> channel_to_module) { ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> channel_to_module) {
fbb_.AddOffset(TopologyMessage::VT_CHANNEL_TO_MODULE, channel_to_module); fbb_.AddOffset(TopologyMessage::VT_CHANNEL_TO_MODULE, channel_to_module);
} }
void add_channel_to_orientation( void add_channel_to_orientation(
::flatbuffers::Offset<::flatbuffers::Vector<int8_t>> channel_to_orientation) { ::flatbuffers::Offset<::flatbuffers::Vector<int8_t>>
fbb_.AddOffset(TopologyMessage::VT_CHANNEL_TO_ORIENTATION, channel_to_orientation); channel_to_orientation) {
} fbb_.AddOffset(TopologyMessage::VT_CHANNEL_TO_ORIENTATION,
void add_connection(Messaging::ConnectionType connection) { channel_to_orientation);
fbb_.AddElement<int8_t>(TopologyMessage::VT_CONNECTION, static_cast<int8_t>(connection), 0); }
} void add_connection(Messaging::ConnectionType connection) {
void add_leader(uint8_t leader) { fbb_.AddElement<int8_t>(TopologyMessage::VT_CONNECTION,
fbb_.AddElement<uint8_t>(TopologyMessage::VT_LEADER, leader, 0); static_cast<int8_t>(connection), 0);
} }
void add_firmware(::flatbuffers::Offset<::flatbuffers::String> firmware) { void add_leader(uint8_t leader) {
fbb_.AddOffset(TopologyMessage::VT_FIRMWARE, firmware); fbb_.AddElement<uint8_t>(TopologyMessage::VT_LEADER, leader, 0);
} }
explicit TopologyMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { void add_firmware(::flatbuffers::Offset<::flatbuffers::String> firmware) {
start_ = fbb_.StartTable(); fbb_.AddOffset(TopologyMessage::VT_FIRMWARE, firmware);
} }
::flatbuffers::Offset<TopologyMessage> Finish() { explicit TopologyMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
const auto end = fbb_.EndTable(start_); : fbb_(_fbb) {
auto o = ::flatbuffers::Offset<TopologyMessage>(end); start_ = fbb_.StartTable();
return o; }
} ::flatbuffers::Offset<TopologyMessage> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<TopologyMessage>(end);
return o;
}
}; };
inline ::flatbuffers::Offset<TopologyMessage> CreateTopologyMessage( inline ::flatbuffers::Offset<TopologyMessage> CreateTopologyMessage(
::flatbuffers::FlatBufferBuilder &_fbb, uint8_t module_id = 0, ::flatbuffers::FlatBufferBuilder &_fbb, uint8_t module_id = 0,
ModuleType module_type = ModuleType_SPLITTER, uint8_t num_channels = 0, ModuleType module_type = ModuleType_SPLITTER, uint8_t num_channels = 0,
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> channel_to_module = 0, ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> channel_to_module = 0,
::flatbuffers::Offset<::flatbuffers::Vector<int8_t>> channel_to_orientation = 0, ::flatbuffers::Offset<::flatbuffers::Vector<int8_t>>
Messaging::ConnectionType connection = Messaging::ConnectionType_DIRECT, uint8_t leader = 0, channel_to_orientation = 0,
Messaging::ConnectionType connection = Messaging::ConnectionType_DIRECT,
uint8_t leader = 0,
::flatbuffers::Offset<::flatbuffers::String> firmware = 0) { ::flatbuffers::Offset<::flatbuffers::String> firmware = 0) {
TopologyMessageBuilder builder_(_fbb); TopologyMessageBuilder builder_(_fbb);
builder_.add_firmware(firmware); builder_.add_firmware(firmware);
builder_.add_channel_to_orientation(channel_to_orientation); builder_.add_channel_to_orientation(channel_to_orientation);
builder_.add_channel_to_module(channel_to_module); builder_.add_channel_to_module(channel_to_module);
builder_.add_leader(leader); builder_.add_leader(leader);
builder_.add_connection(connection); builder_.add_connection(connection);
builder_.add_num_channels(num_channels); builder_.add_num_channels(num_channels);
builder_.add_module_type(module_type); builder_.add_module_type(module_type);
builder_.add_module_id(module_id); builder_.add_module_id(module_id);
return builder_.Finish(); return builder_.Finish();
} }
inline ::flatbuffers::Offset<TopologyMessage> inline ::flatbuffers::Offset<TopologyMessage> CreateTopologyMessageDirect(
CreateTopologyMessageDirect(::flatbuffers::FlatBufferBuilder &_fbb, uint8_t module_id = 0, ::flatbuffers::FlatBufferBuilder &_fbb, uint8_t module_id = 0,
ModuleType module_type = ModuleType_SPLITTER, uint8_t num_channels = 0, ModuleType module_type = ModuleType_SPLITTER, uint8_t num_channels = 0,
const std::vector<uint8_t> *channel_to_module = nullptr, const std::vector<uint8_t> *channel_to_module = nullptr,
const std::vector<int8_t> *channel_to_orientation = nullptr, const std::vector<int8_t> *channel_to_orientation = nullptr,
Messaging::ConnectionType connection = Messaging::ConnectionType_DIRECT, Messaging::ConnectionType connection = Messaging::ConnectionType_DIRECT,
uint8_t leader = 0, const char *firmware = nullptr) { uint8_t leader = 0, const char *firmware = nullptr) {
auto channel_to_module__ = auto channel_to_module__ =
channel_to_module ? _fbb.CreateVector<uint8_t>(*channel_to_module) : 0; channel_to_module ? _fbb.CreateVector<uint8_t>(*channel_to_module) : 0;
auto channel_to_orientation__ = auto channel_to_orientation__ =
channel_to_orientation ? _fbb.CreateVector<int8_t>(*channel_to_orientation) : 0; channel_to_orientation
auto firmware__ = firmware ? _fbb.CreateString(firmware) : 0; ? _fbb.CreateVector<int8_t>(*channel_to_orientation)
return Messaging::CreateTopologyMessage(_fbb, module_id, module_type, num_channels, : 0;
channel_to_module__, channel_to_orientation__, auto firmware__ = firmware ? _fbb.CreateString(firmware) : 0;
connection, leader, firmware__); return Messaging::CreateTopologyMessage(
_fbb, module_id, module_type, num_channels, channel_to_module__,
channel_to_orientation__, connection, leader, firmware__);
} }
inline const Messaging::TopologyMessage *GetTopologyMessage(const void *buf) { inline const Messaging::TopologyMessage *GetTopologyMessage(const void *buf) {
return ::flatbuffers::GetRoot<Messaging::TopologyMessage>(buf); return ::flatbuffers::GetRoot<Messaging::TopologyMessage>(buf);
} }
inline const Messaging::TopologyMessage *GetSizePrefixedTopologyMessage(const void *buf) { inline const Messaging::TopologyMessage *
return ::flatbuffers::GetSizePrefixedRoot<Messaging::TopologyMessage>(buf); GetSizePrefixedTopologyMessage(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Messaging::TopologyMessage>(buf);
} }
inline bool VerifyTopologyMessageBuffer(::flatbuffers::Verifier &verifier) { inline bool VerifyTopologyMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<Messaging::TopologyMessage>(nullptr); return verifier.VerifyBuffer<Messaging::TopologyMessage>(nullptr);
} }
inline bool VerifySizePrefixedTopologyMessageBuffer(::flatbuffers::Verifier &verifier) { inline bool
return verifier.VerifySizePrefixedBuffer<Messaging::TopologyMessage>(nullptr); VerifySizePrefixedTopologyMessageBuffer(::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<Messaging::TopologyMessage>(nullptr);
} }
inline void FinishTopologyMessageBuffer(::flatbuffers::FlatBufferBuilder &fbb, inline void FinishTopologyMessageBuffer(
::flatbuffers::Offset<Messaging::TopologyMessage> root) { ::flatbuffers::FlatBufferBuilder &fbb,
fbb.Finish(root); ::flatbuffers::Offset<Messaging::TopologyMessage> root) {
fbb.Finish(root);
} }
inline void inline void FinishSizePrefixedTopologyMessageBuffer(
FinishSizePrefixedTopologyMessageBuffer(::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Messaging::TopologyMessage> root) { ::flatbuffers::Offset<Messaging::TopologyMessage> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }
} // namespace Messaging } // namespace Messaging

View File

@@ -17,8 +17,10 @@ LIB_API void cleanup();
LIB_API int send_angle_control(int module_id, int angle); LIB_API int send_angle_control(int module_id, int angle);
LIB_API char *get_configuration(int *size_out); LIB_API char *get_configuration(int *size_out);
LIB_API bool control_sentry_init(const char *dsn, const char *environment, const char *release); LIB_API bool control_sentry_init(const char *dsn, const char *environment,
LIB_API void control_sentry_set_app_info(const char *app_name, const char *app_version, const char *release);
LIB_API void control_sentry_set_app_info(const char *app_name,
const char *app_version,
const char *build_number); const char *build_number);
LIB_API void control_sentry_shutdown(void); LIB_API void control_sentry_shutdown(void);
} }

View File

@@ -27,28 +27,29 @@
*/ */
class RobotController { class RobotController {
public: public:
/** /**
* \brief Creates a new RobotController. * \brief Creates a new RobotController.
* *
* Each RobotController will establish unique connections to accessible * Each RobotController will establish unique connections to accessible
* BotChain modules. * BotChain modules.
*/ */
RobotController() RobotController()
: m_messaging_interface(std::make_unique<MessagingInterface>()), : m_messaging_interface(std::make_unique<MessagingInterface>()),
m_metadata_loop(std::thread(&RobotController::metadata_loop, this)), m_metadata_loop(std::thread(&RobotController::metadata_loop, this)),
m_transmit_loop(std::thread(&RobotController::transmit_loop, this)), m_transmit_loop(std::thread(&RobotController::transmit_loop, this)),
m_configuration_loop(std::thread(&RobotController::configuration_loop, this)), m_configuration_loop(
m_sensor_loop(std::thread(&RobotController::sensor_loop, this)), std::thread(&RobotController::configuration_loop, this)),
m_expiry_looop(std::thread(&RobotController::expiry_loop, this)) { m_sensor_loop(std::thread(&RobotController::sensor_loop, this)),
m_logger = spdlog::basic_logger_mt("default_logger", "libcontrol.log"); m_expiry_looop(std::thread(&RobotController::expiry_loop, this)) {
spdlog::flush_on(spdlog::level::info); m_logger = spdlog::basic_logger_mt("default_logger", "libcontrol.log");
spdlog::set_default_logger(m_logger); spdlog::flush_on(spdlog::level::info);
} spdlog::set_default_logger(m_logger);
}
~RobotController(); ~RobotController();
/** /**
* \brief Get a list of accessible modules * \brief Get a list of accessible modules
* *
* Returns a std::vector containing robotic modules. This list includes * Returns a std::vector containing robotic modules. This list includes
@@ -57,9 +58,9 @@ class RobotController {
* commands can be sent by calling the "as" function for the correct * commands can be sent by calling the "as" function for the correct
* type (can be identified through the ModuleType). * type (can be identified through the ModuleType).
*/ */
std::vector<std::weak_ptr<Module>> getModules(); std::vector<std::weak_ptr<Module>> getModules();
/** /**
* \brief Get a module by ID * \brief Get a module by ID
* *
* Returns a std::vector containing robotic modules. This list includes * Returns a std::vector containing robotic modules. This list includes
@@ -68,59 +69,60 @@ class RobotController {
* commands can be sent by calling the "as" function for the correct * commands can be sent by calling the "as" function for the correct
* type (can be identified through the ModuleType). * type (can be identified through the ModuleType).
*/ */
std::optional<std::weak_ptr<Module>> getModule(uint8_t device_id); std::optional<std::weak_ptr<Module>> getModule(uint8_t device_id);
/** /**
* \brief Get a list of all connections. * \brief Get a list of all connections.
* *
* Returns a list containing all connections between modules. * Returns a list containing all connections between modules.
*/ */
std::vector<Flatbuffers::ModuleConnectionInstance> getConnections(); std::vector<Flatbuffers::ModuleConnectionInstance> getConnections();
/** /**
* \brief Get a list of accessible modules. * \brief Get a list of accessible modules.
* *
* Returns a list containing ID and types of each module. * Returns a list containing ID and types of each module.
*/ */
std::vector<Flatbuffers::ModuleInstance> getModuleList(); std::vector<Flatbuffers::ModuleInstance> getModuleList();
/** /**
* \brief Reset the list of modules. * \brief Reset the list of modules.
* *
* Reset the internal list containing known modules. Note: This list is * Reset the internal list containing known modules. Note: This list is
* automatically updated, only call this function when you need to update the * automatically updated, only call this function when you need to update the
* list faster than the internal refresh logic. * list faster than the internal refresh logic.
*/ */
void resetModules(); void resetModules();
/** /**
* \brief Poll for devices accessible to the PC. * \brief Poll for devices accessible to the PC.
* *
* Manually trigger a poll for devices accessible to the PC. * Manually trigger a poll for devices accessible to the PC.
*/ */
void fetchDirectlyConnectedModules(bool block); void fetchDirectlyConnectedModules(bool block);
private: private:
std::shared_ptr<spdlog::logger> m_logger; std::shared_ptr<spdlog::logger> m_logger;
std::unordered_map<uint8_t, std::shared_ptr<Module>> m_id_to_module{}; std::unordered_map<uint8_t, std::shared_ptr<Module>> m_id_to_module{};
std::unordered_map<uint8_t, std::vector<Flatbuffers::ModuleConnectionInstance>> std::unordered_map<uint8_t,
m_connection_map{}; std::vector<Flatbuffers::ModuleConnectionInstance>>
std::shared_mutex m_module_lock{}; m_connection_map{};
std::shared_mutex m_connection_lock{}; std::shared_mutex m_module_lock{};
std::shared_ptr<MessagingInterface> m_messaging_interface; std::shared_mutex m_connection_lock{};
std::atomic<bool> m_stop_thread{false}; // todo: make sure threads stop if we std::shared_ptr<MessagingInterface> m_messaging_interface;
// dont get any messages (timeouts) std::atomic<bool> m_stop_thread{false}; // todo: make sure threads stop if we
std::thread m_metadata_loop; // dont get any messages (timeouts)
std::thread m_transmit_loop; std::thread m_metadata_loop;
std::thread m_configuration_loop; std::thread m_transmit_loop;
std::thread m_sensor_loop; std::thread m_configuration_loop;
std::thread m_expiry_looop; std::thread m_sensor_loop;
std::thread m_expiry_looop;
void metadata_loop(); void metadata_loop();
void transmit_loop(); void transmit_loop();
void configuration_loop(); void configuration_loop();
void sensor_loop(); void sensor_loop();
void expiry_loop(); void expiry_loop();
}; };
#endif // CONTROL_LIBCONTROL_H #endif // CONTROL_LIBCONTROL_H

View File

@@ -7,44 +7,41 @@
class Event; class Event;
class CallbackHandle { class CallbackHandle {
public: public:
CallbackHandle(Event *evt, int id) : evt(evt), id(id) { CallbackHandle(Event *evt, int id) : evt(evt), id(id) {}
} ~CallbackHandle();
~CallbackHandle();
private: private:
Event *evt; Event *evt;
int id; int id;
}; };
class Event { class Event {
public: public:
using Callback = std::function<void()>; using Callback = std::function<void()>;
CallbackHandle addListener(Callback cb) { CallbackHandle addListener(Callback cb) {
int id = nextId++; int id = nextId++;
callbacks[id] = std::move(cb); callbacks[id] = std::move(cb);
return CallbackHandle(this, id); return CallbackHandle(this, id);
} }
void remove(int id) { void remove(int id) { callbacks.erase(id); }
callbacks.erase(id);
}
void fire() { void fire() {
for (auto &kv : callbacks) for (auto &kv : callbacks)
kv.second(); kv.second();
} }
private: private:
friend class CallbackHandle; friend class CallbackHandle;
std::unordered_map<int, Callback> callbacks; std::unordered_map<int, Callback> callbacks;
int nextId = 0; int nextId = 0;
}; };
CallbackHandle::~CallbackHandle() { CallbackHandle::~CallbackHandle() {
if (evt) if (evt)
evt->remove(id); evt->remove(id);
} }
#endif // CONTROL_EVENT_H #endif // CONTROL_EVENT_H

View File

@@ -7,12 +7,12 @@
template <typename K, typename V, typename H> template <typename K, typename V, typename H>
std::vector<V> map_to_values(const std::unordered_map<K, V, H> &map) { std::vector<V> map_to_values(const std::unordered_map<K, V, H> &map) {
std::vector<V> out; std::vector<V> out;
out.reserve(map.size()); out.reserve(map.size());
for (auto const &[key, value] : map) { for (auto const &[key, value] : map) {
out.push_back(value); out.push_back(value);
} }
return out; return out;
} }
#endif // CONTROL_MAP_H #endif // CONTROL_MAP_H

View File

@@ -6,9 +6,9 @@
// Custom hash function for std::pair // Custom hash function for std::pair
template <typename T> struct pair_hash { template <typename T> struct pair_hash {
std::size_t operator()(const std::pair<T, T> &p) const { std::size_t operator()(const std::pair<T, T> &p) const {
return std::hash<T>()(p.first) ^ (std::hash<T>()(p.second) << 1); return std::hash<T>()(p.first) ^ (std::hash<T>()(p.second) << 1);
} }
}; };
#endif // CONTROL_PAIRHASH_H #endif // CONTROL_PAIRHASH_H

View File

@@ -5,7 +5,7 @@
#include <variant> // NOLINT #include <variant> // NOLINT
template <class... Ts> struct overloaded : Ts... { template <class... Ts> struct overloaded : Ts... {
using Ts::operator()...; using Ts::operator()...;
}; };
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>; template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

View File

@@ -2,23 +2,32 @@
#include "flatbuffers/SensorMessageBuilder.h" #include "flatbuffers/SensorMessageBuilder.h"
double Hub::get_position() { double Hub::get_position() {
// no-op // no-op
return 0; return 0;
}
std::string Hub::get_text() {
// no-op
return "";
} }
void Hub::actuate(double /* position */) { void Hub::actuate(double /* position */) {
// no-op // no-op
} }
void Hub::actuate(double /* x */, double /* y */) { void Hub::actuate(double /* x */, double /* y */) {
// no-op // no-op
}
void Hub::actuate(const std::string &text) {
// no-op
} }
std::vector<uint8_t> Hub::get_actuation_message() { std::vector<uint8_t> Hub::get_actuation_message() {
// no-op // no-op
return {}; return {};
} }
void Hub::update_sensor_data(const Flatbuffers::sensor_value & /* value */) { void Hub::update_sensor_data(const Flatbuffers::sensor_value & /* value */) {
// no-op // no-op
} }

View File

@@ -4,40 +4,33 @@
#include "Module.h" #include "Module.h"
std::vector<neighbour> Module::get_neighbours() { std::vector<neighbour> Module::get_neighbours() { return m_neighbours; }
return m_neighbours;
}
uint8_t Module::get_device_id() { uint8_t Module::get_device_id() { return m_device_id; }
return m_device_id;
}
ModuleType Module::get_type() { ModuleType Module::get_type() { return m_module_type; }
return m_module_type;
}
Messaging::ConnectionType Module::get_connection_type() { Messaging::ConnectionType Module::get_connection_type() {
return m_connection_type; return m_connection_type;
} }
uint8_t Module::get_leader() { uint8_t Module::get_leader() { return m_leader; }
return m_leader;
}
std::chrono::time_point<std::chrono::system_clock> Module::get_last_updated_time() { std::chrono::time_point<std::chrono::system_clock>
return m_last_updated; Module::get_last_updated_time() {
return m_last_updated;
} }
void Module::update_module_metadata(const Messaging::TopologyMessage &message) { void Module::update_module_metadata(const Messaging::TopologyMessage &message) {
m_module_type = message.module_type(); m_module_type = message.module_type();
m_connection_type = message.connection(); m_connection_type = message.connection();
m_leader = message.leader(); m_leader = message.leader();
m_last_updated = std::chrono::system_clock::now(); m_last_updated = std::chrono::system_clock::now();
m_neighbours.clear(); m_neighbours.clear();
for (auto [id, ori] : for (auto [id, ori] : std::views::zip(*message.channel_to_module(),
std::views::zip(*message.channel_to_module(), *message.channel_to_orientation())) { *message.channel_to_orientation())) {
m_neighbours.emplace_back(neighbour{id, static_cast<Orientation>(ori)}); m_neighbours.emplace_back(neighbour{id, static_cast<Orientation>(ori)});
} }
} }

View File

@@ -2,6 +2,7 @@
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Hub.h" #include "Hub.h"
#include "actuators/BoundedPositionalActuator1D.h" #include "actuators/BoundedPositionalActuator1D.h"
#include "actuators/OledActuator.h"
#include "actuators/PositionalActuator1D.h" #include "actuators/PositionalActuator1D.h"
#include "flatbuffers_generated/RobotModule_generated.h" #include "flatbuffers_generated/RobotModule_generated.h"
@@ -9,20 +10,25 @@
#define SERVO1_MIN_ANGLE 0 #define SERVO1_MIN_ANGLE 0
#define SERVO1_DEFAULT_ANGLE 90 #define SERVO1_DEFAULT_ANGLE 90
std::shared_ptr<Module> std::shared_ptr<Module> ModuleFactory::createModule(
ModuleFactory::createModule(uint8_t device_id, ModuleType type, uint8_t device_id, ModuleType type,
std::shared_ptr<MessagingInterface> &messaging_interface) { std::shared_ptr<MessagingInterface> &messaging_interface) {
switch (type) { switch (type) {
case ModuleType_SPLITTER: case ModuleType_SPLITTER:
return std::make_shared<Hub>(device_id, type); return std::make_shared<Hub>(device_id, type);
case ModuleType_BATTERY: case ModuleType_BATTERY:
return std::make_shared<Hub>(device_id, type); return std::make_shared<Hub>(device_id, type);
case ModuleType_SERVO_1: case ModuleType_SERVO_1:
case ModuleType_SERVO_2: case ModuleType_SERVO_2:
return std::make_shared<BoundedPositionalActuator1D>( return std::make_shared<BoundedPositionalActuator1D>(
device_id, type, SERVO1_MAX_ANGLE, SERVO1_MIN_ANGLE, SERVO1_DEFAULT_ANGLE); device_id, type, SERVO1_MAX_ANGLE, SERVO1_MIN_ANGLE,
case ModuleType_DC_MOTOR: SERVO1_DEFAULT_ANGLE);
return std::make_shared<PositionalActuator1D>(device_id, type); case ModuleType_DC_MOTOR:
} return std::make_shared<PositionalActuator1D>(device_id, type);
case ModuleType_DISPLAY:
return std::make_shared<OledActuator>(device_id, type);
default:
return nullptr; return nullptr;
}
return nullptr;
} }

View File

@@ -7,37 +7,46 @@
#include "util/Variant.h" #include "util/Variant.h"
double BoundedPositionalActuator1D::get_position() { double BoundedPositionalActuator1D::get_position() {
return m_current_position; return m_current_position;
} }
std::string BoundedPositionalActuator1D::get_text() { return ""; }
void BoundedPositionalActuator1D::actuate(double position) { void BoundedPositionalActuator1D::actuate(double position) {
if (position < m_min_value || position > m_max_value) { if (position < m_min_value || position > m_max_value) {
return; return;
} }
m_target_position = position; m_target_position = position;
} }
void BoundedPositionalActuator1D::actuate(double x, double y) { void BoundedPositionalActuator1D::actuate(double x, double y) {}
}
void BoundedPositionalActuator1D::actuate(const std::string &text) {}
std::vector<uint8_t> BoundedPositionalActuator1D::get_actuation_message() { std::vector<uint8_t> BoundedPositionalActuator1D::get_actuation_message() {
std::vector<uint8_t> message{}; std::vector<uint8_t> message{};
if (m_target_position == m_current_position) { if (m_target_position == m_current_position) {
return message;
}
auto [data, size] = acm_builder->build_angle_control_message(m_target_position);
message.resize(size);
memcpy(message.data(), data, size);
return message; return message;
}
auto [data, size] =
acm_builder->build_angle_control_message(m_target_position);
message.resize(size);
memcpy(message.data(), data, size);
return message;
} }
void BoundedPositionalActuator1D::update_sensor_data(const Flatbuffers::sensor_value &value) { void BoundedPositionalActuator1D::update_sensor_data(
std::visit(overloaded{ const Flatbuffers::sensor_value &value) {
[this](Flatbuffers::target_angle a) { m_current_position = a.angle; }, std::visit(
[this](Flatbuffers::current_angle a) { m_current_position = a.angle; }, overloaded{
}, [this](Flatbuffers::target_angle a) { m_current_position = a.angle; },
value); [this](Flatbuffers::current_angle a) {
m_current_position = a.angle;
},
[this](Flatbuffers::current_text /*t*/) {},
},
value);
} }

View File

@@ -0,0 +1,38 @@
#include "actuators/OledActuator.h"
#include "flatbuffers/SensorMessageBuilder.h"
#include "util/Variant.h"
#include <cstring>
double OledActuator::get_position() { return 0.0; }
std::string OledActuator::get_text() { return m_current_text; }
void OledActuator::actuate(double /* position */) {}
void OledActuator::actuate(double /* x */, double /* y */) {}
void OledActuator::actuate(const std::string &text) { m_target_text = text; }
std::vector<uint8_t> OledActuator::get_actuation_message() {
std::vector<uint8_t> message{};
if (m_target_text == m_current_text) {
return message;
}
auto [data, size] =
m_text_message_builder->build_text_control_message(m_target_text);
message.resize(size);
memcpy(message.data(), data, size);
return message;
}
void OledActuator::update_sensor_data(const Flatbuffers::sensor_value &value) {
std::visit(
overloaded{
[this](Flatbuffers::target_angle /* a */) {},
[this](Flatbuffers::current_angle /* a */) {},
[this](Flatbuffers::current_text t) { m_current_text = t.text; },
},
value);
}

View File

@@ -3,34 +3,42 @@
#include "util/Variant.h" #include "util/Variant.h"
#include <cstring> #include <cstring>
double PositionalActuator1D::get_position() { double PositionalActuator1D::get_position() { return m_current_position; }
return m_current_position;
} std::string PositionalActuator1D::get_text() { return ""; }
void PositionalActuator1D::actuate(double position) { void PositionalActuator1D::actuate(double position) {
m_target_position = position; m_target_position = position;
} }
void PositionalActuator1D::actuate(double /* x */, double /* y */) { void PositionalActuator1D::actuate(double /* x */, double /* y */) {}
}
void PositionalActuator1D::actuate(const std::string &text) {}
std::vector<uint8_t> PositionalActuator1D::get_actuation_message() { std::vector<uint8_t> PositionalActuator1D::get_actuation_message() {
std::vector<uint8_t> message{}; std::vector<uint8_t> message{};
if (m_target_position == m_board_target_position) { if (m_target_position == m_board_target_position) {
return message;
}
auto [data, size] = m_acm_builder->build_angle_control_message(m_target_position);
message.resize(size);
memcpy(message.data(), data, size);
return message; return message;
}
auto [data, size] =
m_acm_builder->build_angle_control_message(m_target_position);
message.resize(size);
memcpy(message.data(), data, size);
return message;
} }
void PositionalActuator1D::update_sensor_data(const Flatbuffers::sensor_value &value) { void PositionalActuator1D::update_sensor_data(
std::visit(overloaded{ const Flatbuffers::sensor_value &value) {
[this](Flatbuffers::target_angle a) { m_board_target_position = a.angle; }, std::visit(overloaded{
[this](Flatbuffers::current_angle a) { m_current_position = a.angle; }, [this](Flatbuffers::target_angle a) {
}, m_board_target_position = a.angle;
value); },
[this](Flatbuffers::current_angle a) {
m_current_position = a.angle;
},
[this](Flatbuffers::current_text /*t*/) {},
},
value);
} }

View File

@@ -7,16 +7,17 @@
namespace Flatbuffers { namespace Flatbuffers {
const Messaging::AngleControlMessage * const Messaging::AngleControlMessage *
AngleControlMessageBuilder::parse_angle_control_message(const uint8_t *buffer) { AngleControlMessageBuilder::parse_angle_control_message(const uint8_t *buffer) {
return flatbuffers::GetRoot<Messaging::AngleControlMessage>(buffer); return flatbuffers::GetRoot<Messaging::AngleControlMessage>(buffer);
} }
SerializedMessage AngleControlMessageBuilder::build_angle_control_message(const int16_t angle) { SerializedMessage
builder_.Clear(); AngleControlMessageBuilder::build_angle_control_message(const int16_t angle) {
builder_.Clear();
const auto message = Messaging::CreateAngleControlMessage(builder_, angle); const auto message = Messaging::CreateAngleControlMessage(builder_, angle);
builder_.Finish(message); builder_.Finish(message);
return {builder_.GetBufferPointer(), builder_.GetSize()}; return {builder_.GetBufferPointer(), builder_.GetSize()};
} }
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -12,38 +12,41 @@ namespace Flatbuffers {
SerializedMessage RobotConfigurationBuilder::build_robot_configuration( SerializedMessage RobotConfigurationBuilder::build_robot_configuration(
const std::vector<ModuleInstance> &modules, const std::vector<ModuleInstance> &modules,
const std::vector<ModuleConnectionInstance> &connections) { const std::vector<ModuleConnectionInstance> &connections) {
builder_.Clear(); builder_.Clear();
std::vector<flatbuffers::Offset<RobotModule>> module_vector; std::vector<flatbuffers::Offset<RobotModule>> module_vector;
std::vector<flatbuffers::Offset<Frontend::ModuleConnection>> connection_vector; std::vector<flatbuffers::Offset<Frontend::ModuleConnection>>
connection_vector;
for (const auto &connection : connections) { for (const auto &connection : connections) {
connection_vector.push_back(Frontend::CreateModuleConnection( connection_vector.push_back(Frontend::CreateModuleConnection(
builder_, connection.from_module_id, connection.to_module_id, connection.from_socket, builder_, connection.from_module_id, connection.to_module_id,
connection.to_socket, connection.orientation)); connection.from_socket, connection.to_socket, connection.orientation));
} }
for (const auto &module : modules) { for (const auto &module : modules) {
// todo: this only works for motors right now // todo: this only works for motors right now
auto motor_state = CreateMotorState(builder_, module.angle); auto motor_state = CreateMotorState(builder_, module.angle);
const flatbuffers::Offset<void> config_union = motor_state.Union(); const flatbuffers::Offset<void> config_union = motor_state.Union();
module_vector.push_back(CreateRobotModule(builder_, module.id, module.type, module_vector.push_back(CreateRobotModule(builder_, module.id, module.type,
ModuleState_MotorState, config_union)); ModuleState_MotorState,
} config_union));
}
const auto connection_vector_fb = builder_.CreateVector(connection_vector); const auto connection_vector_fb = builder_.CreateVector(connection_vector);
const auto module_vector_fb = builder_.CreateVector(module_vector); const auto module_vector_fb = builder_.CreateVector(module_vector);
const auto message = const auto message = Frontend::CreateRobotConfiguration(
Frontend::CreateRobotConfiguration(builder_, module_vector_fb, connection_vector_fb); builder_, module_vector_fb, connection_vector_fb);
builder_.Finish(message); builder_.Finish(message);
return {builder_.GetBufferPointer(), builder_.GetSize()}; return {builder_.GetBufferPointer(), builder_.GetSize()};
} }
const Frontend::RobotConfiguration * const Frontend::RobotConfiguration *
RobotConfigurationBuilder::parse_robot_configuration(const std::uint8_t *buffer) { RobotConfigurationBuilder::parse_robot_configuration(
return flatbuffers::GetRoot<Frontend::RobotConfiguration>(buffer); const std::uint8_t *buffer) {
return flatbuffers::GetRoot<Frontend::RobotConfiguration>(buffer);
} }
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -3,8 +3,9 @@
namespace Flatbuffers { namespace Flatbuffers {
const Messaging::SensorMessage *SensorMessageBuilder::parse_sensor_message(const uint8_t *buffer) { const Messaging::SensorMessage *
return flatbuffers::GetRoot<Messaging::SensorMessage>(buffer); SensorMessageBuilder::parse_sensor_message(const uint8_t *buffer) {
return flatbuffers::GetRoot<Messaging::SensorMessage>(buffer);
} }
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -0,0 +1,21 @@
//
// Created by Johnathon Slightham on 2025-06-30.
//
#include "flatbuffers/TextControlMessageBuilder.h"
namespace Flatbuffers {
SerializedMessage
TextControlMessageBuilder::build_text_control_message(std::string &t) {
builder_.Clear();
auto text_offset = builder_.CreateString(t);
const auto message =
Messaging::CreateTextControlMessage(builder_, text_offset);
builder_.Finish(message);
return {builder_.GetBufferPointer(), builder_.GetSize()};
}
} // namespace Flatbuffers

View File

@@ -7,32 +7,34 @@
#include "flatbuffers/SerializedMessage.h" #include "flatbuffers/SerializedMessage.h"
namespace Flatbuffers { namespace Flatbuffers {
SerializedMessage SerializedMessage TopologyMessageBuilder::build_topology_message(
TopologyMessageBuilder::build_topology_message(const uint8_t module_id, const uint8_t module_id, const ModuleType module_type,
const ModuleType module_type, const std::vector<uint8_t> &channel_to_module,
const std::vector<uint8_t> &channel_to_module, const std::vector<int8_t> &orientation_to_module) {
const std::vector<int8_t> &orientation_to_module) { builder_.Clear();
builder_.Clear();
const auto orientation_to_module_vector = builder_.CreateVector(orientation_to_module); const auto orientation_to_module_vector =
const auto channel_to_module_vector = builder_.CreateVector(channel_to_module); builder_.CreateVector(orientation_to_module);
const auto channel_to_module_vector =
builder_.CreateVector(channel_to_module);
const auto message = const auto message = Messaging::CreateTopologyMessage(
Messaging::CreateTopologyMessage(builder_, module_id, module_type, channel_to_module.size(), builder_, module_id, module_type, channel_to_module.size(),
channel_to_module_vector, orientation_to_module_vector); channel_to_module_vector, orientation_to_module_vector);
builder_.Finish(message); builder_.Finish(message);
return {builder_.GetBufferPointer(), builder_.GetSize()}; return {builder_.GetBufferPointer(), builder_.GetSize()};
} }
const Messaging::TopologyMessage * const Messaging::TopologyMessage *
TopologyMessageBuilder::parse_topology_message(const uint8_t *buffer) { TopologyMessageBuilder::parse_topology_message(const uint8_t *buffer) {
return flatbuffers::GetRoot<Messaging::TopologyMessage>(buffer); return flatbuffers::GetRoot<Messaging::TopologyMessage>(buffer);
} }
bool TopologyMessageBuilder::is_valid_topology_message(const uint8_t *buffer, size_t size) { bool TopologyMessageBuilder::is_valid_topology_message(const uint8_t *buffer,
flatbuffers::Verifier verifier(buffer, size); size_t size) {
return Messaging::VerifyTopologyMessageBuffer(verifier); flatbuffers::Verifier verifier(buffer, size);
return Messaging::VerifyTopologyMessageBuffer(verifier);
} }
} // namespace Flatbuffers } // namespace Flatbuffers

View File

@@ -14,89 +14,93 @@
extern "C" { extern "C" {
const auto robot_controller = std::make_unique<RobotController>(); const auto robot_controller = std::make_unique<RobotController>();
const auto acm_builder = std::make_unique<Flatbuffers::AngleControlMessageBuilder>(); const auto acm_builder =
std::make_unique<Flatbuffers::AngleControlMessageBuilder>();
const auto robot_configuration_builder = std::make_unique<Flatbuffers::RobotConfigurationBuilder>(); const auto robot_configuration_builder =
std::make_unique<Flatbuffers::RobotConfigurationBuilder>();
LIB_API void init() { LIB_API void init() {
spdlog::info("[c_control] Initializing"); spdlog::info("[c_control] Initializing");
robot_controller->fetchDirectlyConnectedModules(false); robot_controller->fetchDirectlyConnectedModules(false);
} }
LIB_API void cleanup() { LIB_API void cleanup() { spdlog::info("[c_control] Cleanup"); }
spdlog::info("[c_control] Cleanup");
}
LIB_API int send_angle_control(int module_id, int angle) { LIB_API int send_angle_control(int module_id, int angle) {
if (const auto maybe_module = robot_controller->getModule(module_id)) { if (const auto maybe_module = robot_controller->getModule(module_id)) {
const auto module = (*maybe_module).lock(); const auto module = (*maybe_module).lock();
module->actuate(angle); module->actuate(angle);
} }
return 0; return 0;
} }
LIB_API char *get_configuration(int *size_out) { LIB_API char *get_configuration(int *size_out) {
std::vector<Flatbuffers::ModuleInstance> modules_vec{}; std::vector<Flatbuffers::ModuleInstance> modules_vec{};
std::vector<Flatbuffers::ModuleConnectionInstance> connections_vec{}; std::vector<Flatbuffers::ModuleConnectionInstance> connections_vec{};
for (const auto &module : robot_controller->getModuleList()) { for (const auto &module : robot_controller->getModuleList()) {
modules_vec.emplace_back(module); modules_vec.emplace_back(module);
} }
for (const auto &connection : robot_controller->getConnections()) { for (const auto &connection : robot_controller->getConnections()) {
connections_vec.emplace_back(connection); connections_vec.emplace_back(connection);
} }
const auto [data, size] = const auto [data, size] =
robot_configuration_builder->build_robot_configuration(modules_vec, connections_vec); robot_configuration_builder->build_robot_configuration(modules_vec,
*size_out = size; connections_vec);
return reinterpret_cast<char *>(data); *size_out = size;
return reinterpret_cast<char *>(data);
} }
LIB_API bool control_sentry_init(const char *dsn, const char *environment, const char *release) { LIB_API bool control_sentry_init(const char *dsn, const char *environment,
sentry_options_t *options = sentry_options_new(); const char *release) {
sentry_options_set_dsn(options, dsn); sentry_options_t *options = sentry_options_new();
sentry_options_set_environment(options, environment); sentry_options_set_dsn(options, dsn);
sentry_options_set_release(options, release); sentry_options_set_environment(options, environment);
sentry_options_set_auto_session_tracking(options, 1); sentry_options_set_release(options, release);
sentry_options_set_auto_session_tracking(options, 1);
sentry_init(options); sentry_init(options);
return true; return true;
} }
LIB_API void control_sentry_shutdown(void) { LIB_API void control_sentry_shutdown(void) { sentry_close(); }
sentry_close();
}
LIB_API void control_sentry_set_app_info(const char *app_name, const char *app_version, LIB_API void control_sentry_set_app_info(const char *app_name,
const char *app_version,
const char *build_number) { const char *build_number) {
sentry_value_t app = sentry_value_new_object(); sentry_value_t app = sentry_value_new_object();
if (app_name && *app_name) { if (app_name && *app_name) {
sentry_value_set_by_key(app, "name", sentry_value_new_string(app_name)); sentry_value_set_by_key(app, "name", sentry_value_new_string(app_name));
} }
if (app_version && *app_version) { if (app_version && *app_version) {
sentry_value_set_by_key(app, "version", sentry_value_new_string(app_version)); sentry_value_set_by_key(app, "version",
} sentry_value_new_string(app_version));
}
if (build_number && *build_number) {
sentry_value_set_by_key(app, "build",
sentry_value_new_string(build_number));
}
sentry_set_context("app", app);
if (app_version && *app_version) {
if (build_number && *build_number) { if (build_number && *build_number) {
sentry_value_set_by_key(app, "build", sentry_value_new_string(build_number)); char release[256];
} snprintf(release, sizeof(release), "%s@%s+%s",
app_name && *app_name ? app_name : "app", app_version,
sentry_set_context("app", app); build_number);
} else {
if (app_version && *app_version) { // Example: mygame@1.2.3
if (build_number && *build_number) { char release[256];
char release[256]; snprintf(release, sizeof(release), "%s@%s",
snprintf(release, sizeof(release), "%s@%s+%s", app_name && *app_name ? app_name : "app", app_name && *app_name ? app_name : "app", app_version);
app_version, build_number);
} else {
// Example: mygame@1.2.3
char release[256];
snprintf(release, sizeof(release), "%s@%s", app_name && *app_name ? app_name : "app",
app_version);
}
} }
}
} }
} }

View File

@@ -29,221 +29,232 @@
#define SENSOR_BUFFER_SIZE 1024 #define SENSOR_BUFFER_SIZE 1024
#define NETWORK_CONFIG_FETCH_RATE 3s #define NETWORK_CONFIG_FETCH_RATE 3s
#define MODULE_EXPIRE_TIME 3s #define MODULE_EXPIRE_TIME 3s
#define CONTROL_MESSAGE_FREQUENCY 33ms #define CONTROL_MESSAGE_FREQUENCY 50ms
using namespace std::chrono_literals; using namespace std::chrono_literals;
RobotController::~RobotController() { RobotController::~RobotController() {
m_stop_thread = true; m_stop_thread = true;
m_metadata_loop.join(); m_metadata_loop.join();
m_transmit_loop.join(); m_transmit_loop.join();
m_configuration_loop.join(); m_configuration_loop.join();
m_sensor_loop.join(); m_sensor_loop.join();
m_expiry_looop.join(); m_expiry_looop.join();
} }
std::vector<std::weak_ptr<Module>> RobotController::getModules() { std::vector<std::weak_ptr<Module>> RobotController::getModules() {
std::vector<std::weak_ptr<Module>> out; std::vector<std::weak_ptr<Module>> out;
std::shared_lock lock(m_module_lock); std::shared_lock lock(m_module_lock);
out.reserve(m_id_to_module.size()); out.reserve(m_id_to_module.size());
for (const auto m : map_to_values(m_id_to_module)) { for (const auto m : map_to_values(m_id_to_module)) {
out.emplace_back(m); out.emplace_back(m);
} }
return out; return out;
} }
std::vector<Flatbuffers::ModuleConnectionInstance> RobotController::getConnections() { std::vector<Flatbuffers::ModuleConnectionInstance>
std::vector<Flatbuffers::ModuleConnectionInstance> out; RobotController::getConnections() {
std::shared_lock lock(m_connection_lock); std::vector<Flatbuffers::ModuleConnectionInstance> out;
std::shared_lock lock(m_connection_lock);
for (auto const &[_, value] : m_connection_map) { for (auto const &[_, value] : m_connection_map) {
for (const auto conn : value) { for (const auto conn : value) {
out.push_back(conn); out.push_back(conn);
}
} }
return out; }
return out;
} }
std::vector<Flatbuffers::ModuleInstance> RobotController::getModuleList() { std::vector<Flatbuffers::ModuleInstance> RobotController::getModuleList() {
std::vector<Flatbuffers::ModuleInstance> out; std::vector<Flatbuffers::ModuleInstance> out;
std::shared_lock lock(m_module_lock); std::shared_lock lock(m_module_lock);
for (auto const &[key, value] : m_id_to_module) { for (auto const &[key, value] : m_id_to_module) {
out.push_back({key, value->get_type()}); out.push_back({key, value->get_type()});
} }
return out; return out;
} }
std::optional<std::weak_ptr<Module>> RobotController::getModule(uint8_t device_id) { std::optional<std::weak_ptr<Module>>
std::shared_lock lock(m_module_lock); RobotController::getModule(uint8_t device_id) {
if (m_id_to_module.contains(device_id)) { std::shared_lock lock(m_module_lock);
return m_id_to_module[device_id]; if (m_id_to_module.contains(device_id)) {
} else { return m_id_to_module[device_id];
return std::nullopt; } else {
} return std::nullopt;
}
} }
void RobotController::resetModules() { void RobotController::resetModules() {
std::unique_lock module_lock(m_module_lock); std::unique_lock module_lock(m_module_lock);
std::unique_lock conn_lock(m_connection_lock); std::unique_lock conn_lock(m_connection_lock);
m_id_to_module.erase(m_id_to_module.begin(), m_id_to_module.end()); m_id_to_module.erase(m_id_to_module.begin(), m_id_to_module.end());
m_connection_map.erase(m_connection_map.begin(), m_connection_map.end()); m_connection_map.erase(m_connection_map.begin(), m_connection_map.end());
} }
void RobotController::fetchDirectlyConnectedModules(bool block) { void RobotController::fetchDirectlyConnectedModules(bool block) {
spdlog::info("[Control] Fetching modules from network"); spdlog::info("[Control] Fetching modules from network");
auto t = std::thread([&] { auto t = std::thread([&] {
auto out = m_messaging_interface->find_connected_modules( auto out = m_messaging_interface->find_connected_modules(
std::chrono::milliseconds(SCAN_DURATION_MS)); std::chrono::milliseconds(SCAN_DURATION_MS));
spdlog::info("[Control] Found {} modules on the network", out.size()); spdlog::info("[Control] Found {} modules on the network", out.size());
}); });
if (block) { if (block) {
t.join(); t.join();
} else { } else {
t.detach(); t.detach();
} }
} }
void RobotController::metadata_loop() { void RobotController::metadata_loop() {
unsigned char buf[TOPOLOGY_BUFFER_SIZE]; unsigned char buf[TOPOLOGY_BUFFER_SIZE];
const auto builder = std::make_unique<Flatbuffers::TopologyMessageBuilder>(); const auto builder = std::make_unique<Flatbuffers::TopologyMessageBuilder>();
while (!m_stop_thread) { while (!m_stop_thread) {
if (auto result = if (auto result = m_messaging_interface->recv(buf, TOPOLOGY_BUFFER_SIZE,
m_messaging_interface->recv(buf, TOPOLOGY_BUFFER_SIZE, TOPOLOGY_CMD_TAG)) { TOPOLOGY_CMD_TAG)) {
const auto &[rx_size, from] = *result; const auto &[rx_size, from] = *result;
flatbuffers::Verifier verifier(buf, rx_size); flatbuffers::Verifier verifier(buf, rx_size);
if (!Messaging::VerifyTopologyMessageBuffer(verifier)) { if (!Messaging::VerifyTopologyMessageBuffer(verifier)) {
continue; continue;
} }
const auto metadata = builder->parse_topology_message(reinterpret_cast<uint8_t *>(buf)); const auto metadata =
std::unique_lock lock(m_module_lock); builder->parse_topology_message(reinterpret_cast<uint8_t *>(buf));
if (!m_id_to_module.contains(metadata->module_id())) { std::unique_lock lock(m_module_lock);
spdlog::info("[Control] Creating module entry for {}", metadata->module_id()); if (!m_id_to_module.contains(metadata->module_id())) {
m_id_to_module.insert( spdlog::info("[Control] Creating module entry for {}",
{metadata->module_id(), metadata->module_id());
ModuleFactory::createModule(metadata->module_id(), metadata->module_type(), m_id_to_module.insert(
m_messaging_interface)}); {metadata->module_id(),
} ModuleFactory::createModule(metadata->module_id(),
metadata->module_type(),
m_messaging_interface)});
}
m_id_to_module[metadata->module_id()]->update_module_metadata(*metadata); m_id_to_module[metadata->module_id()]->update_module_metadata(*metadata);
std::unique_lock conn_lock(m_connection_lock); std::unique_lock conn_lock(m_connection_lock);
std::vector<Flatbuffers::ModuleConnectionInstance> conns; std::vector<Flatbuffers::ModuleConnectionInstance> conns;
for (uint8_t i = 1; i < NUM_CHANNELS; i++) { for (uint8_t i = 1; i < NUM_CHANNELS; i++) {
if (metadata->channel_to_module()->Get(i) > 0) { if (metadata->channel_to_module()->Get(i) > 0) {
conns.push_back(Flatbuffers::ModuleConnectionInstance{ conns.push_back(Flatbuffers::ModuleConnectionInstance{
.from_module_id = metadata->module_id(), .from_module_id = metadata->module_id(),
.to_module_id = metadata->channel_to_module()->Get(i), .to_module_id = metadata->channel_to_module()->Get(i),
.from_socket = i, .from_socket = i,
.to_socket = 0, .to_socket = 0,
.orientation = .orientation = static_cast<Orientation>(
static_cast<Orientation>(metadata->channel_to_orientation()->Get(i))}); metadata->channel_to_orientation()->Get(i))});
}
}
m_connection_map[metadata->module_id()] = conns;
} }
}
m_connection_map[metadata->module_id()] = conns;
} }
}
} }
void RobotController::transmit_loop() { void RobotController::transmit_loop() {
const auto builder = std::make_unique<Flatbuffers::TopologyMessageBuilder>(); const auto builder = std::make_unique<Flatbuffers::TopologyMessageBuilder>();
while (!m_stop_thread) { while (!m_stop_thread) {
std::this_thread::sleep_for(CONTROL_MESSAGE_FREQUENCY); std::this_thread::sleep_for(CONTROL_MESSAGE_FREQUENCY);
std::shared_lock lock(m_module_lock); std::shared_lock lock(m_module_lock);
for (const auto [id, module] : m_id_to_module) { for (const auto [id, module] : m_id_to_module) {
auto out = module->get_actuation_message(); auto out = module->get_actuation_message();
if (out.size() > 0) { if (out.size() > 0) {
m_messaging_interface->send(out.data(), out.size(), id, ACTUATOR_CMD_TAG, false); m_messaging_interface->send(out.data(), out.size(), id,
} ACTUATOR_CMD_TAG, false);
} }
} }
}
} }
void RobotController::configuration_loop() { void RobotController::configuration_loop() {
while (!m_stop_thread) { while (!m_stop_thread) {
std::this_thread::sleep_for(NETWORK_CONFIG_FETCH_RATE); std::this_thread::sleep_for(NETWORK_CONFIG_FETCH_RATE);
fetchDirectlyConnectedModules(true); fetchDirectlyConnectedModules(true);
} }
} }
void RobotController::expiry_loop() { void RobotController::expiry_loop() {
while (!m_stop_thread) { while (!m_stop_thread) {
std::this_thread::sleep_for(MODULE_EXPIRE_TIME); std::this_thread::sleep_for(MODULE_EXPIRE_TIME);
std::unordered_set<uint8_t> delete_modules{}; std::unordered_set<uint8_t> delete_modules{};
std::unique_lock module_lock(m_module_lock); std::unique_lock module_lock(m_module_lock);
std::unique_lock connection_lock(m_connection_lock); std::unique_lock connection_lock(m_connection_lock);
for (auto it = m_id_to_module.begin(); it != m_id_to_module.end();) { for (auto it = m_id_to_module.begin(); it != m_id_to_module.end();) {
if (it->second->get_last_updated_time() < if (it->second->get_last_updated_time() <
std::chrono::system_clock::now() - MODULE_EXPIRE_TIME) { std::chrono::system_clock::now() - MODULE_EXPIRE_TIME) {
delete_modules.emplace(it->first); delete_modules.emplace(it->first);
it = m_id_to_module.erase(it); it = m_id_to_module.erase(it);
} else { } else {
++it; ++it;
} }
}
// todo
// Remove connections
// for (auto it = m_connection_map.begin(); it != m_connection_map.end();) {
// // Remove it->x connections
// if (delete_modules.contains(it->first)) {
// it = m_connection_map.erase(it);
// } else {
// ++it;
// }
// // Remove x->it connections
// for (auto it2 = it->second.begin(); it2 != it->second.end();) {
// if (delete_modules.contains(it2->to_module_id)) {
// it2 = it->second.erase(it2);
// } else {
// ++it2;
// }
// }
// }
} }
// todo
// Remove connections
// for (auto it = m_connection_map.begin(); it != m_connection_map.end();) {
// // Remove it->x connections
// if (delete_modules.contains(it->first)) {
// it = m_connection_map.erase(it);
// } else {
// ++it;
// }
// // Remove x->it connections
// for (auto it2 = it->second.begin(); it2 != it->second.end();) {
// if (delete_modules.contains(it2->to_module_id)) {
// it2 = it->second.erase(it2);
// } else {
// ++it2;
// }
// }
// }
}
} }
void RobotController::sensor_loop() { void RobotController::sensor_loop() {
unsigned char buf[SENSOR_BUFFER_SIZE]; unsigned char buf[SENSOR_BUFFER_SIZE];
const auto builder = std::make_unique<Flatbuffers::SensorMessageBuilder>(); const auto builder = std::make_unique<Flatbuffers::SensorMessageBuilder>();
while (!m_stop_thread) { while (!m_stop_thread) {
if (auto result = m_messaging_interface->recv(buf, SENSOR_BUFFER_SIZE, SENSOR_CMD_TAG)) { if (auto result = m_messaging_interface->recv(buf, SENSOR_BUFFER_SIZE,
const auto &[rx_size, from] = *result; SENSOR_CMD_TAG)) {
const auto &[rx_size, from] = *result;
flatbuffers::Verifier verifier(buf, rx_size); flatbuffers::Verifier verifier(buf, rx_size);
if (!Messaging::VerifySensorMessageBuffer(verifier)) { if (!Messaging::VerifySensorMessageBuffer(verifier)) {
continue; continue;
} }
const auto sensor_message = const auto sensor_message =
builder->parse_sensor_message(reinterpret_cast<uint8_t *>(buf)); builder->parse_sensor_message(reinterpret_cast<uint8_t *>(buf));
if (sensor_message->values()->size() != sensor_message->values_type()->size()) { if (sensor_message->values()->size() !=
spdlog::error( sensor_message->values_type()->size()) {
"[Control] Got a sensor message with different value ({}) and type ({}) sizes", spdlog::error("[Control] Got a sensor message with different value "
sensor_message->values()->size(), sensor_message->values_type()->size()); "({}) and type ({}) sizes",
continue; sensor_message->values()->size(),
} sensor_message->values_type()->size());
continue;
}
std::shared_lock module_lock(m_module_lock); std::shared_lock module_lock(m_module_lock);
if (!m_id_to_module.contains(from)) { if (!m_id_to_module.contains(from)) {
continue; continue;
} }
for (int i = 0; i < sensor_message->values()->size(); i++) { for (int i = 0; i < sensor_message->values()->size(); i++) {
if (auto maybe_value = Flatbuffers::SensorMessageBuilder::build_sensor_value( if (auto maybe_value =
static_cast<Messaging::SensorValue>(sensor_message->values_type()->Get(i)), Flatbuffers::SensorMessageBuilder::build_sensor_value(
sensor_message->values()->Get(i))) { static_cast<Messaging::SensorValue>(
m_id_to_module[from]->update_sensor_data(*maybe_value); sensor_message->values_type()->Get(i)),
} sensor_message->values()->Get(i))) {
} m_id_to_module[from]->update_sensor_data(*maybe_value);
} }
}
} }
}
} }