ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange |
1 | initial version |
Ok, I found a solution to the problem. AsyncSpinner work for this as well. The AsyncSpinner needs its custom queue and needs to be started before and stopped after a while loop, which waits for the timer. So to use the example above:
class Foo {
finished_;
ros::CallbackQueue* queue_;
ros::NodeHandle nh_;
ros::Timer timer_;
Foo(ros::NodeHandle* nh, ros::CallbackQueue* queue) : queue_(queue), nh_(nh){
ros::TimerOptions timer_options(ros::Duration(0.1), &timerCB, queue_);
timer_ = nh_->createTimer(timer_options);
finished_ = false;
ros::SubscribeOptions subscriber_options = ros::SubscribeOptions::create<custom_msgs::Msg>(
"example/topic", 1, &secondCB, ros::VoidPtr(), queue_);
}
void startTimer(){
timer_.start();
}
void timerCB(const ros::TimerEvent& timer_event){
//Do something depending on state and stop timer if finished
if(finishing_condition_met){
timer_.stop();
finished_ = true;
}
void secondCB(const custom_msg::Msg msg){
//Change state if necessary
}
}
class Bar {
ros::CallbackQueue queue_;
ros::NodeHandle* nh_;
Foo* foo;
ros::AsyncSpinner* async_spinner_;
Bar bar(ros::NodeHandle* nh) : nh_(nh){
foo = new Foo(nh_, &queue_);
async_spinner_ = new ros::AsyncSpinner(4, &state_queue_);
}
executeCB(const actionlib_msgs::ExampleGoalConstPtr& goal){
foo = new Foo(nh_, &queue_);
async_spinner->start();
foo.startTimer();
while(ros::ok() && !foo->finished_{
//Wait for Foo to finish
}
async_spinner->stop();
return true;
}
}
I hope it helps someone out there and I would really love to hear from you guys, if there is a better way to do it! Btw, this is just an example so please don't hang yourself up on small mistakes, it's not exactly the way I implemented it. If you find mistakes however, please let me know, I will change them, so maybe someone else doesn't need to fight his/ her way through my wrong code ;)
2 | No.2 Revision |
Ok, I found a solution to the problem. AsyncSpinner work for this as well. The AsyncSpinner needs its custom queue and needs to be started before and stopped after a while loop, which waits for the timer. So to use the example above:
class Foo {
finished_;
ros::CallbackQueue* queue_;
ros::NodeHandle nh_;
ros::Timer timer_;
Foo(ros::NodeHandle* nh, ros::CallbackQueue* queue) : queue_(queue), nh_(nh){
ros::TimerOptions timer_options(ros::Duration(0.1), &timerCB, queue_);
timer_ = nh_->createTimer(timer_options);
finished_ = false;
ros::SubscribeOptions subscriber_options = ros::SubscribeOptions::create<custom_msgs::Msg>(
"example/topic", 1, &secondCB, ros::VoidPtr(), queue_);
}
void startTimer(){
timer_.start();
}
void timerCB(const ros::TimerEvent& timer_event){
//Do something depending on state and stop timer if finished
if(finishing_condition_met){
timer_.stop();
finished_ = true;
}
}
void secondCB(const custom_msg::Msg msg){
//Change state if necessary
}
}
class Bar {
ros::CallbackQueue queue_;
ros::NodeHandle* nh_;
Foo* foo;
ros::AsyncSpinner* async_spinner_;
Bar bar(ros::NodeHandle* nh) : nh_(nh){
foo = new Foo(nh_, &queue_);
async_spinner_ = new ros::AsyncSpinner(4, &state_queue_);
}
executeCB(const actionlib_msgs::ExampleGoalConstPtr& goal){
foo = new Foo(nh_, &queue_);
async_spinner->start();
foo.startTimer();
while(ros::ok() && !foo->finished_{
//Wait for Foo to finish
}
async_spinner->stop();
return true;
}
}
I hope it helps someone out there and I would really love to hear from you guys, if there is a better way to do it! Btw, this is just an example so please don't hang yourself up on small mistakes, it's not exactly the way I implemented it. If you find mistakes however, please let me know, I will change them, so maybe someone else doesn't need to fight his/ her way through my wrong code ;)
3 | No.3 Revision |
Ok, I found a solution to the problem. AsyncSpinner work for this as well. The AsyncSpinner needs its custom queue and needs to be started before and stopped after a while loop, which waits for the timer. So to use the example above:
class Foo {
finished_;
ros::CallbackQueue* queue_;
ros::NodeHandle nh_;
ros::Timer timer_;
Foo(ros::NodeHandle* nh, ros::CallbackQueue* queue) : queue_(queue), nh_(nh){
ros::TimerOptions timer_options(ros::Duration(0.1), &timerCB, queue_);
timer_ = nh_->createTimer(timer_options);
finished_ = false;
ros::SubscribeOptions subscriber_options = ros::SubscribeOptions::create<custom_msgs::Msg>(
"example/topic", ros::SubscribeOptions::create<custom_msgs::Msg>
("example/topic", 1, &secondCB, ros::VoidPtr(), queue_);
}
void startTimer(){
timer_.start();
}
void timerCB(const ros::TimerEvent& timer_event){
//Do something depending on state and stop timer if finished
if(finishing_condition_met){
timer_.stop();
finished_ = true;
}
}
void secondCB(const custom_msg::Msg msg){
//Change state if necessary
}
}
class Bar {
ros::CallbackQueue queue_;
ros::NodeHandle* nh_;
Foo* foo;
ros::AsyncSpinner* async_spinner_;
Bar bar(ros::NodeHandle* nh) : nh_(nh){
foo = new Foo(nh_, &queue_);
async_spinner_ = new ros::AsyncSpinner(4, &state_queue_);
}
executeCB(const actionlib_msgs::ExampleGoalConstPtr& goal){
foo = new Foo(nh_, &queue_);
async_spinner->start();
foo.startTimer();
while(ros::ok() && !foo->finished_{
//Wait for Foo to finish
}
async_spinner->stop();
return true;
}
}
I hope it helps someone out there and I would really love to hear from you guys, if there is a better way to do it! Btw, this is just an example so please don't hang yourself up on small mistakes, it's not exactly the way I implemented it. If you find mistakes however, please let me know, I will change them, so maybe someone else doesn't need to fight his/ her way through my wrong code ;)