설비 여덟 대가 묶인 조립 공정에서, 한 설비가 고장 나면 그 줄 전체가 멈춰 병목이 생기는 문제가 있었다. 이걸 풀려고 설비 상태를 실시간으로 모니터링하고, 고장이 나면 작업을 다른 설비로 우회시키는 통합 관제 시스템을 만들었다. 이 글은 그 과정을 정리한 것이다.
프로젝트 개요
연구실의 레고 조립 공정은 자동화 설비 여덟 대로 구성돼 있다. 설비들이 순서대로 작업을 넘기는 구조라, 중간의 한 대가 멈추면 뒤 공정이 줄줄이 대기에 들어간다.
- 프로젝트: 조립 공정 통합 관제 시스템 Coordinator 개발
- 목표: 설비 상태를 실시간 모니터링하고, 고장 설비의 작업을 다른 설비로 동적 재분배해 병목 해소
- 사용 기술: OPC UA 기반 상태 수집, MQTT 기반 명령 전달, Rule 기반 작업 재분배, MySQL
- 구성: 자동화 설비 8대, 설비별 PC에 OPC UA Server, 중앙통합관제 PC, 근접 센서와 QR 기반 데이터 수집
- 결과: 실제 설비에서 전체 공정 완료 시간 약 15분 단축
문제 정의
연구실 공정은 설비 간 통신이 끊겨 있었다. 각 설비는 자기 일만 할 뿐, 옆 설비가 지금 멈췄는지 돌아가는지를 몰랐다. 그래서 시연 과정에서 중간의 한 설비가 고장 나면 그 작업이 갈 곳을 잃고, 뒤 공정이 통째로 대기에 들어갔다. 한 대의 고장이 라인 전체의 병목으로 번지는 구조였다.
내가 해결해야할 문제는 두가지였다.
- 하나는 지금 어느 설비가 어떤 상태인지를 중앙에서 실시간으로 알아야 한다는 것.
- 다른 하나는 고장을 감지했을 때 그 작업을 멈춰 세우지 않고 일할 수 있는 다른 설비로 넘겨야 한다는 것.
상태를 모으는 문제와 작업을 다시 뿌리는 문제다.
접근 방향 — 왜 OPC UA와 MQTT를 나눠 썼는가
이 시스템에는 성격이 다른 두 종류의 통신이 필요했다. 설비 상태를 끌어올리는 통신과, 설비에 명령을 내리는 통신이다. 둘을 같은 방식으로 묶지 않고 OPC UA와 MQTT로 나눈 게 설계의 핵심이다.
상태 수집에는 OPC UA를 썼다.
산업 현장의 PLC는 벤더에 따라 지원하는 통신 프로토콜이 다르다. 이더캣이나 프로피넷 같은 이더넷 통신도 있고 모드버스나 CC-Link 같은 필드버스도 있다. 이렇게 제각각인 하위 장비를 상위 시스템에서 표준화된 방식으로 읽으려고 나온 게 OPC UA다. ISA-95 기준으로 하위 레벨 장비와 상위 시스템을 표준 아키텍처로 잇는 역할을 한다. 그래서 설비마다 OPC UA Server를 두고, 상위에서는 클라이언트로 붙어 일관된 방식으로 상태를 읽도록 했다.
명령 전달에는 MQTT를 썼다.
한 번에 여러 설비로 명령을 뿌려야 하고, 응답을 기다리며 멈춰 있을 필요가 없는 통신이라 MQTT의 다대다 비동기 구조가 맞았다. 작업 시작이나 특정 설비에 대한 작업 할당, 정지 같은 명령을 토픽으로 쏘면, 각 설비가 자기에게 해당하는 토픽을 구독해 받아 처리한다. 동기 방식이었다면 요청을 보내고 응답이 올 때까지 대기해야 하는데, 설비 여러 대에 명령을 동시에 흘려야 하는 상황에서는 그 대기가 곧 지연이 된다.
정리하면 OPC UA는 올려서 모니터링하는 통로, MQTT는 내려서 명령하는 통로다. 읽기와 쓰기를 다른 프로토콜로 분리한 셈이다.
시스템 구성

