I'm trying to display a mesh resource in Rviz. It must be pretty straightforward as was in ROS1, but I'm not sure why it is not working. Here is a sample code I tried:
// meshpub.cpp
#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/color_rgba.hpp>
#include <geometry_msgs/msg/pose.hpp>
#include <visualization_msgs/msg/marker.hpp>
#include <ament_index_cpp/get_package_share_directory.hpp>
using namespace std;
int main(int argc, char ** argv)
{
(void) argc;
(void) argv;
rclcpp::init(argc, argv);
rclcpp::Node node("shape_pubilsher");
string base_frame = "base_link";
string topic = "/marker";
// Getting the model file path:
auto package_share_directory = ament_index_cpp::get_package_share_directory("package");
auto file_name = package_share_directory.append("/meshes/model.obj");
auto qos = rclcpp::QoS(1000);
auto publisher = node.create_publisher<visualization_msgs::msg::Marker>(topic, qos);
RCLCPP_INFO(node.get_logger(), "Waiting for Rviz to load...");
while(node.get_node_graph_interface()->count_subscribers(topic) == 0) {
rclcpp::sleep_for(200ms);
}
// Creating the marker and initialising its fields
geometry_msgs::msg::Pose pose;
pose.position.x = 0;
pose.position.y = 0;
pose.position.z = 0;
pose.orientation.x = 0;
pose.orientation.y = 0;
pose.orientation.z = 0;
pose.orientation.w = 0;
std_msgs::msg::ColorRGBA colour;
colour.a = 1;
colour.r = 1;
colour.g = 0;
colour.b = 0;
visualization_msgs::msg::Marker marker;
marker.header.frame_id = base_frame;
marker.header.stamp = node.now();
marker.action = visualization_msgs::msg::Marker::ADD;
marker.type = visualization_msgs::msg::Marker::MESH_RESOURCE;
marker.pose = pose;
marker.id = 0;
marker.mesh_resource = file_name;
marker.scale.x = 2;
marker.scale.y = 2;
marker.scale.z = 2;
marker.color = colour;
RCLCPP_INFO(node.get_logger(), "Attempting to publish mesh");
publisher->publish(marker);
while(rclcpp::ok());
return 0;
}
I have installed the meshes
folder which contains 3D model files onto the package share directory. I have tried different model file formats like .obj
, .fbx
, .blend
and .dae
(all were supported in ROS1 Rviz), but Rviz refuses to display it, and all I get is this heartwarming congratulation message:
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rviz2-1]: process started with pid [4733]
[INFO] [meshpub-2]: process started with pid [4735]
[meshpub-2] [INFO] [1664444431.191595500] [meshpub]: Waiting for Rviz to load...
[rviz2-1] QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-amirint'
[rviz2-1] [INFO] [1664444431.789824400] [rviz2]: Stereo is NOT SUPPORTED
[rviz2-1] [INFO] [1664444431.790017200] [rviz2]: OpenGl version: 3.1 (GLSL 1.4)
[rviz2-1] [INFO] [1664444431.863061600] [rviz2]: Stereo is NOT SUPPORTED
[meshpub-2] [INFO] [1664444433.394043100] [meshpub]: Attempting to publish mesh
[rviz2-1] [ERROR] [1664444434.023035400] [rviz2]: Could not load resource [/mnt/e/avnv/ros2_visually/install/package/share/package/meshes/model.obj]: Unable to open file "/mnt/e/avnv/ros2_visually/install/package/share/package/meshes/model.obj".
Although /mnt/e/avnv/ros2_visually/install/package/share/package/meshes/model.obj
is the correct path of the resource, the error message does not specifically tell whether this is a no such file or directory or a file format not supported sort of thing. It only says Unable to open file ...
.
I'm using Ubuntu 20.04 on wsl2 with ROS_DISTRO=galactic.
File paths have to be in the form file:///path/to/file
or package://path/to/file
. I mistakenly assumed
ament_index_cpp::get_package_share_directory("package")
will by default return the path in the mentioned form.
So just manually appending a file://
to the returned path string fixed the issue.