Quiz ex 4.8 server client grader issue

When submitting, I can’t figure out what’s. wrong here. Maybe someone can let me know because the gradebot isn’t making sense to me because the possible error that it states should’nt have been an issue.

:heavy_multiplication_x: [20:37:31] [assess] Could not launch services_quiz service client successfully. Can you believe that? - i launched it on the terminal properly
The launch command exited earlier than expected. What could be wrong? - this I’m unsure about because my client stops once. the request. is sent

  • Does your service client node exit in 10 seconds or less? Did it complete the expected movement? - no, it used to but now doesn’t
  • Did you name the launch file correctly? It should be services_quiz_client.launch.py - yes i did
  • Are you also calling the service from the services_quiz_server.launch.py file? Please don’t. -no i’m not
  • Start the service server and then run ros2 launch services_quiz services_quiz_client.launch.py and fix any errors that appears. (mark: 6.0) - no errors

Your service client should not stop once the request is sent, it should wait until the expected movement is completed.

server:
from geometry_msgs.msg import Twist
from services_quiz_srv.srv import Turn
import rclpy
from rclpy.node import Node

class Service(Node):

def __init__(self):
    super().__init__('turn_server')
    self.srv = self.create_service(Turn, 'movement', self.custom_service_callback)
    self.publisher_ = self.create_publisher(Twist, 'cmd_vel', 10)
    self.msg = Twist()
    self.motion_completed = False

def custom_service_callback(self, request, response):
    angVel = request.angular_velocity
    sleepTime = request.time
    if request.direction == "right":
        self.msg.angular.z = -angVel
        self.publisher_.publish(self.msg)
        self.get_logger().info('Turning to right direction!!')

    elif request.direction == "left":
        self.msg.angular.z = angVel
        self.publisher_.publish(self.msg)
        self.get_logger().info('Turning to left direction!!')

    else:
        response.message = "Moving"
        response.success = False
        # return response
    if self.motion_completed:
        response.success = True
        # program not getting here
        self.get_logger().info("I'm here") 
    # Create a timer for the specified duration
    self.create_timer(sleepTime, self.stop_motion_callback)
    self.get_logger().info(str(response.success))
    # response.success = True
    return response

def stop_motion_callback(self):
    # Stop the motion after the specified duration
    self.msg.angular.z = 0.0
    self.publisher_.publish(self.msg)
    self.get_logger().info('Motion stopped!!')
    self.motion_completed = True
    self.get_logger().info(str(self.motion_completed))

def main(args=None):
rclpy.init(args=args)
service = Service()
rclpy.spin(service)
rclpy.shutdown()

if name == ‘main’:
main()

client:
from services_quiz_srv.srv import Turn
import rclpy
from rclpy.node import Node

class ClientAsync(Node):

def __init__(self):
    super().__init__('turn_client')
    self.client = self.create_client(Turn, 'movement')
    while not self.client.wait_for_service(timeout_sec=1.0):
        self.get_logger().info('service not available, waiting again...')
    
    self.req = Turn.Request()
    

def send_request(self):
    self.req.direction = "right"
    self.req.angular_velocity = 0.2
    self.req.time = 10
    self.future = self.client.call_async(self.req)

def main(args=None):
rclpy.init(args=args)
client = ClientAsync()
client.send_request()

while rclpy.ok():
    rclpy.spin_once(client)
    if client.future.done():
        try:
            response = client.future.result()
            if response.success:  # Exit loop only if response indicates success
                break
        except Exception as e:
            client.get_logger().info('Service call failed %r' % (e,))
        else:
            client.get_logger().info('Response state %r' % (response.success,))
            

client.destroy_node()
rclpy.shutdown()

if name == ‘main’:
main()

I’m not sure what’s wrong here, been at it for hours, if you could point me in the right direction would be very helpful.

I see that your service client only stops after it gets a successful response from the service servers. In that case, the problem might be in your service server - it should only return success when the service is complete, not immediately.

I fixed it by using time.sleep instead of timer_callback function, is there a way to implement it using callback. I see that the solution uses time.sleep as well.

I don’t think it’s a timing issue, unless I’m missing something:

The key thing is that does your server complete the task before sending a “success” response?

time.sleep() might mitigate the situation by adding a delay, but the key is to allow the service to finish its task before responding.

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