Ask Your Question
0

Use variables in main from callback

asked 2017-01-23 10:55:37 -0600

nikkk gravatar image

I need to use three variables that I subscribe from another topic and use it in the main loop. I know that I can use boost function but I don't understand how to use in my case:


double theta1f;
double theta2f;
double theta3f;

class Listener
{
public:
    void callback(const std_msgs::Float32MultiArray::ConstPtr& msg);
};
void Listener::callback(const std_msgs::Float32MultiArray::ConstPtr& msg)
{
    theta1f = msg->data[0];
    theta2f = msg->data[1];
    theta3f = msg->data[2];
}
int main(int argc, char **argv)
{
    ros::init(argc, argv, "node_joint");
    ros::NodeHandle nh;
    ros::Rate loop_rate(30); 
    Listener listener;
    ros::Subscriber sub = nh.subscribe<std_msgs::float32multiarray>("topic_subscribed", 1, &Listener::callback, &listener);
while (ros::ok())
    {  
      cout  theta1f endl;
      }
    loop_rate.sleep();
    ros::spin();
    return 0;
}

I need to use theta1f in this main (cout is only an example and i know that is missing the <<). How can I do it using boost function? There are other solutions better than this?

Thank you for your answers.

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
1

answered 2017-01-23 11:16:57 -0600

Steven_Daniluk gravatar image

updated 2018-02-18 18:58:00 -0600

Boost does not seem necessary in this case. You can simply declare theta1f, theta2f, and theta3f as properties of your class listener. Since you create a Listener object in main, you would then have access to its properties. Basically, whenever you have a callback function for messages, you will need to use a class to utilize the data from that callback somewhere else. Like this:

class Listener 
{
  public:
    double theta1f;
    double theta2f;
    double theta3f;

    void callback(const std_msgs::Float32MultiArray::ConstPtr& msg);
};

void Listener::callback(const std_msgs::Float32MultiArray::ConstPtr& msg) 
{
    theta1f = msg->data[0];
    theta2f = msg->data[1];
    theta3f = msg->data[2];
}

int main(int argc, char **argv) 
{
    ros::init(argc, argv, "node_joint");
    ros::NodeHandle nh;
    ros::Rate loop_rate(30); 
    Listener listener;
    ros::Subscriber sub = nh.subscribe<std_msgs::float32multiarray>("topic_subscribed", 1, &Listener::callback, &listener);
    while (ros::ok()) 
    {
        ros::spinOnce();
        ROS_INFO("This is theta1f: %.2f", listener.theta1f);
        ROS_INFO("This is theta2f: %.2f", listener.theta2f);
        ROS_INFO("This is theta2f: %.2f", listener.theta2f);
        loop_rate.sleep();
    }

    return 0;
}

Also, in general it is discouraged to use global variables unless absolutely necessary.

edit flag offensive delete link more

Comments

Thank you for the answer. This works without problem.

nikkk gravatar image nikkk  ( 2017-01-23 12:00:33 -0600 )edit

This did not work for me until I deleted loop_rate.sleep(); , ros::spin(); , return 0;. Then I had to add the following lines inside the while loop: ros::spinOnce; , loop_rate.sleep();.

reben gravatar image reben  ( 2018-02-17 22:50:18 -0600 )edit

Yep, you are correct. That's my bad, this is what happens when you write code snippets directly in a comment. I've edited my response to correct that mistake.

Steven_Daniluk gravatar image Steven_Daniluk  ( 2018-02-18 18:59:40 -0600 )edit

I'm a bit confused between the difference of ros::spinOnce() and ros::spin()... Why does calling ros::spinOnce(); inside the while loop does not produce the same result as calling ros::spin() outside the while loop here.

dj95 gravatar image dj95  ( 2020-02-17 16:59:14 -0600 )edit
0

answered 2018-01-16 05:00:35 -0600

Lauran gravatar image

updated 2018-01-16 05:03:58 -0600

Hello, I am having the same issue. I have tried to use the code of Jan and implement it in my situation. When I want to display my variable in the terminal it says it's 0.00. Which it shouldn't be. In a different code I was able to see that my variable "x" was send properly so I think the problem isn't in the sending part. Now I want to use my variable in my main. This is my code:

using namespace std;
class MoveRobot {
    public:
        double x;
        double y;
        double z;
        double roll;
        double pitch;
        double yaw;
        double a;
        void PublishCoordinatesCallback(const ur5_inf3480::Coor msg);
};

void MoveRobot::PublishCoordinatesCallback(const ur5_inf3480::Coor msg) {
    x = msg.x;
    y = msg.y;
    z = msg.z;
    roll = msg.roll;
    pitch = msg.pitch;
    yaw = msg.yaw;
    a = msg.a;
}

int main(int argc, char **argv) {
    ros::init(argc, argv, "coordinates");
    ros::NodeHandle nh;
    ros::Rate loop_rate(30);
    MoveRobot moverobot;
    ros::Subscriber sub = nh.subscribe<ur5_inf3480::Coor>("topic_subscribed", 1, &MoveRobot::PublishCoordinatesCallback, &moverobot);
    while (ros::ok())
    {
        ROS_INFO("This is x: %.2f", moverobot.x);
    }
    loop_rate.sleep();
    ros::spin();
    return 0;
}

Thank you for your help!

edit flag offensive delete link more

Comments

Please don't use an answer to ask a question. Please create a new question and reference this one if needed. This isn't a forum.

jayess gravatar image jayess  ( 2018-01-16 10:38:31 -0600 )edit

Okay, I wasn't sure if I had to start a new question. Thank you

Lauran gravatar image Lauran  ( 2018-01-16 16:56:34 -0600 )edit

Yes, answers are for answering questions and questions are for asking questions.

jayess gravatar image jayess  ( 2018-01-16 16:58:04 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2017-01-23 10:55:37 -0600

Seen: 5,143 times

Last updated: Feb 18 '18