0
$\begingroup$

Rosanswers logo

I am trying to calibrate my ov7251 camera using the camera_calibration package. I adapted a sample camera driver that I found which use the UV4L API so that I can try to publish images to the ROS topic /camera/image. I am also publishing to /camera/camera_info. However, what I need now is to be able to run the /camera/set_camera_info service so that I can use the calibration package.

Here is my code for publishing to /camera/image and /camera/camera_info:

int main(int argc, char **argv) {
    dev_name = "/dev/video2";

    namedWindow( "Camera Preview", WINDOW_AUTOSIZE );// Create a window for display.
    ros::init(argc, argv, "image_publisher");
    ros::NodeHandle nh;
    image_transport::ImageTransport it(nh);
    image_transport::Publisher pub = it.advertise("camera/image", 1);

    ros::Publisher pub_info = nh.advertise<sensor_msgs::CameraInfo>("camera/camera_info", 100);
    sensor_msgs::CameraInfo cam_info;

    open_device();
    init_device();
    start_capturing();

    while (nh.ok()) {
        read_frame();
        if (!prev.empty()) {
            cv::Mat image = prev;
            sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg();

            ros::Rate loop_rate(5);

            cam_info.header.stamp = ros::Time::now();
            pub_info.publish(cam_info);
            pub.publish(msg);
            ros::spinOnce();
            loop_rate.sleep();
        }  
    }

   ...

   return 0;
}

When I ran rostopic list, this is what I get:

/camera/camera_info
/camera/image
/camera/image/compressed
/camera/image/compressed/parameter_descriptions
/camera/image/compressed/parameter_updates
/camera/image/compressedDepth
/camera/image/compressedDepth/parameter_descriptions
/camera/image/compressedDepth/parameter_updates
/camera/image/theora
/camera/image/theora/parameter_descriptions
/camera/image/theora/parameter_updates
/camera/image_raw
/rosout
/rosout_agg
/statistics
/svo/dense_input
/svo/image
/svo/image/compressed
/svo/image/compressed/parameter_descriptions
/svo/image/compressed/parameter_updates
/svo/image/compressedDepth
/svo/image/compressedDepth/parameter_descriptions
/svo/image/compressedDepth/parameter_updates
/svo/image/theora
/svo/image/theora/parameter_descriptions
/svo/image/theora/parameter_updates
/svo/info
/svo/keyframes
/svo/points
/svo/pose
/svo/remote_key
/tf

And when I run rosservice list:

/camera/image/compressed/set_parameters
/camera/image/compressedDepth/set_parameters
/camera/image/theora/set_parameters
/image_publisher/get_loggers
/image_publisher/set_logger_level
/rosout/get_loggers
/rosout/set_logger_level
/rqt_gui_py_node_13721/get_loggers
/rqt_gui_py_node_13721/set_logger_level
/rqt_gui_py_node_13807/get_loggers
/rqt_gui_py_node_13807/set_logger_level
/svo/get_loggers
/svo/image/compressed/set_parameters
/svo/image/compressedDepth/set_parameters
/svo/image/theora/set_parameters
/svo/set_logger_level

As you can see, I don't have a /set_camera_info service, which I think is the main problem I am having with trying to run the camera_calibration package. If anyone can please provide me with a simple sample code for using the camera_info_manager, it would be much appreciated.

EDIT: For now, I wish to simply initialize a camera_info_manager object so that I can use its functions to run the set_camera_info service, but I am not well-versed with C++ so I am having some problems understanding the tutorial for camera_info_manager.

EDIT2: I added these two lines in, based on @joq's comments:

boost::shared_ptr<camera_info_manager::CameraInfoManager> cinfo;
cinfo(new camera_info_manager::CameraInfoManager(nh));

but I only get this error:

no match for call to ‘(boost::shared_ptr<camera_info_manager::CameraInfoManager>) (camera_info_manager::CameraInfoManager*)’
cinfo(new camera_info_manager::CameraInfoManager(nh));

As a separate approach, I have also tried to simply do this to instantiate a camera info manager:

camera_info_manager::CameraInfoManager cinfo(nh, "camera","");

but then I get this error:

CMakeFiles/vga_cam_publisher.dir/src/vga_cam_publisher.cpp.o: In function `vga_cam_publisher::vga_cam_publisher()':
vga_cam_publisher.cpp:(.text._ZN15vga_cam_publisherC2Ev[_ZN15vga_cam_publisherC5Ev]+0x147): undefined reference to `camera_info_manager::CameraInfoManager::CameraInfoManager(ros::NodeHandle, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status

Originally posted by trixr4kdz on ROS Answers with karma: 45 on 2018-01-02

Post score: 2


Original comments

Comment by Ameer Hamza Khan on 2018-01-04:
Have you tried usb_cam package. It will automatically start the required service for camera calibration.

Comment by trixr4kdz on 2018-01-04:
Yes, I have. But the main problem with the drivers that I looked through was that they did not give me the option to enter a "device_id", just the "device_name". Although I can set the param as "/dev/videoN", I think I need to be able to set the "device_id" to 0 or 1.

Comment by trixr4kdz on 2018-01-04:
The error that I would get is [ERROR] [1515087853.012401358]: VIDIOC_S_FMT error 22, Invalid argument

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Camera info manager will declare that service for you. The "tutorial" is just a link to the first driver that used camera_info_manager, not entirely self-explanatory.

To use camera_info_manager, you must:

There is not a lot more to it than that.


Originally posted by joq with karma: 25443 on 2018-01-03

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by trixr4kdz on 2018-01-03:
Thank you, and this might sound like a stupid question but why would we need to declare a pointer to an instance of ImageTransport? And would using Boost really be necessary?

I've also edited my original post to have the error I keep getting when I try to create a CameraInfoManager object

Comment by joq on 2018-01-03:
Boost pointers are not required, just useful for avoiding memory leaks. The main advantage of using a pointer is being able to control when the class is instantiated. Sometimes you need to process some ROS parameters first, and a static allocation would happen before then.

Comment by joq on 2018-01-03:
The error message looks like a CamelCase error in your boost pointer declaration, the class says camerainfomanager instead of CameraInfoManager.

Comment by joq on 2018-01-03:
Since you're using C++11, std::shared_ptr is built-in, so you don't need Boost.

Comment by trixr4kdz on 2018-01-03:
Oh that's weird, the ROS forums text box is changing the case of CameraInfoManager to all lowercase. I do have the error as saying CameraInfoManager. I've made it into a code block here to correct it.

Comment by trixr4kdz on 2018-01-04:
When I run catkin_make it seems to be able to link my file, but then I get the error about "undefined reference to `camera_info_manager::CameraInfoManager::CameraInfoManager(ros::NodeHandle, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, ...

Comment by joq on 2018-01-04:
Is camera_info_manager listed as a dependency in your package.xml?

Comment by trixr4kdz on 2018-01-04:
It actually isn't but when I added it to the CMakeLists.txt file instead of the package.xml file, the error about undefined reference to CameraInfoManager disappeared. In any case, thank you for all the help. I will now do the rest of the steps you listed on your answer.

Comment by trixr4kdz on 2018-01-04:
Now, I'm at the point of setting the camera info url, but I keep getting this error: no matching function for call to ‘image_transport::CameraPublisher::CameraPublisher(image_transport::Publisher)’ camera_info_url_(""). What could be causing this error?

Comment by joq on 2018-01-05:
Re package.xml: you should list the dependency there, too.

Comment by joq on 2018-01-05:
Maybe you could update your question to show the code you're running now, and where the error appears.

$\endgroup$

Your Answer

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