Skip to content

Commit 3c0601b

Browse files
authored
fix: Small regression from manuscript results with different point types. Reverting. (#4)
1 parent 3f3c076 commit 3c0601b

File tree

6 files changed

+97
-21
lines changed

6 files changed

+97
-21
lines changed

form/feature/extraction.tpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ FeatureExtractor::extract(const std::vector<Point> &scan, size_t scan_idx) const
108108
compute_normal(idx, scan, valid_mask);
109109
if (normal.has_value()) {
110110
result_planar_tbb.emplace_back(
111-
static_cast<double>(point.x()), static_cast<double>(point.y()),
112-
static_cast<double>(point.z()), static_cast<double>(normal.value().x()),
111+
static_cast<double>(point.x), static_cast<double>(point.y),
112+
static_cast<double>(point.z), static_cast<double>(normal.value().x()),
113113
static_cast<double>(normal.value().y()),
114114
static_cast<double>(normal.value().z()), static_cast<size_t>(scan_idx));
115115
}
@@ -124,8 +124,8 @@ FeatureExtractor::extract(const std::vector<Point> &scan, size_t scan_idx) const
124124
for (const size_t &idx : point_indices) {
125125
const Point &point = scan[idx];
126126
result_point.emplace_back(
127-
static_cast<double>(point.x()), static_cast<double>(point.y()),
128-
static_cast<double>(point.z()), static_cast<size_t>(scan_idx));
127+
static_cast<double>(point.x), static_cast<double>(point.y),
128+
static_cast<double>(point.z), static_cast<size_t>(scan_idx));
129129
}
130130

