I'm struggling making an action server where I have to use the subscribe to odometry data to use it in the action callback. I managed to get the pose data and I know its okay cause I have printed it inside the subscriber callback. My problem is that when I want to use this data outside I get this error:
ERROR] [1672904624.503538, 1251.206000]: Exception in your execute callback: 'move_turtle' object has no attribute 'xOdom'
Traceback (most recent call last):
File "/home/simulations/public_sim_ws/src/all/actionlib/actionlib/src/actionlib/simple_action_server.py", line 289, in executeLoop
self.execute_callback(goal)
File "/home/user/catkin_ws/src/real_robot/scripts/action_server.py", line 51, in callback
print(self.xOdom)
AttributeError: 'move_turtle' object has no attribute 'xOdom'
Here is my code:
#! /usr/bin/env python
from math import degrees, sqrt
import rospy
import actionlib
import numpy as np
from real_robot.msg import OdomRecordAction, OdomRecordResult, OdomRecordFeedback
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Point32
from tf.transformations import euler_from_quaternion
odom_record_data=Point32()
class move_turtle(object):
# create messages that are used to publish feedback and results
_result = OdomRecordResult()
_feedback = OdomRecordFeedback()
def __init__(self):
# creates the action server
self._as = actionlib.SimpleActionServer("record_odom", OdomRecordAction, self.callback, False)
self._as.start()
self.ctrl_c = False
self.rate = rospy.Rate(1)
self.subodom = rospy.Subscriber('/odom', Odometry, self.call_record_odom)
def call_record_odom(self,data):
self.xOdom = data.pose.pose.position.x
self.yOdom = data.pose.pose.position.y
self.thOdom = data.pose.pose.orientation.z
def callback(self,goal):
rospy.loginfo("executing odometry record")
i=0
distance = 0
dist_x = np.array((1, ), dtype = float)
dist_y = np.array((1, ), dtype = float)
orient_z = np.array((1, ), dtype = float)
lap=100
flag=False
while distance<=lap:
#calc traveled distance
print(self.xOdom)
dist_x= np.append(dist_x,self.xOdom)
dist_y = np.append(dist_y,self.yOdom)
orient_z = np.append(orient_z,self.thOdom)
distance += sqrt( pow(dist_x[i] - dist_x[i-1], 2 ) + ( dist_y[i] - dist_y[i-1] )**2 )
print("travelled distance:", distance)
print(dist_x)
# check that preempt (cancelation) has not been requested by the action client
if self._as.is_preempt_requested():
rospy.loginfo('The goal has been cancelled/preempted')
# the following line, sets the client in preempted state (goal cancelled)
self._as.set_preempted()
# build and publish the feedback message
self._feedback.current_total = distance
self._as.publish_feedback(self._feedback)
# the sequence is computed at 1 Hz frequency
self.rate.sleep()
flag=True
i+=i
if flag is True:
self._result.list_of_odoms.x = dist_x
self._result.list_of_odoms.y = dist_y
self._result.list_of_odoms.z = orient_z
self._as.set_succeeded(self._result.list_of_odoms)
rospy.loginfo("Returning odometry values")
if __name__ == '__main__':
rospy.init_node('Odom_record_node')
move_turtle()
rospy.spin()
I dont understand whats the error telling me.
I would like to know first whats the meaning of the error.
second, I would like to append the xOdom data into the dist_x variable for each sensor reading.
The error is because your action is being called before your subscriber. This is because the subscriber is what actually creates the attribute that gets used in the action callback. If you have someone publish on the topic before the action is called the code will work fine. However, you should instead make sure your odom attributes are initialized in __init__
and before you set up a subscriber or action callback like so:
def __init__(self):
# creates the action server
self.xOdom = None
self.yOdom = None
self.thOdom = None
self._as = actionlib.SimpleActionServer("record_odom", OdomRecordAction, self.callback, False)
self._as.start()
self.ctrl_c = False
self.rate = rospy.Rate(1)
self.subodom = rospy.Subscriber('/odom', Odometry, self.call_record_odom)
Then you may have to check that the values are initialized before using them.