RobotLocomotion / drake

Model-based design and verification for robotics.
https://drake.mit.edu
Other
3.25k stars 1.25k forks source link

PackageMap doesn't handle package:// identifier in URDF correctly #5584

Closed kunimatsu-tri closed 7 years ago

kunimatsu-tri commented 7 years ago

Problem: When I tried loading an URDF file that contains package:// for mesh filenames and visualizing it with drake-visualizer, drake-visualizer failed loading these mesh files.

Detail: The code that loads the URDF:

rake::parsers::PackageMap package_map;
package_map.Add("package_a", "path_to_package_a/package_a");
drake::parsers::urdf::AddModelInstanceFromUrdfFileSearchingInRosPackages(
    urdf_filename, package_map, multibody::joints::kQuaternion, nullptr, tree.get());

The URDF:

...
<visual>
  <geometry>
    <mesh filename="package://package_a/meshes/hand/finger.obj"/>
  </geometry>
</visual>
...

Then, I created RigidBodyPlant and DrakeVisualizer systems and connected those two.

When I ran the program and drake-visualizer, drake-visualizer output the following warning message:

failed to resolve filename, unknown package: package://package_a/meshes/hand/finger.obj
warning, cannot find file: package://package_a/meshes/hand/finger.obj

and displayed nothing in drake-visualizer's window.

When I replaced package://package_a with ... which is a relative path from the URDF to the mesh file, it worked without any problems.

So, my guess is that PackageMap doesn't handle package information correctly, but the root cause might be somewhere else.

patmarion commented 7 years ago

drake c++ programs do not communicate package map information to the drake-visualizer process. The drake-visualizer program only knows about packages in the drake source dir and in paths specified by the ROS_PACKAGE_PATH or DRAKE_PACKAGE_PATH environment variables.

kunimatsu-tri commented 7 years ago

If I understand correctly, C++ programs don't need to send package map information to drake-visualizer, but the URDF parser needs to resolve the actual path of a mesh file using the package map information and then the resolved file path should be sent to drake-visualizer.

This is the function that should resolve the file path: https://github.com/RobotLocomotion/drake/blob/master/drake/multibody/parsers/parser_common.h#L42 but somehow not working.

patmarion commented 7 years ago

The package:// url is sent to drake-visualizer rather than the resolved filename. Here:

https://github.com/RobotLocomotion/drake/blob/master/drake/systems/rendering/drake_visualizer_client.cc#L50

I can't remember why this behavior is used. I think it might be so that lcm logs are playable on other computers, since the logs contain package:// urls instead of resolved filepaths which are specific to the computer where the log was recorded. I'm not sure how common this use case really is, and I can't think of another reason to use this behavior, but maybe I am forgetting something.

jwnimmer-tri commented 7 years ago

As I understand it, the use of package:// in a resource is explicitly a choice to use mapped resources, where all interacting processes agree to use package:// when talking about resources, and to have a pre-established map from package names to filesystem paths. Given that, when running e.g. a Drake simulation that loads resources with package:// and feeds geometry to drake-visualizer, the user must ensure that drake-visualizer has ROS_PACKAGE_PATH or DRAKE_PACKAGE_PATH configured consistently with the Drake simulation.

kunimatsu-tri commented 7 years ago

Thanks both. Setting either ROS_PACKAGE_PATH or DRAKE_PACKAGE_PATH in a terminal that runs drake-visualizer resolved this issue.

TIL: The resolved file path is for Drake's internal use, but not for external uses like drake-visualizer.

will close this issue.