Icarus
Vehicle Simulation as a Transformable Computational Graph, built on Vulcan and Janus
Loading...
Searching...
No Matches
SignalRouter.hpp
Go to the documentation of this file.
1#pragma once
2
11
12#include <icarus/core/Error.hpp>
14
15#include <cstdint>
16#include <set>
17#include <string>
18#include <unordered_set>
19#include <vector>
20
21namespace icarus {
22namespace signal {
23
32 std::string input_path;
33 std::string output_path;
34
35 // Optional transformations
36 double gain = 1.0;
37 double offset = 0.0;
38 double delay = 0.0;
39
41 std::set<int32_t> active_phases;
42
43 SignalRoute() = default;
44 SignalRoute(std::string input, std::string output, double g = 1.0, double o = 0.0,
45 double d = 0.0)
46 : input_path(std::move(input)), output_path(std::move(output)), gain(g), offset(o),
47 delay(d) {}
48
51 [[nodiscard]] double EffectiveGain(int32_t current_phase) const {
52 if (active_phases.empty()) {
53 return gain; // No phase restriction - always active
54 }
55 if (active_phases.contains(current_phase)) {
56 return gain; // Active in this phase
57 }
58 return 0.0; // Inactive: zero the output
59 }
60
62 [[nodiscard]] bool IsActiveInPhase(int32_t current_phase) const {
63 return active_phases.empty() || active_phases.contains(current_phase);
64 }
65
67 [[nodiscard]] std::vector<std::string> Validate() const {
68 std::vector<std::string> errors;
69 if (input_path.empty()) {
70 errors.push_back("SignalRoute: input_path is empty");
71 }
72 if (output_path.empty()) {
73 errors.push_back("SignalRoute: output_path is empty");
74 }
75 if (delay < 0.0) {
76 errors.push_back("SignalRoute: delay cannot be negative");
77 }
78 return errors;
79 }
80};
81
103template <typename Scalar> class SignalRouter {
104 public:
108 void AddRoute(const SignalRoute &route) { routes_.push_back(route); }
109
113 void AddRoute(const std::string &input_path, const std::string &output_path,
114 double gain = 1.0) {
115 routes_.emplace_back(input_path, output_path, gain);
116 }
117
128 // First pass: validate all signals exist
129 auto errors = ValidateRoutes(bp);
130 if (!errors.empty()) {
131 std::string msg = "Signal routing validation failed:\n";
132 for (const auto &err : errors) {
133 msg += " - " + err + "\n";
134 }
135 throw RoutingError(msg);
136 }
137
138 // Second pass: wire with gains
139 for (const auto &route : routes_) {
140 bp.WireWithGain(route.input_path, route.output_path, route.gain);
141 }
142 }
143
150 [[nodiscard]] std::vector<std::string> ValidateRoutes(const Backplane<Scalar> &bp) const {
151 std::vector<std::string> errors;
152
153 for (const auto &route : routes_) {
154 if (!bp.HasOutput(route.output_path)) {
155 errors.push_back("Output not found: '" + route.output_path + "'");
156 }
157 if (!bp.HasInput(route.input_path)) {
158 errors.push_back("Input not found: '" + route.input_path + "'");
159 }
160 }
161
162 return errors;
163 }
164
173 [[nodiscard]] std::vector<std::string> GetUnwiredInputs(const Backplane<Scalar> &bp) const {
174 // Get all declared inputs from backplane
175 auto all_inputs = bp.GetDeclaredInputs();
176
177 // Build set of wired inputs
178 std::unordered_set<std::string> wired;
179 for (const auto &route : routes_) {
180 wired.insert(route.input_path);
181 }
182
183 // Find unwired
184 std::vector<std::string> unwired;
185 for (const auto &input : all_inputs) {
186 if (wired.find(input) == wired.end()) {
187 unwired.push_back(input);
188 }
189 }
190
191 return unwired;
192 }
193
197 [[nodiscard]] const std::vector<SignalRoute> &GetRoutes() const { return routes_; }
198
202 void Clear() { routes_.clear(); }
203
207 [[nodiscard]] std::size_t Size() const { return routes_.size(); }
208
209 private:
210 std::vector<SignalRoute> routes_;
211};
212
213} // namespace signal
214} // namespace icarus
Component-facing facade for signal registration and resolution.
Consolidated error handling for Icarus.
Component-facing facade for signal registration and resolution.
Definition Backplane.hpp:32
std::vector< std::string > GetDeclaredInputs() const
Get all declared input paths.
Definition Backplane.hpp:427
void WireWithGain(const std::string &input_path, const std::string &output_path, double gain=1.0)
Wire an input to a source with a gain factor.
Definition Backplane.hpp:389
bool HasOutput(const std::string &full_name) const
Check if an output signal exists.
Definition Backplane.hpp:411
bool HasInput(const std::string &full_name) const
Check if an input port exists.
Definition Backplane.hpp:418
Centralized signal routing configuration.
Definition SignalRouter.hpp:103
std::vector< std::string > ValidateRoutes(const Backplane< Scalar > &bp) const
Validate routes without applying.
Definition SignalRouter.hpp:150
const std::vector< SignalRoute > & GetRoutes() const
Get all routes for inspection.
Definition SignalRouter.hpp:197
std::size_t Size() const
Get number of routes.
Definition SignalRouter.hpp:207
void AddRoute(const std::string &input_path, const std::string &output_path, double gain=1.0)
Add a route with parameters.
Definition SignalRouter.hpp:113
void AddRoute(const SignalRoute &route)
Add a route.
Definition SignalRouter.hpp:108
std::vector< std::string > GetUnwiredInputs(const Backplane< Scalar > &bp) const
Get unwired inputs after routing.
Definition SignalRouter.hpp:173
void ApplyRoutes(Backplane< Scalar > &bp)
Apply all routes to the backplane.
Definition SignalRouter.hpp:127
void Clear()
Clear all routes.
Definition SignalRouter.hpp:202
Definition SignalRouter.hpp:22
Definition AggregationTypes.hpp:13
WiringError RoutingError
Definition Error.hpp:431
A single signal route with optional transformations.
Definition SignalRouter.hpp:31
std::string input_path
Full path: Entity.Component.signal (destination).
Definition SignalRouter.hpp:32
double gain
Scale factor applied on read.
Definition SignalRouter.hpp:36
double EffectiveGain(int32_t current_phase) const
Definition SignalRouter.hpp:51
double offset
Bias added after gain.
Definition SignalRouter.hpp:37
std::vector< std::string > Validate() const
Validate route paths.
Definition SignalRouter.hpp:67
bool IsActiveInPhase(int32_t current_phase) const
Check if route is active in given phase.
Definition SignalRouter.hpp:62
std::set< int32_t > active_phases
Phase gating: if non-empty, route only active when current phase is in this set.
Definition SignalRouter.hpp:41
std::string output_path
Full path: Entity.Component.signal (source).
Definition SignalRouter.hpp:33
double delay
Transport delay in seconds.
Definition SignalRouter.hpp:38
SignalRoute(std::string input, std::string output, double g=1.0, double o=0.0, double d=0.0)
Definition SignalRouter.hpp:44