Problem with exercise 3.5

Hi,
about exercise 3.5, I creates the working requested server

when I execute the command to call the service I get the pose of the robot even if I get the error below too.
user:~/catkin_ws/src/get_pose/launch$ rosservice call /get_pose_service “{}”
ERROR: service [/get_pose_service] responded with an error: b’service cannot process request: service handler returned None’

I get the pose

user:/opt/ros/noetic/share/std_srvs/srv$ roslaunch get_pose get_pose_launch.launch
… logging to /home/user/.ros/log/83877550-9966-11ec-aa79-0242ac120007/roslaunch-1_xterm-13947.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://1_xterm:37491/

SUMMARY

PARAMETERS

  • /rosdistro: noetic
  • /rosversion: 1.15.9

NODES
/
get_pose_node (get_pose/get_pose_service.py)

ROS_MASTER_URI=http://1_simulation:11311

process[get_pose_node-1]: started with pid [13955]
[INFO] [1646150041.332582, 7447.687000]: [‘position: 0.07, 0.00, 0.00 - orientation: 0.00, 0.00, -0.01, 1.00’]
[INFO] [1646150407.848289, 7813.066000]: [‘position: -1.98, 3.90, 0.00 - orientation: 0.00, 0.00, 1.00, 0.03’]
[INFO] [1646150602.986185, 8007.600000]: [‘position: 13.07, 11.58, 0.00 - orientation: 0.00, 0.00, 0.71, 0.71’]

How can I avoid this error?
thanks
Salvatore

Hi @saxosun ,

Could you post the code of your service server?

Hi Marco, sure

#! /usr/bin/env python
import rospy
from geometry_msgs.msg import PoseWithCovarianceStamped
from std_srvs.srv import Trigger, TriggerResponse
class GetPoseClass(object):

    def __init__(self):
        self.sub = rospy.Subscriber(
            "/amcl_pose", PoseWithCovarianceStamped, self.subscriber_callback)

        self.get_pose_service_server = rospy.Service(
            "/get_pose_service", Trigger, self.service_callback)

        self.data = PoseWithCovarianceStamped()
        self.response = TriggerResponse()
        self.string = []

    def service_callback(self, request):
        self.response.success = True
        self.response.message = self.string
        rospy.loginfo(self.string)

    def subscriber_callback(self, msg):
        x = msg.pose.pose.position.x
        y = msg.pose.pose.position.y
        z = msg.pose.pose.position.z
        a = msg.pose.pose.orientation.x
        b = msg.pose.pose.orientation.y
        g = msg.pose.pose.orientation.z
        w = msg.pose.pose.orientation.w
        self.string = [
            'position: %.2f, %.2f, %.2f - orientation: %.2f, %.2f, %.2f, %.2f' % (x, y, z, a, b, g, w)]

if __name__ == "__main__":
    rospy.init_node("get_pose_node")
    try:
        GetPoseClass()
        rospy.spin()
    except rospy.ROSInterruptException:
        pass

@saxosun ,

Your service_callback must return a TriggerResponse object

There is an assignment inside the __init__ that may be not necessary:

self.response = TriggerResponse()

You need to do this inside the callback and return this object

I changed the code as you suggested

#! /usr/bin/env python
import rospy
from geometry_msgs.msg import PoseWithCovarianceStamped
from std_srvs.srv import Trigger, TriggerResponse

class GetPoseClass(object):

    def __init__(self):
        self.sub = rospy.Subscriber(
            "/amcl_pose", PoseWithCovarianceStamped, self.subscriber_callback)
        self.get_pose_service_server = rospy.Service(
            "/get_pose_service", Trigger, self.service_callback)
        self.string = []

    def service_callback(self, request):
        self.response = TriggerResponse()
        self.response.success = True
        self.response.message = self.string
        rospy.loginfo(self.string)
        return self.response

    def subscriber_callback(self, msg):
        x = msg.pose.pose.position.x
        y = msg.pose.pose.position.y
        z = msg.pose.pose.position.z
        a = msg.pose.pose.orientation.x
        b = msg.pose.pose.orientation.y
        g = msg.pose.pose.orientation.z
        w = msg.pose.pose.orientation.w
        self.string = [x, y, z, a, b, g, w]

if __name__ == "__main__":
    rospy.init_node("get_pose_node")
    try:
        GetPoseClass()
        rospy.spin()
    except rospy.ROSInterruptException:

but

process[get_pose_node-1]: started with pid [21018]
[INFO] [1646154057.428599, 11424.972000]: [13.070857331917631, 11.581616244908755, 0.0, 0.0, 0.0, 0.7072980836522808, 0.7069154269513512]
[ERROR] [1646154057.431728, 11424.975000]: Error processing request: ‘list’ object has no attribute ‘encode’
[‘Traceback (most recent call last):\n’, ’ File “/opt/ros/noetic/lib/python3/dist-packages/rospy/impl/tcpros_service.py”, line 636, in _handle_request\n transport.send_message(response, self.seq)\n’, ’ File “/opt/ros/noetic/lib/python3/dist-packages/rospy/impl/tcpros_base.py”, line672, in send_message\n serialize_message(self.write_buff, seq, msg)\n’, ’ File “/opt/ros/noetic/lib/python3/dist-packages/rospy/msg.py”, line 152, in serialize_message\n msg.serialize(b)\n’, ’ File “/opt/ros/noetic/lib/python3/dist-packages/std_srvs/srv/_Trigger.py”, line 154, in serialize\n _x = _x.encode(‘utf-8’)\n’, “AttributeError: ‘list’ object has no attribute ‘encode’\n”]

user:~/catkin_ws/src/get_pose/launch$ rosservice call /get_pose_service “{}”
ERROR: service [/get_pose_service] responded with an error: b"error processing request: ‘list’ object has no attribute ‘encode’"
user:~/catkin_ws/src/get_pose/launch$
pass

In the code, it tries to assign a list to a string

self.response.message = self.string

You would need to convert this list to a string first, or even declare as a string from the beginning:

Something like: "%s %s %s" % (msg.pose.pose.position.x, ...)

Because python runtime is trying to apply the encode method to a list, and it does not exist.

I resolved. tks----------------------------------------------------

1 Like