我正在努力使一个动作服务器,我必须使用订阅里程计数据在动作回调中使用它。我设法获得姿势数据,我知道它是好的,因为我已经在订阅者回调中打印了它。我的问题是,当我想在外面使用这个数据时,我得到这个错误:
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'
下面是我的代码:
#! /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()
我不明白错误告诉我什么。
我想先知道这个错误是什么意思。
其次,我想将xdom数据附加到每个传感器读取的dist_x变量中。
此错误是因为您的操作在订阅者之前被调用。这是因为订阅者实际创建了在动作回调中使用的属性。如果有人在操作之前发布主题,则代码将正常工作。但是,您应该确保在之前在__init__
和中初始化您的odom属性。您像这样设置订阅者或操作回调:
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)
那么,在使用这些值之前,您可能必须检查它们是否已初始化。
AttributeError: 'move_turtle'对象没有属性'xOdom'
表示你试图引用move_turtle对象的属性xOdom,但该对象没有该属性。
第51行是
print(self.xOdom)
,它实际上是在引用xdom属性。
你的xOdom属性仅由call_record_odom方法设置,所以看起来该方法不能正常工作或根本没有被调用。
事实上,move_turtle()
并不是一个真正的函数调用(move_turtle是一个类)。
它创建了move_turtle类的一个实例,换句话说就是一个对象。
这会触发__init__(self)
方法,它调用call_record_odom和callback,但是顺序错误。
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)
注意callback
(需要xOdom
)是如何在call_record_odom
(设置xOdom
)之前调用的?这就是为什么它不起作用。当代码到达callback
方法(及其打印)时,xOdom
还没有定义,当您尝试打印它时,它返回AttributeError,因为确实,move_turtle
对象没有属性xOdom
。