35#include <imgui_internal.h>
59 return "LowPassFilter";
69 return "Data Processor";
76 ImGui::TextUnformatted(
"Please connect the input pin to show the options");
84 if (noMoreItems) { ImGui::BeginDisabled(); }
96 if (ImGui::Selectable(item.c_str(), is_selected))
102 ImGui::SetItemDefaultFocus();
108 if (ImGui::Button(fmt::format(
"Add##Filter item {}",
size_t(
id)).c_str()))
112 bool selectionChanged =
false;
122 selectionChanged =
true;
140 if (noMoreItems) { ImGui::EndDisabled(); }
145 std::optional<size_t> itemToDelete;
150 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
151 if (ImGui::CollapsingHeader(fmt::format(
"{}##{}", item.dataDescription,
size_t(
id)).c_str(), &keep))
153 ImGui::SetNextItemWidth(COMBO_WIDTH);
154 if (ImGui::BeginCombo(fmt::format(
"Filter Type##{}",
size_t(
id)).c_str(),
to_string(item.filterType)))
158 const bool is_selected = (
static_cast<size_t>(item.filterType) == i);
162 LOG_DEBUG(
"{}: filterType changed to {}",
nameId(), fmt::underlying(item.filterType));
167 ImGui::SetItemDefaultFocus();
175 ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(ImGui::GetCursorScreenPos().x + size / 1.2F,
176 ImGui::GetCursorScreenPos().y + size * 1.8F),
179 ? ImColor(0.0F, 255.0F, 0.0F)
180 : ImColor(255.0F, 0.0F, 0.0F));
181 ImGui::Dummy(ImVec2(2 * size, 3.0F * size));
182 if (ImGui::IsItemHovered())
184 ImGui::SetTooltip(item.modified
185 ?
"Indicates wether the filter is working."
186 :
"Indicates wether the filter is working.\n"
187 "Reasons why it is not working can be:\n"
188 "- Data rate of the incoming values must be greater then 2 * dt\n"
189 "- The data was never included in the observations (dynamic data)\n"
190 "- The data cannot be modified because it is not implemented yet");
196 ImGui::SetNextItemWidth(ITEM_WIDTH);
197 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"))
199 LOG_DEBUG(
"{}: Cutoff Freq. {} changed to {}",
nameId(), item.dataDescription, item.linear_filter_cutoff_frequency);
205 if (!keep) { itemToDelete = i; }
225 if (j.contains(
"availableItems")) { j.at(
"availableItems").get_to(
_availableItems); }
226 if (j.contains(
"filterItems")) { j.at(
"filterItems").get_to(
_filterItems); }
235 item.dataToFilter.clear();
236 item.modified =
false;
244 LOG_TRACE(
"{}: called for {} ==> {}",
nameId(),
size_t(startPin.
id),
size_t(endPin.id));
246 if (endPin.parentNode->id !=
id)
261 if (
auto* endPin = link.getConnectedPin())
276 if (
auto* connectedPin = link.getConnectedPin())
312 for (
const auto& desc : obs->dynamicDataDescriptors())
314 if (std::ranges::none_of(
_availableItems, [&](
const auto& header) {
return header == desc; }))
325 LOG_DATA(
"{}: [{}] {}",
nameId(), item.dataIndex, item.dataDescription);
326 if (item.dataIndex < out->staticDescriptorCount())
328 if (
auto value = out->getValueAt(item.dataIndex))
330 if (
auto newValue =
filterData(item, out->insTime, *value))
332 item.modified |= out->setValueAt(item.dataIndex, *newValue);
336 else if (
auto value = out->getDynamicDataAt(item.dataDescription))
338 if (
auto newValue =
filterData(item, out->insTime, *value))
340 item.modified |= out->setDynamicDataAt(item.dataDescription, *newValue);
357 std::erase_if(item.
dataToFilter, [&](
const auto& pair) { return static_cast<double>((insTime - pair.first).count()) > dt; });
362 auto N11 =
static_cast<double>(item.
dataToFilter.size());
369 auto delta_t =
static_cast<double>((key_val.first - insTime).count());
371 N22 += delta_t * delta_t;
372 n1 += key_val.second;
373 n2 += delta_t * key_val.second;
375 double determinant_inverse = 1.0 / (N11 * N22 - N12 * N12);
376 return determinant_inverse * (N22 * n1 - N12 * n2);
410 if (j.contains(
"dataDescription")) { j.at(
"dataDescription").get_to(data.
dataDescription); }
411 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.
std::string nameId() const
Node name and id.
std::string name
Name of the Node.
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'.
OutputPin * CreateOutputPin(Node *node, 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.
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.
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.