I am building a single node which subscribes to receive Pose information. The subscriber callback updates class state fields (like self.x). This node also contains an ActionServer, which upon client request, will use the state information (which should be continually updated from the pose subscription) to execute a "move_to." This action repeatedly publishes Twist information on a different topic.
On startup, I can tell that the subscriber is working effectively, and the Node continually updates its pose successfully. However, once the ActionServer execution callback starts, I notice that the subscriber callback is never called, and as a result the pose state is never updated.
I would like to create a Node which can continually receive new state information updates while it executes an action. Is this possible / am I going about this in the correct manner?
Here is an abbreviated (extensive math removed) version of my Node definition:
class ActionSrv(Node):
def __init__(self):
super().__init__('action_srv')
self.action_server = ActionServer(
self,
CustomAction,
'custom_action',
self.move_to_callback)
self.subscription = self.create_subscription(
Pose,
'pose',
self.pose_callback,
10)
self.publisher = self.create_publisher(Twist, 'output', 10)
self.x_dest = 0.0
self.y_dest = 0.0
self.x = 0.0
self.y = 0.0
self.r = 999.99
self.twist = Twist()
def pose_callback(self, pose):
self.get_logger().info('Pose: %s' % (pose))
self.x = pose.x
self.y = pose.y
def move_to_callback(self, goal_handle):
self.get_logger().info('Executing Custom Action...') # once this code begins, fields such as self.x are never updated
self.x_dest = goal_handle.request.x_dest
self.y_dest = goal_handle.request.y_dest
self.r = self.get_distance()
feedback_msg = MoveTo.Feedback()
while self.r > 0.2:
# perform calculations
# publish updates
self.publisher.publish(self.twist)
# give feedback
feedback_msg.x_curr = self.x
feedback_msg.y_curr = self.y
goal_handle.publish_feedback(feedback_msg)
goal_handle.succeed()
result = MoveTo.Result()
result.x_final = self.x
result.y_final = self.y
return result
def main(args=None):
rclpy.init(args=args)
server = ActionSrv()
rclpy.spin(server)
if __name__ == '__main__':
main()
Originally posted by exuberantshark on ROS Answers with karma: 23 on 2020-07-04
Post score: 2