Skip to content

Conversation

@Schmluk
Copy link
Contributor

@Schmluk Schmluk commented Sep 11, 2025

  • Adds infrastructure for traversability estimation and place extraction. This largely does not touch existing Hydra.
  • Depends on Spark-DSG#64

Parts affecting Hydra:

  • Factored out the node deformation interpolation so several updaters can use it. These params are never set so the configs remain unchanged.
  • Adds reset DSG on loopclosure flag to the DSG updater, default behavior is as before
  • Various small patches for Places2d and Frontiers to avoid segfaults
  • For now added sane traversability params to the uHumans config. No preference whether they should be in or not.

Tests:

  • Builds and tests pass
  • Tested on uHumans

Copy link
Collaborator

@nathanhhughes nathanhhughes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

#include <config_utilities/config.h>
#include <config_utilities/types/conversions.h>
#include <config_utilities/types/enum.h>
#include <config_utilities/validation.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) not needed here

Comment on lines 48 to 49
src/place_fixtures.cpp
src/resources.cpp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) idk if you're using an automatic alphabetical sorter or doing it by hand, but main.cpp and src/* are slightly distinct to the actual test files, so I'd have a slight preference to keeping them at the top

Thank you for cleaning up the order on the files though!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was alphabetical sort, the intention was to keep main at the top though 😅

bool enable_place_mesh_mapping = false;
config::VirtualConfig<SurfacePlacesInterface> surface_places;
config::VirtualConfig<FreespacePlacesInterface> freespace_places;
bool use_frontiers = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks!

Comment on lines 167 to 171
auto node_ptr = dsg.findNode(node.id);
if (node_ptr) {
node_ptr->attributes().position = node.attributes().position;
}
// dsg.setNodeAttributes(node.id, node.attributes().clone());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we drop the commented code and add a note that this is copying the newly interpolated positions from the unmerged graph to the merged graph? I probably should have added the note myself when I wrote this (took me a minute to refresh my memory as to what the implementation was supposed to do)

Comment on lines 231 to 234
inline static const auto registration_ =
config::RegistrationWithConfig<TraversabilityClustering,
BlockTraversabilityClustering,
Config>("BlockTraversabilityClustering");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto regarding where the registration is defined

Comment on lines 80 to 83
inline static const auto registration_ =
config::RegistrationWithConfig<SurfacePlacesInterface,
TraversabilityPlaceExtractor,
Config>("traversability");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto for registration definition location

Comment on lines 103 to 105
inline static const auto registration_ =
config::RegistrationWithConfig<TraversabilityProcessor, ErosionDilation, Config>(
"ErosionDilation");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto for registration location

Comment on lines +213 to +266
auto& to_attrs = dsg.getNode(to_id).attributes<TraversabilityNodeAttributes>();
// Avoid merging nodes with active window (temporal) overlap.
if (from_attrs.last_observed_ns >= to_attrs.first_observed_ns &&
from_attrs.first_observed_ns <= to_attrs.last_observed_ns) {
continue;
}

// Check boundaries.
auto to_boundary = Boundary(to_attrs);
if (!to_boundary.intersects(from_boundary)) {
continue;
}

// Simple case: If places are completely contained.
if (isContained(to_boundary, from_boundary)) {
result.push_back({to_id, from_node.id});
merged.insert(to_id);
continue;
}
if (isContained(from_boundary, to_boundary)) {
result.push_back({from_node.id, to_id});
merged.insert(from_node.id);
continue;
}

// Large overlap: No need to keep both, as transition is always possible between.
auto intersection = from_boundary.intersection(to_boundary);
if (intersection.height() < config.min_place_size ||
intersection.width() < config.min_place_size) {
// TODO(lschmid): Can consider cropping and dropping in the future.
// Always update the classification of the boundary sides.
overlapping_nodes_to_cleanup_.insert({from_node.id, to_id});
continue;
}

// Aligned in X or Y direction: Merge by fusing boundary.
if ((std::abs(from_boundary.min.x() - to_boundary.min.x()) < config.tolerance &&
std::abs(from_boundary.max.x() - to_boundary.max.x()) < config.tolerance) ||
(std::abs(from_boundary.min.y() - to_boundary.min.y()) < config.tolerance &&
std::abs(from_boundary.max.y() - to_boundary.max.y()) < config.tolerance)) {
merged.insert(to_id);
result.push_back({to_id, from_node.id});
continue;
}

// If not fuseable easily keep larger.
if (from_boundary.area() >= to_boundary.area()) {
result.push_back({to_id, from_node.id});
merged.insert(to_id);
} else {
result.push_back({from_node.id, to_id});
merged.insert(from_node.id);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) I'd maybe split this up into a helper function or two, but definitely not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was hoping to make this clearer but I can't think of a great way to break this up, since essentially the 'how to fuse traversability attrs' is a bit of cases/branching problem.

Comment on lines +299 to +302
if ((std::abs(from_boundary.min.x() - to_boundary.min.x()) < config.tolerance &&
std::abs(from_boundary.max.x() - to_boundary.max.x()) < config.tolerance) ||
(std::abs(from_boundary.min.y() - to_boundary.min.y()) < config.tolerance &&
std::abs(from_boundary.max.y() - to_boundary.max.y()) < config.tolerance)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) this feels like something that could be a method in the boundary

@Schmluk Schmluk force-pushed the port/traversability branch from 1a26912 to e3e3474 Compare September 15, 2025 19:57
@Schmluk Schmluk merged commit d2dd781 into develop Sep 15, 2025
2 checks passed
@Schmluk Schmluk deleted the port/traversability branch September 15, 2025 20:38
nathanhhughes added a commit that referenced this pull request Sep 15, 2025
* WIP: part 1

* Port traversability: Part 2/2

* updates to new hydra architecture and few missed updates, builds and passes tests

* update gitignore

* minor fixes and config

* run linting

* fix missing distance adaptor call

* Update src/utils/nearest_neighbor_utilities.cpp

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>

* address review comments

* run linter

---------

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>
nathanhhughes added a commit that referenced this pull request Sep 29, 2025
* WIP: part 1

* Port traversability: Part 2/2

* updates to new hydra architecture and few missed updates, builds and passes tests

* update gitignore

* minor fixes and config

* run linting

* fix missing distance adaptor call

* Update src/utils/nearest_neighbor_utilities.cpp

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>

* address review comments

* run linter

---------

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>
nathanhhughes added a commit that referenced this pull request Oct 8, 2025
* WIP: part 1

* Port traversability: Part 2/2

* updates to new hydra architecture and few missed updates, builds and passes tests

* update gitignore

* minor fixes and config

* run linting

* fix missing distance adaptor call

* Update src/utils/nearest_neighbor_utilities.cpp

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>

* address review comments

* run linter

---------

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>
nathanhhughes added a commit that referenced this pull request Oct 31, 2025
* WIP: part 1

* Port traversability: Part 2/2

* updates to new hydra architecture and few missed updates, builds and passes tests

* update gitignore

* minor fixes and config

* run linting

* fix missing distance adaptor call

* Update src/utils/nearest_neighbor_utilities.cpp

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>

* address review comments

* run linter

---------

Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants