cam2를 마스터, cam1/cam3를 슬레이브로 하는 노출·게인 동기화 설정, README 한글화

camera_params_cam1/2/3.yaml에 새로 추가된 sync_role/gain_auto/use_software_ae/
ae_* 파라미터를 실제로 채워넣었다. cam2(가운데)는 sync_role: "master"로 두고
게인 자동조절·소프트웨어 ROI 측광 관련 파라미터를 미리 선언해뒀다(조리개/초점이
아직 확정 전이라 gain_auto/use_software_ae 자체는 꺼둔 상태 — 값만 준비).
cam1/cam3는 sync_role: "slave" + sync_master_camera_ns: "cam2"만 추가했다
(슬레이브에서는 나머지 AE 파라미터가 무시되므로 넣지 않음). 이 상태만으로도
cam2의 실제 적용 노출/게인이 방송되어 3대가 항상 같은 값을 쓰게 된다.

README.md를 영어에서 한글로 전면 재작성하고, 마스터 off/on에 따라 슬레이브가
고정값을 쓰는지 실시간으로 추종하는지에 대한 동작 요약을 추가했다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Dongubak
2026-08-17 00:03:42 +09:00
parent 6eeb6a8297
commit 5a587b0149
4 changed files with 133 additions and 86 deletions
+100 -86
View File
@@ -3,141 +3,155 @@
# hik_camera_ros2_driver
## Overview
## 개요
The `hik_camera_ros2_driver` package provides a ROS 2 driver for controlling and interfacing with Hikvision cameras. It supports functionalities such as camera initialization, parameter configuration, and image publishing. This package is intended for applications requiring reliable and configurable image data acquisition in a ROS 2 environment.
`hik_camera_ros2_driver` 패키지는 Hikvision 카메라를 제어하고 연동하기 위한 ROS 2 드라이버다. 카메라 초기화, 파라미터 설정, 이미지 발행 등의 기능을 제공한다. ROS 2 환경에서 신뢰성 있고 설정 가능한 이미지 데이터 취득이 필요한 애플리케이션을 위한 패키지다.
### Executables
### 실행 파일
The package includes the `hik_camera_node`, which manages the camera and publishes image data along with camera information to ROS 2 topics.
이 패키지는 `hik_camera_node`를 포함하며, 카메라를 관리하고 이미지 데이터와 카메라 정보를 ROS 2 토픽으로 발행한다.
### Subscribed Topics
### 구독 토픽
None.
없음. (단, `sync_role: "slave"`일 때는 마스터 카메라의 `ae_exposure_time_us`/`ae_gain_db` 토픽을 구독한다 — 아래 `sync_role` 참조)
### Published Topics
### 발행 토픽
- `<camera_topic>` (sensor_msgs/msg/Image)
- The image data captured by the Hikvision camera.
- Hikvision 카메라가 캡처한 이미지 데이터.
- `<camera_topic>/camera_info` (sensor_msgs/msg/CameraInfo)
- Camera calibration information.
- 카메라 캘리브레이션 정보.
### Parameters
- `<camera_name>/ae_exposure_time_us` (std_msgs/msg/Float64)
- 매 프레임 실제로 적용된 노출시간[µs]. `sync_role`과 무관하게 항상 발행되므로, 다른 노드가 관찰용으로 구독해도 된다.
- `exposure_auto` (bool, default: `false`)
- Enable continuous auto exposure. When `true`, the camera controls exposure automatically and `exposure_time` is ignored.
- `<camera_name>/ae_gain_db` (std_msgs/msg/Float64)
- 매 프레임 실제로 적용된 게인[dB]. 위와 동일하게 항상 발행된다.
- `exposure_time` (double, default: `5000`)
- Manual exposure time in microseconds. Used only when `exposure_auto` is `false`.
### 파라미터
- `exposure_auto_target_brightness` (int, default: `128`, range: `0-255`)
- Target brightness for auto exposure. Active only when `exposure_auto` is `true`. Can be changed at runtime:
- `exposure_auto` (bool, 기본값: `false`)
- Continuous 자동 노출을 켠다. `true`면 카메라가 노출을 자동으로 제어하고 `exposure_time`은 무시된다.
- `exposure_time` (double, 기본값: `5000`)
- 수동 노출시간[µs]. `exposure_auto``false`일 때만 사용된다.
- `exposure_auto_target_brightness` (int, 기본값: `128`, 범위: `0-255`)
- 자동 노출의 목표 밝기. `exposure_auto``true`일 때만 적용된다. 런타임에 변경 가능:
```bash
ros2 param set /hik_camera_ros2_driver exposure_auto_target_brightness 100
```
- `exposure_auto_min` (double, default: `100.0`)
- Auto exposure lower limit in microseconds. Active only when `exposure_auto` is `true`. Can be changed at runtime.
- `exposure_auto_min` (double, 기본값: `100.0`)
- 자동 노출 하한[µs]. `exposure_auto` `true`일 때만 적용된다. 런타임에 변경 가능.
- `exposure_auto_max` (double, default: `10000.0`)
- Auto exposure upper limit in microseconds. Active only when `exposure_auto` is `true`. Can be changed at runtime.
- `exposure_auto_max` (double, 기본값: `10000.0`)
- 자동 노출 상한[µs]. `exposure_auto` `true`일 때만 적용된다. 런타임에 변경 가능.
- `gain` (double)
- Manual gain, used when `gain_auto` is `false`. Can be changed at runtime:
- 수동 게인[dB]. `gain_auto` `false`일 때 사용된다. 런타임에 변경 가능:
```bash
ros2 param set /hik_camera_ros2_driver gain 2.0
```
- `gain_auto` (bool, default: `false`)
- Enable auto gain. Onboard `Continuous` when `use_software_ae` is `false`; controlled by the
software AE/AG loop (see below) when `use_software_ae` is `true`. Can be changed at runtime.
- `gain_auto` (bool, 기본값: `false`)
- 자동 게인을 켠다. `use_software_ae` `false`면 카메라 온보드 `Continuous` 모드로, `true`면 아래
소프트웨어 AE/AG 루프로 조절된다. 런타임에 변경 가능.
- `gain_auto_max_db` (double, default: `12.0`)
- Ceiling for auto gain, in dB. Independent from `gain`'s own hardware range — lets you cap
auto gain below the hardware maximum (e.g. this camera's real limit is ~16.9 dB) to bound
noise.
- `gain_auto_max_db` (double, 기본값: `12.0`)
- 자동 게인 상한[dB]. `gain` 파라미터 자체의 하드웨어 범위와는 별개 값으로, 하드웨어 실측 상한
(이 카메라는 약 16.9 dB)보다 낮게 잡아 노이즈를 제한하는 용도.
- `use_software_ae` (bool, default: `false`)
- The camera's onboard `ExposureAuto`/`GainAuto` always meter the *full* captured frame — this
SDK has no GenICam node for a metering-only ROI distinct from the capture AOI. When `true`,
onboard auto is disabled and exposure/gain are instead computed each frame in software from a
percentile of the ROI defined by `ae_roi_top_ratio`, then written directly via
`ExposureTime`/`Gain`. Requires `exposure_auto` and/or `gain_auto` to also be `true` to
actually adjust anything (otherwise held fixed at `exposure_time`/`gain`). Can be changed at
runtime.
- `use_software_ae` (bool, 기본값: `false`)
- 카메라 온보드 `ExposureAuto`/`GainAuto`는 항상 캡처된 프레임 **전체**를 측광한다 — 이 SDK에는
캡처 AOI와 별개로 측광에만 쓰는 ROI를 지정하는 GenICam 노드가 없다. `true`면 온보드 auto를 끄고,
대신 `ae_roi_top_ratio`로 정한 ROI의 퍼센타일 밝기를 매 프레임 소프트웨어에서 직접 계산해
`ExposureTime`/`Gain`에 바로 써넣는다. 실제로 뭔가 조절되게 하려면 `exposure_auto`와/또는
`gain_auto`도 함께 `true`여야 한다 (아니면 `exposure_time`/`gain` 값에 고정됨). 런타임에 변경 가능.
- `ae_roi_top_ratio` (double, default: `0.0`)
- Fraction of frame height excluded from the top when metering under `use_software_ae`. `0.5`
meters only the bottom half (e.g. to exclude sky).
- `ae_roi_top_ratio` (double, 기본값: `0.0`)
- `use_software_ae`에서 측광 시 상단부터 제외할 프레임 높이 비율. `0.5`면 하단 절반만 측광한다
(예: 하늘 제외).
- `ae_target_percentile` / `ae_target_dn` (default: `70.0` / `130`)
- Software AE/AG target: adjust exposure/gain so this percentile of the ROI reaches this DN.
- `ae_target_percentile` / `ae_target_dn` (기본값: `70.0` / `130`)
- 소프트웨어 AE/AG의 목표값: ROI 내 이 퍼센타일이 이 DN에 도달하도록 노출/게인을 조절한다.
- `ae_saturation_percentile` / `ae_saturation_dn` (default: `98.0` / `245`)
- Hard ceiling: never brighten past the point where this percentile would exceed this DN, even
if the target above hasn't been reached.
- `ae_saturation_percentile` / `ae_saturation_dn` (기본값: `98.0` / `245`)
- 하드 제약: 위 목표에 도달하지 못했더라도, 이 퍼센타일이 이 DN을 넘어설 정도로는 절대 밝게 하지
않는다.
- `ae_step_gain` (double, default: `0.5`)
- Per-frame correction damping (0-1) for the software AE/AG loop.
- `ae_step_gain` (double, 기본값: `0.5`)
- 소프트웨어 AE/AG 루프의 프레임당 보정 댐핑(0~1).
- `sync_role` (string, default: `"independent"`)
- `"independent"`: this camera decides its own exposure/gain (default, unchanged behavior).
- `"master"`: publishes the actually-applied exposure/gain (from the SDK's per-frame frame info,
valid regardless of AE mode) on `<camera_name>/ae_exposure_time_us` and
`<camera_name>/ae_gain_db`.
- `"slave"`: ignores its own auto exposure/gain and instead applies whatever `sync_master_camera_ns`
publishes, directly. Use this to make one camera (e.g. the center one) drive exposure/gain for
the others.
- `sync_role` (string, 기본값: `"independent"`)
- `"independent"`: 이 카메라가 자기 노출/게인을 스스로 결정한다 (기본값, 기존 동작과 동일).
- `"master"`: SDK가 매 프레임 주는 실제 적용값(AE 모드와 무관하게 항상 유효)을
`<camera_name>/ae_exposure_time_us`, `<camera_name>/ae_gain_db`로 발행한다.
- `"slave"`: 자기 자신의 자동 노출/게인 로직을 완전히 무시하고, `sync_master_camera_ns`
발행하는 값을 그대로 적용한다. 카메라 여러 대 중 하나(예: 가운데 카메라)가 나머지의
노출/게인을 결정하게 하고 싶을 때 사용한다.
- `sync_master_camera_ns` (string, default: `""`)
- When `sync_role` is `"slave"`, the `camera_name` of the master camera to subscribe to (e.g.
`"cam2"`).
- `sync_master_camera_ns` (string, 기본값: `""`)
- `sync_role` `"slave"`일 때, 구독할 마스터 카메라의 `camera_name` (예: `"cam2"`).
- `acquisition_frame_rate` (double, default: `165`)
- The acquisition frame rate in hz for the camera.
> **동작 요약:** 마스터(예: `cam2`)의 `exposure_auto`/`gain_auto`(및 `use_software_ae`)가 전부
> `false`이면, 마스터는 `exposure_time`/`gain`에 고정된 값으로 구동되고 그 고정값이 그대로
> 슬레이브(`cam1`, `cam3`)에 방송되어 **3대 전부 같은 고정 노출/게인**으로 구동된다.
> 마스터에서 `exposure_auto`/`gain_auto`(또는 `use_software_ae`)를 켜면, 마스터가 그때그때
> 계산한 실제 적용값이 프레임마다 방송되고 **슬레이브는 그 값을 그대로 추종**한다. 이때 슬레이브
> 자신의 `exposure_auto`/`gain_auto`/`use_software_ae` 값은 (설정되어 있더라도) 완전히
> 무시된다 — 노출/게인 자동 조절 여부는 오직 마스터 쪽 설정만으로 결정된다.
- `pixel_format` (string, default: `RGB8Packed`)
- The pixel format for the image data. Supported values: `Mono8`, `Mono10`, `Mono12`, `RGB8Packed`, `BGR8Packed`, `YUV422_YUYV_Packed`, `YUV422Packed`, `BayerRG8`, `BayerRG10`, `BayerRG10Packed`, `BayerRG12`, `BayerRG12Packed`.
- `acquisition_frame_rate` (double, 기본값: `165`)
- 카메라의 취득 프레임률[Hz].
- `adc_bit_depth` (string, default: `Bits_8`)
- The ADC bit depth for the camera. Supported values: `Bits_8`, `Bits_12`.
- `pixel_format` (string, 기본값: `RGB8Packed`)
- 이미지 데이터의 픽셀 포맷. 지원값: `Mono8`, `Mono10`, `Mono12`, `RGB8Packed`, `BGR8Packed`,
`YUV422_YUYV_Packed`, `YUV422Packed`, `BayerRG8`, `BayerRG10`, `BayerRG10Packed`, `BayerRG12`,
`BayerRG12Packed`.
- `use_sensor_data_qos` (bool, default: true)
- Whether to use the `sensor_data` QoS profile for image topic publication.
- `adc_bit_depth` (string, 기본값: `Bits_8`)
- 카메라의 ADC 비트 심도. 지원값: `Bits_8`, `Bits_12`.
- `camera_name` (string, default: `camera`)
- The name of the camera for identification purposes.
- `use_sensor_data_qos` (bool, 기본값: true)
- 이미지 토픽 발행에 `sensor_data` QoS 프로파일을 쓸지 여부.
- `frame_id` (string, default: `<camera_name>_optical_frame`)
- The frame_id assigned to the published image data.
- `camera_name` (string, 기본값: `camera`)
- 카메라 식별용 이름.
- `camera_topic` (string, default: `<camera_name>/image`)
- The topic name for publishing image and info data.
- `frame_id` (string, 기본값: `<camera_name>_optical_frame`)
- 발행되는 이미지 데이터에 붙는 frame_id.
- `camera_info_url` (string, default: `package://hik_camera_ros2_driver/config/camera_info.yaml`)
- The URL for the camera calibration information file.
- `camera_topic` (string, 기본값: `<camera_name>/image`)
- 이미지·정보 데이터를 발행할 토픽 이름.
- `trigger_enable` (bool, default: `false`)
- Enable hardware trigger mode (LINE0). When `true`, frame rate is controlled by the trigger signal.
- `camera_info_url` (string, 기본값: `package://hik_camera_ros2_driver/config/camera_info.yaml`)
- 카메라 캘리브레이션 정보 파일의 URL.
- `use_trigger_timestamp` (bool, default: `false`)
- Use the shared memory timestamp written by the LiDAR driver instead of system time.
- `trigger_enable` (bool, 기본값: `false`)
- 하드웨어 트리거 모드(LINE0)를 켠다. `true`면 프레임률이 트리거 신호로 제어된다.
- `serial_number` (string, default: `""`)
- Select a specific camera by serial number. If empty, the first detected camera is used.
- `use_trigger_timestamp` (bool, 기본값: `false`)
- 시스템 시간 대신, LiDAR 드라이버가 기록한 공유 메모리 타임스탬프를 사용한다.
- `enable_interval_log` (bool, default: `false`)
- Print per-frame timestamp interval logs (`[TS]`). Also prints a rolling summary every 10 frames (avg / min / max / jitter). Can be toggled at runtime:
- `serial_number` (string, 기본값: `""`)
- 시리얼 번호로 특정 카메라를 선택한다. 비어 있으면 처음 검출된 카메라를 사용한다.
- `enable_interval_log` (bool, 기본값: `false`)
- 프레임별 타임스탬프 간격 로그(`[TS]`)를 출력한다. 10프레임마다 평균/최소/최대/지터 요약도
함께 출력한다. 런타임에 토글 가능:
```bash
ros2 param set /hik_camera_ros2_driver enable_interval_log true
```
### Usage
### 사용법
#### Installation
#### 설치
To use this package, build it from source or include it in your ROS 2 workspace. Ensure that all dependencies are installed. You **don't** need to install the Hikvision camera SDK and include its libraries in your environment.
이 패키지를 사용하려면 소스로 빌드하거나 ROS 2 워크스페이스에 포함시키면 된다. 의존 패키지가 모두
설치되어 있는지 확인할 것. Hikvision 카메라 SDK를 별도로 설치하고 그 라이브러리를 환경에 포함시킬
필요는 **없다**.
```bash
mkdir -p ~/ros_ws/src
@@ -157,9 +171,9 @@ rosdep install -r --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
```
#### Run
#### 실행
You can use the provided launch file for starting the camera node with default or custom parameters:
제공된 launch 파일로 기본값 또는 커스텀 파라미터를 사용해 카메라 노드를 실행할 수 있다:
```bash
ros2 launch hik_camera_ros2_driver hik_camera_launch.py
@@ -49,6 +49,12 @@
exposure_time: 50 # Unit: us
gain: 0.0 # Range: 0.0 ~ 16.9, Unit: dB
# 노출/게인 동기화 — cam2(가운데)를 마스터로 따라감. exposure_auto/gain_auto/
# use_software_ae는 슬레이브에서는 무시된다 (마스터가 ae_exposure_time_us/ae_gain_db로
# 방송하는 실제 적용값을 그대로 ExposureTime/Gain에 적용).
sync_role: "slave"
sync_master_camera_ns: "cam2"
# 화이트밸런스 — cam1/cam2 겹치는 영역 색감을 맞추기 위해 두 카메라에 동일한
# 수동 R/G/B 비율을 고정한다 (2026-07-15, 두 카메라 Continuous AWB 수렴값의 평균).
# cam1 실측: R=1414 G=1024 B=2060 / cam2 실측: R=1408 G=1024 B=2184 → 평균 적용
@@ -49,6 +49,27 @@
exposure_time: 50 # Unit: us
gain: 0.0 # Range: 0.0 ~ 16.9, Unit: dB
# 게인 자동 조절 — 조리개/초점 확정 전이라 아직 꺼둠 (수동 게인 유지)
gain_auto: false
gain_auto_max_db: 12.0 # 자동 게인 켤 때 상한. 하드웨어 실측 상한(~16.9dB)보다 낮게 제한
# 소프트웨어 AE/AG — 온보드 auto는 풀프레임만 측광 가능해서(하늘 포함 시 바닥이
# 어두워지는 문제, camera_exposure_design_notes.md 4절) 하단부만 측광하려면 이 경로가
# 필요함. 지금은 꺼둠 — 조리개/초점 확정 후 켤 것.
use_software_ae: false
ae_roi_top_ratio: 0.5 # 켤 경우 상단 50%(하늘) 제외하고 측광
ae_target_percentile: 70.0
ae_target_dn: 130
ae_saturation_percentile: 98.0
ae_saturation_dn: 245
ae_step_gain: 0.5
# 노출/게인 동기화 — cam2(가운데)가 마스터. 실제 적용된 노출/게인을
# ae_exposure_time_us / ae_gain_db 토픽으로 매 프레임 방송한다. 지금은
# exposure_auto/gain_auto가 꺼져 있어 위 수동 고정값을 그대로 방송하므로,
# cam1/cam3가 이 값을 따라가서 3대가 항상 같은 노출/게인을 쓰게 된다.
sync_role: "master"
# 화이트밸런스 — cam1/cam2 겹치는 영역 색감을 맞추기 위해 두 카메라에 동일한
# 수동 R/G/B 비율을 고정한다 (2026-07-15, 두 카메라 Continuous AWB 수렴값의 평균).
# cam1 실측: R=1414 G=1024 B=2060 / cam2 실측: R=1408 G=1024 B=2184 → 평균 적용
@@ -49,6 +49,12 @@
exposure_time: 50 # Unit: us
gain: 0.0 # Range: 0.0 ~ 16.9, Unit: dB
# 노출/게인 동기화 — cam2(가운데)를 마스터로 따라감. exposure_auto/gain_auto/
# use_software_ae는 슬레이브에서는 무시된다 (마스터가 ae_exposure_time_us/ae_gain_db로
# 방송하는 실제 적용값을 그대로 ExposureTime/Gain에 적용).
sync_role: "slave"
sync_master_camera_ns: "cam2"
# 화이트밸런스 — cam1/cam2 겹치는 영역 색감을 맞추기 위해 두 카메라에 동일한
# 수동 R/G/B 비율을 고정한다 (2026-07-15, 두 카메라 Continuous AWB 수렴값의 평균).
# cam1 실측: R=1414 G=1024 B=2060 / cam2 실측: R=1408 G=1024 B=2184 → 평균 적용