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>