christianrauch / camera_ros

ROS 2 node for libcamera supported cameras (V4L2, Raspberry Pi Camera Modules)
https://libcamera.org
MIT License
64 stars 28 forks source link

Is there an example launch file? #24

Closed mzahana closed 5 months ago

mzahana commented 6 months ago

Hi @christianrauch Thank you very much for this great package.

Could you please provide an example launch file to run the camera node and set its parameters?

Also, can the camera node be containerized with another ros2 node?

Thanks.

christianrauch commented 6 months ago

I guess I should add a README to this repo :-)

In short, you can either use this package with the "standalone" node via ros2 run camera_ros camera_node or use its composable node camera::CameraNode via ros2 component standalone camera_ros camera::CameraNode. The node has a couple of fixed parameters, such as camera, height, width, format and role, and some that are generated dynamically based on the camera control returned by libcamera. To introspect the parameters, I suggest launching the node with the defaults and then using ros2 param to list and describe the parameters.

mzahana commented 6 months ago

Thank you for your reply @christianrauch .

An explanation of the settable parameters would be highly appreciated. For example, how to get the supported image size and the frame rate. I ran the node with the default params using ros2 run camera_ros camera_node and I got 30 FPS using ros2 topic hz /camera/image_raw. I think the camera I have can support highers FPS for some images sizes, but I am not sure which ones. Is there a way to figure this out?

Another question. I am using a stereo camera from arducam, and both images are published as one image to the same topic. Is there a way to use the same node to split them, or I need to implement another node for this task?

Thank you.

christianrauch commented 6 months ago

An explanation of the settable parameters would be highly appreciated.

I can add the common parameters to the documentation, sure.

For example, how to get the supported image size and the frame rate.

If you run the node without specifying the format or resolution, e.g. via ros2 run camera_ros camera_node --ros-args -p camera:=1, it will print the supported formats:

[INFO] [1711749920.430023105] [camera]: 
>> stream formats:
   - Pixelformat: MJPEG (320x180 - 1280x720)
   - Pixelformat: YUYV (320x180 - 1280x720)
[WARN] [1711749920.430383811] [camera]: no pixel format selected, using default: "MJPEG"
[INFO] [1711749920.430535365] [camera]: 
>> MJPEG format sizes:
   - 320x180
   - 320x240
   - 352x288
   - 424x240
   - 640x360
   - 640x480
   - 848x480
   - 960x540
   - 1280x720
[WARN] [1711749920.430635685] [camera]: no dimensions selected, auto-selecting: "1280x720"
[25:36:19.544437934] [645599]  INFO Camera camera.cpp:1183 configuring streams: (0) 1280x720-MJPEG
[INFO] [1711749920.471949547] [camera]: camera "\_SB_.PCI0.XHC_.RHUB.HS08-8:1.0-5986:2115" configured with 1280x720-MJPEG stream

Since there are no enum parameter types, you have to specify the format (MJPEG or YUYV) and the resolution manually.

I ran the node with the default params using ros2 run camera_ros camera_node and I got 30 FPS using ros2 topic hz /camera/image_raw. I think the camera I have can support highers FPS for some images sizes, but I am not sure which ones. Is there a way to figure this out?

Setting the framerate is more complicated since libcamera does not expose a control for this yet. The framerate has to be set indirectly via the frame timings like the maximum frame duration and exposure time. See https://github.com/christianrauch/camera_ros/issues/11 for an example how to set the framerate for a camera that supports the FrameDurationLimits control.

mzahana commented 6 months ago

Thanks @christianrauch for your reply.

Does the node always publish at a fixed frame rate of 30 FPS, or it depends on how fast it receives frames from the camera ?

I am asking because the camera supports multiple image sizes at different frame rates.

christianrauch commented 6 months ago

Does the node always publish at a fixed frame rate of 30 FPS, or it depends on how fast it receives frames from the camera ?

The node publishes a message when it receives a new image from the camera (when a Request is completed). And as per the linked example above, this depends on the frame timing.

mzahana commented 6 months ago

I am trying to set the format parameter.

First, I ran the node with the default parameters. and I got the following

   - Pixelformat: NV21 (64x64 - 2560x800)
   - Pixelformat: YUV420 (64x64 - 2560x800)
   - Pixelformat: NV12 (64x64 - 2560x800)
   - Pixelformat: YVU420 (64x64 - 2560x800)
   - Pixelformat: XBGR8888 (64x64 - 2560x800)
   - Pixelformat: BGR888 (64x64 - 2560x800)
   - Pixelformat: RGB888 (64x64 - 2560x800)
   - Pixelformat: XRGB8888 (64x64 - 2560x800)
   - Pixelformat: RGB565 (64x64 - 2560x800)
   - Pixelformat: YVYU (64x64 - 2560x800)
   - Pixelformat: YUYV (64x64 - 2560x800)
   - Pixelformat: VYUY (64x64 - 2560x800)
   - Pixelformat: UYVY (64x64 - 2560x800)
   - [WARN] [1711888778.279925356] [camera]: no pixel format selected, using default: "XBGR8888"