131131
return std::make_tuple(result_planar, result_point);
@@ -244,14 +244,14 @@ FeatureExtractor::compute_curvature(const std::vector<Point> &scan,
244244
// If valid compute the curvature
245245
else {
246246
// Initialize with the difference term
247-
double dx = -(2.0 * params.neighbor_points) * scan[idx].x();
248-
double dy = -(2.0 * params.neighbor_points) * scan[idx].y();
249-
double dz = -(2.0 * params.neighbor_points) * scan[idx].z();
247+
double dx = -(2.0 * params.neighbor_points) * scan[idx].x;
248+
double dy = -(2.0 * params.neighbor_points) * scan[idx].y;
249+
double dz = -(2.0 * params.neighbor_points) * scan[idx].z;
250250
// Iterate over neighbors and accumulate
251251
for (size_t n = 1; n <= params.neighbor_points; n++) {
252-
dx = dx + scan[idx - n].x() + scan[idx + n].x();
253-
dy = dy + scan[idx - n].y() + scan[idx + n].y();
254-
dz = dz + scan[idx - n].z() + scan[idx + n].z();
252+
dx = dx + scan[idx - n].x + scan[idx + n].x;
253+
dy = dy + scan[idx - n].y + scan[idx + n].y;
254+
dz = dz + scan[idx - n].z + scan[idx + n].z;
255255
}
256256
curvature.emplace_back(idx, dx * dx + dy * dy + dz * dz);
257257
}
@@ -313,7 +313,7 @@ FeatureExtractor::compute_normal(
313313
// std::printf("---- Found %zu neighbors\n", neighbors.size());
314314
Eigen::Matrix<T, Eigen::Dynamic, 3> A(neighbors.size(), 3);
315315
for (size_t j = 0; j < neighbors.size(); ++j) {
316-
A.row(j) = neighbors[j] - point;
316+
A.row(j) = neighbors[j].vec3() - point.vec3();
317317
}
318318
A /= neighbors.size();
319319
Eigen::Matrix<T, 3, 3> Cov = A.transpose() * A;
@@ -410,7 +410,7 @@ FeatureExtractor::find_closest(const Point &point, const size_t &start,
410410
if (!valid_mask[idx]) {
411411
continue;
412412
}
413-
const double dist2 = (scan[idx] - point).squaredNorm();
413+
const double dist2 = (scan[idx].vec4() - point.vec4()).squaredNorm();
414414
if (dist2 < min_dist2) {
415415
min_dist2 = dist2;
416416
closest_point = idx;
@@ -427,7 +427,7 @@ void FeatureExtractor::find_neighbors(const size_t &idx,
427427
const auto &point = scan[idx];
428428
for (size_t i = 1; i <= params.neighbor_points; i++) {
429429
const auto &neighbor = scan[idx + i];
430-
const double range2 = (neighbor - point).squaredNorm();
430+
const double range2 = (neighbor.vec4() - point.vec4()).squaredNorm();
431431
if (range2 < params.radius * params.radius) {
432432
out.push_back(neighbor);
433433
} else {
@@ -438,7 +438,7 @@ void FeatureExtractor::find_neighbors(const size_t &idx,
438438
// search in the negative direction
439439
for (size_t i = 1; i <= params.neighbor_points; i++) {
440440
const auto &neighbor = scan[idx - i];
441-
const double range2 = (neighbor - point).squaredNorm();
441+
const double range2 = (neighbor.vec4() - point.vec4()).squaredNorm();
442442
if (range2 < params.radius * params.radius) {
443443
out.push_back(neighbor);
444444
} else {

form/form.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Estimator::Estimator(const Estimator::Params &params) noexcept
3838
KeypointMap<PointFeat>(m_params.map)} {}
3939

4040
std::tuple<std::vector<PlanarFeat>, std::vector<PointFeat>>
41-
Estimator::register_scan(const std::vector<Eigen::Vector3f> &scan) noexcept {
41+
Estimator::register_scan(const std::vector<PointXYZf> &scan) noexcept {
4242
constexpr auto SEQ = std::make_index_sequence<2>{};
4343

4444
//

form/form.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ struct Estimator {
8080

8181
/// @brief Register a new scan and return the extracted features
8282
std::tuple<std::vector<PlanarFeat>, std::vector<PointFeat>>
83-
register_scan(const std::vector<Eigen::Vector3f> &scan) noexcept;
83+
register_scan(const std::vector<PointXYZf> &scan) noexcept;
8484
};
8585

8686
} // namespace form

form/utils.hpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,67 @@
2929
#include <tbb/task_arena.h>
3030
#include <tuple>
3131

32+
#include <Eigen/Dense>
33+
#include <gtsam/geometry/Pose3.h>
34+
3235
namespace form {
3336

37+
/// @brief Simple 3D point structure for loading in points
38+
struct PointXYZf {
39+
using Scalar = float;
40+
float x;
41+
float y;
42+
float z;
43+
float _ = static_cast<float>(0);
44+
45+
PointXYZf(float x, float y, float z) : x(x), y(y), z(z), _(0) {}
46+
47+
// ------------------------- Getters ------------------------- //
48+
[[nodiscard]] inline Eigen::Map<Eigen::Matrix<float, 3, 1>> vec3() noexcept {
49+
return Eigen::Map<Eigen::Matrix<float, 3, 1>>(&x);
50+
}
51+
52+
[[nodiscard]] inline Eigen::Map<const Eigen::Matrix<float, 3, 1>>
53+
vec3() const noexcept {
54+
return Eigen::Map<const Eigen::Matrix<float, 3, 1>>(&x);
55+
}
56+
57+
[[nodiscard]] inline Eigen::Map<const Eigen::Matrix<float, 4, 1>>
58+
vec4() const noexcept {
59+
return Eigen::Map<const Eigen::Matrix<float, 4, 1>>(&x);
60+
}
61+
62+
[[nodiscard]] inline Eigen::Map<Eigen::Array<float, 3, 1>> array() noexcept {
63+
return Eigen::Map<Eigen::Array<float, 3, 1>>(&x);
64+
}
65+
66+
[[nodiscard]] inline Eigen::Map<const Eigen::Array<float, 3, 1>>
67+
array() const noexcept {
68+
return Eigen::Map<const Eigen::Array<float, 3, 1>>(&x);
69+
}
70+
71+
// ------------------------- Misc ------------------------- //
72+
inline void transform_in_place(const gtsam::Pose3 &pose) noexcept {
73+
vec3() = (pose * vec3().template cast<double>()).template cast<float>();
74+
}
75+
76+
[[nodiscard]] inline PointXYZf transform(const gtsam::Pose3 &pose) const noexcept {
77+
auto point = *this;
78+
point.transform_in_place(pose);
79+
return point;
80+
}
81+
82+
[[nodiscard]] inline float squaredNorm() const noexcept {
83+
return vec4().squaredNorm();
84+
}
85+
86+
[[nodiscard]] inline float norm() const noexcept { return vec4().norm(); }
87+
88+
[[nodiscard]] constexpr bool operator==(const PointXYZf &other) const noexcept {
89+
return x == other.x && y == other.y && z == other.z;
90+
}
91+
};
92+
3493
namespace tuple {
3594
// Some helpers ot make iterating over tuples easier
3695
// https://www.cppstories.com/2022/tuple-iteration-apply/

python/bindings.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ template <typename Point> evalio::Point point_to_evalio(const Point &point) {
4040
};
4141
}
4242

43-
Eigen::Vector3f point_to_form(const evalio::Point &point) {
44-
return Eigen::Vector3f(point.x, point.y, point.z);
43+
form::PointXYZf point_to_form(const evalio::Point &point) {
44+
return form::PointXYZf(point.x, point.y, point.z);
4545
}
4646

4747
// ------------------------- Pipeline ------------------------- //
@@ -147,7 +147,7 @@ class FORM : public evalio::Pipeline {
147147
std::map<std::string, std::vector<evalio::Point>>
148148
add_lidar(evalio::LidarMeasurement mm) override {
149149
// convert to evalio
150-
std::vector<Eigen::Vector3f> scan;
150+
std::vector<form::PointXYZf> scan;
151151
auto start = mm.stamp;
152152
auto end = mm.stamp + delta_time_;
153153

@@ -214,9 +214,15 @@ NB_MODULE(_core, m) {
214214
m.def("extract_keypoints", [](const std::vector<Eigen::Vector3d> &points,
215215
const form::FeatureExtractor::Params &params,
216216
evalio::LidarParams &lidar_params) {
217+
// Convert to form points
218+
std::vector<form::PointXYZf> points_form;
219+
for (const auto &point : points) {
220+
points_form.emplace_back(point.x(), point.y(), point.z());
221+
}
222+
217223
// Call the keypoint extraction function from the Tclio class
218224
auto [planar_keypoints, point_keypoints] =
219-
form::FeatureExtractor(params, 0).extract(points, 0);
225+
form::FeatureExtractor(params, 0).extract(points_form, 0);
220226

221227
// return a tuple of (planar_points, normals, point_points)
222228
std::vector<Eigen::Vector3d> planar_points;

uv.lock

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)