Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add primary secondary example file #181

Merged
merged 2 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions spinnaker_camera_driver/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,20 @@ that you can customize as needed.
ros2 launch spinnaker_camera_driver driver_node.launch.py camera_type:=blackfly_s serial:="'20435008'"


Using multiple cameras at the same time
=======================================

The FLIR Spinnaker does not support two programs accessing the Spinnaker SDK at the same time,
even if two different cameras are accessed. Strange things happen, in particular with USB3 cameras.
You can however run multiple cameras in the same
address space using ROS2's Composable Node concept, see the example
launch file ``multiple_cameras.launch.py``.

If you are using hardware synchronized cameras please use the ``spinnaker_synchronized_camera_driver``,
which will associate the images triggered by the same sync pulse with each other
and give them identical time stamps.


About time stamps
=================

Expand Down
131 changes: 131 additions & 0 deletions spinnaker_camera_driver/launch/multiple_cameras.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# -----------------------------------------------------------------------------
# Copyright 2022 Bernd Pfrommer <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument as LaunchArg
from launch.actions import OpaqueFunction
from launch.substitutions import LaunchConfiguration as LaunchConfig
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
from launch_ros.substitutions import FindPackageShare

camera_params = {
'debug': False,
'compute_brightness': True,
'dump_node_map': False,
'adjust_timestamp': True,
'gain_auto': 'Off',
'gain': 0,
'exposure_auto': 'Off',
'exposure_time': 9000,
'line2_selector': 'Line2',
'line2_v33enable': False,
'line3_selector': 'Line3',
'line3_linemode': 'Input',
'trigger_selector': 'FrameStart',
'trigger_mode': 'On',
'trigger_source': 'Line3',
'trigger_delay': 9,
'trigger_overlap': 'ReadOut',
'chunk_mode_active': True,
'chunk_selector_frame_id': 'FrameID',
'chunk_enable_frame_id': True,
'chunk_selector_exposure_time': 'ExposureTime',
'chunk_enable_exposure_time': True,
'chunk_selector_gain': 'Gain',
'chunk_enable_gain': True,
'chunk_selector_timestamp': 'Timestamp',
'chunk_enable_timestamp': True,
}


def make_camera_node(name, camera_type, serial):
parameter_file = PathJoinSubstitution(
[FindPackageShare('spinnaker_camera_driver'), 'config', camera_type + '.yaml']
)

node = ComposableNode(
package='spinnaker_camera_driver',
plugin='spinnaker_camera_driver::CameraDriver',
name=name,
parameters=[camera_params, {'parameter_file': parameter_file, 'serial_number': serial}],
remappings=[
('~/control', '/exposure_control/control'),
],
extra_arguments=[{'use_intra_process_comms': True}],
)
return node


def launch_setup(context, *args, **kwargs):
"""Create multiple camera."""
container = ComposableNodeContainer(
name='stereo_camera_container',
namespace='',
package='rclcpp_components',
executable='component_container',
composable_node_descriptions=[
#
# These two camera nodes run independently from each other,
# but in the same address space
#
make_camera_node(
LaunchConfig('cam_0_name'),
LaunchConfig('cam_0_type').perform(context),
LaunchConfig('cam_0_serial'),
),
make_camera_node(
LaunchConfig('cam_1_name'),
LaunchConfig('cam_1_type').perform(context),
LaunchConfig('cam_1_serial'),
),
],
output='screen',
) # end of container
return [container]


def generate_launch_description():
"""Create composable node by calling opaque function."""
return LaunchDescription(
[
LaunchArg(
'cam_0_name',
default_value=['cam_0'],
description='camera name (ros node name) of camera 0',
),
LaunchArg(
'cam_1_name',
default_value=['cam_1'],
description='camera name (ros node name) of camera 1',
),
LaunchArg('cam_0_type', default_value='blackfly_s', description='type of camera 0'),
LaunchArg('cam_1_type', default_value='blackfly_s', description='type of camera 1'),
LaunchArg(
'cam_0_serial',
default_value="'20435008'",
description='FLIR serial number of camera 0 (in quotes!!)',
),
LaunchArg(
'cam_1_serial',
default_value="'20415937'",
description='FLIR serial number of camera 1 (in quotes!!)',
),
OpaqueFunction(function=launch_setup),
]
)
145 changes: 0 additions & 145 deletions spinnaker_camera_driver/launch/stereo_synced.launch.py

This file was deleted.

6 changes: 5 additions & 1 deletion spinnaker_synchronized_camera_driver/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Exposure controller parameters
Example usage
-------------

The driver comes with two example launch files that need to be modified for your purposes (update serial numbers etc).
The driver comes with several example launch files that need to be modified for your purposes (update serial numbers etc).
The ``follower_example.launch.py`` can be used as template for stereo cameras, the ``master_example.launch.py`` for situations
where each camera should run their own exposure control.

Expand All @@ -133,6 +133,10 @@ Carefully examine the camera parameters that are set in the launch file, in part
- ``exposure_auto`` must be off (disable the individual camera controller).
- ``chunk_mode_active`` must be true, and chunk exposure time, gain and frame id must be enabled

For the special case where one camera (primary) triggers the sync pulse of a secondary camera, see
the example launch file ``primary_secondary.launch.py``. If you don't use Blackfly S cameras you will have
to adjust the digital I/O parameters.


Known issues
============
Expand Down
Loading
Loading