Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic loading of different mesh formats #66

Merged
merged 17 commits into from
Nov 20, 2024

Conversation

amock
Copy link
Collaborator

@amock amock commented Nov 15, 2024

What I did:

  • One can load meshes from common mesh file formats now. It is also possible to load a specific mesh from a whole scene as navigation mesh. One problem remained: Loading the ".dae"s of the mesh nav tutorials gave wrong results. I don't know why. Internally it is divided into an input file and working file. The input file is an arbitrary mesh format (that can be loaded by assimp or HDF5) the working file is always a HDF5. I added a service which can be used to save the current state to the working file.
  • The layers are now stored in the HDF5 file by their name. This allows us to integrate many layers of the same type.
  • I quickly tested some of the tutorials and everything worked out fine. So it should be downwards compatible.
  • Some bug fixes.

@amock amock requested a review from Cakem1x November 15, 2024 19:08
Copy link
Member

@Cakem1x Cakem1x left a comment

Choose a reason for hiding this comment

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

Nice additions to the map! I also like that you removed the service code.
Being able to load more kinds of meshes sounds very useful.

I added a few comments, the logic looks good.
I have some remarks that hopefully increase readability/maintainability, please check them out.

rcl_interfaces::msg::FloatingPointRange range;
range.from_value = 0.0;
range.to_value = 1.0;
descriptor.floating_point_range.push_back(range);
config_.factor = node_->declare_parameter(mesh_map::MeshMap::MESH_MAP_NAMESPACE + "." + layer_name_ + ".factor", config_.factor);
config_.factor = node_->declare_parameter(mesh_map::MeshMap::MESH_MAP_NAMESPACE + "." + layer_name_ + ".factor", config_.factor, descriptor);
Copy link
Member

Choose a reason for hiding this comment

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

Whoops, was the descriptor never used when declaring the parameter? 🫢
Nice fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, but at least it was described for anyone reading the code 😅


//! dynamic params callback handle
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr config_callback;

rclcpp::Service<std_srvs::srv::Empty>::SharedPtr save_service;
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be nice to get a response on whether saving worked out.

# empty request?
string path_to_map # or maybe allow defining a path here?
---
bool was_successful
string failure_reason # empty string if was_successful is true. Otherwise, e.g. "cannot open file '/path/to/map'"

Still, leaving it like it is now is a nice upgrade on the previous version. 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I would like this too. Perhaps something for the near future. Is there a std_srvs service for that already?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, indeed: std_srvs/Trigger

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I changed the service from Empty to Trigger

@@ -141,6 +141,9 @@ class BorderLayer : public mesh_map::AbstractLayer
double border_cost = 1.0;
double factor = 1.0;
} config_;

// put this to base class?
std::string name;
Copy link
Member

Choose a reason for hiding this comment

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

codestyle

Suggested change
std::string name;
std::string name_;

Copy link
Member

Choose a reason for hiding this comment

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

Wait, is this even used? I think you're only using the layer_name_ attribute from the base class in the cpp file.

Looks like this is a leftover from experimenting.

Copy link
Collaborator Author

@amock amock Nov 19, 2024

Choose a reason for hiding this comment

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

Yes, it's basically how it is written in the comments. "Put this to base class" then I jumped to the base class and saw, there is a variable already. So "name" can be removed safely.

Comment on lines 437 to 447
//! mesh file
std::string mesh_file;

//! mesh part
std::string mesh_part;

//! mesh working file
std::string mesh_working_file;

//! mesh working part
std::string mesh_working_part;
Copy link
Member

Choose a reason for hiding this comment

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

The comments are superfluous, since they only consist of the variable's name. Leaving them in place does not add any clarity and they might become out-of-date when the code changes, leading to confusion.
Either remove them or replace them by an explanation, if necessary.

Copy link
Member

Choose a reason for hiding this comment

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

Also, you could add a path or file_path to the variable name, if it is a path. I think e.g. mesh_file is probably not the actual file (or pointer to some data in that file), but just the filesystem path. Since its type is std::string! :) But that might just be my personal preference. 🤷

Copy link
Member

Choose a reason for hiding this comment

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

What working means could use an explanation.
Why are there working and non-working versions of file&part?

