Skip to content

Commit bbaaf62

Browse files
authored
Fix logic error in offline node (ros) and interval imu stats compute (core) (#29)
* cleaner error messages and log parsed imu and lidar frames for ros * patch rviz config to change the global frame if a different odom frame is used * revert offline node bag and buffer completion handling logic * cannot compute accel mag variance if imu count is 1. modify the check preventing divide by 0 errors * remove python/config/default.yaml since --dump_config does the same job * bump version to v0.1.1 and update python readme slightly
1 parent 18a064c commit bbaaf62

File tree

11 files changed

+57
-43
lines changed

11 files changed

+57
-43
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
---
22
name: Bug report
3-
about: Create a report in case rko lio is not working as expected
3+
about: Please use this if rko lio has an error, otherwise use the blank template
44
title: "[BUG]"
55
labels: bug
66
assignees: ''
77

88
---
99

10+
<!--
11+
If you think your issue doesn't require all the following details, use the blank issue template instead.
12+
Please do note however, if you do fill in all the following details, you make life easier for me to debug the error.
13+
Otherwise, I might have to ask you some of these details again anyways.
14+
-->
15+
1016
**Environment**
1117
- Which OS are you using?
1218
- What version of Python (eg., 3.10) or ROS (e.g., Jazzy) are you using?

cpp/rko_lio/core/lio.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,8 @@ namespace rko_lio::core {
254254
// ==========================
255255

256256
void LIO::initialize(const Secondsd lidar_time) {
257-
std::cout << "Initializing LIO.\n";
258-
259257
if (interval_stats.imu_count == 0) {
260-
std::cerr << "WARNING: Cannot initialize. No imu measurements received.\n";
258+
std::cerr << "[WARNING] Cannot initialize. No imu measurements received.\n";
261259
_initialized = true;
262260
return;
263261
}
@@ -283,14 +281,18 @@ void LIO::initialize(const Secondsd lidar_time) {
283281

284282
// use the acceleration kalman filter to compute the two values we need for ori. reg.
285283
std::optional<AccelInfo> LIO::get_accel_info(const Sophus::SO3d& rotation_estimate, const Secondsd& time) {
286-
if (interval_stats.imu_count == 0) {
287-
// avoid nans, divide by 0
284+
if (interval_stats.imu_count <= 1) {
285+
std::cerr << "[WARNING] " << interval_stats.imu_count
286+
<< " IMU message(s) in interval between two lidar scans. Cannot compute "
287+
"acceleration statistics for orientation regularisation. Please check your data and its "
288+
"timestamping as likely there should not be so few IMU measurements between two LiDAR scans.\n";
288289
return std::nullopt;
289290
}
290291

291292
const Eigen::Vector3d avg_imu_accel = interval_stats.imu_acceleration_sum / interval_stats.imu_count;
292293
const double accel_mag_variance = interval_stats.welford_sum_of_squares / (interval_stats.imu_count - 1);
293294
const double dt = (time - lidar_state.time).count();
295+
294296
const Eigen::Vector3d& body_accel_measurement = avg_imu_accel + rotation_estimate.inverse() * gravity();
295297

296298
const double max_acceleration_change = config.max_expected_jerk * dt;
@@ -320,7 +322,11 @@ std::optional<AccelInfo> LIO::get_accel_info(const Sophus::SO3d& rotation_estima
320322

321323
void LIO::add_imu_measurement(const ImuControl& base_imu) {
322324
if (lidar_state.time < EPSILON_TIME) {
323-
std::cout << "Skipping IMU, waiting for first LiDAR message.\n";
325+
static bool warning_skip_till_first_lidar = false;
326+
if (!warning_skip_till_first_lidar) {
327+
std::cerr << "[WARNING - ONCE] Skipping IMU, waiting for first LiDAR message.\n";
328+
warning_skip_till_first_lidar = true;
329+
}
324330
_last_real_imu_time = base_imu.time;
325331
_last_real_base_imu_ang_vel = base_imu.angular_velocity;
326332
return;
@@ -334,7 +340,7 @@ void LIO::add_imu_measurement(const ImuControl& base_imu) {
334340

335341
if (dt < 0.0) {
336342
// messages are out of sync. thats a problem, since we integrate gyro from last lidar time onwards
337-
std::cerr << "WARNING: Received IMU message from the past. Can result in errors.\n";
343+
std::cerr << "[WARNING] Received IMU message from the past. Can result in errors.\n";
338344
// skip this imu reading?
339345
}
340346

@@ -379,7 +385,7 @@ void LIO::add_imu_measurement(const Sophus::SE3d& extrinsic_imu2base, const ImuC
379385
// causes numerical issues otherwise
380386
static bool warning_imu_too_close = false;
381387
if (!warning_imu_too_close) {
382-
std::cerr << "WARNING - ONCE: Received IMU message with a very short delta to previous IMU message. Ignoring "
388+
std::cerr << "[WARNING - ONCE] Received IMU message with a very short delta to previous IMU message. Ignoring "
383389
"all such messages.\n";
384390
warning_imu_too_close = true;
385391
}
@@ -416,13 +422,13 @@ Vector3dVector LIO::register_scan(const Vector3dVector& scan, const TimestampVec
416422
return {Eigen::Vector3d::Zero(), Eigen::Vector3d::Zero()};
417423
}
418424
if (interval_stats.imu_count == 0) {
419-
std::cerr << "WARNING: No Imu measurements in interval to average. Assuming constant velocity motion.\n";
425+
std::cerr << "[WARNING] No Imu measurements in interval to average. Assuming constant velocity motion.\n";
420426
return {Eigen::Vector3d::Zero(), lidar_state.angular_velocity};
421427
}
422428
const Eigen::Vector3d avg_body_accel = interval_stats.body_acceleration_sum / interval_stats.imu_count;
423429
const Eigen::Vector3d avg_ang_vel = interval_stats.angular_velocity_sum / interval_stats.imu_count;
424430
if (avg_body_accel.norm() > 50.0) {
425-
std::cerr << "WARNING: Erratic body acceleration computed, norm > 50 m/s2. Either IMU data is corrupted, or you "
431+
std::cerr << "[WARNING] Erratic body acceleration computed, norm > 50 m/s2. Either IMU data is corrupted, or you "
426432
"should report an issue.";
427433
}
428434
return {avg_body_accel, avg_ang_vel};
@@ -538,7 +544,7 @@ void LIO::dump_results_to_disk(const std::filesystem::path& results_dir, const s
538544
std::cout << "Configuration written to " << config_file << "\n";
539545
}
540546
} catch (const std::filesystem::filesystem_error& ex) {
541-
std::cerr << "WARNING: Cannot write files to disk, encountered filesystem error: " << ex.what() << "\n";
547+
std::cerr << "[WARNING] Cannot write files to disk, encountered filesystem error: " << ex.what() << "\n";
542548
}
543549
}
544550
} // namespace rko_lio::core

python/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ This is deprecated and planned to be removed in a future release. I'm prioritisi
158158

159159
### Configuration
160160

161-
All configurable parameters are defined in [`config/default.yaml`](config/default.yaml).
161+
You can dump the default set of parameters using `rko_lio --dump_config`.
162162
For descriptions of each parameter, see [config.md](../docs/config.md).
163+
Apart from these, you can specify `extrinsic_imu2base_quat_xyzw_xyz`, `extrinsic_lidar2base_quat_xyzw_xyz` in a config file (only) if you require.
164+
163165
Some further requirements on the data are given in [data.md](../docs/data.md).

python/config/default.yaml

Lines changed: 0 additions & 15 deletions
This file was deleted.

python/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
44

55
[project]
66
name = "rko_lio"
7-
version = "0.1.0"
7+
version = "0.1.1"
88
description = "A Robust Approach for LiDAR-Inertial Odometry Without Sensor-Specific Modelling"
99
authors = [{ name = "Meher Malladi", email = "rm.meher97@gmail.com" }]
1010
readme = "README.md"

python/rko_lio/cli.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,6 @@ def cli(
309309
if log_results and results_dir:
310310
results_dir.mkdir(parents=True, exist_ok=True)
311311
pipeline.dump_results_to_disk(results_dir, run_name)
312-
print(f"Results dumped to: {results_dir} [prefix: {run_name}]")
313312

314313

315314
if __name__ == "__main__":

ros/README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ Clone the repository into a colcon workspace's `src`. From the workspace folder,
1616
colcon build --packages-select rko_lio # --symlink-install --event-handlers console_direct+
1717
```
1818

19-
We provide a `colcon.pkg` [file](colcon.pkg) which defines default values for some CMake arguments. Details from [build.md](../docs/build.md) apply here, but most importantly we have `RKO_LIO_FETCH_CONTENT_DEPS=ON` by default. This option handles our optional dependencies automatically.
19+
We provide a `colcon.pkg` [file](colcon.pkg) which defines a default CMake configuration.
20+
Details from [build.md](../docs/build.md) apply here, but most importantly we have `CMAKE_BUILD_TYPE=Release` and `RKO_LIO_FETCH_CONTENT_DEPS=ON` by default.
21+
The last option handles our optional dependencies automatically.
2022

21-
In case you'd like to provide our optional dependencies yourself, either modify `colcon.pkg` or override those CMake flags when invoking colcon, for example, by
23+
In case you'd like to change the build type or provide our optional dependencies yourself, please modify `colcon.pkg` manually.
2224

23-
```bash
24-
colcon build --packages-select rko_lio --cmake-args -DRKO_LIO_FETCH_CONTENT_DEPS=OFF # --event-handlers console_direct+
25-
```
25+
> I'd earlier assumed one could override colcon.pkg arguments via --cmake-args when invoking colcon, but this doesn't seem to be the case. If anyone knows a fix, please open an issue or PR!
2626
27-
Also consider using `Ninja` as a generator to speed up builds instead of `Make`. If you do use Make, make sure (pun intended) to parallelize the build.
27+
Also consider using `Ninja` as a generator to speed up builds instead of `Make`.
28+
If you do use Make, make sure (pun intended) to parallelize the build.
2829

2930
## Usage
3031

ros/launch/odometry.launch.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,20 +381,23 @@ def prepare_rviz_config(rviz_config_file: Path, parameters: dict) -> Path:
381381
rviz_config_file = Path(get_package_share_directory("rko_lio")) / rviz_config_file
382382

383383
base_frame = parameters.get("base_frame", "")
384-
if not base_frame:
384+
odom_frame = parameters.get("odom_frame", "")
385+
if not base_frame and not odom_frame:
385386
return rviz_config_file # no override needed
386387

387388
# Load default config
388389
with open(rviz_config_file, "r") as f:
389390
rviz_cfg = yaml.safe_load(f)
390391

391392
try:
392-
rviz_cfg["Visualization Manager"]["Views"]["Current"][
393-
"Target Frame"
394-
] = base_frame
393+
# Patch whichever frame is specified
394+
if base_frame:
395+
rviz_cfg["Visualization Manager"]["Views"]["Current"]["Target Frame"] = base_frame
396+
if odom_frame:
397+
rviz_cfg["Visualization Manager"]["Global Options"]["Fixed Frame"] = odom_frame
395398
except Exception as e:
396399
raise RuntimeError(
397-
f"Could not patch RViz config with base_frame ({base_frame}): {e}"
400+
f"Could not patch RViz config with frames (base_frame={base_frame}, odom_frame={odom_frame}): {e}"
398401
)
399402

400403
# Write to a temp file

ros/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?><package format="3">
33
<name>rko_lio</name>
4-
<version>0.1.0</version>
4+
<version>0.1.1</version>
55
<description>A Robust Approach for LiDAR-Inertial Odometry Without Sensor-Specific Modelling</description>
66
<maintainer email="rm.meher97@gmail.com">Meher Malladi</maintainer>
77
<license>MIT</license>

ros/rko_lio/node.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ void Node::imu_callback(const sensor_msgs::msg::Imu::ConstSharedPtr& imu_msg) {
180180
"Either specify the frame id or the extrinsic manually.");
181181
}
182182
imu_frame = imu_msg->header.frame_id;
183+
RCLCPP_INFO_STREAM(node->get_logger(), "Parsed the imu frame id as: " << imu_frame);
183184
}
184185
if (!check_and_set_extrinsics()) {
185186
// we assume that extrinsics are static. if they change, its better to query the tf directly in the registration
@@ -203,6 +204,7 @@ void Node::lidar_callback(const sensor_msgs::msg::PointCloud2::ConstSharedPtr& l
203204
"Either specify the frame id or the extrinsic manually.");
204205
}
205206
lidar_frame = lidar_msg->header.frame_id;
207+
RCLCPP_INFO_STREAM(node->get_logger(), "Parsed the lidar frame id as: " << lidar_frame);
206208
}
207209
if (!check_and_set_extrinsics()) {
208210
return;

0 commit comments

Comments
 (0)