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

Markers are not re-displayed in rviz when using multiple server names in the same node #96

Open
heuristicus opened this issue Jul 20, 2022 · 1 comment

Comments

@heuristicus
Copy link

heuristicus commented Jul 20, 2022

When using multiple servers which have different names within the same node, disabling and re-enabling the visualisation of the markers in rviz does not work correctly.

The cause of this is likely the update_full topic being used to know when there are markers available. Because this is a latched topic generated by the server, it only retains the last published message on the topic. Each server with a different server_id publishes to the same topic, which means that it's only possible for the process function to get the init message for a single one of the servers.

void SingleClient::process(const visualization_msgs::InteractiveMarkerInit::ConstPtr& msg, bool enable_autocomplete_transparency)

void InteractiveMarkerClient::subscribeInit()
{
if ( state_ != INIT && !topic_ns_.empty() )
{
try
{
init_sub_ = nh_.subscribe( topic_ns_+"/update_full", 100, &InteractiveMarkerClient::processInit, this );
DBG_MSG( "Subscribed to init topic: %s", (topic_ns_+"/update_full").c_str() );
state_ = INIT;
}
catch( ros::Exception& e )
{
callbacks_.statusCb( ERROR, "General", "Error subscribing: " + std::string(e.what()) );
}
}
}

Use the code below to reproduce.

First, start rviz and add an interactive marker visualiser on the topic /test/interactive. Then, run this node. You will see a couple of markers appear, like this:

Screenshot from 2022-07-20 12-07-32

The messages are as expected:

Screenshot from 2022-07-20 12-15-14

Then, uncheck the box to display the markers, and re-check it. You will now only be able to see the arrow marker, since that is the last one which was published on update_full. The status indicates that the circle client is still waiting for an initialisation message.

Screenshot from 2022-07-20 12-16-44

#!/usr/bin/env python
import rospy

from interactive_markers.interactive_marker_server import InteractiveMarkerServer
from visualization_msgs.msg import InteractiveMarker, InteractiveMarkerControl, Marker
from geometry_msgs.msg import Point, Vector3
from std_msgs.msg import ColorRGBA, Header


def generate_circle():
    int_marker = InteractiveMarker()
    int_marker.header.frame_id = "map"
    int_marker.scale = 1
    int_marker.name = "circle"
    int_marker.description = "Move and rotate circle"

    int_marker.pose.position = Point(x=1)

    plane_plus_rot = InteractiveMarkerControl()
    plane_plus_rot.name = "planar_plus_rotation"
    plane_plus_rot.orientation.w = 1
    plane_plus_rot.orientation.x = 0
    plane_plus_rot.orientation.y = 1
    plane_plus_rot.orientation.z = 0
    plane_plus_rot.interaction_mode = InteractiveMarkerControl.MOVE_ROTATE
    int_marker.controls.append(plane_plus_rot)

    z_adjustment = InteractiveMarkerControl()
    z_adjustment.name = "z_adjustment"
    z_adjustment.orientation.w = 1
    z_adjustment.orientation.x = 0
    z_adjustment.orientation.y = 1
    z_adjustment.orientation.z = 0
    z_adjustment.interaction_mode = InteractiveMarkerControl.MOVE_AXIS
    int_marker.controls.append(z_adjustment)

    return int_marker


def generate_arrow():
    int_marker = InteractiveMarker()
    int_marker.header.frame_id = "map"
    int_marker.scale = 1
    int_marker.name = "arrow"
    int_marker.description = "Arrow control"

    int_marker.pose.position.x = 0.5
    int_marker.pose.orientation.w = 1

    arrow_control = InteractiveMarkerControl()
    direction_marker = Marker(
        pose=int_marker.pose,
        id=-1,
        type=Marker.ARROW,
        scale=Vector3(0.2, 0.1, 0.1),
        color=ColorRGBA(r=1, b=1, a=1),
        header=Header(frame_id="map"),
        ns="edges/temp",
        action=Marker.ADD,
    )
    arrow_control.markers.append(direction_marker)
    arrow_control.always_visible = True
    arrow_control.interaction_mode = InteractiveMarkerControl.MENU
    arrow_control.name = "arrow_menu_control"
    int_marker.controls.append(arrow_control)

    return int_marker


if __name__ == "__main__":
    rospy.init_node("multiple_server_test")
    circle_marker_server = InteractiveMarkerServer(
        "/test/interactive", server_id="circle"
    )
    arrow_marker_server = InteractiveMarkerServer(
        "/test/interactive", server_id="arrow"
    )
    # Allow servers to initialise
    rospy.sleep(1)

    circle_marker_server.insert(generate_circle())
    circle_marker_server.applyChanges()

    arrow_marker_server.insert(generate_arrow())
    arrow_marker_server.applyChanges()

    rospy.spin()

@Southyang
Copy link

Hello, have you solved this problem?

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

2 participants