Maybe salvage a few words from your PR description:
Internally it is divided into an input file and working file. The input file is an arbitrary mesh format (that can be loaded by assimp or HDF5) the working file is always a HDF5. I added a service which can be used to save the current state to the working file.

Or maybe find better names, e.g. call them mesh_input_file/mesh_input_part and mesh_working_file/mesh_working_part.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The comments are superfluous, since they only consist of the variable's name. Leaving them in place does not add any clarity and they might become out-of-date when the code changes, leading to confusion. Either remove them or replace them by an explanation, if necessary.

Agree. I was just adapting to the comment style that was already there 😁 There could be a complete PR about cleaning up all of the comments plus all the error messages.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also, you could add a path or file_path to the variable name, if it is a path. I think e.g. mesh_file is probably not the actual file (or pointer to some data in that file), but just the filesystem path. Since its type is std::string! :) But that might just be my personal preference. 🤷

Agree, I was again just adapting the style. However, I would move that to a seperate "better style" PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What working means could use an explanation. Why are there working and non-working versions of file&part?

Maybe salvage a few words from your PR description: Internally it is divided into an input file and working file. The input file is an arbitrary mesh format (that can be loaded by assimp or HDF5) the working file is always a HDF5. I added a service which can be used to save the current state to the working file.

Or maybe find better names, e.g. call them mesh_input_file/mesh_input_part and mesh_working_file/mesh_working_part.

Agree. I will push a commit with some docs soon.

Copy link
Member

Choose a reason for hiding this comment

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

Great, thanks!

mesh_map/include/mesh_map/mesh_map.h Outdated Show resolved Hide resolved
Comment on lines 469 to 471
// RCLCPP_INFO_STREAM(node->get_logger(), "Writing '" << layer_name << "' to file.");
// layer_plugin->writeLayer();
// RCLCPP_INFO_STREAM(node->get_logger(), "Finished writing '" << layer_name << "' to file.");
Copy link
Member

Choose a reason for hiding this comment

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

Please delete these lines, if they are not necessary anymore.

Or, if you think they might become useful later, maybe make them DEBUG logs. This will ensure they get considered in refactorings and won't become weird dead code (comments) in the long run.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

Comment on lines 498 to 499
// TODO how to declare param for each plugin?
// Needs to be done after plugins are loaded, which happens when the map gets loaded. Who calls readMap() and when?
Copy link
Member

Choose a reason for hiding this comment

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

Is this outdated?

Each plugin needs to define its own parameters. They do that in the initialize() method, but I see that you already found that method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

outdated. removed

mesh_map/src/util.cpp Outdated Show resolved Hide resolved
namespace mesh_map
{

// again this function
Copy link
Member

Choose a reason for hiding this comment

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

What do you mean by that? Did you write / see this function someplace else already?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was just a joke. Because in 2024 I still have to write a split_by_delimiter function for a std::string. I removed it

Copy link
Member

Choose a reason for hiding this comment

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

I see ^^

std::shared_ptr<std_srvs::srv::Empty::Response> response)
{
saveLayers();
});
}

bool MeshMap::readMap()
Copy link
Member

Choose a reason for hiding this comment

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

Reading the code that loads the mesh map was a bit confusing with all the different cases and different ways the working/non-working variables can be filled (via user or automatically).
Is there a way to simplify the logic?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Perhaps there is a way. But I haven't found it yet :D

@Cakem1x Cakem1x self-requested a review November 19, 2024 13:52
Copy link
Member

@Cakem1x Cakem1x left a comment

Choose a reason for hiding this comment

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

thanks for reiterating! 👍

@@ -434,16 +441,22 @@ class MeshMap
//! global frame / coordinate system id
std::string global_frame;

//! mesh file
//! Filename of the input mesh. Can be any format the assimp library supports to load.
//! https://github.com/assimp/assimp/blob/master/doc/Fileformats.md
Copy link
Member

Choose a reason for hiding this comment

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

nice

@amock
Copy link
Collaborator Author

amock commented Nov 19, 2024

I tested the three maps from the mesh nav tutorials and everything went fine.

@amock amock requested a review from Cakem1x November 19, 2024 23:46
@amock amock merged commit fedea89 into naturerobots:humble Nov 20, 2024
1 check passed
@Cakem1x
Copy link
Member

Cakem1x commented Nov 20, 2024

I just ran a few successful tests with your branch and our tutorials.

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.

2 participants