Waiting for service to become available-ROS2 basics course-Python

Hello I get this result. I checked the interfaces and services. The service is ‘find_wall’ and they are on the list. What am I doing wrong?

user:~$ ros2 service call /find_wall std_srvs/srv/Empty '{}'
waiting for service to become available...
user:~$ ros2 service list
/apply_joint_effort
/apply_link_wrench
/clear_joint_efforts
/clear_link_wrenches
/delete_entity
/find_wall

1

2

Thanks

What kind of message does your server node expect?
Seeing in the screenshots you provided you created a custom message:
custom_interfaces/srv/Findwall
Maybe you also programmed to expect this message? If so then you should call it:
user:~$ ros2 service call /find_wall custom_interfaces/srv/FindWall ‘{}’

Hi. Thanks for your message. No I haven’t added a message like that. I just expect the robot to find the wall with this service call. The problem is that the service seems working when I list it on terminal. But when I call it with " ros2 service call /find_wall std_srvs/srv/Empty ‘{}’ ", it says “waiting for service to become available…” and nothing happens.

Can you share your find_wall server code?

from custom_interfaces.srv import FindWall
from std_srvs.srv import Empty
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
from rclpy.qos import ReliabilityPolicy, QoSProfile
import rclpy
from rclpy.node import Node
import time

class Wall_finder(Node):

def __init__(self):
    # Here you have the class constructor

    # call the class constructor to initialize the node as service_moving
    super().__init__('wall_finder')
    # create the Service Server object
    # defines the type, name, and callback function
    self.srv = self.create_service(FindWall, 'find_wall', self.empty_callback)
    # create the Publisher object
    # in this case, the Publisher will publish on /cmd_vel topic with a queue size of 10 messages.
    # use the Twist module
    self.subscriber = self.create_subscription(LaserScan, '/scan', self.laser_callback, QoSProfile(depth=10, reliability=ReliabilityPolicy.RELIABLE))
    self.angular_velocity = 0.5
    self.linear_velocity = 0.2
    self.min_distance = 0.3
    self.target_angle = 270
    self.latest_laser_data = None
    self.publisher_ = self.create_publisher(Twist, 'cmd_vel', 10)
    
def laser_callback(self, laser_data):
    self.latest_laser_data = laser_data

def empty_callback(self, request, response):

    if self.latest_laser_data is None:
        self.get_logger().info('No data received yet!')
        return response
    else:

        shortest_ray_index = self.latest_laser_data.ranges.index(min(self.latest_laser_data.ranges))
        while shortest_ray_index!=0:
            self.rotate(self.angular_velocity)
        self.stop_movement()

        while self.latest_laser_data.ranges[0] > self.min_distance:
            self.move_forward(self.linear_velocity)
        self.stop_movement()

        while shortest_ray_index != self.target_angle:
            self.rotate(self.angular_velocity)
        self.stop_movement()
    
    # return the response parameter
        return response

def rotate(self, angular_velocity):
    twist = Twist()
    twist.angular.z = angular_velocity
    self.publisher_.publish(twist)
    self.get_logger().info('Rotating!')
    time.sleep(0.1)

def move_forward(self, linear_velocity):
    twist = Twist()
    twist.linear.x = linear_velocity
    self.publisher_.publish(twist)
    self.get_logger().info('Moving forward!')
    time.sleep(0.1)

def stop_movement(self):
    twist = Twist()
    self.publisher_.publish(twist)
    self.get_logger().info('Stop!')

def main(args=None):
# initialize the ROS communication
rclpy.init(args=args)
# declare the node constructor
moving_service = Wall_finder()
# pause the program execution, waits for a request to kill the node (ctrl+c)
rclpy.spin(moving_service)
# shutdown the ROS communication
rclpy.shutdown()

if name == ‘main’:
main()

Well we can see here you importing the custom message for the service.

# import the Empty module from std_servs Service interface
from custom_interfaces.srv import FindWall

And here you are using it for the service server, so your server will want to receive a FindWall message

# create the Service Server object
# defines the type, name, and callback function
self.srv = self.create_service(FindWall, 'find_wall', self.empty_callback)

So when you run on terminal ros2 service call /find_wall std_srvs/srv/Empty '{}' it will not work. If your service message file is setup correctly then you should call like so:
ros2 service call /find_wall custom_interfaces/srv/FindWall ‘{}’

I tried your code and got this result:

By the way I am following the instructions on the project and it says this code should work. Am I missing something?

the quotes got formatted weirdly, use "
ros2 service call /find_wall custom_interfaces/srv/FindWall “{}”

also don’t trust the instructions 100%, they were made by humans, and sometimes they make mistakes

1 Like

You are right. It worked now. The instruction is not correct. Thank you very much for your help.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.