Hi, i was wondering how to create ros action client with feedback and active Cbs using classes.
I have successfully to create ros action client with feedback and active Callbacks without using classes.
But i want to create the code using classes. There’s tutorial on actionlib wiki ros using boost:bind. But there’s only doneCb on the tutorials. Can you guys help me?
Thanks in advance
on actionlib wiki ros:
ac.sendGoal(goal,
boost::bind(&MyNode::doneCb, this, _1, _2),
Client::SimpleActiveCallback(),
Client::SimpleFeedbackCallback());
1 Like
Hi, can you give us a little more context on your question? Can you share the code you want to convert to a class structure?
Hi, I have the same question as @xbillynugraha.
I think it’s just about how to append a custom function in the sendgoal call.
In other words, what must Client::SimpleActiveCallback()
and Client::SimpleFeedbackCallback()
be replaced with?
And how to define which parameters are passed to the activeCb or feedbackCb function?
Here is my minimal example that does not work:
#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib_tutorials/FibonacciAction.h>
using namespace actionlib_tutorials;
typedef actionlib::SimpleActionClient<FibonacciAction> Client;
class MyNode
{
public:
MyNode() : ac("fibonacci", true)
{
ROS_INFO("Waiting for action server to start.");
ac.waitForServer();
ROS_INFO("Action server started, sending goal.");
}
void doStuff(int order)
{
FibonacciGoal goal;
goal.order = order;
ac.sendGoal(goal,
boost::bind(&MyNode::doneCb, this, _1, _2),
boost::bind(&MyNode::activeCb, this, _1, _2),
boost::bind(&MyNode::feedbackCb, this, _1, _2));
}
void doneCb(const actionlib::SimpleClientGoalState& state,
const FibonacciResultConstPtr& result)
{
ROS_INFO("Finished in state [%s]", state.toString().c_str());
ROS_INFO("Answer: %i", result->sequence.back());
ros::shutdown();
}
void activeCb()
{
ROS_INFO("Goal just went active");
}
void feedbackCb(const FibonacciFeedbackConstPtr& feedback)
{
ROS_INFO("Got Feedback of length %lu", feedback->sequence.size());
}
private:
Client ac;
};
int main (int argc, char **argv)
{
ros::init(argc, argv, "test_fibonacci_class_client");
MyNode my_node;
my_node.doStuff(10);
ros::spin();
return 0;
}
Hi,
I just figured it out myself. This should work:
#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib_tutorials/FibonacciAction.h>
using namespace actionlib_tutorials;
typedef actionlib::SimpleActionClient<FibonacciAction> Client;
class MyNode
{
public:
MyNode() : ac("fibonacci", true)
{
ROS_INFO("Waiting for action server to start.");
ac.waitForServer();
ROS_INFO("Action server started, sending goal.");
}
void doStuff(int order)
{
FibonacciGoal goal;
goal.order = order;
ac.sendGoal(goal,
boost::bind(&MyNode::doneCb, this, _1, _2),
boost::bind(&MyNode::activeCb, this),
boost::bind(&MyNode::feedbackCb, this, _1));
}
void doneCb(const actionlib::SimpleClientGoalState& state,
const FibonacciResultConstPtr& result)
{
ROS_INFO("Finished in state [%s]", state.toString().c_str());
ROS_INFO("Answer: %i", result->sequence.back());
ros::shutdown();
}
void activeCb()
{
ROS_INFO("Goal just went active");
}
void feedbackCb(const FibonacciFeedbackConstPtr& feedback)
{
ROS_INFO("Got Feedback of length %lu", feedback->sequence.size());
}
private:
Client ac;
};
int main (int argc, char **argv)
{
ros::init(argc, argv, "test_fibonacci_class_client");
MyNode my_node;
my_node.doStuff(10);
ros::spin();
return 0;
}
1 Like
I am trying to do something similar but in python but no tutorials exist in python. I have the following code and my response is as follows. This shows clearly that it never executed the callback_cb function
#! /usr/bin/env python
import rospy
import actionlib
import turtle2.msg
from turtle2.msg import turtlemvmtAction, turtlemvmtGoal, turtlemvmtResult, turtlemvmtFeedback
import rospy
import sensor_msgs.msg
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
from std_msgs.msg import String
class ActionClient():
def init(self, dist):
self. dist = dist
self.sub = rospy.Subscriber(‘/scan’, LaserScan, self.callback)
def callback(self,msg):
dist = (msg.ranges[180])
self.call_server()
print (dist)
def feedback_cb(self,msg1):
print (msg1, "sent")
def call_server(self):
print ("server called")
client = actionlib.SimpleActionClient('sharedspace', turtlemvmtAction)
client.wait_for_server()
goal = turtlemvmtGoal()
goal.ranges = self.dist
client.send_goal(goal, feedback_cb = self.feedback_cb)
client.wait_for_result()
result = client.get_result()
return result
if name == ‘main’:
try:
rospy.init_node(‘action_client’)
j = ActionClient(dist=)
print (‘The result is:’,)
rospy.spin()
except rospy.ROSInterruptException as e:
print (‘Something went wrong:’, e)
output:
The result is:
server called
0.9700070023536682
Any thoughs from those previously involved in the post? Any thoughts from previously amazing moderators @_RM @marco.nc.arruda @duckfrost @u1802520 @bayodesegun ?
Hi, what does turtlemvmtGoal()
contain? I found this implementation of a callback-based actionlib client in python that might help you…
https://answers.ros.org/question/292061/how-do-i-create-a-callback-based-actionlib-client-in-python/?answer=292069#post-id-292069