19#include <Eigen/src/Core/util/Meta.h>
32#include <unsupported/Eigen/MatrixFunctions>
53 return "AllanDeviation";
63 return "Data Processor";
73 ImGui::SetNextItemWidth(200.0F);
80 const std::array<std::string, 3> legendEntries{
"x",
"y",
"z" };
81 constexpr std::array<double, 5> slopeTicks = { -2, -1, 0, 1, 2 };
83 if (ImGui::BeginTabBar(
"AllanDeviationTabBar", ImGuiTabBarFlags_None))
87 auto sensorType =
static_cast<SensorType>(sensorIter);
88 const char* sensorName =
to_string(sensorType);
89 auto& sensor =
_sensors.at(sensorIter);
90 std::scoped_lock<std::mutex> lg(sensor.mutex);
92 if (ImGui::BeginTabItem(fmt::format(
"{}##TabItem {}", sensorName,
size_t(
id)).c_str()))
94 if (ImPlot::BeginPlot(fmt::format(
"Allan Deviation of {}##Plot {}", sensorName,
size_t(
id)).c_str()))
96 ImPlot::SetupLegend(ImPlotLocation_SouthWest, ImPlotLegendFlags_None);
97 ImPlot::SetupAxes(
"τ [s]", fmt::format(
"σ(τ) [{}]",
unitString(sensorType)).c_str(),
98 ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
99 ImPlot::SetupAxisScale(ImAxis_X1, ImPlotScale_Log10);
100 ImPlot::SetupAxisScale(ImAxis_Y1, ImPlotScale_Log10);
102 for (
size_t d = 0; d < 3; d++)
106 ImPlot::PlotShaded(legendEntries.at(d).data(),
108 sensor.allanDeviationConfidenceIntervals.at(d).at(0).data(),
109 sensor.allanDeviationConfidenceIntervals.at(d).at(1).data(),
112 ImPlot::PlotLine(legendEntries.at(d).data(),
114 sensor.allanDeviation.at(d).data(),
119 if (ImGui::TreeNode(
"Slopes"))
121 if (ImPlot::BeginPlot(
"Slopes of Allan Variance"))
123 ImPlot::SetupLegend(ImPlotLocation_SouthWest, ImPlotLegendFlags_None);
124 ImPlot::SetupAxis(ImAxis_X1,
"τ [s]", ImPlotAxisFlags_AutoFit);
125 ImPlot::SetupAxis(ImAxis_Y1,
"µ [ ]", ImPlotAxisFlags_Lock);
126 ImPlot::SetupAxisScale(ImAxis_X1, ImPlotScale_Log10);
127 ImPlot::SetupAxisLimits(ImAxis_Y1, -2.5, 2.5);
128 ImPlot::SetupAxisTicks(ImAxis_Y1, slopeTicks.data(), 5,
nullptr,
false);
129 for (
size_t d = 0; d < 3; d++)
131 ImPlot::PlotLine(legendEntries.at(d).data(),
133 sensor.slope.at(d).data(),
163 if (j.contains(
"displayConfidence")) { j.at(
"displayConfidence").get_to(
_displayConfidence); }
164 if (j.contains(
"confidenceFillAlpha")) { j.at(
"confidenceFillAlpha").get_to(
_confidenceFillAlpha); }
165 if (j.contains(
"updateLast")) { j.at(
"updateLast").get_to(
_updateLast); }
176 std::scoped_lock<std::mutex> lg(sensor.mutex);
177 sensor.cumSum = { Eigen::Vector3d::Zero() };
178 sensor.allanSum = {};
179 sensor.allanVariance = {};
180 sensor.allanDeviation = {};
182 sensor.allanDeviationConfidenceIntervals = {};
205 auto obs = std::static_pointer_cast<const ImuObs>(queue.
extract_front());
207 bool lastMessage =
false;
224 std::scoped_lock<std::mutex> lg(
_sensors.at(
Gyro).mutex);
236 for (
size_t d = 0; d < 3; d++)
238 sensor.allanSum.at(d).push_back(0);
256 std::scoped_lock<std::mutex> lg(sensor.mutex);
257 Eigen::Vector3d tempSum = sensor.cumSum.at(
_imuObsCount)
261 for (
size_t d = 0; d < 3; d++)
263 sensor.allanSum.at(d).at(k) += pow(tempSum(
static_cast<Eigen::Index
>(d)), 2);
283 std::scoped_lock<std::mutex> lg(sensor.mutex);
284 for (
size_t d = 0; d < 3; d++)
289 for (
size_t j = 0; j < 2; j++)
291 sensor.allanDeviationConfidenceIntervals.at(d).at(j).resize(
_averagingFactors.size(), 0.);
298 sensor.allanDeviation.at(d).at(k) = sqrt(sensor.allanVariance.at(d).at(k));
306 for (
size_t d = 0; d < 3; d++) { sensor.slope.at(d).resize(
_averagingFactors.size(), 0.); }
310 size_t lo = (k == 0 ? k : k - 1);
315 for (
size_t d = 0; d < 3; d++)
317 sensor.slope.at(d).at(k) = log(sensor.allanVariance.at(d).at(hi) / sensor.allanVariance.at(d).at(lo)) / divisor;
326 for (
auto& sensor :
_sensors) { sensor.cumSum.clear(); }
335 return "Accelerometer";
339 return "Error: Count";
353 return "Error: Count";
Computes Allan Deviation.
nlohmann::json json
json namespace
Text Help Marker (?) with Tooltip.
Parent Class for all IMU Observations.
Utility class for logging to console and file.
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
std::vector< double > _averagingFactors
averaging factors (n) used for Allan Variance computation
unsigned int _imuObsCount
number of IMU observations / length of cumulative sums
~AllanDeviation() override
Destructor.
static const char * unitString(SensorType sensorType)
Returns a string for the unit of the type.
static std::string category()
String representation of the Class Category.
std::vector< double > _averagingTimes
averaging times (τ)
static constexpr size_t INPUT_PORT_INDEX_IMU_OBS
Flow (ImuObs)
static std::string typeStatic()
String representation of the Class Type.
InsTime _startingInsTime
Time of first epoch received.
json save() const override
Saves the node into a json object.
std::array< Sensor, SensorType_COUNT > _sensors
Sensor data.
float _confidenceFillAlpha
The alpha value for the shaded plot of the confidence intervals.
double _samplingInterval
sampling interval
void deinitialize() override
Deinitialize the node.
unsigned int _nextAveragingFactor
next averaging factor to be appended to _averagingFactors
AllanDeviation()
Default constructor.
std::vector< double > _confidenceMultiplicationFactor
multiplication factor for simple confidence
bool _updateLast
Flag wether to update the plot for each message or once at the end.
bool _displayConfidence
Flag wether to display confidence intervals.
@ SensorType_COUNT
Amount of sensors to use.
static const char * to_string(SensorType sensorType)
Returns a string representation of the type.
double _averagingFactorsPerDecade
number of averaging factors per decade
void restore(const json &j) override
Restores the node from a json object.
unsigned int _nextAveragingFactorExponent
exponent of next averaging factor
void receiveImuObs(InputPin::NodeDataQueue &queue, size_t pinIdx)
Receive Sensor Data.
bool initialize() override
Initialize the node.
std::string type() const override
String representation of the Class Type.
void guiConfig() override
ImGui config window which is shown on double click.
std::vector< double > _observationCount
number of observations for each τ
static std::string type()
Returns the type of the data class.
ImVec2 _guiConfigDefaultWindowSize
Node(std::string name)
Constructor.
std::vector< InputPin > inputPins
List of input pins.
std::string nameId() const
Node name and id.
bool _lockConfigDuringRun
Lock the config when executing post-processing.
std::string name
Name of the Node.
bool _hasConfig
Flag if the config window should be shown.
auto extract_front()
Returns a copy of the first element in the container and removes it from the container.
bool empty() const noexcept
Checks if the container has no elements, i.e. whether 'begin() == end()'.
InputPin * CreateInputPin(Node *node, const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier={}, InputPin::Callback callback=static_cast< InputPin::FlowFirableCallbackFunc >(nullptr), InputPin::FlowFirableCheckFunc firable=nullptr, int priority=0, int idx=-1)
Create an Input Pin object.
void ApplyChanges()
Signals that there have been changes to the flow.
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.