3#include <async/async_integrator.hpp>
8#include <unordered_map>
15namespace diffeq::signal {
26 std::chrono::steady_clock::time_point timestamp;
28 double priority = 1.0;
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))
41template<
typename Handler,
typename Signal>
43 { h(s) } -> std::same_as<void>;
52template<system_state S, can_be_time T =
double>
57 using value_type =
typename S::value_type;
58 using integrator_type = AsyncIntegrator<S, T>;
66 : integrator_(std::move(integrator)) {
69 setup_default_callbacks();
76 for (
const auto& [name, value] : signal.data) {
86 if (signal.data.size() >= 6) {
87 control_targets_ = signal.data;
88 last_control_update_ = signal.timestamp;
97 for (
const auto& [symbol, value] : signal.data) {
98 market_data_[symbol] = value;
100 last_market_update_ = signal.timestamp;
107 return control_targets_;
114 auto it = market_data_.find(symbol);
115 return (it != market_data_.end()) ? it->second : 0.0;
122 parameters_[name] = value;
126 integrator_->update_parameter_async(name, value);
134 auto it = parameters_.find(name);
135 return (it != parameters_.end()) ? it->second : 0.0;
141 template<
typename SignalType, SignalHandler<SignalType> Handler>
144 custom_handlers_[signal_type] = [h = std::forward<Handler>(handler)](
const std::any& signal) {
146 const auto& typed_signal = std::any_cast<const SignalType&>(signal);
148 }
catch (
const std::bad_any_cast&) {
157 template<
typename SignalType>
159 auto it = custom_handlers_.find(signal.type_id);
160 if (it != custom_handlers_.end()) {
161 it->second(std::any(signal));
166 std::shared_ptr<integrator_type> integrator_;
169 std::unordered_map<std::string, double> parameters_;
170 std::vector<double> control_targets_;
171 std::unordered_map<std::string, double> market_data_;
174 std::chrono::steady_clock::time_point last_control_update_;
175 std::chrono::steady_clock::time_point last_market_update_;
178 std::unordered_map<std::string, std::function<void(
const std::any&)>> custom_handlers_;
180 void setup_default_callbacks() {
181 if (!integrator_)
return;
184 integrator_->set_step_callback([
this](
const state_type& state, time_type t) {
185 on_step_completed(state, t);
189 integrator_->set_parameter_callback([
this](
const std::string& name,
double value) {
190 on_parameter_updated(name, value);
194 integrator_->set_emergency_callback([
this]() {
199 void on_step_completed(
const state_type& state, time_type t) {
203 void on_parameter_updated(
const std::string& name,
double value) {
205 parameters_[name] = value;
208 void on_emergency_stop() {
210 control_targets_.clear();
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));
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};
236template<
typename SignalType>
239 using signal_type = SignalType;
240 using generator_function = std::function<SignalType()>;
242 SignalGenerator(generator_function gen, std::chrono::microseconds interval)
243 : generator_(std::move(gen))
244 , interval_(interval)
251 template<
typename Handler>
252 void start(Handler&& handler) {
253 if (running_.exchange(
true)) {
257 thread_ = std::thread([
this, h = std::forward<Handler>(handler)]() {
258 while (running_.load()) {
259 auto signal = generator_();
262 std::this_thread::sleep_for(interval_);
268 if (!running_.exchange(
false)) {
272 if (thread_.joinable()) {
278 generator_function generator_;
279 std::chrono::microseconds interval_;
280 std::atomic<bool> running_;
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 ¶m_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.