33#include <imgui_internal.h>
57 return "LowPassFilter";
67 return "Data Processor";
74 ImGui::TextUnformatted(
"Please connect the input pin to show the options");
82 if (noMoreItems) { ImGui::BeginDisabled(); }
94 if (ImGui::Selectable(item.c_str(), is_selected))
100 ImGui::SetItemDefaultFocus();
106 if (ImGui::Button(fmt::format(
"Add##Filter item {}",
size_t(
id)).c_str()))
110 bool selectionChanged =
false;
120 selectionChanged =
true;
138 if (noMoreItems) { ImGui::EndDisabled(); }
143 std::optional<size_t> itemToDelete;
148 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
149 if (ImGui::CollapsingHeader(fmt::format(
"{}##{}", item.dataDescription,
size_t(
id)).c_str(), &keep))
151 ImGui::SetNextItemWidth(COMBO_WIDTH);
152 if (ImGui::BeginCombo(fmt::format(
"Filter Type##{}",
size_t(
id)).c_str(),
to_string(item.filterType)))
156 const bool is_selected = (
static_cast<size_t>(item.filterType) == i);
160 LOG_DEBUG(
"{}: filterType changed to {}",
nameId(), fmt::underlying(item.filterType));
165 ImGui::SetItemDefaultFocus();
173 ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(ImGui::GetCursorScreenPos().x + size / 1.2F,
174 ImGui::GetCursorScreenPos().y + size * 1.8F),
177 ? ImColor(0.0F, 255.0F, 0.0F)
178 : ImColor(255.0F, 0.0F, 0.0F));
179 ImGui::Dummy(ImVec2(2 * size, 3.0F * size));
180 if (ImGui::IsItemHovered())
182 ImGui::SetTooltip(item.modified
183 ?
"Indicates wether the filter is working."
184 :
"Indicates wether the filter is working.\n"
185 "Reasons why it is not working can be:\n"
186 "- Data rate of the incoming values must be greater then 2 * dt\n"
187 "- The data was never included in the observations (dynamic data)\n"
188 "- The data cannot be modified because it is not implemented yet");
194 ImGui::SetNextItemWidth(ITEM_WIDTH);
195 if (
ImGui::InputDoubleL(fmt::format(
"Cutoff Frequency##{} {}",
size_t(
id), item.dataDescription).c_str(), &item.linear_filter_cutoff_frequency, 1e-5, 1e5, 0.0, 0.0,
"%.5f Hz"))
197 LOG_DEBUG(
"{}: Cutoff Freq. {} changed to {}",
nameId(), item.dataDescription, item.linear_filter_cutoff_frequency);
203 if (!keep) { itemToDelete = i; }
223 if (j.contains(
"availableItems")) { j.at(
"availableItems").get_to(
_availableItems); }
224 if (j.contains(
"filterItems")) { j.at(
"filterItems").get_to(
_filterItems); }
233 item.dataToFilter.clear();
234 item.modified =
false;
242 LOG_TRACE(
"{}: called for {} ==> {}",
nameId(),
size_t(startPin.
id),
size_t(endPin.id));
244 if (endPin.parentNode->id !=
id)
259 if (
auto* endPin = link.getConnectedPin())
274 if (
auto* connectedPin = link.getConnectedPin())
310 for (
const auto& desc : obs->dynamicDataDescriptors())
312 if (std::ranges::none_of(
_availableItems, [&](
const auto& header) {
return header == desc; }))
323 LOG_DATA(
"{}: [{}] {}",
nameId(), item.dataIndex, item.dataDescription);
324 if (item.dataIndex < out->staticDescriptorCount())
326 if (
auto value = out->getValueAt(item.dataIndex))
328 if (
auto newValue =
filterData(item, out->insTime, *value))
330 item.modified |= out->setValueAt(item.dataIndex, *newValue);
334 else if (
auto value = out->getDynamicDataAt(item.dataDescription))
336 if (
auto newValue =
filterData(item, out->insTime, *value))
338 item.modified |= out->setDynamicDataAt(item.dataDescription, *newValue);
355 std::erase_if(item.
dataToFilter, [&](
const auto& pair) { return static_cast<double>((insTime - pair.first).count()) > dt; });
360 auto N11 =
static_cast<double>(item.
dataToFilter.size());
367 auto delta_t =
static_cast<double>((key_val.first - insTime).count());
369 N22 += delta_t * delta_t;
370 n1 += key_val.second;
371 n2 += delta_t * key_val.second;
373 double determinant_inverse = 1.0 / (N11 * N22 - N12 * N12);
374 return determinant_inverse * (N22 * n1 - N12 * n2);
408 if (j.contains(
"dataDescription")) { j.at(
"dataDescription").get_to(data.
dataDescription); }
409 if (j.contains(
"filterType")) { j.at(
"filterType").get_to(data.
filterType); }
Transformation collection.
nlohmann::json json
json namespace
Text Help Marker (?) with Tooltip.
Data storage class for simulated IMU observations.
Data storage class for one VectorNavImu observation.
Utility class for logging to console and file.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Utility class which specifies available nodes.
Utility functions for working with std::strings.
The class is responsible for all time-related tasks.
void afterCreateLink(OutputPin &startPin, InputPin &endPin) override
Called when a new link was established.
void restore(const json &j) override
Restores the node from a json object.
std::vector< FilterItem > _filterItems
Items to filter.
static std::string category()
String representation of the Class Category.
LowPassFilter()
Default constructor.
size_t _gui_availableItemsSelection
Selected item in the combo.
bool resetNode() override
Resets the node. It is guaranteed that the node is initialized when this is called.
static std::optional< double > filterData(FilterItem &item, const InsTime &insTime, double value)
Filter the provided data.
void afterDeleteLink(OutputPin &startPin, InputPin &endPin) override
Called when a link was deleted.
~LowPassFilter() override
Destructor.
static constexpr size_t INPUT_PORT_INDEX_FLOW
Flow.
FilterType
Types of available filters (to be extended)
@ Linear
Linear fit filter.
@ COUNT
Amount of items in the enum.
static std::string typeStatic()
String representation of the Class Type.
json save() const override
Saves the node into a json object.
void guiConfig() override
ImGui config window which is shown on double click.
std::string type() const override
String representation of the Class Type.
static const char * to_string(FilterType value)
Converts the enum to a string.
std::vector< std::string > _availableItems
Available items.
static constexpr size_t OUTPUT_PORT_INDEX_FLOW
Flow.
void receiveObs(InputPin::NodeDataQueue &queue, size_t pinIdx)
Callback when receiving data on a port.
static std::string type()
Returns the type of the data class.
ImVec2 _guiConfigDefaultWindowSize
std::vector< OutputPin > outputPins
List of output pins.
Node(std::string name)
Constructor.
std::vector< InputPin > inputPins
List of input pins.
OutputPin * CreateOutputPin(const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier, OutputPin::PinData data=static_cast< void * >(nullptr), int idx=-1)
Create an Output Pin object.
std::string nameId() const
Node name and id.
std::string name
Name of the Node.
InputPin * CreateInputPin(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 invokeCallbacks(size_t portIndex, const std::shared_ptr< const NodeData > &data)
Calls all registered callbacks on the specified output port.
ax::NodeEditor::NodeId id
Unique Id of the Node.
bool _hasConfig
Flag if the config window should be shown.
Node * parentNode
Reference to the parent node.
ax::NodeEditor::PinId id
Unique Id of the Pin.
std::vector< std::string > dataIdentifier
One or multiple Data Identifiers (Unique name which is used for data flows)
auto extract_front()
Returns a copy of the first element in the container and removes it from the container.
static float windowFontRatio()
Ratio to multiply for GUI window elements.
static float defaultFontRatio()
Ratio to multiply for default GUI elements.
bool InputDoubleL(const char *label, double *v, double v_min, double v_max, double step, double step_fast, const char *format, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'double'.
std::vector< std::string > GetStaticDataDescriptors(const std::vector< std::string > &dataIdentifier)
Returns a vector of data descriptors for the pin data identifiers.
std::shared_ptr< NodeData > CopyNodeData(const std::shared_ptr< const NodeData > &nodeData)
Creates a copy of the data.
void ApplyChanges()
Signals that there have been changes to the flow.
void to_json(json &j, const Node &node)
Converts the provided node into a json object.
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.
void from_json(const json &j, Node &node)
Converts the provided json object into a node object.
std::string dataDescription
Description of the data.
FilterType filterType
Selected filter type in the GUI.
double linear_filter_cutoff_frequency
Cutoff frequency [Hz], inverse of this parameter equals to fitting period.
std::map< InsTime, double > dataToFilter
Map which stores all last data points which were used in the previous fit.