Action server not working

Im having trouble getting my action server to return the result to the action client and i keep getting errors. i looked at the solution but i can’t see why my code is wrong since all its supposed to do is return a odometry array. Here is my code.

#! /usr/bin/env python
import rospy
import time
import actionlib
from my_turtlebot_actions.msg import record_odomAction, record_odomResult, record_odomFeedback
from nav_msgs.msg import Odometry
from odom_sub import OdomSub
from std_msgs.msg import Empty

class IsOut():

    def __init__(self):
        # creates the action server
        self._as = actionlib.SimpleActionServer("record_odom_as", record_odomAction, self.goal_callback, False)
        self._as.start()
        #self.ctrl_c = False
        #self.rate = rospy.Rate(10)
        self.read_odom = OdomSub()
        #self.odom_data = self.read_odom.get_odomdata()
        self._result = record_odomResult()
        

    def goal_callback(self,goal):
        success = True
        self.odom_data = self.read_odom.get_odomdata()
        self.odom_pose = self.odom_data.pose.pose.position
        rate = rospy.Rate(1)
        

        # this callback is called when the action server is called.
        # and returns to the node that called the action server
        print('as has been called')
        #print(self.odom_data)
        print(self.odom_pose)
        #self.l = [1,2]
        i=0
        while i < 10:
            self._result.result_odom_array.append(self.read_odom.get_odomdata)
            i +=1
            rate.sleep()

        rospy.loginfo('Succeeded')
        
        # If success, then we publish the final result
        # If not success, we do not publish anything in the result
        if success:
            self._as.set_succeeded(self._result)

if __name__ == '__main__':
  rospy.init_node('recoord_odom_as_node')
  IsOut()
  rospy.spin()

Here is my error when I try to call it.

user:~/catkin_ws/src/my_turtlebot_actions/src$ python action_server.py

[WARN] [1609557919.440018, 9321.483000]: Inbound TCP/IP connection failed: connection from sender terminated before handshake header received. 0 bytes were received. Please check sender for additional details.
as has been called
x: -3.64741445896
y: -8.18342546336
z: -0.00017957276511
[INFO] [1609557932.118607, 9334.100000]: Succeeded
[ERROR] [1609557932.121599, 9334.103000]: Exception in your execute callback: 'function' object has no attribute 'header'
Traceback (most recent call last):
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/actionlib/simple_action_server.py", line 289, in executeLoop
    self.execute_callback(goal)
  File "action_server.py", line 47, in goal_callback
    self._as.set_succeeded(self._result)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/actionlib/simple_action_server.py", line 162, in set_succeeded
    self.current_goal.set_succeeded(result, text)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/actionlib/server_goal_handle.py", line 195, in set_succeeded
    self.action_server.publish_result(self.status_tracker.status, result)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/actionlib/action_server.py", line 182, in publish_result
    self.result_pub.publish(ar)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/rospy/topics.py", line 882, in publish
    self.impl.publish(data)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/rospy/topics.py", line 1066, in publish
    serialize_message(b, self.seq, message)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/rospy/msg.py", line 152, in serialize_message
    msg.serialize(b)
  File "/home/user/catkin_ws/devel/lib/python2.7/dist-packages/my_turtlebot_actions/msg/_record_odomActionResult.py", line 231, in serialize
    _v1 = val1.header
AttributeError: 'function' object has no attribute 'header'

[ERROR] [1609557932.122512, 9334.104000]: To transition to an aborted state, the goal must be in a preempting or active state, it is currently in state: 3

The client I use to test it is simple and i don’t think its the issue but here is the client code.

#! /usr/bin/env python
import rospy
import time
import actionlib
from my_turtlebot_actions.msg import record_odomAction, record_odomResult, record_odomGoal


def feedback_callback(feedback):
    pass
# initializes the action client node
rospy.init_node('action_client')
# create the connection to the action server
client = actionlib.SimpleActionClient('/record_odom_as', record_odomAction)
# waits until the action server is up and running
client.wait_for_server()
# creates a goal to send to the action server
goal = record_odomGoal()
#no goal
client.send_goal(goal, feedback_cb=feedback_callback)

client.wait_for_result()
print('[Result] State: %d'%(client.get_state()))

if it helps any, this is my OdomSub.

#! /usr/bin/env python

import time
import rospy
from nav_msgs.msg import Odometry

class OdomSub:
    def __init__(self):
        self.sub = rospy.Subscriber('/odom', Odometry, self.callback)
        self._odomdata = Odometry()

    def callback(self, msg): 
        
       # print msg.pose.pose.position.y
        self._odomdata = msg
        #rospy.logdebug(self._laserdata)

    def get_odomdata(self):
        """
        Returns the newest odom data

    std_msgs/Header header
      uint32 seq
      time stamp
      string frame_id
    string child_frame_id
    geometry_msgs/PoseWithCovariance pose
      geometry_msgs/Pose pose
        geometry_msgs/Point position
          float64 x
          float64 y
          float64 z
        geometry_msgs/Quaternion orientation
          float64 x
          float64 y
          float64 z
          float64 w
      float64[36] covariance
    geometry_msgs/TwistWithCovariance twist
      geometry_msgs/Twist twist
        geometry_msgs/Vector3 linear
          float64 x
          float64 y
          float64 z
       geometry_msgs/Vector3 angular
          float64 x
          float64 y
          float64 z
      float64[36] covariance

        """
        return self._odomdata

if __name__ == "__main__":
    rospy.init_node('odom_subscriber', log_level=rospy.INFO)
    odom_reader_object = OdomSub()
    time.sleep(2)
    rate = rospy.Rate(0.5)
    #print odom_reader_object.get_msg()
    #rospy.spin()
    
    ctrl_c = False
    def shutdownhook():
        # works better than the rospy.is_shut_down()
        global ctrl_c
        print "shutdown time!"
        ctrl_c = True

    rospy.on_shutdown(shutdownhook)

    while not ctrl_c:
        data = odom_reader_object.get_odomdata()
        rospy.loginfo(data)
        rate.sleep()

Thanks in advanced to anyone who can help me troubleshoot this.

1 Like

Grrr. I figured it out. I forgot to add parenthesis at the end of my get_odomdata() funtion.

2 Likes