0
$\begingroup$

Rosanswers logo

The below code works for sometime before giving a segmentation fault. I have been looking at some of the answers on the page but haven't been able to solve this issue. I am using the following code as a plugin and then running the code using rosrun. Changing the rate does not seem to improve the situation as well.
There are two other class definitions that are used, both of them do not crash, but the below code crashes after a few minutes of running.
Any suggestions on what to change in the code or logical errors would be helpful!

#ifndef FUNCTIONBLOCKS_FUNCTION_ASSETS_H_
#define FUNCTIONBLOCKS_FUNCTION_ASSETS_H_

#include <ros/ros.h>
#include "functionblocks/functionBlock.h"
#include "functionblocks/sensor.h"
#include "functionblocks/actuator.h"
#include <unistd.h>

namespace function_assets {

class SubscribeAndPublish_fb {
public:
  SubscribeAndPublish_fb() {
    // Topic you want to publish
    pub_ = n_.advertise<functionblocks::functionBlock>("functionBlocks", 1000);

    // Topic you want to subscribe
    publish();
    sub_ =
        n_.subscribe("sensors", 1000, &SubscribeAndPublish_fb::callback, this);
    ros::spin();
  }

  void callback(const functionblocks::sensor::ConstPtr &input) {
    ROS_INFO("sensor state : %d", input->state);
    ROS_INFO("sensor name : %s", input->name.c_str());
    if (!input->name.empty()) {
      msg1.sensor.push_back(input->name.c_str());
    }
    ROS_INFO("sensor id : %d", input->id);
    ROS_INFO("sensor memory : %ld", (long int)input->memory);
    msg1.spare = msg1.spare - input->memory;
    // ros::Rate loop_rate(10);
    while (ros::ok()) {
      pub_.publish(msg1);
      msg1.spare = mem;
      ros::spinOnce(); // done to handle callbacks
      // loop_rate.sleep(); //sleep till the time is done --10
    }
  }

  void publish() {
    std::cout << "Enter block name:";
    std::cin >> block_n;
    std::cout << "Enter block memory:";
    std::cin >> mem;
    std::cout << "Enter block handling:";
    std::cin >> handling;
    msg1.block_n = block_n;
    msg1.spare = mem;
    msg1.memory = mem;
    msg1.handling = handling;
  }

private:
  ros::NodeHandle n_;
  ros::Publisher pub_;
  ros::Subscriber sub_;
  functionblocks::functionBlock msg1;
  long int mem;
  std::string block_n;
  int handling;

}; // End of class SubscribeAndPublish

};

#endif here

Originally posted by ashwath1993 on ROS Answers with karma: 70 on 2017-01-23

Post score: 0


Original comments

Comment by gvdhoorn on 2017-01-23:
Without looking at the rest of your code (or trying to figure out what is causing the SEGFAULT): I see a while(ros::ok()) in your Subcriber callback and ros::spin() in your constructor.

Both of those cannot work properly. I'd advise you to remove them and restructure your program.

Comment by ashwath1993 on 2017-01-24:
I am fairly new to ROS, I am using those from the tutorials. What can I do to replace them? I have a similar structure in the other codes as well. Thanks!

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

The tutorial (this one probably?) doesn't put an infinite while in a constructor, nor in a callback. Callbacks should be short, deal with the msg. Not run an eventloop of their own.

You're also running an eventloop (while (ros::ok()) { ros::spinOnce() }) inside another eventloop (ros::spin() in your callback). You want to study carefully what the tutorial does. Note where ros::spin() is called.

If you want to use a class, instantiate it in a main and run your eventloop in the main.


Originally posted by gvdhoorn with karma: 86574 on 2017-01-24

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by ashwath1993 on 2017-01-25:
Thank you, it worked. I just added a ros::spin() in the main instead of inside the class definition. You can post that so I can mark it as the answer!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.