0
$\begingroup$

Rosanswers logo

I have a class that has a member variable which is an object of another class

class SuperScanner {
     public:
      SuperScanner(ros::NodeHandle& nh, std::string cameraIP); 
       // Other functions
     private:
      Motor _motor;
      Camera _camera;
     // Other variables and functions
.....
}

Within a function in the SuperScanner class, I'm creating a new thread that invokes image acquisition and then starts the motor motion. The camera needs to start recording before the motion starts, but must continue for a certain duration of time while the motor still moves.To do this, I'm using boost threads.

SuperScanner::getData() {
  boost::function<void()> scanFunc = boost::bind(&Camera::startAcquiring, _camera, scanTime, 
  boost::ref(cameraStatus), boost::ref(_results));

  // Start acquiring
  std::shared_ptr<boost::thread> threadPtr = std::make_shared<boost::thread>(scanFunc);

  // Send motor to target position
  _motor.send();

  // Join thread
  threadPtr->join();

 _log.print("Finished the acquisition");
}

This seems to run into trouble sometimes, with the ros spin thread getting blocked and not executing any callbacks to other topics subscribed to in SuperScanner. The "Finished the acquisition" statement does get printed out though, so I know the thread has joined. A ronsode info on the node shows the list of topics, but says "communication with node failed". Could this have anything to do with the member variables within the instance of the _camera object getting updated in its startAcquiring() function?

Here's how the node gets started:

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

  n.param("/camera_scanner/device_ip", deviceIP, deviceIP);
  SuperScanner superScanner(n, deviceIp);
  ros::spin();
  return 0;
}

Originally posted by space on ROS Answers with karma: 13 on 2020-06-17

Post score: 0


Original comments

Comment by Solrac3589 on 2020-06-18:
Maybe this comment is a little offtopic, but i personally feel like you could have better control of the system if you used a separate nodelet for image adquisition.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Looking at how your node get started - your SuperScanner class isn't even running - once you call "ros::spin()" that's will execute until the node is shutdown - it doesn't return. If you put a print statement in your SuperScanner constructor, you'll see that it won't print until after you CTRL-C the node. See the page on spinning for more details.


Originally posted by fergs with karma: 13902 on 2020-06-18

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by space on 2020-06-18:
My bad. I removed some other classes that were being constructed in main() for clarity for this question and ended up putting that line in the wrong place. Edited to reflect the original sequence now.

Comment by fergs on 2020-06-18:
in that case, your example code doesn't show how/who calls getData() - I presume it is a ROS service/subscriber callback? What does scanFunc do? If it is also relying on something ROS related, your spin() call is single-threaded, and your join() is going to block in that callback - meaning other callbacks won't get serviced. There is a multi-threaded spinner (see the same link I posted above) - but you'll want to make sure your callbacks are thread safe.

Comment by space on 2020-06-18:
Yes, getData() is invoked in a ROS callback in the SuperScanner class. startAcquiring does not use any ROS callbacks though. In fact, the Camera object is an instance of a standalone, non ROS API for camera communication.

$\endgroup$

Your Answer

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