[INFO] [1711888778.280017532] [camera]: 
>> XBGR8888 format sizes:
   - 160x120
   - 240x160
   - 320x240
   - 400x240
   - 480x320
   - 640x360
   - 640x480
   - 720x480
   - 768x480
   - 854x480
   - 720x576
   - 800x600
   - 960x540
   - 1024x576
   - 960x640
   - 1024x600
   - 1024x768
   - 1280x720
   - 1280x800
   - 1360x768
   - 1366x768

The camera I have is stereocamera, with two monochrome imagers, global shutter, published as a single stitched frame. I tried all listed formats. Only XBGR8888 and UYVY worked. Otherwise, I get the an error that the pixel format is unsupported and the node shuts down. So are these listed formats the ones actually supported by the camera, or it is just a general list of all possible formats that the node accepts?

christianrauch commented 6 months ago

So are these listed formats the ones actually supported by the camera, or it is just a general list of all possible formats that the node accepts?

The list that is printed on the screen is the list of formats that I get from libcamera. If you select a pixel format that is not in this list, you get an exception ending with unsupported by camera. But not all these pixel formats are directly supported by the ROS image message, meaning that there is no ROS image format that has the same memory layout as the requested pixel format from the camera. If you select a pixel format that does not have a matching ROS image format, you get an exception ending unsupported by node.

At the moment, I am not converting between image formats to avoid memory copies. This should be fine as long as your camera supports one of the ROS image formats.

christianrauch commented 6 months ago

I tried all listed formats. Only XBGR8888 and UYVY worked. Otherwise, I get the an error that the pixel format is unsupported and the node shuts down. So are these listed formats the ones actually supported by the camera, or it is just a general list of all possible formats that the node accepts?

I created https://github.com/christianrauch/camera_ros/pull/28 to address this confusion. The node will now list only pixel formats supported by the camera and the node.

A Raspberry Pi "Camera Module v1" (OV5647) would then list the following supported formats:

>> stream formats:
   - Pixelformat: XBGR8888 (64x64 - 2592x1944)
   - Pixelformat: BGR888 (64x64 - 2592x1944)
   - Pixelformat: RGB888 (64x64 - 2592x1944)
   - Pixelformat: XRGB8888 (64x64 - 2592x1944)
   - Pixelformat: YUYV (64x64 - 2592x1944)
   - Pixelformat: UYVY (64x64 - 2592x1944)

Note that a pixel format such as RGB565, which is supported by the camera but not by the ROS image message, does not appear in this list now.

mzahana commented 6 months ago

Thank you @christianrauch . I will test it.

I was also thinking to make a separate node based on the current camera node to publish two image topics, right and left of a stereocamera. This is at least useful for some Arducam cameras that publish both image frames stitched together in a single topic. There are also some modules where multiple cameras (up to 4 cameras ) are published in a single topic.

christianrauch commented 6 months ago

If you need to split the images again, I suggest writing a composable node that is loaded into the same component container that is hosting camera::CameraNode in order to use efficient intra-process communication and avoid image data copies. If you fork the node just for this feature, it will be difficult to maintain and keep up with upstream changes. Such a "splitting" node would also be useful for other camera nodes that concatenate the images in this way.

mzahana commented 6 months ago

Thanks@christianrauch for your suggestions. I was actually thinking doing the same thing as you suggested. However, I was concerned about any delays that might happen in the communication between messages. I hope writing a composable node and using intra process communication can help mitigate this issue.

mzahana commented 6 months ago

@christianrauch I tested #28 and it works as expected. Now, it shows the pixels supported by both camera and node. Thanks!

mzahana commented 6 months ago

@christianrauch One thing that I am not able to solve is the frame rate. The camera I have should be able to stream some resolutions at 60FPS. However, all the image sizes that I set using the width and height parameters still result in 30FPS. Is there something else I am missing to get higher stream rate?

christianrauch commented 6 months ago

Did the hint about FrameDurationLimits in https://github.com/christianrauch/camera_ros/issues/24#issuecomment-2027800746 not help? What are your framerate limits and do they change with the resolution?

mzahana commented 6 months ago

Setting FrameDurationLimits worked for me. Thanks

christianrauch commented 5 months ago

I added an example launch file and wrote some documentation; see https://github.com/christianrauch/camera_ros/pull/27. Does this help you to answer the questions you had in this issue?

mzahana commented 5 months ago

Thanks. Looks good. It would also be nice to set parameters in the launch file.

christianrauch commented 5 months ago

I added some sensible defaults to the launch file. But other than this, I would simply refer to the standard ROS 2 documentation and tutorial, such as https://docs.ros.org/en/foxy/How-To-Guides/Launch-file-different-formats.html, on how to use launch files and set parameters.