How to fix RViz2 [ERROR]: Could not load resource [....]: Unable to open file: "..."
Problem
When running ROS2’s RViz2 with a custom URDF model from file, you see an error message like this:
[ERROR] [1736351067.730994512] [rviz2]: Could not load resource [./meshes/robot_arms/fr3/visual/link0.dae]: Unable to open file "./meshes/robot_arms/fr3/visual/link0.dae".
Solution
The issue here is that a filename
attribute is not treated as a filename:
<mesh filename="./meshes/robot_arms/fr3/visual/link0.dae"/>
Instead, it’s loaded using assimp_loader.getScene()
using the OpenAssetImporter
library like this:
const aiScene * scene = assimp_loader.getScene(resource_path);
which calls Assimp::Importer::ReadFile()
here
which contains the following code:
// First check if the file is accessible at all
if( !pimpl->mIOHandler->Exists( pFile)) {
pimpl->mErrorString = "Unable to open file \"" + pFile + "\".";
ASSIMP_LOG_ERROR(pimpl->mErrorString);
return nullptr;
}
There are many different IO handlers for Assimp
, but rviz2
uses ResourceIOSystem
which is a ROS/rviz2-specific implementation:
importer_->SetIOHandler(new ResourceIOSystem());
This is just a thin wrapper around a resource_retriever::Retriever
which is located in the ros/resource_retriever
project.
The implementation of the resource_retriever::Retriever
is here
We now need to look at Retriever::get
to see how input strings are handled.
Generally this function will pass any input string to CURL, which will then try to open the URL or file. However, Retriever::get
will handle package://
-schemes URLs differently.
These are essentially ROS-specific URLs and these will, in the end, be converted to absolute file://
-schemed URLs, referenced to the package://
directory.
The package directory is determined here
package_path = ament_index_cpp::get_package_share_directory(package);
This function is from the ament resource index project.
Notably, this will not refer to the package root directly, but to the share
directory of the package
return get_package_prefix(package_name) + "/share/" + package_name;
How to insert files directly
This tracedown shows us that rviz2
will only support URLs and not direct file paths.
To insert files directly, you can use the file://
-scheme which only work with absolute URL paths since libcurl
doesn’t support relativ file://
URLs
Loading files from the network
Since every non-package://
URL is passed directly to libcurl
, you can also load files from the network such as using https://
or similar URLs.