# goal status in Callback in actionserver in C++

Hi all, My client sends the goal but gets status ABORTED instead of SUCCEEDED and server gives following error:

[ WARN] [1337607518.317686823]: Your executeCallback did not set the goal to a terminal status. This is a bug in your ActionServer implementation. Fix your code! For now, the ActionServer will set this goal to aborted


My callback is

void startnode(const my_msgs::myGoalConstPtr& goal, Server* as)
{
my_msgs::myResult result_;
result_.result = 1;
as->setSucceeded(result_);
}


Can anyone help me fix this problem?? Thanks in advance. Regards

edit retag close merge delete

1

Hi, I know this is an old post. But i have your same problem. Did you solve it?? I have been trying to solve by myself for a week with no dice!!! Could you help me??? Thanks

( 2014-07-31 08:58:09 -0500 )edit
1

Hi, I am having the same issue, do you have a lead?

( 2016-03-16 10:48:19 -0500 )edit

This unanswered thread was closed due to 'off-topic or outdated', but I find the same error can still happen today and no other threads discuss this error. So I reopened it.

( 2016-12-01 18:47:42 -0500 )edit

Sort by » oldest newest most voted

As pointed out by the error message, fix the termination state in your Action Server. In rospy sample, not calling set_succeeded can lead to the error in this question. OP asks for C++ but I haven't tried, so I can only assume that the equivalent is setSucceeded.

more

I to got this error when I didn't use the function .set_preempted() in .is_preempt_requested() function. I can see that your code have no function during preempt is requested(i.e., goal is cancelled) and I hope this might be the error. my error got resolved, when I used .set_preemted() function in server code whenever preemted. and it resolved my error. hope this helps you. Thanks.

more

Hi here I leave a simple example that you can run in any robot with an odom topic that it might clear up some doubts on how this works. Basically that error appears when the result is not correctly set up in the setSucceeded method.

Here you have the GIT

Here you have the ROSJECT

Here you have a Video explaining how to launch it and the basic ideas behind this: VIDEO

And here the main elements of code for those that preffer having it here in the Forum, hope it helps:

MonitorDistance.cpp

#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include <std_msgs/Empty.h>
#include <nav_msgs/Odometry.h>
#include <math.h>
#include <action_status_cpp_qanda/ActOdomAction.h>

class ActOdomTurtle {
public:

int hz;
float time_to_make_distance; //duration
bool action_active;
float x;
float y;
bool finish;
float distance_to_make;
float hypt;

ros::NodeHandle nh;
nav_msgs::Odometry *odom_hold; // I need this shi to hold my nav_msgs/Odom I DONT THINK I DID THIS RIGHT
ros::Rate *rate_;
actionlib::SimpleActionServer<action_status_cpp_qanda::ActOdomAction> as_; // i might wanna rename this later
std::string action_name_; // i need to input this for the action name;
action_status_cpp_qanda::ActOdomResult result_; //basically in the msg these r the thing im returning

nav_msgs::Odometry latest_odometry;

ActOdomTurtle(std::string name):
as_(nh, name, boost::bind(&ActOdomTurtle::executeCB, this, _1), false),
action_name_(name)
{
ROS_INFO("Inside ActOdomTurtle Action Init...");

this->hz = 20;
this->distance_to_make = 3;
this->time_to_make_distance = 100;

this->action_active = false;
this->finish = false;

rate_= new ros::Rate(this->hz);

as_.start();

ROS_INFO("Inside ActOdomTurtle Action Init...END");

}

void executeCB(const action_status_cpp_qanda::ActOdomGoalConstPtr &gg){

ROS_INFO("Action has been called...Time Starts Counting to get out of the maze");
this->action_active = true;

while (this->time_to_make_distance > 0 && this->finish == false ){

if (as_.isPreemptRequested() || !ros::ok()){
ROS_INFO("%s: Preempted", action_name_.c_str());
as_.setPreempted();
break;
}

this->finish = this->are_we_out_of_maze();

time_to_make_distance -= 1/(float)hz;
this->rate_->sleep();
ROS_INFO("the time left is %f", time_to_make_distance);
}

// If we finished because we got out of the maze, then its a success.
if(this->finish) {
ROS_INFO("%s: Succeeded", action_name_.c_str());
as_.setSucceeded(result_);
}else
{
ROS_INFO("%s: Aborted", action_name_.c_str());
//set the action state to aborted
as_.setAborted(result_);
}

this->action_active = false;
}

void giveOdomMod(const nav_msgs::Odometry::ConstPtr &_msg){
/***
* We Fetch the latest odometry data and save it in a vector
*
* **/

this->latest_odometry.child_frame_id = _msg->child_frame_id;
this->latest_odometry.pose = _msg->pose;

if (this->action_active)
{
this->result_.result_odom_array.push_back(this->latest_odometry);
}

}

bool are_we_out_of_maze()
{
bool result = false;

// This is a security mesure to guarantee that the saved element in the vector is
// what we use for calculating.
if (!this->result_.result_odom_array.empty())
{
nav_msgs::Odometry last_odom = this->result_.result_odom_array.back();
float last_x = last_odom.pose.pose.position.x;
float last_y = last_odom.pose.pose.position.y;

float hypt = sqrt(pow(last_x,2)+pow(last_y,2));
// Because the robot starts at the origin we dont have to save the init position
// To then compare with the latest.
if (hypt >= this->distance_to_make ){
ROS_WARN("SUCCESS Distance ...
more