Program Listing for File signal_processor_old.hpp
↰ Return to documentation for file (include/signal/signal_processor_old.hpp
)
#pragma once
#include <async/async_integrator.hpp>
#include <functional>
#include <memory>
#include <vector>
#include <array>
#include <unordered_map>
#include <string>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <chrono>
namespace diffeq::signal {
template<typename T>
struct Signal {
T data;
std::chrono::steady_clock::time_point timestamp;
std::string type_id;
double priority = 1.0;
template<typename U>
Signal(U&& signal_data, std::string type = "", double prio = 1.0)
: data(std::forward<U>(signal_data))
, timestamp(std::chrono::steady_clock::now())
, type_id(std::move(type))
, priority(prio) {}
};
template<typename Handler, typename Signal>
concept SignalHandler = requires(Handler h, const Signal& s) {
{ h(s) } -> std::same_as<void>;
};
template<system_state S, can_be_time T = double>
class SignalProcessor {
public:
using state_type = S;
using time_type = T;
using value_type = typename S::value_type;
using integrator_type = AsyncIntegrator<S, T>;
// Signal types for different domains
using parameter_signal = Signal<std::unordered_map<std::string, double>>;
using control_signal = Signal<std::vector<double>>;
using market_signal = Signal<std::unordered_map<std::string, double>>;
explicit SignalProcessor(std::shared_ptr<integrator_type> integrator)
: integrator_(std::move(integrator)) {
// Set up default callbacks
setup_default_callbacks();
}
void process_parameter_signal(const parameter_signal& signal) {
for (const auto& [name, value] : signal.data) {
update_parameter(name, value);
}
}
void process_control_signal(const control_signal& signal) {
// Update control targets
if (signal.data.size() >= 6) { // 6-DOF robot example
control_targets_ = signal.data;
last_control_update_ = signal.timestamp;
}
}
void process_market_signal(const market_signal& signal) {
// Update market data
for (const auto& [symbol, value] : signal.data) {
market_data_[symbol] = value;
}
last_market_update_ = signal.timestamp;
}
const std::vector<double>& get_control_targets() const {
return control_targets_;
}
double get_market_data(const std::string& symbol) const {
auto it = market_data_.find(symbol);
return (it != market_data_.end()) ? it->second : 0.0;
}
void update_parameter(const std::string& name, double value) {
parameters_[name] = value;
// Notify integrator asynchronously
if (integrator_) {
integrator_->update_parameter_async(name, value);
}
}
double get_parameter(const std::string& name) const {
auto it = parameters_.find(name);
return (it != parameters_.end()) ? it->second : 0.0;
}
template<typename SignalType, SignalHandler<SignalType> Handler>
void register_handler(const std::string& signal_type, Handler&& handler) {
// Store handler in type-erased form
custom_handlers_[signal_type] = [h = std::forward<Handler>(handler)](const std::any& signal) {
try {
const auto& typed_signal = std::any_cast<const SignalType&>(signal);
h(typed_signal);
} catch (const std::bad_any_cast&) {
// Handle type mismatch gracefully
}
};
}
template<typename SignalType>
void process_signal(const SignalType& signal) {
auto it = custom_handlers_.find(signal.type_id);
if (it != custom_handlers_.end()) {
it->second(std::any(signal));
}
}
private:
std::shared_ptr<integrator_type> integrator_;
// Signal data storage
std::unordered_map<std::string, double> parameters_;
std::vector<double> control_targets_;
std::unordered_map<std::string, double> market_data_;
// Timestamps
std::chrono::steady_clock::time_point last_control_update_;
std::chrono::steady_clock::time_point last_market_update_;
// Custom handlers
std::unordered_map<std::string, std::function<void(const std::any&)>> custom_handlers_;
void setup_default_callbacks() {
if (!integrator_) return;
// Set up step callback to update internal state
integrator_->set_step_callback([this](const state_type& state, time_type t) {
on_step_completed(state, t);
});
// Set up parameter callback
integrator_->set_parameter_callback([this](const std::string& name, double value) {
on_parameter_updated(name, value);
});
// Set up emergency callback
integrator_->set_emergency_callback([this]() {
on_emergency_stop();
});
}
void on_step_completed(const state_type& state, time_type t) {
// Override in derived classes for domain-specific processing
}
void on_parameter_updated(const std::string& name, double value) {
// Handle parameter updates
parameters_[name] = value;
}
void on_emergency_stop() {
// Clear all targets and data
control_targets_.clear();
// Additional emergency procedures can be added here
}
};
template<system_state S, can_be_time T = double>
auto make_signal_processor(std::shared_ptr<AsyncIntegrator<S, T>> integrator) {
return std::make_unique<SignalProcessor<S, T>>(std::move(integrator));
}
template<typename SignalType>
auto make_signal(const typename SignalType::value_type& data,
const std::string& type = "",
double priority = 1.0) {
return SignalType{data, type, priority};
}
template<typename SignalType>
class SignalGenerator {
public:
using signal_type = SignalType;
using generator_function = std::function<SignalType()>;
SignalGenerator(generator_function gen, std::chrono::microseconds interval)
: generator_(std::move(gen))
, interval_(interval)
, running_(false) {}
~SignalGenerator() {
stop();
}
template<typename Handler>
void start(Handler&& handler) {
if (running_.exchange(true)) {
return;
}
thread_ = std::thread([this, h = std::forward<Handler>(handler)]() {
while (running_.load()) {
auto signal = generator_();
h(signal);
std::this_thread::sleep_for(interval_);
}
});
}
void stop() {
if (!running_.exchange(false)) {
return;
}
if (thread_.joinable()) {
thread_.join();
}
}
private:
generator_function generator_;
std::chrono::microseconds interval_;
std::atomic<bool> running_;
std::thread thread_;
};
} // namespace diffeq::signal