Services_quiz : My code works correctly but gradebot did not give me full grades

This is the autofeedback:

✖ [20:45:33] [assess] Could not launch services_quiz service client successfully.
The launch command exited earlier than expected. Speechless!
- Does your service client complete both squares as specified? Could it have completed them so early?
- Did you name the launch file correctly? It should be call_bb8_move_in_square_custom_service_server.launch
- Are you also calling the service from the start_bb8_move_custom_service_server.launch file? Please don't.
- Start the service server and then run roslaunch services_quiz call_bb8_move_in_square_custom_service_server.launch and fix any errors that appears. (mark: 6)

Here is my code for bb8_move_custom_service_server.py:

#! /usr/bin/env python

import rospy
from services_quiz.srv import BB8CustomServiceMessage, BB8CustomServiceMessageResponse
from geometry_msgs.msg import Twist
import time


class MoveSquareServiceServer:
    def __init__(self):
        rospy.init_node('move_square_custom_service_server') 

        self.pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
        self.move = Twist()

        self.service = rospy.Service('move_bb8_in_square_custom', BB8CustomServiceMessage, self.callback) # create the Service called my_service with the defined callback
        rospy.loginfo("Service move_bb8_in_square_custom Ready")

        rospy.on_shutdown(self.stop)

    def move_straight(self, side_factor):
        '''
        Move the robot forward to form one side of the square.
        '''
        rospy.loginfo(f"Moving straight with side factor: {side_factor}")

        self.move.linear.x = 0.4
        self.move.angular.z = 0.0

        # Base duration to move one side of the square (can be tuned)

        move_straight_duration = 1 / self.move.linear.x * side_factor

        end_time = rospy.Time.now() + rospy.Duration(move_straight_duration)
        rate = rospy.Rate(10)
        
        while rospy.Time.now() < end_time and not rospy.is_shutdown():
            self.pub.publish(self.move)
            rate.sleep()
        
        return not rospy.is_shutdown()

    def turn_90_degrees(self):
        rospy.loginfo("Turning 90 degrees")
        
        self.move.linear.x = 0.0
        self.move.angular.z = 0.4 # rad/s

        # Calculate turn duration for 90 degrees (π/2 radians)
        turn_duration = (3.14159 / 2) / self.move.angular.z # Duration in seconds
        end_time = rospy.Time.now() + rospy.Duration(turn_duration)
        rate = rospy.Rate(10)
        
        while rospy.Time.now() < end_time and not rospy.is_shutdown():
            self.pub.publish(self.move)
            rate.sleep()
        
        return not rospy.is_shutdown()

    def callback(self, request):
        rospy.loginfo("Service move_bb8_in_square_custom has been called")
        
        success = False
        for _ in range(request.repetitions):
            for _ in range(4):  # Four sides of the square and four turns to complete a square.
                self.move_straight(request.side)
                self.turn_90_degrees()
        self.stop()
        rospy.loginfo("Finished service move_bb8_in_square_custom")
        success = True

        response = BB8CustomServiceMessageResponse()
        response.success = success

        return response

    def spin(self):
        rospy.spin() # maintain the service open.

    def stop(self):
        rospy.loginfo("Stopping the robot...")
        self.move.linear.x = 0
        self.move.angular.z = 0
        self.pub.publish(self.move)  # Publish the stop command
        




if __name__ == '__main__':
    service_server = MoveSquareServiceServer()
    try:
        service_server.spin()
    except rospy.ROSInterruptException:
        service_server.stop()

And code for bb8_move_custom_service_client.py:

#! /usr/bin/env python

import rospy
# Import the serviceMsg used by the service 
from services_quiz.srv import BB8CustomServiceMessage, BB8CustomServiceMessageRequest
import time

class MoveSquareServiceClient:
    def __init__(self):
        
        # Initialise a ROS node with the name service_client
        rospy.init_node('move_square_custom_service_client')

        # Wait for the service client to be running
        rospy.wait_for_service('/move_bb8_in_square_custom')

        # Create the connection object to the service
        self.service = rospy.ServiceProxy('/move_bb8_in_square_custom', BB8CustomServiceMessage)

        # Create a MsgRequest object
        self.request = BB8CustomServiceMessageRequest()


    def send_request(self, side, repetitions): 
        #time.sleep(2)  # Add a delay to ensure the service server is ready
        
        self.request.repetitions = repetitions
        self.request.side = side
        
        start_time = time.time()
        timeout = 3 * 60  # 3 minutes

        rospy.loginfo("Doing Service Call...")
        try:
            # Send the MsgRequest object through the connection object to be executed by the robot
            result =self.service(self.request)

            end_time = time.time()
            total_time_duration = end_time - start_time
            rospy.loginfo("Total service call duration: %.2f seconds" % total_time_duration)

            if total_time_duration > timeout:
                rospy.logwarn("Service call exceeded the timeout limit of 3 minutes. Quit")
                return 
            
            rospy.loginfo("END of Service call...")
            # Print the result given by the service called
            rospy.loginfo(result)


        except rospy.ServiceException as e:
            rospy.logerr("Service call failed: %s", e)

if __name__ == '__main__':
    service_client = MoveSquareServiceClient()
    try:
        service_client.send_request(side=1, repetitions=1)
        service_client.send_request(side=2, repetitions=1)
    except rospy.ROSInterruptException:
        pass


My call_bb8_move_in_square_custom_service_server.launch file:

<launch>

  <node pkg ="services_quiz"
        type="bb8_move_custom_service_client.py"
        name="move_square_custom_service_client"
        output="screen">
  </node>

</launch>

start_bb8_move_custom_service_server.launch file

<launch>

  <node pkg ="services_quiz"
        type="bb8_move_custom_service_server.py"
        name="move_square_custom_service_server"
        output="screen">
  </node>

</launch>


Hi @min.wang.1997.01.13,

I was checking the logs here, and it seems that your code indeed worked as expected:

process[move_square_custom_service_client-1]: started with pid [763]
[INFO] [1716230704.774888, 0.000000]: Doing Service Call...
[INFO] [1716230704.781172, 94.493000]: Service move_bb8_in_square_custom has been called
[INFO] [1716230704.784616, 94.496000]: Moving straight with side factor: 1.0
[INFO] [1716230707.311149, 96.999000]: Turning 90 degrees
[INFO] [1716230711.375724, 101.001000]: Moving straight with side factor: 1.0
[INFO] [1716230713.912663, 103.503000]: Turning 90 degrees
[INFO] [1716230717.964237, 107.504000]: Moving straight with side factor: 1.0
[INFO] [1716230720.492118, 110.006000]: Turning 90 degrees
[INFO] [1716230724.561839, 114.008000]: Moving straight with side factor: 1.0
[INFO] [1716230727.098897, 116.509000]: Turning 90 degrees
[INFO] [1716230731.155176, 120.511000]: Stopping the robot...
[INFO] [1716230731.159316, 120.511000]: Finished service move_bb8_in_square_custom
[INFO] [1716230731.161956, 120.514000]: Total service call duration: 26.39 seconds
[INFO] [1716230731.163574, 120.515000]: END of Service call...
[INFO] [1716230731.165124, 120.516000]: success: True
[move_square_custom_service_client-1] process has finished cleanly

The problem seems to be on our script that expected to have your script running after 30 seconds, but the script “finished too early”

If you just add a rospy.spin() at the end of your service client, your test will probably pass.
I would recommend adding this rospy.spin() while we have the automated test for this Unit fixed.

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