Search code examples
c++rosros2rviz

ROS2 publish mesh marker


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.


Solution

  • 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.