ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 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 ;)

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 ;)

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 ;)