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

How to call callback at a specific period?

asked 2016-03-14 22:36:34 -0500

Thang Nguyen gravatar image

updated 2016-03-15 00:16:38 -0500

ahendrix gravatar image

I start learning ROS and these are my practice for subscribe callback. If my question is not clear, please let me know. I write a program to move robot for a certain distance and turn a certain angle. I have this part working. Beside that I would like to print out current information of robot before movement and after movement. I tried with two methods but none of them works.

#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "turtlesim/Pose.h"
//#include "ros/callback_queue.h"

//to print current position
void poseCallback(const turtlesim::Pose& msg)
{
    ROS_INFO_STREAM("Current Position: " << msg.x << ", " << msg.y << ", Direction: " << msg.theta);
}

int main(int argc, char **argv){
    const double FORWARD_SPEED_MPS = 0.1;
    const double PI = 3.14159265358979323846;
    const double TURN_SPEED_RPS = PI/20;
    ros::init(argc, argv, "move_turtle");
        ros::NodeHandle node;
    ros::Publisher pub = node.advertise<geometry_msgs::Twist>("turtle1/cmd_vel",10);
    ros::Subscriber sub = node.subscribe("turtle1/pose",10,poseCallback);

     geometry_msgs::Twist msg;
    //ros::CallbackQueue my_queue;
    //my_queue.callOne();
    ros::spinOnce();

    ros::Time start_time = ros::Time::now();

    //Go straight 1m
     ros::Rate rate(10);
     while(ros::ok() && ros::Time::now() - start_time < ros::Duration(10)){
                               msg.linear.x = FORWARD_SPEED_MPS;
        pub.publish(msg);
        rate.sleep();
    }
    msg.linear.x = 0;
    start_time = ros::Time::now();
    //Turn 45deg
    while(ros::ok() && ros::Time::now() - start_time < ros::Duration(5)){
                                   msg.angular.z = TURN_SPEED_RPS;
        pub.publish(msg);
        rate.sleep();   
    }
    msg.angular.z = 0;
    //my_queue.callOne();
    ros::spinOnce();
}
  • 1st: I call spinOnce before and after while loop for moving and turning. With this it prints out a hole queue which includes 10 elements of pose information of robot before it move. But these information is printed out after it move.There is no pose information after robot move) Below is how it looks. Angle is start from 45deg so it has value 1.68.

    viki@c3po:~/Documents/Workspace_IntroToRobotics$ rosrun turtle_move_package move_turtle [ INFO] [1458011783.446882695]: Current Position: 7.08517, 6.3085, Direction: 1.68138 [ INFO] [1458011783.447260117]: Current Position: 7.08517, 6.3085, Direction: 1.68389 [ INFO] [1458011783.447343927]: Current Position: 7.08517, 6.3085, Direction: 1.68641 [ INFO] [1458011783.447429971]: Current Position: 7.08517, 6.3085, Direction: 1.68892 [ INFO] [1458011783.447564346]: Current Position: 7.08517, 6.3085, Direction: 1.69143 [ INFO] [1458011783.447654022]: Current Position: 7.08517, 6.3085, Direction: 1.69395 [ INFO] [1458011783.447737273]: Current Position: 7.08517, 6.3085, Direction: 1.69646 [ INFO] [1458011783.447841755]: Current Position: 7.08517, 6.3085, Direction: 1.69897 [ INFO] [1458011783.447923889]: Current Position: 7.08517, 6.3085, Direction: 1.70149 [ INFO] [1458011783.447927520]: Current Position: 7.08517, 6.3085, Direction: 1.704

  • 2nd: I tried to use callOne but it doesn't do anything. I comment it out in my above code.

Thank you for your time reading and answering my question.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2016-03-15 02:03:47 -0500

updated 2016-03-15 09:09:29 -0500

Everytime spinOnce() is called, callbacks in the queue are processed. If you put a spinOnce() call into your while loops, things should thus work as you expect. Note that this is ok for a toy example, but generally this kind of open loop motion will be highly inaccurate.

/edit: No, you should not use callOne(). You can add spinOnce() in each of your two while loops however and it should work.

edit flag offensive delete link more

Comments

@Stefan: Thanks for your answer.

Based on your answer, I should use callOne instead of spinOnce. Am I correct? but why when I use spinOnce, it didn't see any print out on terminal. You can still see callOne in the comment out line in my code. Could you please tell me why it didn't work?

Regarding

Thang Nguyen gravatar image Thang Nguyen  ( 2016-03-15 09:50:47 -0500 )edit

I only want to print 2 lines, like below example. I don't want to print out every loop interval.

// Start run

Current Position: 0, 0, Direction: 0

//Robot move in turtlesim

Current Position: 1, 0, Direction: 1.68641

Please tell me how to make this sequence happens. Thanks

Thang Nguyen gravatar image Thang Nguyen  ( 2016-03-15 09:55:13 -0500 )edit

In that case you can write the pose to a member (or in this case, public) variable in the callback and then print out the info message spitting out data from the variable after your loops.

Stefan Kohlbrecher gravatar image Stefan Kohlbrecher  ( 2016-03-15 11:12:29 -0500 )edit

Thanks Stefan, I will try to implement what you say. I believe this solves my problem.

Thang Nguyen gravatar image Thang Nguyen  ( 2016-03-15 12:08:10 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2016-03-14 22:36:34 -0500

Seen: 924 times

Last updated: Mar 15 '16