- 데이터 수집: 근접 IN 센서, QR ID, 근접 OUT 센서로 설비에 들어오고 나가는 제품과 상태를 잡는다.
- 설비단: 설비마다 PC에 OPC UA Server를 두고, 장비 데이터를 모아 상태가 바뀔 때마다 노드 값을 실시간으로 갱신한다.
- 중앙단: 중앙통합관제 PC가 클라이언트로 각 OPC UA Server에 붙어 Subscription 방식으로 상태와 생산 지표를 모니터링한다.
- 명령: 설비 상태에 따라 MQTT로 각 설비에 실행 명령을 보내 작업을 재분배한다.
- 저장: 수집한 데이터는 MySQL에 적재한다.
설비 PC를 게이트웨이로 두고, 상태 변화를 이벤트로 OPC UA Server에 올리는 구조다. 폴링으로 끊임없이 묻는 대신 상태가 바뀔 때만 갱신하고 구독하는 쪽이 부하가 적었다.
고장을 어떻게 정의하고 감지했는가
작업을 재분배하려면 그 앞에 "이 설비가 지금 일을 못 하고 있다"를 판단하는 단계가 있어야 한다. 사실 이 부분이 시스템의 출발점인데, 처음에는 여기를 가볍게 봤다.
연구실 운영에서는 담당자가 공정을 지켜보다가 "어 저거 멈췄네" 하고 사람이 판단하는 식이었다. 데모 환경이라 사람이 옆에 붙어 있었고, 설비가 멈추면 눈으로 바로 보였기 때문이다. 그런데 통합 관제 시스템을 만드는 이상, 사람 눈에 의존하는 감지는 그대로 둘 수 없었다. 중앙 시스템이 스스로 고장을 인식해야 작업을 자동으로 우회시킬 수 있다.
그래서 현업에서 설비 고장을 어떻게 감지하는지를 기준으로 삼아 설계했다. 산업 현장에서 설비 이상은 보통 세 가지 층위로 잡힌다.
- 첫째는 설비가 스스로 내보내는 상태값이다. 산업 설비는 자기 상태를 IDLE, RUN, DOWN, ERROR 같은 상태머신으로 갖고 있고, 이 상태를 표준 인터페이스로 올린다. 반도체 쪽 SECS/GEM 표준만 봐도 설비의 상태머신과 알람 관리, 상태 데이터 수집을 규격으로 정의해 둔다. 관제 시스템은 이 상태값을 읽어 ERROR나 DOWN이면 고장으로 판단한다. 이 프로젝트에서 OPC UA 노드로 올라온 상태값을 읽어 ERROR 설비를 후보에서 거른 것이 여기에 해당한다.
- 둘째는 알람 이벤트다. 상태값과 별개로 설비가 구체적인 에러 코드를 이벤트로 올린다. 어떤 종류의 고장인지를 코드로 구분할 수 있어서, 단순히 멈췄다가 아니라 왜 멈췄는지까지 받을 수 있다.
- 셋째는 통신 두절 감지다. 이게 상태값만으로는 못 잡는 영역이다. 설비가 ERROR를 올리는 건 그래도 살아서 말을 하는 상태이고, 전원이나 통신이 끊기면 설비는 아무 말도 못 한다. 그래서 현업에서는 설비가 주기적으로 보내는 신호, 흔히 heartbeat라고 부르는 신호를 두고, 그게 정해진 시간 안에 안 오면 통신 두절이나 설비 정지로 판단한다. 와야 할 신호가 안 오는 것 자체를 고장 신호로 쓰는 것이다. 상태값이 ERROR로 바뀌는 것과 응답이 아예 없는 것은 다른 고장이라, 둘을 같이 봐야 한다.
여기서 산업과 연구실의 차이를 짚어야 한다.
산업 현장의 고장은 부품 마모, 안전 인터락 작동, 물리적 설비 다운처럼 하드웨어가 실제로 멈추는 경우가 많고, 라인 정지가 곧 큰 비용과 안전 문제로 이어진다. 그래서 진동이나 온도로 고장을 미리 예측하는 예지보전까지 들어간다. 반면 연구실 공정의 고장은 대부분 더 소프트하다. 작업이 끼이거나, 제품이 제때 안 빠지거나, 처리가 밀려 멈춘 것처럼 보이는 경우다. 본인 공정의 S-Path도 하드웨어가 부서진 게 아니라 처리가 밀려 병목이 된 쪽에 가까웠다.
그래서 이 프로젝트의 감지는 상태값을 기본으로 하되, 센서 흐름으로 멈춤을 보조 판단하는 수준으로 잡았다. 근접 IN 센서로 제품이 들어온 게 잡혔는데 정해진 시간 안에 근접 OUT 센서에서 안 빠지면, 그 설비가 작업을 못 끝내고 멈춰 있다고 본 것이다. 데모 규모에서는 상태값과 센서 흐름만으로 "지금 일을 못 하고 있다"를 충분히 잡을 수 있었고, 더 정교한 감지는 산업 규모로 갈 때 필요한 부분으로 남겨 두었다.
작업 재분배 로직
고장을 감지하면 그 작업을 어느 설비로 보낼지 정해야 한다. 여기는 복잡한 학습 기반이 아니라 Rule 기반으로 짰다. 규칙이 명확하고 동작을 예측할 수 있어야 현장에서 믿고 쓸 수 있다고 봤다.
우선순위는 세 단계다. 먼저 ERROR 상태가 아닌 설비만 후보로 남긴다. 그다음 그 작업을 실제로 수행할 수 있는 설비로 좁힌다. 마지막으로 남은 후보 중에서 예상 완료 시간이 가장 짧은 설비에 작업을 할당한다.
예상 완료 시간은 그 설비에 쌓인 대기 작업 수에 해당 설비의 Cycle Time을 곱해 계산했다.
예상 완료 시간 = 현재 대기 작업 수 × 해당 설비 Cycle Time
단순히 "비어 있는 설비"가 아니라 "지금 보내면 가장 빨리 끝나는 설비"를 고르는 게 핵심이다. 큐가 짧아도 Cycle Time이 길면 늦어지고, Cycle Time이 짧아도 줄이 길면 밀린다. 둘을 곱해 비교하면 그 순간 가장 빨리 처리해줄 설비가 나온다.
고장 설비 우회로 전체 공정 완료 시간15분 단축
통합 관제를 붙인 뒤로는 S-Path가 고장 또는 병목 상태로 감지되면 그 설비를 작업 분배 후보에서 빼버렸다. 막혀 있는 설비에 더 보내지 않고, 그 작업을 수행 가능한 다른 멀쩡한 설비로 돌린 것이다. 일을 못 하는 설비에 작업이 쌓이는 걸 막자 라인 전체가 덜 막혔다.
이 덕분에 실제 설비에서 전체 공정 완료 시간을 약 15분 단축했다. 고장 설비에 작업이 계속 몰려 대기가 길어지던 구조를, 고장 설비를 빼고 멀쩡한 설비로 일을 돌리는 구조로 바꿈으로서 병목 문제를 해결할 수 있었다.
현장 적용 관점에서의 고민
- 고장 감지의 수준이 시스템의 고장 감지는 상태값과 센서 흐름에 기댄다. 데모 규모에서는 충분했지만, 산업 라인이라면 부족하다. 현업에서는 설비 알람 코드로 고장 종류를 구분하고, heartbeat로 통신 두절을 잡고, 진동이나 온도 데이터로 고장을 미리 예측하는 예지보전까지 들어간다. 본인 공정은 소프트한 멈춤 위주라 거기까지 갈 필요가 없었지만, 하드웨어가 실제로 다운되고 안전이 걸린 환경으로 가면 감지 체계 자체를 SECS/GEM 같은 표준 알람 모델 위에 다시 세워야 한다.
- MQTT의 토픽 우선순위 부재: MQTT는 토픽에 우선순위가 없다. 이 공정에서는 우선순위가 충돌하는 상황이 생기지 않아 실질적인 문제는 아니었다. 다만 공정이 커져서 중요도가 다른 메시지가 함께 다뤄진다면, 수신 측에서 토픽별로 처리 순서를 다르게 두는 방식으로 보완해야 한다.
- 설비 수가 늘어났을 때의 부하: 설비가 늘면 메시지 수와 연결 수, 이벤트 처리량이 함께 늘어난다. MQTT 브로커가 단일 구조면 모든 메시지가 한 브로커에 몰려 부하가 생긴다. 이건 브로커 클러스터링으로 풀 수 있다. 브로커 여러 대를 클러스터로 묶고, 클라이언트는 로드밸런서로 여러 브로커에 분산 접속하게 한다. 브로커 사이에 세션 정보와 토픽 라우팅 정보를 공유하면 어느 브로커에 붙어도 메시지가 전달된다. 이렇게 하면 수평 확장이 가능하고 장애가 나도 가용성을 확보할 수 있다.
시행착오
- 처음에 고장 감지를 너무 가볍게 봤다. 담당자가 보다가 멈춘 걸 알아채는 식으로 굴러가니, 자동 감지를 따로 만들 생각을 안 했다. 그런데 중앙 시스템이 고장 설비를 빼고 작업을 자동으로 다시 뿌리려면, 사람 눈이 아니라 시스템이 고장을 인식해야 했다. 사람이 빠진 자리를 무엇으로 메울지 정하면서, 현업의 상태값과 센서 기반 감지를 끌어와 채웠다. 이 단계가 빠져 있었으면 재분배 로직은 돌릴 입력 자체가 없었다.
- 통신 방식도 처음엔 하나로 통일하려 했다. 상태도 명령도 한 프로토콜로 묶으면 단순하지 않을까 했는데, 두 통신은 성격이 너무 달랐다. 상태 수집은 제각각인 설비를 표준 방식으로 읽어야 하는 문제라 OPC UA가 맞았고, 명령 전달은 여러 설비에 동시에 비동기로 뿌려야 하는 문제라 MQTT가 맞았다. 하나로 묶으려던 걸 둘로 나눈 게 오히려 깔끔했다.
- 재분배 로직에서도 처음엔 그냥 비어 있는 설비로 보내면 된다고 생각했다. 그런데 비어 있다고 빨리 끝나는 게 아니었다. Cycle Time이 긴 설비는 줄이 짧아도 늦었다. 그래서 대기 작업 수와 Cycle Time을 곱해 예상 완료 시간으로 비교하는 쪽으로 바꿨다. 빈자리가 아니라 가장 빨리 끝낼 자리를 고르는 게 맞았다.
프로젝트 회고
- 잘한 점
- 사람 눈에 의존하던 고장 인식을, 상태값과 센서 흐름 기반의 자동 감지로 옮겨 중앙 시스템이 스스로 판단하게 했다.
- 상태 수집과 명령 전달을 OPC UA와 MQTT로 나눠, 각 통신의 성격에 맞는 프로토콜을 골랐다.
- 설비 상태를 이벤트 기반으로 올리고 구독하는 구조로, 폴링 부담 없이 실시간 모니터링을 구현했다.
- 재분배를 Rule 기반으로 명확하게 짜되, 예상 완료 시간으로 후보를 골라 단순 빈자리 할당보다 합리적으로 분배했다.
- 고장 설비에 작업이 계속 몰려 대기가 길어지던 구조를, 고장 설비를 빼고 멀쩡한 설비로 일을 돌리는 구조로 바꿔, 실제 설비에서 공정 완료 시간을 15분 단축했다.
- 고장 감지가 상태값과 센서 흐름 수준에 머물렀다. 알람 코드 분류나 heartbeat 기반 통신 두절 감지, 예지보전까지는 가지 못했다.
- MQTT 단일 브로커 구조라, 설비가 크게 늘어나면 부하가 몰리는 한계가 있다. 확장 시 클러스터링이 필요하다.
- 토픽 우선순위가 없어, 중요도가 다른 메시지가 섞이는 환경으로 커지면 수신 측 처리 순서 설계가 추가로 필요하다.
'스마트팩토리 프로젝트' 카테고리의 다른 글
| [연구실 과제] VLA 성능 향상을 위한 데이터 수집 (1) | 2026.06.29 |
|---|---|
| [연구실 과제] 조립 불량 검사 기반 제품 적재 공정 자동화 (0) | 2026.06.29 |
| [연구실 과제] 3D Pick & Place (0) | 2026.06.29 |
| [산학과제] 도메인 분리 표현 학습으로 내부 균열 탐지 모델 성능 개선 (0) | 2026.06.24 |
| [팀 프로젝트] PINN을 활용하여 외삽 구간 SoC 성능 추정 (0) | 2026.06.24 |