Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using multiple visual-tags in URDF, but the material-tag of the first one is used for both #1293

Open
M-Schroeder opened this issue Nov 8, 2024 · 6 comments

Comments

@M-Schroeder
Copy link

I am creating an urdf and want to show 2 meshes for one link. One of them should be transparent and the other one not. My idea was to put both meshes inside their own visual tag and one of them has a material-tag, that defines the transparency. To test it, I modified the following section of this xacro:

    <!-- Base link -->
    <link name="base_link">

        <visual>
            <origin xyz="0 0 0.2" rpy="0 0 0" />
            <geometry>
                <mesh filename="package://agilex_scout_mini_description/meshes/wheel.dae" />
            </geometry>
            <material name="half_transparent">
                <color rgba="0 0 0 0.5"/>
            </material>
        </visual>

        <visual>
            <origin
                    xyz="0 0 0"
                    rpy="1.5707 0 -1.5707" />
            <geometry>
                <mesh filename="package://scout_description/meshes/scout_mini_base_link.dae" />
            </geometry>
        </visual>

        <collision>
            <origin xyz="0 0 0" rpy="1.5707 0 -1.5707" />
          <geometry>
            <mesh filename="package://scout_description/meshes/scout_mini_base_link.dae" />
          </geometry>
        </collision>
    </link>

Not only the first mesh (here wheel.dae) is transparent, but both. If I switch the order, none of them is transparent. Even if I explicitly define a material with <color rgba="0 0 0 1"/> for the second mesh, it stays transparent.

It was tested with ROS2 humble.

@ANogin
Copy link

ANogin commented Nov 20, 2024

I am seeing the same or similar issue with Rviz 12.4.8 (ROS 2 Iron). Specifically, I have a URDF with multiple visual tags for a single link tags, and when the robot is visualized by a MoveIt2's moveit_rviz_plugin/MotionPlanning with Scene Robot: {Show Robot Collision: false, Show Robot Visual: true} settings, and all meshes for each given link are shown based on the material for the 1st visual, ignoring the material for all subsequent visuals for that link.

P.S. As far as I can tell, an Rviz1 patch for this was created about 10 years ago in ros-visualization/rviz#812 and then a few years later was merged - for Kinetic in ros-visualization/rviz#1079 and for Indigo in ros-visualization/rviz#1080, and as far as I can tell, these changes are all in there in Rviz2

@Tanneguydv
Copy link

Tanneguydv commented Dec 3, 2024

I had a similar issue lately : using .dae files along with a <material> tag in a .xacro file.
It seems that when there is a material specified in your .dae file, it generates a conflict with the <material> tag and the result is a transparent display.
I resolved it by deleting the <material> tags in my xacro file.

See if there is a material specified in your .dae file that overwrites the material specified in your xacro

@ANogin
Copy link

ANogin commented Dec 3, 2024

I had a similar issue lately : using .dae files along with a <material> tag in a .xacro file. It seems that when there is a material specified in your .dae file, it generates a conflict with the <material> tag and the result is a transparent display. I resolved it by deleting the <material> tags in my xacro file.

See if there is a material specified in your .dae file that overwrites the material specified in your xacro

I do not have .dae files in my setup, only <material> tags in .xacro with RBGA colors.

@Tanneguydv
Copy link

Obviously I was commenting the initial post by @M-Schroeder and I only suggest a lead in material specification conflict.

@M-Schroeder if you take a look at the original wheel.dae file you can see that there is material specified in that file, that causes conflict with this adding

 <material name="half_transparent">
   <color rgba="0 0 0 0.5"/>
 </material>

@sloretz
Copy link
Contributor

sloretz commented Dec 13, 2024

@ahcorde Do you have any ideas what might be happening here? 🧇

@ANogin
Copy link

ANogin commented Jan 4, 2025

OK, I think I traced the code, for at least the MoveIt plugin case - I believe the issue is happening in rviz_default_plugins::robot::RobotLink as follows:

  1. RobotLink::createVisualizable calls createEntityForGeometryElement with an empty value for the material:
    Ogre::Entity * mesh = createEntityForGeometryElement(
    link, *link_visual_element->geometry, link_visual_element->origin, "", scene_node);
    and
    Ogre::Entity * mesh = createEntityForGeometryElement(
    link, *visualizable_element->geometry, visualizable_element->origin, "", scene_node);
  2. RobotLink::createEntityForGeometryElement creates an Orge entity without dealing with it's material properties from URDF and calls RobotLink::assignMaterialsToEntities with the same empty name:
    default_material_ = getMaterialForLink(link, material_name);
  3. RobotLink::assignMaterialsToEntities calls RobotLink::getMaterialForLink:
    default_material_ = getMaterialForLink(link, material_name);
  4. RobotLink::getMaterialForLink calls RobotLink::getVisualWithMaterial:
    urdf::VisualSharedPtr visual = getVisualWithMaterial(link, material_name);
    with the same empty material_name
  5. RobotLink::getVisualWithMaterial which does not actually do what the name suggests. Instead, it goes over all the visual element in a no-op loop as is iteration checks !material_name.empty() which does not change and remains false:
    for (const auto & visual_array_element : link->visual_array) {
    if (visual_array_element &&
    !material_name.empty() &&
    visual_array_element->material_name == material_name)
    then just returns link->visual - the first visual element of the link, whether it has a material or not.
  6. RobotLink::getMaterialForLink then creates an Ogre material based on what that first visual has.
  7. RobotLink::assignMaterialsToEntities than goes ahead and uses that material to set the material for all subentities. The comment there says // Assign materials only if the submesh does not have one already:
    // Assign materials only if the submesh does not have one already
    but in reality it does so if the preexisting name is not "BaseWhite" or "BaseWhiteNoLighting":
    if (sub_material_name == "BaseWhite" || sub_material_name == "BaseWhiteNoLighting") {
    sub->setMaterialName(default_material_name_);
    I am guessing one of them would be returned by default when none was actually set? Given the entity was just created in step 2 without any material, then, assuming the comment is correct, the material on the Orge entity would at this point be set based on what RobotLink::getMaterialForLink returned, ignoring whatever was actually in URDF.

IMHO what needs to happen is that RobotLink::createEntityForGeometryElement should, rather than calling RobotLink::assignMaterialsToEntities, in step 2. be directly creating the material using the same code as in RobotLink::getMaterialForLink in step 6, (but perhaps only for visual entities, while still calling RobotLink::assignMaterialsToEntities for collision ones?). Does this make sense? Should I try implementing and testing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants