Skip to content

Arena SDK

Lucid Vision Camera ROS2 Driver with Arena SDK

연결 워크플로우 개요

단계

메서드

설명

1. 시스템 초기화

from arena_api.system import system

import 시 자동 초기화 (싱글턴)

2. 장치 검색

system.device_infos

네트워크상의 카메라 탐색

3. 장치 생성

system.create_device()

카메라와 제어 채널 연결

4. 장치 선택

system.select_device()

다중 장치 중 선택

5. 스트림 설정

device.tl_stream_nodemap

패킷 크기, 재전송 등 설정

6. 이미지 획득

device.start_stream()

스트리밍 시작 및 버퍼 수신

7. 정리

system.destroy_device()

제어 채널 해제 및 리소스 반환

시스템 초기화

ARENA SDK의 시스템 객체는 싱글턴 패턴으로 구현되어 있으며, import 시 자동으로 초기화됩니다.

from arena_api.system import system

# 별도의 open/close 호출 불필요
# 모듈 언로드 시 자동으로 정리됨
  • examples/py_enumeration.py (Lines 23-29)

장치 검색 (Discovery)

네트워크에 연결된 카메라를 탐색합니다.

기본 검색

device_infos = system.device_infos
print(f"발견된 장치: {len(device_infos)}대")

for info in device_infos:
    print(f"  모델: {info['model']}")
    print(f"  시리얼: {info['serial']}")
    print(f"  IP: {info['ip']}")
    print(f"  MAC: {info['mac']}")

device_infos 반환 정보

system.device_infos는 딕셔너리 리스트를 반환하며, 각 항목은 다음 키를 포함합니다.

설명

예시

model

카메라 모델명

"PHX050S-MC"

vendor

제조사

"LUCID Vision Labs"

serial

시리얼 번호

"123456789"

ip

IP 주소

"169.254.1.1"

subnetmask

서브넷 마스크

"255.255.0.0"

defaultgateway

기본 게이트웨이

"0.0.0.0"

mac

MAC 주소

"00:30:F1:02:03:04"

name

사용자 정의 이름

"Camera_01"

version

펌웨어 버전

"1.2.0"

dhcp

DHCP 활성화 여부

True / False

persistentip

고정 IP 활성화 여부

True / False

lla

Link-Local Address 여부

True / False

검색 타임아웃 설정

# 기본값: 100ms
# LUCID 카메라는 100ms 이내 응답, GigE Vision 스펙상 최대 1초
system.DEVICE_INFOS_TIMEOUT_MILLISEC = 200  # 필요시 늘릴 수 있음
device_infos = system.device_infos
  • examples/py_enumeration.py (Lines 63-81)

장치 생성 (연결)

검색된 카메라와 제어 채널을 열어 연결합니다.

모든 장치 연결

devices = system.create_device()

재시도 로직 포함

import time

tries = 0
tries_max = 6
sleep_time_secs = 10

while tries < tries_max:
    devices = system.create_device()
    if devices:
        print(f"{len(devices)}대 연결 성공")
        break
    print(f"시도 {tries+1}/{tries_max}: {sleep_time_secs}초 대기 중...")
    time.sleep(sleep_time_secs)
    tries += 1
else:
    raise Exception("장치를 찾을 수 없습니다")

특정 장치만 연결

# MAC 주소로 필터링
target_mac = "00:30:F1:02:03:04"
target_info = [d for d in system.device_infos if d['mac'] == target_mac]
devices = system.create_device(device_infos=target_info)

# 특정 인덱스의 장치만 연결
device_info = system.device_infos[0]
devices = system.create_device(device_infos=device_info)

# 여러 장치를 선택적으로 연결
all_infos = system.device_infos
devices = system.create_device(device_infos=all_infos[:2])  # 처음 2대만

장치 선택

devices = system.create_device()
device = system.select_device(devices)  # 1대면 자동 선택, 여러 대면 사용자 선택

NOTE

첫 번째 프로세스가 읽기/쓰기 권한을 획득하며, 이후 프로세스는 읽기 전용으로 접속됩니다.

  • examples/py_simple_acquisition.py (Lines 32-70)
  • examples/py_enumeration_mac.py (Lines 38-74)

네트워크 설정

Force IP (임시 IP 할당)

장치의 IP를 임시로 변경합니다. 재부팅 시 원래 설정으로 복원됩니다.

# 단일 장치
system.force_ip({
    'mac': '00:30:F1:02:03:04',
    'ip': '192.168.1.50',
    'subnetmask': '255.255.255.0',
    'defaultgateway': '192.168.1.1'
})

# 다중 장치 동시 설정
system.force_ip([
    {'mac': '00:30:F1:02:03:04', 'ip': '192.168.1.50',
     'subnetmask': '255.255.255.0', 'defaultgateway': '192.168.1.1'},
    {'mac': '00:30:F1:02:03:05', 'ip': '192.168.1.51',
     'subnetmask': '255.255.255.0', 'defaultgateway': '192.168.1.1'}
])

WARNING

Force IP는 임시 설정입니다. 장치 재부팅 시 초기화됩니다.

  • examples/py_force_ip.py (Lines 86-133)

고정 IP 설정 (영구)

장치에 영구적인 IP 주소를 설정합니다.

import ipaddress

devices = system.create_device()
device = system.select_device(devices)
nodemap = device.nodemap

# IP 주소 설정
new_ip = ipaddress.IPv4Address("169.254.3.2")
new_mask = ipaddress.IPv4Address("255.255.0.0")

nodemap.get_node("GevPersistentIPAddress").value = int(new_ip)
nodemap.get_node("GevPersistentSubnetMask").value = int(new_mask)

# 고정 IP 활성화, DHCP 비활성화
nodemap.get_node("GevCurrentIPConfigurationPersistentIP").value = True
nodemap.get_node("GevCurrentIPConfigurationDHCP").value = False

# (선택) ARP 충돌 감지 비활성화
nodemap.get_node("GevPersistentARPConflictDetectionEnable").value = False

IP 설정 관련 노드

노드

설명

타입

GevPersistentIPAddress

고정 IP 주소

Integer (IPv4를 정수로 변환)

GevPersistentSubnetMask

고정 서브넷 마스크

Integer

GevPersistentDefaultGateway

고정 기본 게이트웨이

Integer

GevCurrentIPConfigurationPersistentIP

고정 IP 활성화

Boolean

GevCurrentIPConfigurationDHCP

DHCP 활성화

Boolean

GevCurrentIPConfigurationLLA

Link-Local Address

Boolean (비활성화 불가)

GevPersistentARPConflictDetectionEnable

ARP 충돌 감지

Boolean

IP 설정 우선순위

우선순위

조건

적용 방식

1

고정 IP + DHCP 모두 활성화

고정 IP 사용

2

고정 IP만 활성화

고정 IP 사용

3

DHCP만 활성화

DHCP로 할당

4

모두 비활성화

LLA 자동 사용 (폴백)

  • examples/py_ipconfig_manual.py (Lines 28-74)

유니캐스트 검색 (다른 서브넷)

브로드캐스트가 도달하지 않는 다른 서브넷의 카메라를 검색합니다.

# 유니캐스트 대상 추가
system.add_unicast_discovery_device("192.168.2.50")

# 검색 시 원격 장치도 포함됨
device_infos = system.device_infos

# 유니캐스트 대상 제거
system.remove_unicast_discovery_device("192.168.2.50")

# 모든 유니캐스트 대상 제거
system.remove_unicast_discovery_device(None)
  • examples/py_enumeration_unicast.py (Lines 59-94)

스트림 설정

이미지를 수신하기 전에 스트림 관련 설정을 구성합니다.

tl_stream = device.tl_stream_nodemap

# 패킷 크기 자동 협상 (권장)
tl_stream['StreamAutoNegotiatePacketSize'].value = True

# 패킷 재전송 활성화 (UDP 손실 복구)
tl_stream['StreamPacketResendEnable'].value = True

# 버퍼 핸들링 모드 설정
tl_stream['StreamBufferHandlingMode'].value = 'NewestOnly'

스트림 설정 노드:

노드

설명

권장값

StreamAutoNegotiatePacketSize

최대 안전 패킷 크기 자동 협상

True

StreamPacketResendEnable

손실된 UDP 패킷 재전송 요청

True

StreamBufferHandlingMode

버퍼 처리 방식

'NewestOnly' (최신 프레임 우선)

  • examples/py_simple_acquisition.py (Lines 72-79)
  • examples/py_acquisition.py (Lines 59-104)

이미지 획득

# 컨텍스트 매니저 사용 (권장)
with device.start_stream():
    buffer = device.get_buffer()
    print(f"이미지: {buffer.width}x{buffer.height}, 포맷: {buffer.pixel_format.name}")
    device.requeue_buffer(buffer)

# 여러 프레임 획득
with device.start_stream():
    for i in range(10):
        buffer = device.get_buffer(timeout=2000)  # 2초 타임아웃
        print(f"프레임 {i}: {buffer.width}x{buffer.height}")
        device.requeue_buffer(buffer)
  • examples/py_simple_acquisition.py
  • examples/py_acquisition.py

장치 해제 (연결 종료)

# 모든 장치 해제
system.destroy_device()

# 특정 장치만 해제
system.destroy_device(device)

# 여러 장치 선택 해제
system.destroy_device([device1, device2])

NOTE

destroy_device()는 장치 설정을 초기화하지 않습니다. 설정을 리셋하려면 장치를 재부팅하거나 DeviceReset 노드를 사용하세요.

연결 해제 감지 (콜백)

카메라가 예기치 않게 연결 해제될 때 알림을 받을 수 있습니다.

from arena_api.callback import callback, callback_function

# 콜백 함수 정의
@callback_function.system.on_device_disconnected
def on_disconnect(device):
    print(f'장치 연결 해제됨: {device}')

# 콜백 등록
handle = callback.register(system, on_disconnect, watched_device=device)

# 연결 상태 확인
if device.is_connected():
    print("연결됨")
else:
    print("연결 해제됨")

# 콜백 해제
callback.deregister(handle)
  • examples/py_callback_on_device_disconnected.py (Lines 61-100)

다중 장치 연결

여러 카메라를 동시에 사용하는 방법입니다.

import threading

# 모든 장치 생성
devices = system.create_device()

# 각 장치 설정
for device in devices:
    nodemap = device.nodemap
    tl_stream = device.tl_stream_nodemap

    nodemap.get_node("AcquisitionMode").value = "Continuous"
    tl_stream['StreamAutoNegotiatePacketSize'].value = True
    tl_stream['StreamPacketResendEnable'].value = True
    tl_stream['StreamBufferHandlingMode'].value = 'NewestOnly'

# 병렬 획득 함수
def acquire(device, num_frames=10):
    with device.start_stream():
        for i in range(num_frames):
            buffer = device.get_buffer(timeout=2000)
            print(f"[{device}] 프레임 {i}: {buffer.width}x{buffer.height}")
            device.requeue_buffer(buffer)

# 스레드로 병렬 실행
threads = [threading.Thread(target=acquire, args=(d,)) for d in devices]
for t in threads:
    t.start()
for t in threads:
    t.join()

# 정리
system.destroy_device()
  • examples/py_acquisition_multi_device.py

전체 연결 예제 (종합)

import time
from arena_api.system import system

def main():
    # 1. 장치 검색
    print("장치 검색 중...")
    device_infos = system.device_infos
    print(f"발견된 장치: {len(device_infos)}대")

    if not device_infos:
        print("장치를 찾을 수 없습니다")
        return

    # 2. 장치 생성 (재시도 포함)
    tries = 0
    while tries < 6:
        devices = system.create_device()
        if devices:
            break
        print(f"대기 중... ({tries+1}/6)")
        time.sleep(10)
        tries += 1
    else:
        raise Exception("장치 연결 실패")

    # 3. 장치 선택
    device = system.select_device(devices)

    # 4. 스트림 설정
    tl_stream = device.tl_stream_nodemap
    tl_stream['StreamAutoNegotiatePacketSize'].value = True
    tl_stream['StreamPacketResendEnable'].value = True

    # 5. 이미지 획득
    with device.start_stream():
        buffer = device.get_buffer()
        print(f"이미지: {buffer.width}x{buffer.height}")
        print(f"포맷: {buffer.pixel_format.name}")
        device.requeue_buffer(buffer)

    # 6. 정리
    system.destroy_device()
    print("연결 종료")

if __name__ == '__main__':
    main()

관련 예제 파일 목록

주제

파일

기본 장치 검색

examples/py_enumeration.py

MAC 주소로 검색

examples/py_enumeration_mac.py

유니캐스트 검색

examples/py_enumeration_unicast.py

Force IP (임시)

examples/py_force_ip.py

고정 IP 설정 (영구)

examples/py_ipconfig_manual.py

기본 이미지 획득

examples/py_simple_acquisition.py

상세 이미지 획득

examples/py_acquisition.py

다중 장치

examples/py_acquisition_multi_device.py

연결 해제 콜백

examples/py_callback_on_device_disconnected.py

Exposure (노출) 제어

카메라 조도를 조절하는 가장 핵심적인 방법입니다.

노드

설명

비고

ExposureAuto

자동 노출 On/Off

'Off', 'On'

ExposureTime

수동 노출 시간

단위: 마이크로초(μs)

ExposureTimeSelector

다중 노출 모드 선택

HDR 등에서 사용

Example:

nodes = nodemap.get_node(['ExposureAuto', 'ExposureTime'])
nodes['ExposureAuto'].value = 'Off'
nodes['ExposureTime'].value = 4000.0  # 마이크로초
  • examples/py_exposure.py — 기본 노출 제어
  • examples/py_exposure_forhdr.py — HDR 노출
  • examples/py_exposure_long.py — 장시간 노출

Gain (게인) 제어

센서 신호를 증폭하여 이미지 밝기를 조절합니다.

노드

설명

ConversionGain

센서 신호 증폭

'Low', 'High'

Example:

nodemap['ConversionGain'].value = 'Low'
  • examples/py_helios_smooth_results.py

Binning (비닝)

여러 픽셀을 하나로 합쳐 노이즈를 줄이고 밝기를 향상시키는 방식입니다.

노드

설명

비고

BinningSelector

비닝 대상 선택

'Sensor'

BinningVertical

합칠 행(Row) 수

정수값

BinningHorizontal

합칠 열(Column) 수

정수값

BinningVerticalMode

수직 비닝 모드

'Sum'(밝기 증가), 'Average'

BinningHorizontalMode

수평 비닝 모드

'Sum'(밝기 증가), 'Average'

NOTE

'Sum' 모드는 픽셀 값을 합산하여 밝기가 증가하며, 'Average' 모드는 평균을 계산하여 밝기를 유지합니다.

  • examples/py_acquisition_sensor_binning.py

LUT (Look Up Table)

입력 밝기 값을 출력 밝기 값으로 매핑하여 감마, 대비 등을 세밀하게 조절합니다.

노드

설명

비고

LUTEnable

LUT 활성화/비활성화

True / False

LUTIndex

입력 강도 인덱스

0 ~ 최대값

LUTValue

해당 인덱스의 출력 강도 값

매핑 결과값

Example:

nodemap.get_node("LUTEnable").value = True

node_lut_index = nodemap.get_node("LUTIndex")
node_lut_value = nodemap.get_node("LUTValue")

# 강도 반전 예시
SLOPE = -1
for i in range(node_lut_index.max + 1):
    node_lut_index.value = i
    node_lut_value.value = SLOPE * i + node_lut_index.max
  • examples/py_lut.py

프레임 레이트 제어

프레임 레이트를 낮추면 더 긴 노출 시간을 확보할 수 있어, 간접적으로 조도에 영향을 줍니다.

노드

설명

비고

AcquisitionFrameRateEnable

프레임 레이트 제어 활성화

True / False

AcquisitionFrameRate

프레임 레이트 설정

단위: fps

  • examples/py_exposure_long.py

픽셀 결함 보정

죽은 픽셀(Dead Pixel)이나 고정 픽셀(Stuck Pixel)을 보정합니다.

노드

설명

타입

DefectCorrectionEnable

결함 보정 활성화

Boolean

DefectCorrectionCount

보정된 픽셀 수

Integer (읽기 전용)

DefectCorrectionIndex

보정 항목 인덱스

Integer

DefectCorrectionPositionX

보정 대상 X 좌표

Integer

DefectCorrectionPositionY

보정 대상 Y 좌표

Integer

DefectCorrectionGetNewDefect

새 결함 픽셀 추가

Command

DefectCorrectionApply

보정 목록 적용

Command

DefectCorrectionSave

보정 정보를 카메라에 저장

Command

DefectCorrectionRemove

보정 목록에서 제거

Command

  • examples/py_pixel_correction.py

3D 카메라 전용 파라미터 (Helios/HLT)

Helios 시리즈 등 3D 카메라에서 사용할 수 있는 추가 조절 옵션입니다.

노드

설명

비고

Scan3dImageAccumulation

다중 프레임 누적

밝기 및 SNR 향상

Scan3dSpatialFilterEnable

공간 필터링 활성화

노이즈 감소

Scan3dConfidenceThresholdEnable

신뢰도 필터링 활성화

저품질 데이터 제거

  • examples/py_helios_smooth_results.py

공통 사용 패턴

모든 노드는 값 설정 전에 쓰기 가능 여부와 허용 범위를 확인하는 것이 권장됩니다.

# 노드 값 설정 전 범위 확인
node = nodemap.get_node('ExposureTime')
if node.is_writable:
    value = min(max(desired_value, node.min), node.max)
    node.value = value

# 열거형 노드의 사용 가능한 값 확인
enum_node = nodemap.get_node('ExposureAuto')
print(enum_node.enumentry_names)  # ['Off', 'Once', 'Continuous']

# 커맨드 노드 실행
cmd_node = nodemap.get_node('DefectCorrectionApply')
cmd_node.execute()

조도 조절 방법 요약

방법

직접/간접

효과

부작용

ExposureTime 증가

직접

밝기 증가

모션 블러 발생 가능

ConversionGain 증가

직접

밝기 증가

노이즈 증가

Binning (Sum 모드)

직접

밝기 증가

해상도 감소

LUT 조절

직접

밝기/대비 커스터마이징

다이나믹 레인지 손실 가능

프레임 레이트 감소

간접

더 긴 노출 시간 확보

초당 프레임 수 감소

Scan3dImageAccumulation

직접 (3D 전용)

SNR 및 밝기 향상

촬영 시간 증가

공통 인터페이스 참고 사항

  • 대부분의 노드는 .min, .max 속성으로 유효 범위를 확인할 수 있습니다.
  • .is_readable, .is_writable 속성으로 읽기/쓰기 가능 여부를 확인할 수 있습니다.
  • 열거형 노드는 .enumentry_names로 사용 가능한 값 목록을 확인할 수 있습니다.
  • Float/Integer 노드는 .inc 속성으로 증분 단위를 확인할 수 있습니다.

See also

Favorite site