Closed astumpf closed 3 months ago
Thank you! I'm glad to hear it's useful. So far we didn't have plans for a feature like this, but we could add it. I have a few questions to make sure I understand your use case :)
Hello and sorry for the late reply. Yes, we have already found that hashed-octree works much better and will very likely use it in the future.
Since my requested feature could obviously be easily implemented for hashed-octree, I already thought of doing it myself. But then I decided to coordinate with you on what your plans are. I assume that you can implement it even faster and cleaner in your framework :-).
What is your main motivation to drop distant blocks?
To answer your questions, yes and yes. We are concerned about the memory consumption due to the small compute units used. Also, there may still be localization drift, so revisiting the same location multiple times would mess up the map without closed loop optimization. So in our case we are more interested in hard distance thresholding, but I can also see interesting use cases for time thresholding (aging out old nodes).
Hi Alexander, Great that the hashed-octrees would also work for you. For these data structures, it'd be very easy to drop distant blocks and wavemap already contains some utilities that might be useful. I'll create a branch and link it here. Then we can work on it together. Out of curiosity, what kind of compute units are you using (unless it's confidential of course)?
The draft is now available on the feature/local_mapping branch.
I tested it with these general settings:
map:
general:
world_frame: "odom"
body_frame: "body" # New: Set to a frame that moves with the robot
thresholding_period: { seconds: 2.0 }
pruning_period: { seconds: 2.0 } # Controls how often the pruning incl. block dropping happens
publication_period: { seconds: 2.0 }
data_structure:
type: hashed_chunked_wavelet_octree
min_cell_width: { meters: 0.1 }
remove_blocks_beyond_distance: { meters: 25.0 } # New: Distance beyond which to drop blocks
Let me know how it works for you, and feel free to modify the code :)
Awesome! Thank you so much for your efforts! I'm currently very busy but definitely will take a look into that asap.
Out of curiosity, what kind of compute units are you using (unless it's confidential of course)?
We are using currently Jetson Xavier as compute units.
Welcome! No rush :)
We are using currently Jetson Xavier as compute units.
Oh nice, we're using Xavier's on our drones as well.
Hi Alexander, we're considering merging the local mapping feature into a release sometime in the next two weeks. Did you have a chance to try it? Are there any options that you'd like to use but are still missing?
My plan is to test this out next week using real robots :-).
Hi Victor,
Finally, I've tested this branch. Looks great so far! I have already some feedback for you:
remove_blocks_beyond_distance
should also be checked during integration. Although it may be contradictory, but if integrator_max_range < remove_blocks_beyond_distance
, you will see flickering caused by adding and immediately removing nodes.Thanks for your great work!
Hi Alexander, Great that you got to test it!
The pruning is currently done at the (hash) block level. The reason for this is that to set an entire block to zero, it can simply be deleted. It's also possible to prune at a higher resolution, and this can be done efficiently by exploiting the Haar wavelet's properties, but it'd take a custom algorithm. Unfortunately, I won't have much time in the coming weeks. Are smooth borders for the sliding window important to you? If they are and you have some time to work on it, we could discuss how to do it.
In which situations would the max range need to be larger than the sliding window's radius? Both radii have a similar purpose, and the flickering can be avoided by adjusting either of them s.t. integrator_max_range
< remove_blocks_beyond_distance
. It's probably cleaner to just print a warning when wavemap starts up and integrator_max_range
> remove_blocks_beyond_distance
, explaining that it'll cause flickering and how to avoid this.
Cannot await to see that feature merged soon! :-)
block_width = min_cell_width * 2^(tree_height)
We don't have a method to introspect this yet. One option would be to add a member method to the data structures along the lines of getBlockWidth()
in a similar fashion to the getMinCellWidth()
method that already exists. Alternatively, you could calculate the block width based on the min_cell_width
and tree_height
fields in the ROS messages:
rostopic echo "/wavemap/map/hashed_wavelet_octree[0]" --noarr
Cannot await to see that feature merged soon! :-)
We're planning to review and merge this feature once PR#37 is ready :)
@astumpf, I just wanted to update you on our timeline. We're planning to refactor the wavemap_server, to make the additional operations it can perform more modular and extendable. This new structure will also provide a cleaner way to incorporate the code and configuration options for the sliding window functionality, so we plan to release the sliding window feature and refactored server together - probably around mid-November.
I am very excited, looking forward to it!
The new wavemap_server structure on the feature/plugin_system branch now supports local mapping through a map cropping plugin. It can be enabled and configured by adding an entry of type: crop_map
to the operations
.
Taking the default Ouster OS0 config for illustration, you could replace the operations array with:
operations:
- type: threshold_map
once_every: { seconds: 2.0 }
- type: prune_map
once_every: { seconds: 10.0 }
- type: crop_map
once_every: { seconds: 2.0 }
body_frame: "body"
remove_blocks_beyond_distance: { meters: 25.0 }
- type: publish_map
once_every: { seconds: 2.0 }
The main advantage we see is that it groups all the relevant settings in one place and improves the internal structure of the wavemap server. It also makes it easy to add additional plugins in the future, including custom plugins by users. Would this new structure work well for you?
Definitely yes. I like the new structure. Does that mean we can also add new plugins ourselves?
Yes, that would be the goal. The idea so far is that users can create classes derived from InputBase or OperationBase, and then register them with the wavemap server by calling something like wavemap_server.addInput(std::move(your_custom_input))
or wavemap_server.addOperation(std::move(your_custom_operation))
. This part is not yet implemented though :)
Thank you very much for the great effort you put into wavemap! It is a great new tool!
I wonder if there are any plans for local mapping, like a rolling window approach. That would be a nice feature where nodes that are too far away from the moving robot are automatically pruned.