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

[Roscpp] How to subscribe to a topic once ?

asked 2015-12-05 16:41:51 -0500

Chickenman gravatar image

Hi guys

I have a little problem here. I am writing just small code for basic joint moves of my arm manipulator in ros. I want to start with topics some services and work with parameters just to train ROS basics. I already created URDF and model in moveit but for first time a just want to move it easy way and then start with actionlib.

This is my simple code. I setup voltages there and I created publisher which is publishing arms positions and I subscribe to it. This is just Main there are 5 more proceses and one service server for comunication.

I have a problem in case 2 where I want to subscribe for the topic and read positions for one time. I have problem when i use ros::spin() it cannot stop subscribing and when i use ros::spinOnce() it just stay in a loop and never broke it. Can you help me how to read just for once and then jump to loop and wait for another prikaz(comman in english) for case.

Thank you for your time and any ideas.

prikaz is global variable

while(ros::ok() && vyp){

    if (prikaz == 0){
      printf("Prikazy na komunikaciu\n");
      printf("Napatia su vycitane, komunikacia s ramenom prebieha na nodu sa publikuju uhly\n");
      printf("Ak chcete pootocit klbom zadajte prikaz 1 \n");
      printf("Pred pootocenim je rameno odbrzdene a nastavena a spusteny motor\n");
      printf("Po pootoceni sa rameno znova zabrzdi a vypne sa motor\n");
      printf("Hybe sa konstantnou rychlostou co najpomalsie\n");
      printf("Ak chcete vycitat napatia zadajte prikaz dva 2 \n");
      printf("Ak chcete vycitat len polohy zadajte prikaz 3 \n");
      printf("Pre VYPNUTIE ZADAJTE PRIKAZ 5 \n");
      scanf("%d",&prikaz);
      clear();
    }
    printf("!!!!!!!!!!!!!!%d!!!!!!!!!!",prikaz);

    switch(prikaz){
      case 1:{
    break;
      }
      case 2:{
    while (ros::ok() && prikaz){
      ros::Subscriber sub3 = n.subscribe("D3toMain", 1000, arrayCallback); 
      ros::spinOnce();
      ROS_INFO("SOM Taaaaaam");
    }
      }
    break;
      case 3 :{
    ros::param::set("/cit_uhol", false);
    while(ros::ok() && joint.data<5){
      mainToD4_pub.publish(joint);
      joint.data++;
      loop_rate.sleep();
    }
    joint.data=0;
    prikaz=0;
    while(ros::ok()){
      ros::param::set("/cit_uhol", true);
      if(ros::param::has("/cit_uhol"))
        break;
    }
      }
    break;
      case 5:{
    //signal(SIGINT, mySigintHandler);
    //ros::spinOnce();
    vyp=false;
    break;
      }
      default:
    vyp=false;
    break;



    }

  }
  ros::param::set("/cit_uhol", false);
  ros::shutdown();
  return 0;

void arrayCallback(const std_msgs::Float64MultiArray::ConstPtr& array)
{

    int i = 0;
    ROS_INFO("SOM TUUUUUUUUUUUUUUUU");
    for(std::vector<double>::const_iterator it = array->data.begin(); it != array->data.end(); ++it)
    {
        angle[i] = *it;
        ROS_INFO("Uhol klbu %d je: %lf \n ",i+1,angle[i]);
        i++;
    }
    prikaz=0;
    return;
}
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
3

answered 2015-12-06 05:31:12 -0500

gvdhoorn gravatar image

updated 2015-12-06 05:32:14 -0500

Please take a look at ros::topic::waitForMessage(..).

That would allow you to receive a single message without having to manage while loops and variables yourself, but I'm not sure this is really the best way to go about this.

edit flag offensive delete link more

Comments

thank you I will try that too maybe it will be better :).

Chickenman gravatar image Chickenman  ( 2015-12-06 14:45:08 -0500 )edit
0

answered 2015-12-06 04:23:54 -0500

Chickenman gravatar image

updated 2015-12-06 04:26:12 -0500

Ok i found a solution ros subscribe cannot be in the loop too. I created a global variable sub3

ros::Subscriber* sub3;

initialize it in main

sub3 = new ros::Subscriber;

and case looks like this

 case 2:{
          *sub3 = n.subscribe("D3toMain", 100, arrayCallback);  
          while(ros::ok() && prikaz){
          ros::spinOnce();
          }
      break;
      }

and callback function looks like this after one reading I set prikaz = 0 it stops my loop and send me back to menu and then I just for sure use sub3->shutdown(); and I shutdown subscribing. Maybe it could help somenone

void arrayCallback(const std_msgs::Float64MultiArray::ConstPtr& array)
{

    int i = 0;

    for(std::vector<double>::const_iterator it = array->data.begin(); it != array->data.end(); ++it)

    {
        angle[i] = *it;
        ROS_INFO("Uhol klbu %d je: %lf \n ",i+1,angle[i]);
        i++;
    }
    prikaz=0;
    sub3->shutdown(); 
    return;
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-12-05 16:41:51 -0500

Seen: 8,673 times

Last updated: Dec 06 '15