50 return "Data Provider";
72 if (ImGui::BeginTable(fmt::format(
"##ImuHeaders ({})",
id.AsPointer()).c_str(), 3,
73 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
75 ImGui::TableSetupColumn(
"Time", ImGuiTableColumnFlags_WidthFixed);
76 ImGui::TableSetupColumn(
"IMU", ImGuiTableColumnFlags_WidthFixed);
77 ImGui::TableSetupColumn(
"Delta IMU", ImGuiTableColumnFlags_WidthFixed);
78 ImGui::TableHeadersRow();
80 auto TextColoredIfExists = [
this](
int index,
const char* displayText,
const char* searchText,
bool alwaysNormal =
false) {
81 ImGui::TableSetColumnIndex(index);
83 || std::ranges::find_if(
_headerColumns, [&searchText](
const std::string& header) {
84 return header.starts_with(searchText);
87 ImGui::TextUnformatted(displayText);
91 ImGui::TextDisabled(
"%s", displayText);
95 ImGui::TableNextRow();
96 TextColoredIfExists(0,
"GpsCycle",
"GpsCycle");
97 TextColoredIfExists(1,
"Mag",
"MagX");
98 TextColoredIfExists(2,
"DeltaTime",
"DeltaTime");
99 ImGui::TableNextRow();
100 TextColoredIfExists(0,
"GpsWeek",
"GpsWeek");
101 TextColoredIfExists(1,
"Acc",
"AccX");
102 TextColoredIfExists(2,
"DeltaTheta",
"DeltaThetaX");
103 ImGui::TableNextRow();
104 TextColoredIfExists(0,
"GpsToW",
"GpsToW");
105 TextColoredIfExists(1,
"Gyro",
"GyroX");
106 TextColoredIfExists(2,
"DeltaVel",
"DeltaVelX");
107 ImGui::TableNextRow();
108 TextColoredIfExists(0,
"TimeStartup",
"TimeStartup");
109 TextColoredIfExists(1,
"Temperature",
"Temperature");
131 if (j.contains(
"FileReader"))
135 if (j.contains(
"Imu"))
145 bool success =
false;
156 if (col.starts_with(
"DeltaTime")
157 || col.starts_with(
"DeltaThetaX") || col.starts_with(
"DeltaThetaY") || col.starts_with(
"DeltaThetaZ")
158 || col.starts_with(
"DeltaVelX") || col.starts_with(
"DeltaVelY") || col.starts_with(
"DeltaVelZ"))
176 if (
auto* pin = link.getConnectedPin())
201 std::shared_ptr<ImuObs> obs;
203 else { obs = std::make_shared<ImuObs>(
_imuPos); }
209 line.erase(line.begin(), std::ranges::find_if(line, [](
int ch) { return std::isgraph(ch); }));
217 std::stringstream lineStream(line);
220 std::optional<uint16_t> gpsCycle = 0;
221 std::optional<uint16_t> gpsWeek;
222 std::optional<long double> gpsToW;
223 std::optional<double> magX;
224 std::optional<double> magY;
225 std::optional<double> magZ;
226 std::optional<double> accelX;
227 std::optional<double> accelY;
228 std::optional<double> accelZ;
229 std::optional<double> gyroX;
230 std::optional<double> gyroY;
231 std::optional<double> gyroZ;
233 std::optional<double> deltaTime;
234 std::optional<double> deltaThetaX;
235 std::optional<double> deltaThetaY;
236 std::optional<double> deltaThetaZ;
237 std::optional<double> deltaVelX;
238 std::optional<double> deltaVelY;
239 std::optional<double> deltaVelZ;
244 if (std::getline(lineStream, cell,
','))
247 cell.erase(std::ranges::find_if(cell, [](
int ch) {
return std::iscntrl(ch); }), cell.end());
249 if (cell.empty()) {
continue; }
251 if (column.starts_with(
"GpsCycle"))
253 gpsCycle =
static_cast<uint16_t
>(std::stoul(cell));
255 else if (column.starts_with(
"GpsWeek"))
257 gpsWeek =
static_cast<uint16_t
>(std::stoul(cell));
259 else if (column.starts_with(
"GpsToW"))
261 gpsToW = std::stold(cell);
263 else if (column.starts_with(
"MagX"))
265 magX = std::stod(cell);
267 else if (column.starts_with(
"MagY"))
269 magY = std::stod(cell);
271 else if (column.starts_with(
"MagZ"))
273 magZ = std::stod(cell);
275 else if (column.starts_with(
"AccX"))
277 accelX = std::stod(cell);
279 else if (column.starts_with(
"AccY"))
281 accelY = std::stod(cell);
283 else if (column.starts_with(
"AccZ"))
285 accelZ = std::stod(cell);
287 else if (column.starts_with(
"GyroX"))
289 gyroX = std::stod(cell);
291 else if (column.starts_with(
"GyroY"))
293 gyroY = std::stod(cell);
295 else if (column.starts_with(
"GyroZ"))
297 gyroZ = std::stod(cell);
299 else if (column.starts_with(
"Temperature"))
301 obs->temperature.emplace(std::stod(cell));
303 else if (column.starts_with(
"DeltaTime"))
305 deltaTime = std::stod(cell);
307 else if (column.starts_with(
"DeltaThetaX"))
309 deltaThetaX = std::stod(cell);
311 else if (column.starts_with(
"DeltaThetaY"))
313 deltaThetaY = std::stod(cell);
315 else if (column.starts_with(
"DeltaThetaZ"))
317 deltaThetaZ = std::stod(cell);
319 else if (column.starts_with(
"DeltaVelX"))
321 deltaVelX = std::stod(cell);
323 else if (column.starts_with(
"DeltaVelY"))
325 deltaVelY = std::stod(cell);
327 else if (column.starts_with(
"DeltaVelZ"))
329 deltaVelZ = std::stod(cell);
336 if (deltaTime && deltaThetaX && deltaThetaY && deltaThetaZ && deltaVelX && deltaVelY && deltaVelZ)
338 if (
auto obsWDelta = std::reinterpret_pointer_cast<ImuObsWDelta>(obs))
340 obsWDelta->dtime = deltaTime.value();
341 obsWDelta->dtheta = { deltaThetaX.value(), deltaThetaY.value(), deltaThetaZ.value() };
342 obsWDelta->dvel = { deltaVelX.value(), deltaVelY.value(), deltaVelZ.value() };
347 LOG_ERROR(
"{}: Columns 'DeltaTime', 'DeltaThetaX', 'DeltaThetaY', 'DeltaThetaZ', 'DeltaVelX', 'DeltaVelY', 'DeltaVelZ' are needed.",
nameId());
352 if (!gpsCycle || !gpsWeek || !gpsToW)
354 LOG_ERROR(
"{}: Fields 'GpsCycle', 'GpsWeek', 'GpsToW' are needed.",
nameId());
357 if (!accelX || !accelY || !accelZ)
362 if (!gyroX || !gyroY || !gyroZ)
364 LOG_ERROR(
"{}: Fields 'GyroX', 'GyroY', 'GyroZ' are needed.",
nameId());
368 obs->insTime =
InsTime(gpsCycle.value(), gpsWeek.value(), gpsToW.value());
369 obs->p_acceleration = { accelX.value(), accelY.value(), accelZ.value() };
370 obs->p_angularRate = { gyroX.value(), gyroY.value(), gyroZ.value() };
372 if (magX && magY && magZ)
374 obs->p_magneticField.emplace(magX.value(), magY.value(), magZ.value());
Transformation collection.
nlohmann::json json
json namespace
File Reader for Imu log files.
Data storage class for one VectorNavImu observation.
Parent Class for all IMU Observations.
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_ERROR
Error occurred, which stops part of the program to work, but not everything.
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Utility functions for working with std::strings.
bool initialize()
Initialize the file reader.
void restore(const json &j)
Restores the node from a json object.
std::string _path
Path to the file.
@ PATH_CHANGED
The path changed and exists.
std::vector< std::string > _headerColumns
Header Columns of a CSV file.
GuiResult guiConfig(const char *vFilters, const std::vector< std::string > &extensions, size_t id, const std::string &nameId)
ImGui config.
void resetReader()
Moves the read cursor to the start.
auto & getline(std::string &str)
Reads a line from the filestream.
json save() const
Saves the node into a json object.
void deinitialize()
Deinitialize the file reader.
void restore(const json &j) override
Restores the node from a json object.
void deinitialize() override
Deinitialize 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.
static std::string category()
String representation of the Class Category.
bool resetNode() override
Resets the node. Moves the read cursor to the start.
std::shared_ptr< const NodeData > pollData()
Polls data from the file.
json save() const override
Saves the node into a json object.
static constexpr size_t OUTPUT_PORT_INDEX_IMU_OBS
Flow (ImuObs)
bool initialize() override
Initialize the node.
~ImuFile() override
Destructor.
static std::string typeStatic()
String representation of the Class Type.
ImuFile()
Default constructor.
bool _withDelta
Flag if the header has delta values.
static std::string type()
Returns the type of the data class.
static std::string type()
Returns the type of the data class.
json save() const override
Saves the node into a json object.
void restore(const json &j) override
Restores the node from a json object.
void guiConfig() override
ImGui config window which is shown on double click.
Imu(const Imu &)=delete
Copy constructor.
ImuPos _imuPos
Position and rotation information for conversion from platform to body frame.
The class is responsible for all time-related tasks.
bool doDeinitialize(bool wait=false)
Asks the node worker to deinitialize the node.
ImVec2 _guiConfigDefaultWindowSize
std::vector< OutputPin > outputPins
List of output 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.
bool doReinitialize(bool wait=false)
Asks the node worker to reinitialize the node.
void invokeCallbacks(size_t portIndex, const std::shared_ptr< const NodeData > &data)
Calls all registered callbacks on the specified output port.
bool _hasConfig
Flag if the config window should be shown.
void ApplyChanges()
Signals that there have been changes to the flow.
static bool replace(std::string &str, const std::string &from, const std::string &to, CaseSensitivity cs=RespectCase)
Replaces the first occurrence of a search pattern with another sequence.