52 return "Data Provider";
74 if (ImGui::BeginTable(fmt::format(
"##ImuHeaders ({})",
id.AsPointer()).c_str(), 3,
75 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
77 ImGui::TableSetupColumn(
"Time", ImGuiTableColumnFlags_WidthFixed);
78 ImGui::TableSetupColumn(
"IMU", ImGuiTableColumnFlags_WidthFixed);
79 ImGui::TableSetupColumn(
"Delta IMU", ImGuiTableColumnFlags_WidthFixed);
80 ImGui::TableHeadersRow();
82 auto TextColoredIfExists = [
this](
int index,
const char* displayText,
const char* searchText,
bool alwaysNormal =
false) {
83 ImGui::TableSetColumnIndex(index);
85 || std::ranges::find_if(
_headerColumns, [&searchText](
const std::string& header) {
86 return header.starts_with(searchText);
89 ImGui::TextUnformatted(displayText);
93 ImGui::TextDisabled(
"%s", displayText);
97 ImGui::TableNextRow();
98 TextColoredIfExists(0,
"GpsCycle",
"GpsCycle");
99 TextColoredIfExists(1,
"Mag",
"MagX");
100 TextColoredIfExists(2,
"DeltaTime",
"DeltaTime");
101 ImGui::TableNextRow();
102 TextColoredIfExists(0,
"GpsWeek",
"GpsWeek");
103 TextColoredIfExists(1,
"Acc",
"AccX");
104 TextColoredIfExists(2,
"DeltaTheta",
"DeltaThetaX");
105 ImGui::TableNextRow();
106 TextColoredIfExists(0,
"GpsToW",
"GpsToW");
107 TextColoredIfExists(1,
"Gyro",
"GyroX");
108 TextColoredIfExists(2,
"DeltaVel",
"DeltaVelX");
109 ImGui::TableNextRow();
110 TextColoredIfExists(0,
"TimeStartup",
"TimeStartup");
111 TextColoredIfExists(1,
"Temperature",
"Temperature");
133 if (j.contains(
"FileReader"))
137 if (j.contains(
"Imu"))
157 if (col.starts_with(
"DeltaTime")
158 || col.starts_with(
"DeltaThetaX") || col.starts_with(
"DeltaThetaY") || col.starts_with(
"DeltaThetaZ")
159 || col.starts_with(
"DeltaVelX") || col.starts_with(
"DeltaVelY") || col.starts_with(
"DeltaVelZ"))
175 if (
auto* pin = link.getConnectedPin())
200 std::shared_ptr<ImuObs> obs;
202 else { obs = std::make_shared<ImuObs>(
_imuPos); }
208 line.erase(line.begin(), std::ranges::find_if(line, [](
int ch) { return std::isgraph(ch); }));
216 std::stringstream lineStream(line);
219 std::optional<uint16_t> gpsCycle = 0;
220 std::optional<uint16_t> gpsWeek;
221 std::optional<long double> gpsToW;
222 std::optional<double> magX;
223 std::optional<double> magY;
224 std::optional<double> magZ;
225 std::optional<double> accelX;
226 std::optional<double> accelY;
227 std::optional<double> accelZ;
228 std::optional<double> gyroX;
229 std::optional<double> gyroY;
230 std::optional<double> gyroZ;
232 std::optional<double> deltaTime;
233 std::optional<double> deltaThetaX;
234 std::optional<double> deltaThetaY;
235 std::optional<double> deltaThetaZ;
236 std::optional<double> deltaVelX;
237 std::optional<double> deltaVelY;
238 std::optional<double> deltaVelZ;
243 if (std::getline(lineStream, cell,
','))
246 cell.erase(std::ranges::find_if(cell, [](
int ch) {
return std::iscntrl(ch); }), cell.end());
248 if (cell.empty()) {
continue; }
250 if (column.starts_with(
"GpsCycle"))
252 gpsCycle =
static_cast<uint16_t
>(std::stoul(cell));
254 else if (column.starts_with(
"GpsWeek"))
256 gpsWeek =
static_cast<uint16_t
>(std::stoul(cell));
258 else if (column.starts_with(
"GpsToW"))
260 gpsToW = std::stold(cell);
262 else if (column.starts_with(
"MagX"))
264 magX = std::stod(cell);
266 else if (column.starts_with(
"MagY"))
268 magY = std::stod(cell);
270 else if (column.starts_with(
"MagZ"))
272 magZ = std::stod(cell);
274 else if (column.starts_with(
"AccX"))
276 accelX = std::stod(cell);
278 else if (column.starts_with(
"AccY"))
280 accelY = std::stod(cell);
282 else if (column.starts_with(
"AccZ"))
284 accelZ = std::stod(cell);
286 else if (column.starts_with(
"GyroX"))
288 gyroX = std::stod(cell);
290 else if (column.starts_with(
"GyroY"))
292 gyroY = std::stod(cell);
294 else if (column.starts_with(
"GyroZ"))
296 gyroZ = std::stod(cell);
298 else if (column.starts_with(
"Temperature"))
300 obs->temperature.emplace(std::stod(cell));
302 else if (column.starts_with(
"DeltaTime"))
304 deltaTime = std::stod(cell);
306 else if (column.starts_with(
"DeltaThetaX"))
308 deltaThetaX = std::stod(cell);
310 else if (column.starts_with(
"DeltaThetaY"))
312 deltaThetaY = std::stod(cell);
314 else if (column.starts_with(
"DeltaThetaZ"))
316 deltaThetaZ = std::stod(cell);
318 else if (column.starts_with(
"DeltaVelX"))
320 deltaVelX = std::stod(cell);
322 else if (column.starts_with(
"DeltaVelY"))
324 deltaVelY = std::stod(cell);
326 else if (column.starts_with(
"DeltaVelZ"))
328 deltaVelZ = std::stod(cell);
335 if (deltaTime && deltaThetaX && deltaThetaY && deltaThetaZ && deltaVelX && deltaVelY && deltaVelZ)
337 if (
auto obsWDelta = std::reinterpret_pointer_cast<ImuObsWDelta>(obs))
339 obsWDelta->dtime = deltaTime.value();
340 obsWDelta->dtheta = { deltaThetaX.value(), deltaThetaY.value(), deltaThetaZ.value() };
341 obsWDelta->dvel = { deltaVelX.value(), deltaVelY.value(), deltaVelZ.value() };
346 LOG_ERROR(
"{}: Columns 'DeltaTime', 'DeltaThetaX', 'DeltaThetaY', 'DeltaThetaZ', 'DeltaVelX', 'DeltaVelY', 'DeltaVelZ' are needed.",
nameId());
351 if (!gpsCycle || !gpsWeek || !gpsToW)
353 LOG_ERROR(
"{}: Fields 'GpsCycle', 'GpsWeek', 'GpsToW' are needed.",
nameId());
356 if (!accelX || !accelY || !accelZ)
361 if (!gyroX || !gyroY || !gyroZ)
363 LOG_ERROR(
"{}: Fields 'GyroX', 'GyroY', 'GyroZ' are needed.",
nameId());
367 obs->insTime =
InsTime(gpsCycle.value(), gpsWeek.value(), gpsToW.value());
368 obs->p_acceleration = { accelX.value(), accelY.value(), accelZ.value() };
369 obs->p_angularRate = { gyroX.value(), gyroY.value(), gyroZ.value() };
371 if (magX && magY && magZ)
373 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.
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.
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.
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.