작성: 테크챌린지 우승팀 이스라엘 블랑카스 알바레스, 이그나시오 카라 마르틴, 니콜라스 게레로 가르시아, 베니토 팔라시오스 산체스.
1년 전 우리는 제4회 ETSIIT 기술 챌린지(영상)에 도전했습니다. 우리는 스페인 그라나다 대학교 전기공학·컴퓨터공학과 학생 넷입니다.
우리 팀 '프로메테우스'는 RTI 후원 테크 챌린지에서 우승했습니다. 4~5인 팀이 외부 파트너가 제시한 실세계 문제를 해결하는 제품을 만드는 과제였고, 올해 주제는 "멀티 에이전트 비디오 분산 시스템"이었습니다.
실무 경험을 쌓기 위해 참가했고, 1년 뒤 여전히 학생 신분으로 상업적 기회를 포착해 경쟁력 있는 제품 '로카뷰어(Locaviewer)'를 설계하고 시장 전략을 수립하고 작동 프로토타입을 완성했습니다. 학업 병행하며 이룬 성과입니다.
Locaviewer
많은 부모가 어린이집 자녀의 건강과 발달을 걱정합니다. Locaviewer는 부모에게 자녀의 실시간 가시성을 제공합니다. 홍보 영상을 제작했고, 소스 코드는 MIT 라이선스로 GitHub에 공개했습니다.
팀 조직과 일정
약 250시간 소요. 주 1회 최소 4시간, 마지막 달엔 주 20시간으로 확대. 효율을 위해 두 서브팀으로 분할: 실내 블루투스 위치 알고리즘 팀, 비디오 캡처·인코딩·디코딩·RTI Connext DDS 배포 팀.
위치 알고리즘
핵심은 어린이집 내 각 아동 위치 파악. 각 아동은 블루투스 센서가 내장된 손목 밴드를 착용해 벽면 고정 동글에 수신 신호 강도(RSSI)를 지속 보고. RSSI 값을 거리로 매핑해 신뢰성 있는 관계 수립.
그림 2. 각도와 거리에 따른 블루투스 신호 실증 측정.그림 3. Locaviewer 착용형 기기.
RSSI 읽기는 미니 컴퓨터(라즈베리 파이 또는 MK802 III)로 전송되어 삼각측량 알고리즘으로 각 아동 위치 산출. 카메라 위치를 알면 각 아동에게 최적의 카메라 선택 가능.
그림 4. 실내 삼각측량.
비디오 녹화 애플리케이션
GStreamer for Java로 실시간 비디오 캡처, 인코딩, 디코딩, 디스플레이 처리. vlcj 같은 대안은 라즈베리 파이 미지원이나 지연 요건 미충족. GStreamer가 적합해 AppSink, AppSource 요소로 인코딩된 비디오 버퍼에 접근해 DDS 토픽으로 발행.
VP8(WebM) 인코더 선택. Java 래퍼가 GStreamer 0.10과 호환돼 해상도를 낮춰 플랫폼 제약 맞춤. 테스트 구성은 라즈베리 파이, 향후 MK802 III로 이전해 동일 비용으로 더 높은 처리 성능 확보 계획.
그림 5. 녹화·인코딩·비디오 획득용 GStreamer 파이프라인.
VP8 인코더 생성 Java 코드:
Element codec = ElementFactory.make("vp8enc", null); codec.set("threads", 5); codec.set("max-keyframe-distance", 20); codec.set("speed", 5); Element capsDst = ElementFactory.make("capsfilter", null); capsDst.setCaps(Caps.fromString("video/x-vp8 profile=(string)2"));
클라이언트 측 파이프라인 구성:
그림 6. 설정·디코딩·재생용 GStreamer 파이프라인.
VP8 디코더 Java 코드:
String caps = "video/x-vp8, width=(int)320, height=(int)240, framerate=15/1"; Element capsSrc = ElementFactory.make("capsfilter", null); capsSrc.setCaps(Caps.fromString(caps)); Element queue = ElementFactory.make("queue2", null); Element codec = ElementFactory.make("vp8dec", null); Element convert = ElementFactory.make("ffmpegcolorspace", null);
JPEG 인코딩도 실험했으나 패킷 크기가 커 실시간 스트리밍에 비현실적.
DDS 아키텍처
발행-구독 모델이 핵심으로, 소켓 연결을 수동 관리할 필요 제거. 자체 래퍼 라이브러리 DDStheus로 DDS 상호작용 추상화.
그림 7. 시스템 전체 DDS 아키텍처.
최종 시스템은 3개 언어로 구현된 6개 프로그램이 3개 토픽 공유:
Python: 저수준 블루투스 처리
MATLAB/Octave: 삼각측량 스크립트
Java: RTI Connext DDS 통합 및 GUI 개발
그림 8. 센서 프로그램 플로차트.
비디오 캡처·인코딩 후 Java 프로그램 Gava가 비디오 데이터 토픽으로 스트림 전송, 각 패킷에 카메라 ID와 방 정보 태깅. ContentFilteredTopic으로 카메라 위치·방별 스트림 필터링.
카메라 메타데이터(ID, 방, 위치)는 각 발행자의 USER_DATA QoS 필드에 저장. 삼각측량 미니컴퓨터가 방 안 모든 카메라 발견, 신규/오프라인 카메라 실시간 감지, 카메라 선택 알고리즘 조정.
그림 9. 비디오 프로그램 플로차트.
최종 단계: 센서·비디오 데이터를 아동 데이터 토픽으로 집계. 방 서버(라즈베리 파이 또는 MK802 III)가 아동 위치 삼각측량 및 최적 카메라 선택. 방별 센서 필터링, 카메라 정보 조회, Octave 스크립트로 아동 위치·최적 카메라 계산, 결과 클라우드 발행. 아동 ID와 비디오 품질을 필터 키로 사용해 효율적 구독.
리소스 최적화를 위해 방 서버는 특정 아동 데이터 구독 요청 시에만 삼각측량 스크립트 실행(구독자 발견 및 ContentFilteredTopic 필터로 판단).
장애 허용 메커니즘도 구현: 각 미니컴퓨터가 USER_DATA에 우선순위 ID 발행. 가장 낮은 ID 노드가 새 노드 중 더 낮은 ID 참여 전까지 활성 서버 역할.
그림 10. 방 서버 프로그램 플로차트.
사용자 애플리케이션
두 가지 최종 사용자 앱 개발. 첫째, 부모가 자녀 실시간 시청. 둘째, 어린이집 직원이 모든 카메라 모니터링, 부모 접근 관리, 출석 자동 통제.
그림 11. 부모용 클라이언트 앱.그림 12. 어린이집용 보안 카메라 프로그램.
마무리하며
두 가지 주요 과제:
저가 블루투스 기기(~$5)에서 정확한 RSSI 값 획득. 위치 오차 3m에서 0.5m로 줄이는 알고리즘 개발. Java에 저수준 블루투스 지원이 없어 Python(pybluez)과 Java 연동으로 데이터 교환.
비디오 인코딩 최적화. 인코딩 버퍼를 노출하는 라이브러리 찾기 어려웠고, 라즈베리 파이에서 GStreamer 0.10 튜닝 난항. 최종 구성 3~5초 지연. MK802 III(와이파이, 듀얼 코어 Cortex-A9)로 교체 시 성능 개선 기대.
RTI Connext DDS가 네트워킹, 직렬화, QoS 처리해 큰 노력 절감. 공대와 RTI의 기회와 자원 지원에 감사드립니다.