Load extra MuJoCo plugins using a simulate shim - #12
Conversation
dfd3e68 to
e282171
Compare
| // Load all .so plugins from a directory, following symlinks. | ||
| void loadPluginsFromDirectory(const std::string& plugin_dir) { | ||
| std::error_code ec; | ||
| if (!std::filesystem::is_directory(plugin_dir, ec)) { | ||
| return; | ||
| } | ||
|
|
||
| for (const auto& entry : std::filesystem::directory_iterator(plugin_dir, ec)) { | ||
| if (!entry.is_regular_file(ec)) { | ||
| continue; | ||
| } | ||
|
|
||
| const auto& path = entry.path(); | ||
| if (path.extension() != ".so") { | ||
| continue; | ||
| } | ||
|
|
||
| int before = mjp_pluginCount(); | ||
| mj_loadPluginLibrary(path.c_str()); | ||
| int after = mjp_pluginCount(); | ||
| if (after > before) { | ||
| std::printf("Plugins registered by library '%s':\n", path.filename().c_str()); | ||
| for (int i = before; i < after; ++i) { | ||
| std::printf(" %s\n", mjp_getPluginAtSlot(i)->name); | ||
| } | ||
| } else { | ||
| std::printf("No plugins loaded from: '%s':\n", path.filename().c_str()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| __attribute__((constructor)) | ||
| void loadAmentResourcePlugins() { | ||
| std::printf("Loading plugins from ament resources...\n"); | ||
|
|
||
| try { | ||
| // Try to find all packages that registered mujoco plugins via the ament resource index | ||
| auto plugins = ament_index_cpp::get_resources("mujoco_plugins"); | ||
| for (const auto& [package_name, _] : plugins) { | ||
| std::string content; | ||
| std::string prefix; | ||
| if (ament_index_cpp::get_resource("mujoco_plugins", package_name, content, &prefix)) { | ||
| const std::string plugin_dir = prefix + "/" + content; | ||
| std::printf("Loading MuJoCo plugins from package '%s': %s\n", package_name.c_str(), | ||
| plugin_dir.c_str()); | ||
| loadPluginsFromDirectory(plugin_dir); | ||
| } | ||
| } | ||
| } catch (const std::exception& e) { | ||
| std::fprintf(stderr, "mujoco_plugin_shim: skipping ament plugin discovery: %s\n", e.what()); | ||
| } | ||
|
|
||
| std::printf("Finished loading plugins from ament resources!\n"); | ||
| } |
There was a problem hiding this comment.
do you think this stuff should stay here as-is, or worth making a portable library that we can reuse in mujoco_ros2_control instead of copy pasting?
|
Instead of shimming |
That was my initial idea too, but there were concerns about copy-pasting too much code (basically 550 LOC + having to keep up with updates)... but I'm all for that approach instead :) |
This PR removes the need of having to copy built MuJoCo extensions / plugins to the same folder as MuJoCo just so that
simulateworks with new plugins. See the discussions in ros-controls/mujoco_ros2_control#205This is done by replacing the direct symlink to
simulatewith a shim script that modifiesLD_PRELOADand finds registered plugins via ament resources before launching the MuJoCo simulate app.One open question: This means we still need this shim to be built in RoboStack, so we'll have to modify the patch that @traversaro applied if we go down this path.