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

[Bug] Can't use ROS Service with Zenoh namespace #223

Open
sabrinaacardoso opened this issue Aug 27, 2024 · 1 comment
Open

[Bug] Can't use ROS Service with Zenoh namespace #223

sabrinaacardoso opened this issue Aug 27, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@sabrinaacardoso
Copy link

Describe the bug

When a namespace is configured in the zenoh_config.json5 file under the ros2dds plugin, the service communication between my TurtleBot2i (acting as a client) and my Ubuntu computer (acting as a server) fails. Removing the namespace resolves the issue. But I need to use namespace in my application.

To reproduce

  1. Zenoh Configuration on TurtleBot2i:

    {
        mode: "peer",
        connect: { endpoints: ["tcp/104.0.0.20:7447"] },
        plugins: {
            ros2dds: {
                id: "turtlebot",
                namespace: "/turtlebot",
                deny: {
                    publishers: [".*/rosout", ".*/.*parameter.*", ".*/_internal/.*"],
                    subscribers: [".*/rosout", ".*/.*parameter.*", ".*/_internal/.*"],
                    service_servers: [".*/.*parameter.*", ".*/_internal/.*"],
                    Service_clients: [".*/.*parameter.*", ".*/_internal/.*"],
                    action_servers: [".*/_internal/.*"],
                    action_clients: [".*/_internal/.*"]
                }
            },
            rest: { http_port: 8000 }
        }
    }
  2. Zenoh Configuration on Ubuntu:

    {
        mode: "router",
        listen: { endpoints: ["tcp/0.0.0.0:7447"] },
        plugins: {
            ros2dds: {
                id: "edgeserver",
                namespace: "/turtlebot",
                deny: {
                    publishers: [".*/rosout", ".*/.*parameter.*", ".*/_internal/.*"],
                    subscribers: [".*/rosout", ".*/.*parameter.*", ".*/_internal/.*"],
                    service_servers: [".*/.*parameter.*", ".*/_internal/.*"],
                    Service_clients: [".*/.*parameter.*", ".*/_internal/.*"],
                    action_servers: [".*/_internal/.*"],
                    action_clients: [".*/_internal/.*"]
                }
            },
            rest: { http_port: 8000 }
        }
    }
  3. Service Implementation on Ubuntu:

    import rclpy
    from rclpy.node import Node
    from std_srvs.srv import Trigger
    from lifecycle_msgs.srv import GetState
    
    class MapService(Node):
        def __init__(self):
            super().__init__('map_service')
            self.srv = self.create_service(Trigger, 'check_mapping', self.check_mapping_callback)
            self.lifecycle_client = self.create_client(GetState, '/rtabmap/get_state')
            while not self.lifecycle_client.wait_for_service(timeout_sec=1.0):
                self.get_logger().info('Waiting for lifecycle service to be available...')
    
        def check_mapping_callback(self, request, response):
            self.get_logger().info('Received request to check mapping status')
            future = self.lifecycle_client.call_async(GetState.Request())
            rclpy.spin_until_future_complete(self, future)
            lifecycle_state = future.result().current_state.label
    
            if lifecycle_state == 'active':
                response.success = True
                response.message = 'Mapping node is active'
            else:
                response.success = False
                response.message = f'Mapping node is in {lifecycle_state} state'
    
            self.get_logger().info(f'Sending response: {response.message}')
            return response
    
    def main(args=None):
        rclpy.init(args=args)
        node = MapService()
        rclpy.spin(node)
        rclpy.shutdown()
    
    if __name__ == '__main__':
        main()
  4. Client Implementation on TurtleBot2i:

    import rclpy
    from rclpy.node import Node
    from std_srvs.srv import Trigger
    import os
    
    class MapClient(Node):
        def __init__(self):
            super().__init__('map_client')
            self.client = self.create_client(Trigger, 'check_mapping')
            while not self.client.wait_for_service(timeout_sec=1.0):
                self.get_logger().info('Waiting for map_service to be available on Ubuntu...')
            self.timer = self.create_timer(5.0, self.check_mapping_status)
    
        def check_mapping_status(self):
            request = Trigger.Request()
            future = self.client.call_async(request)
            future.add_done_callback(self.handle_response)
    
        def handle_response(self, future):
            try:
                response = future.result()
                if not response.success:
                    self.get_logger().info('Mapping is not active on Ubuntu, starting it locally on NUC.')
                    self.start_local_mapping()
            except Exception as e:
                self.get_logger().error(f'Service call failed: {str(e)}')
    
        def start_local_mapping(self):
            # Iniciar o mapeamento localmente no NUC
            os.system('ros2 launch my_package start_mapping_launch.py')
    
    def main(args=None):
        rclpy.init(args=args)
        node = MapClient()
        rclpy.spin(node)
        rclpy.shutdown()
    
    if __name__ == '__main__':
        main()
  5. Start the service on the Ubuntu computer.

  6. Attempt to call the service from the TurtleBot2i.

  7. Observe the error:
    WARN zenoh_plugin_ros2dds::route_service_cli] Route Service Client (ROS:/check_mapping <-> Zenoh:turtlebot/check_mapping): received NO reply for request (6b771a6ecb3be14d,1) - cannot reply to client, it will hang until timeout.

The same happens with the add_two_ints_client and add_two_ints_server services from the demo_nodes_py package when the client is run before the server.

System info

  • Platform: Ubuntu 22.04 64-bit
  • CPU: Intel NUC BOXNUC6CAYH
  • Zenoh version/commit: zenoh-bridge-ros2dds v0.10.1-rc.2 built with rustc 1.72.0 (5680fa18f 2023-08-23)
@sabrinaacardoso sabrinaacardoso added the bug Something isn't working label Aug 27, 2024
@JEnoch
Copy link
Member

JEnoch commented Dec 3, 2024

Hi @sabrinaacardoso ,
Apologies for this late reply.
Did you try again with recent version (1.0.x) ?

I tried to run a modified version of your example, because I miss your /rtabmap/get_state Node:
removing the lines calling self.client I don't see your error (the bridge running with or without namespace config).
Are you sure your server was not hanging in the callback and thus not sending a response ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants