Ask Your Question
1

Subscriber and publisher in the same node not working with costum msg

asked 2014-10-19 09:14:34 -0600

RSA_kustar gravatar image

updated 2014-10-19 09:24:43 -0600

Hello,

I know that this question might be asked before, but I did not find the final solution for it. Here is the question:

I want to write a node that subscribe for data from a topic then publish these data to another topic. So, mainly I want a publisher and subscriber in the same node. So What I did so far is the following:

#include "ros/ros.h"
#include <geometry_msgs/Twist.h>
#include "pctx_control/Control.h"
#include "std_msgs/String.h"
#include "pctx_control/pctx.h" 
#include <sstream>


pctx_control::Control controlmsg ;

void function_callback (const geometry_msgs::Twist &msg) 
 {

controlmsg.ch = 0 ;
controlmsg.values[0] = msg.linear.x;
controlmsg.values[1] = msg.linear.y;
controlmsg.values[2] = msg.linear.z;
std::cout << "d1"<<controlmsg.values[0] << std::endl ;
std::cout << "d2" <<controlmsg.values[1]<< std::endl ;
std::cout << "d3" <<controlmsg.values[2]<< std::endl ;

}

int main(int argc, char **argv)
{

 ros::init(argc, argv, "my_node");
  ros::NodeHandle n;
 ros::Publisher pub = n.advertise<pctx_control::Control>("topic2", 100);

  ros::Subscriber sub = n.subscribe("topic1", 1000, function_callback);

 ros::Rate loop_rate(10);
 ros::spinOnce();

 int count = 0;
 while (ros::ok())
  {

    pub.publish(controlmsg);

  ros::spin();
  loop_rate.sleep();

 }

return 0;
 }

I want to save data that I want to publish in a "custom msg" pctx_control::Control type;

This msg has the following format:

int32 ch
int32 value
int16[] values
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
3

answered 2014-10-19 10:57:30 -0600

kmhallen gravatar image

updated 2014-10-20 09:08:24 -0600

If you make the publisher global, you can publish as soon as the message is received in function_callback(). Then the while() loop can be replaced with just ros::spin();

#include "ros/ros.h"
#include <geometry_msgs/Twist.h>
#include "pctx_control/Control.h"
#include "std_msgs/String.h"
#include "pctx_control/pctx.h" 
#include <sstream>

ros::Publisher pub;
pctx_control::Control controlmsg;

void function_callback (const geometry_msgs::Twist &msg) 
{
  controlmsg.ch = 0;
  controlmsg.values.resize(3);
  controlmsg.values[0] = msg.linear.x;
  controlmsg.values[1] = msg.linear.y;
  controlmsg.values[2] = msg.linear.z;
  pub.publish(controlmsg);
  std::cout << "d1" << controlmsg.values[0] << std::endl;
  std::cout << "d2" << controlmsg.values[1] << std::endl;
  std::cout << "d3" << controlmsg.values[2] << std::endl;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "my_node");
  ros::NodeHandle n;

  pub = n.advertise<pctx_control::Control>("topic2", 100);

  ros::Subscriber sub = n.subscribe("topic1", 1000, function_callback);

  // Handle ROS callbacks until shutdown
  ros::spin();

  return 0;
}

Edit: Changed vector indexing to push_back()
Edit: Changed vector indexing back to brackets, and reinitialize with resize() every iteration per comment from @dornhege

edit flag offensive delete link more

Comments

@kmhallen
I did what you said, I got an error said Segmentation fault (core dumped) .

RSA_kustar gravatar imageRSA_kustar ( 2014-10-20 02:27:35 -0600 )edit

I was tracing the problem it give me this error after this line of code

controlmsg.values[0] = msg.linear.x;

I maigh be filling this one in the wrong way.. what should I do ?? can you check the message type, please.

RSA_kustar gravatar imageRSA_kustar ( 2014-10-20 02:42:46 -0600 )edit

I knew how to fill it using push_pack().. Thanks for your help

RSA_kustar gravatar imageRSA_kustar ( 2014-10-20 04:13:55 -0600 )edit
1

Careful, this code is buggy. You must clear the values in the controlmsg every time before publishing or mvoe that to a local variable.

dornhege gravatar imagedornhege ( 2014-10-20 08:58:35 -0600 )edit
0

answered 2014-10-19 10:33:01 -0600

kramer gravatar image

You definitely want to change that ros.spin() within the loop to ros.spinOnce().

edit flag offensive delete link more

Comments

Just to expand on this, ros::spin() blocks until your node is stopped, so the remainder of your loop will never execute.

ahendrix gravatar imageahendrix ( 2014-10-19 12:06:37 -0600 )edit

@kramer & @ahendrix it runs but when I try rostopic echo /topic2 I get the following data..

 channel: 0
 value: 0  
 values: []

It does not fill the topic with the data from topic 1

RSA_kustar gravatar imageRSA_kustar ( 2014-10-20 02:17:25 -0600 )edit

The C++ IDL defines values as a std::vector; this means that it starts at size 0, and you have to use resize() or push_back() if you want to add elements to it.

ahendrix gravatar imageahendrix ( 2014-10-20 02:43:37 -0600 )edit

yes I used push_back and it worked.. Thank you..

RSA_kustar gravatar imageRSA_kustar ( 2014-10-20 04:14:53 -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

1 follower

Stats

Asked: 2014-10-19 09:14:34 -0600

Seen: 655 times

Last updated: Oct 20 '14