DiffEq - Modern C++ ODE Integration Library 1.0.0
High-performance C++ library for solving ODEs with async signal processing
Loading...
Searching...
No Matches
signal_processor_old.hpp
1#pragma once
2
3#include <async/async_integrator.hpp>
4#include <functional>
5#include <memory>
6#include <vector>
7#include <array>
8#include <unordered_map>
9#include <string>
10#include <cmath>
11#include <algorithm>
12#include <numeric>
13#include <chrono>
14
15namespace diffeq::signal {
16
23template<typename T>
24struct Signal {
25 T data;
26 std::chrono::steady_clock::time_point timestamp;
27 std::string type_id;
28 double priority = 1.0;
29
30 template<typename U>
31 Signal(U&& signal_data, std::string type = "", double prio = 1.0)
32 : data(std::forward<U>(signal_data))
33 , timestamp(std::chrono::steady_clock::now())
34 , type_id(std::move(type))
35 , priority(prio) {}
36};
37
41template<typename Handler, typename Signal>
42concept SignalHandler = requires(Handler h, const Signal& s) {
43 { h(s) } -> std::same_as<void>;
44};
45
52template<system_state S, can_be_time T = double>
53class SignalProcessor {
54public:
55 using state_type = S;
56 using time_type = T;
57 using value_type = typename S::value_type;
58 using integrator_type = AsyncIntegrator<S, T>;
59
60 // Signal types for different domains
61 using parameter_signal = Signal<std::unordered_map<std::string, double>>;
62 using control_signal = Signal<std::vector<double>>;
64
65 explicit SignalProcessor(std::shared_ptr<integrator_type> integrator)
66 : integrator_(std::move(integrator)) {
67
68 // Set up default callbacks
69 setup_default_callbacks();
70 }
71
76 for (const auto& [name, value] : signal.data) {
77 update_parameter(name, value);
78 }
79 }
80
85 // Update control targets
86 if (signal.data.size() >= 6) { // 6-DOF robot example
87 control_targets_ = signal.data;
88 last_control_update_ = signal.timestamp;
89 }
90 }
91
96 // Update market data
97 for (const auto& [symbol, value] : signal.data) {
98 market_data_[symbol] = value;
99 }
100 last_market_update_ = signal.timestamp;
101 }
102
106 const std::vector<double>& get_control_targets() const {
107 return control_targets_;
108 }
109
113 double get_market_data(const std::string& symbol) const {
114 auto it = market_data_.find(symbol);
115 return (it != market_data_.end()) ? it->second : 0.0;
116 }
117
121 void update_parameter(const std::string& name, double value) {
122 parameters_[name] = value;
123
124 // Notify integrator asynchronously
125 if (integrator_) {
126 integrator_->update_parameter_async(name, value);
127 }
128 }
129
133 double get_parameter(const std::string& name) const {
134 auto it = parameters_.find(name);
135 return (it != parameters_.end()) ? it->second : 0.0;
136 }
137
141 template<typename SignalType, SignalHandler<SignalType> Handler>
142 void register_handler(const std::string& signal_type, Handler&& handler) {
143 // Store handler in type-erased form
144 custom_handlers_[signal_type] = [h = std::forward<Handler>(handler)](const std::any& signal) {
145 try {
146 const auto& typed_signal = std::any_cast<const SignalType&>(signal);
147 h(typed_signal);
148 } catch (const std::bad_any_cast&) {
149 // Handle type mismatch gracefully
150 }
151 };
152 }
153
157 template<typename SignalType>
158 void process_signal(const SignalType& signal) {
159 auto it = custom_handlers_.find(signal.type_id);
160 if (it != custom_handlers_.end()) {
161 it->second(std::any(signal));
162 }
163 }
164
165private:
166 std::shared_ptr<integrator_type> integrator_;
167
168 // Signal data storage
169 std::unordered_map<std::string, double> parameters_;
170 std::vector<double> control_targets_;
171 std::unordered_map<std::string, double> market_data_;
172
173 // Timestamps
174 std::chrono::steady_clock::time_point last_control_update_;
175 std::chrono::steady_clock::time_point last_market_update_;
176
177 // Custom handlers
178 std::unordered_map<std::string, std::function<void(const std::any&)>> custom_handlers_;
179
180 void setup_default_callbacks() {
181 if (!integrator_) return;
182
183 // Set up step callback to update internal state
184 integrator_->set_step_callback([this](const state_type& state, time_type t) {
185 on_step_completed(state, t);
186 });
187
188 // Set up parameter callback
189 integrator_->set_parameter_callback([this](const std::string& name, double value) {
190 on_parameter_updated(name, value);
191 });
192
193 // Set up emergency callback
194 integrator_->set_emergency_callback([this]() {
195 on_emergency_stop();
196 });
197 }
198
199 void on_step_completed(const state_type& state, time_type t) {
200 // Override in derived classes for domain-specific processing
201 }
202
203 void on_parameter_updated(const std::string& name, double value) {
204 // Handle parameter updates
205 parameters_[name] = value;
206 }
207
208 void on_emergency_stop() {
209 // Clear all targets and data
210 control_targets_.clear();
211 // Additional emergency procedures can be added here
212 }
213};
214
218template<system_state S, can_be_time T = double>
219auto make_signal_processor(std::shared_ptr<AsyncIntegrator<S, T>> integrator) {
220 return std::make_unique<SignalProcessor<S, T>>(std::move(integrator));
221}
222
226template<typename SignalType>
227auto make_signal(const typename SignalType::value_type& data,
228 const std::string& type = "",
229 double priority = 1.0) {
230 return SignalType{data, type, priority};
231}
232
236template<typename SignalType>
238public:
239 using signal_type = SignalType;
240 using generator_function = std::function<SignalType()>;
241
242 SignalGenerator(generator_function gen, std::chrono::microseconds interval)
243 : generator_(std::move(gen))
244 , interval_(interval)
245 , running_(false) {}
246
248 stop();
249 }
250
251 template<typename Handler>
252 void start(Handler&& handler) {
253 if (running_.exchange(true)) {
254 return;
255 }
256
257 thread_ = std::thread([this, h = std::forward<Handler>(handler)]() {
258 while (running_.load()) {
259 auto signal = generator_();
260 h(signal);
261
262 std::this_thread::sleep_for(interval_);
263 }
264 });
265 }
266
267 void stop() {
268 if (!running_.exchange(false)) {
269 return;
270 }
271
272 if (thread_.joinable()) {
273 thread_.join();
274 }
275 }
276
277private:
278 generator_function generator_;
279 std::chrono::microseconds interval_;
280 std::atomic<bool> running_;
281 std::thread thread_;
282};
283
284} // namespace diffeq::signal
Timer-based signal generator for testing.
void process_parameter_signal(const parameter_signal &signal)
Process parameter update signal.
void process_control_signal(const control_signal &signal)
Process control signal (for robotics)
const std::vector< double > & get_control_targets() const
Get current control targets.
void process_market_signal(const market_signal &signal)
Process market signal (for finance)
void process_signal(const SignalType &signal)
Process generic signal.
void update_parameter(const std::string &name, double value)
Update integration parameter.
void register_handler(const std::string &signal_type, Handler &&handler)
Register custom signal handler.
void update_parameter(const std::string &param_name, double value)
Update integration parameters.
double get_market_data(const std::string &symbol) const
Get market data for symbol.
double get_parameter(const std::string &name) const
Get parameter value.
Generic signal data structure.