Home > Mobile >  std::thread and ros::ok() do not work in ROS
std::thread and ros::ok() do not work in ROS

Time:07-10

I have a function that is executing by std::thread. I want it works until the user closes the terminal that running roscore by pressing Ctrl C. Because of that I use this inside the thread:

void publish_camera_on_topic(std::vector<Camera> cameras, const std::vector<ros::Publisher> publishers, const int camera_index)
{ 
  
  int frameSize;
  BYTE *imagePtr;

  // frame id
  int frame_id = 0;

  cv_bridge::CvImage img_bridge;
  sensor_msgs::Image img_msg;

  while (ros::ok()) {
    // Grab and display a single image from each camera
    
    imagePtr = cameras[camera_index].getRawImage();

    frameSize = cameras[camera_index].getFrameSize();

    cameras[camera_index].createRGBImage(imagePtr,frameSize);

    unsigned char* pImage = cameras[camera_index].getImage();
    if (NULL != pImage) {

      Mat image(cameras[camera_index].getMatSize(), CV_8UC3, pImage, Mat::AUTO_STEP);

      // release asap
      cameras[camera_index].releaseImage(); 

      //cvtColor(image, image, CV_BGR2RGB,3);

      // publish on ROS topic
      std_msgs::Header header; // empty header
      header.seq = frame_id; // user defined counter
      header.stamp = ros::Time::now(); // time
      img_bridge = cv_bridge::CvImage(header, sensor_msgs::image_encodings::RGB8, image);
      img_bridge.toImageMsg(img_msg); // from cv_bridge to sensor_msgs::Image
      publishers[camera_index].publish(img_msg); // ros::Publisher pub_img = node.advertise<sensor_msgs::Image>("topic", queuesize);

    }

    // increase frame Id
    frame_id = frame_id   1;
  }

  std::cout << "ROS closing for thread of camera " << camera_index << " recieved." << std::endl;

}

Also, I create thread like this:

 // image publisher 
  // for each camera create an publisher
  std::vector<ros::Publisher> publishers;
  for (size_t i = 0; i < cameras.size(); i  ) {
    char topic_name[200];
    sprintf(topic_name, "/lumenera_camera_package/%d", i   1);
    publishers.push_back(nh.advertise<sensor_msgs::Image>(topic_name, 10));
  }
  
  // work with each camera on a seprate thread
  std::vector<std::thread> thread_vector;
  for(size_t i=0; i < cameras.size(); i  ) {
    thread_vector.push_back(std::thread(publish_camera_on_topic, cameras, publishers, i));
  }

  ros::spin();

  std::for_each(thread_vector.begin(), thread_vector.end(), [](std::thread &t){t.join(); });

  for(size_t i=0; i < cameras.size(); i  ) {
    cameras[i].stopStreaming();
  }

  ROS_INFO("Node: [lumenera_camera_node] has been Ended.");

However, when I press Ctrl C in the terminal and stop the roscore, the threads keep running, and the value of ros::ok() does not change.

CodePudding user response:

The problem is solved. The issue is ros::ok() does not check for ROS master. Instead of this line:

while (ros::ok()) { //do sth}

This line should be used:

while (ros::ok() && ros::master::check()) { // do sth}

  • Related