ISO 13374 표준 기반 PHM 시스템 설계: OSA-CBM 6단계 아키텍처로 구현하는 산업 표준 예지정비 플랫폼

Updated Feb 6, 2026

ISO 13374와 OSA-CBM: 예지정비의 국제 표준

예지정비(PHM, Prognostics and Health Management) 시스템을 구축할 때 가장 먼저 부딪히는 문제는 “어떤 아키텍처로 설계해야 하는가?”입니다. 이 질문에 대한 산업계의 답이 바로 ISO 13374 표준OSA-CBM(Open System Architecture for Condition-Based Maintenance) 모델입니다.

ISO 13374는 상태 모니터링 및 진단을 위한 데이터 처리, 통신 및 프레젠테이션에 관한 국제 표준으로, 예지정비 시스템의 상호 운용성과 확장성을 보장합니다.

OSA-CBM은 6단계 계층 구조로 센서 데이터가 최종 의사결정까지 전달되는 과정을 정의하며, 각 계층은 독립적으로 개발·교체 가능한 모듈로 설계됩니다.

OSA-CBM 6단계 아키텍처 상세

1단계: Data Acquisition (데이터 수집)

센서로부터 원시 신호(raw signal)를 수집하는 계층입니다. 진동, 온도, 압력, 전류 등 물리량을 디지털 신호로 변환합니다.

주요 기술:
– DAQ(Data Acquisition) 보드: NI DAQ, Advantech 등
– 샘플링 레이트: 설비 회전속도의 2.5~10배 (나이퀴스트 정리)
– 타임스탬프 동기화: GPS, PTP(Precision Time Protocol)

import nidaqmx
from datetime import datetime

def acquire_vibration_data(channel, sample_rate=25600, duration=10):
    """
    NI DAQ를 이용한 진동 데이터 수집
    sample_rate: 25.6 kHz (10 kHz 회전체 기준 2.56배)
    """
    with nidaqmx.Task() as task:
        task.ai_channels.add_ai_voltage_chan(channel)
        task.timing.cfg_samp_clk_timing(
            rate=sample_rate,
            sample_mode=nidaqmx.constants.AcquisitionType.FINITE,
            samps_per_chan=sample_rate * duration
        )
        data = task.read(number_of_samples_per_channel=nidaqmx.constants.READ_ALL_AVAILABLE)
        timestamp = datetime.utcnow().isoformat()
        return {"timestamp": timestamp, "raw_signal": data, "fs": sample_rate}

2단계: Data Manipulation (데이터 전처리)

원시 신호를 분석 가능한 형태로 가공합니다. 노이즈 제거, 정규화, 단위 변환 등을 수행합니다.

주요 처리:
– High-pass filter: DC 성분 제거 (cutoff ~1 Hz)
– Anti-aliasing filter: 고주파 노이즈 제거
– 가속도 → 속도 → 변위 적분 변환
– Engineering unit 변환 (V → m/s²)

import numpy as np
from scipy.signal import butter, filtfilt

def preprocess_vibration(raw_signal, fs, sensitivity=100):
    """
    진동 신호 전처리
    sensitivity: 센서 감도 (mV/g)
    """
    # 1. V to m/s² 변환
    accel_ms2 = (raw_signal / sensitivity) * 1000 * 9.81

    # 2. High-pass filter (DC 제거)
    b, a = butter(4, 1.0, btype='high', fs=fs)
    accel_filtered = filtfilt(b, a, accel_ms2)

    return accel_filtered

3단계: State Detection (상태 감지)

전처리된 신호에서 특징(feature)을 추출하여 설비의 현재 상태를 수치화합니다.

시간 도메인 특징:

특징 수식 의미
RMS 1Ni=1Nxi2\sqrt{\frac{1}{N}\sum_{i=1}^{N} x_i^2} 전체 진동 에너지
Peak max(xi)\max(|x_i|) 충격 성분 감지
Crest Factor PeakRMS\frac{\text{Peak}}{\text{RMS}} 충격 대 평균 비율 (베어링 결함 지표)
Kurtosis 1Ni=1N(xiμσ)4\frac{1}{N}\sum_{i=1}^{N}\left(\frac{x_i – \mu}{\sigma}\right)^4 분포의 뾰족함 (이상치 감지)

주파수 도메인 특징:

import numpy as np
from scipy.fft import fft

def extract_features(signal, fs):
    """
    OSA-CBM Layer 3: 상태 감지 특징 추출
    """
    # 시간 도메인
    rms = np.sqrt(np.mean(signal**2))
    peak = np.max(np.abs(signal))
    crest_factor = peak / rms
    kurtosis = np.mean(((signal - np.mean(signal)) / np.std(signal))**4)

    # 주파수 도메인
    fft_vals = np.abs(fft(signal))
    freqs = np.fft.fftfreq(len(signal), 1/fs)

    # BPFO, BPFI 대역 에너지 (예: 100-200 Hz)
    bearing_band = (freqs > 100) & (freqs < 200)
    bearing_energy = np.sum(fft_vals[bearing_band]**2)

    return {
        "rms": rms,
        "peak": peak,
        "crest_factor": crest_factor,
        "kurtosis": kurtosis,
        "bearing_energy": bearing_energy
    }

4단계: Health Assessment (건전성 평가)

추출된 특징을 기반으로 설비의 건전성 점수(Health Index, HI)를 계산합니다. 정상 범위를 벗어난 정도를 정량화합니다.

건전성 지수 계산 예시:

<br/>HI=1Feature<em>currentFeature</em>baselineFeature<em>thresholdFeature</em>baseline<br/><br /> HI = 1 – \frac{\text{Feature}<em>{\text{current}} – \text{Feature}</em>{\text{baseline}}}{\text{Feature}<em>{\text{threshold}} – \text{Feature}</em>{\text{baseline}}}<br />

여기서:
HI=1HI = 1: 완전 정상 (새 설비 수준)
HI=0HI = 0: 고장 임계점 도달
Feature<em>baseline\text{Feature}<em>{\text{baseline}}: 정상 운전 시 평균값
Feature</em>threshold\text{Feature}</em>{\text{threshold}}: 고장으로 간주되는 한계값

def assess_health(features, baseline, threshold):
    """
    OSA-CBM Layer 4: 건전성 평가
    """
    health_indices = {}
    for key in features:
        if key in baseline and key in threshold:
            hi = 1 - (features[key] - baseline[key]) / (threshold[key] - baseline[key])
            health_indices[key] = np.clip(hi, 0, 1)  # 0~1 범위로 클리핑

    # 종합 건전성 지수 (가중 평균)
    weights = {"rms": 0.3, "crest_factor": 0.3, "kurtosis": 0.2, "bearing_energy": 0.2}
    overall_hi = sum(health_indices.get(k, 1) * weights.get(k, 0) for k in weights)

    return {"health_indices": health_indices, "overall_health": overall_hi}

5단계: Prognostics (예지)

건전성 지수의 시계열 추세를 분석하여 잔여 수명(RUL, Remaining Useful Life)을 예측합니다.

RUL 예측 방법론:

방법 설명 장점 단점
선형 회귀 과거 HI 추세를 직선으로 외삽 구현 간단, 해석 용이 비선형 열화 패턴 대응 불가
지수 평활 EWMA로 추세 추정 최근 데이터에 가중치 부여 장기 예측 정확도 낮음
LSTM 딥러닝 기반 시계열 예측 복잡한 패턴 학습 데이터 필요량 多, 블랙박스
Particle Filter 베이지안 추론 기반 확률적 예측 불확실성 정량화 계산 비용 高

선형 회귀 기반 RUL 예측 예시:

import numpy as np
from sklearn.linear_model import LinearRegression

def predict_rul(health_history, failure_threshold=0.3):
    """
    OSA-CBM Layer 5: RUL 예측 (선형 회귀)
    health_history: [(timestamp, HI), ...] 리스트
    """
    times = np.array([h[0] for h in health_history]).reshape(-1, 1)
    his = np.array([h[1] for h in health_history])

    # 선형 회귀 모델 학습
    model = LinearRegression()
    model.fit(times, his)

    # HI가 failure_threshold에 도달하는 시점 계산
    # HI = a * t + b → t = (HI - b) / a
    a, b = model.coef_[0], model.intercept_
    if a >= 0:  # 열화가 진행되지 않음
        return float('inf')

    rul_time = (failure_threshold - b) / a
    current_time = times[-1][0]
    rul_days = (rul_time - current_time) / (24 * 3600)  # 초 → 일 변환

    return max(0, rul_days)

6단계: Decision Support (의사결정 지원)

RUL 예측 결과를 정비 전략, 부품 재고, 생산 일정과 통합하여 최적 정비 시점을 권고합니다.

의사결정 로직:

def recommend_action(rul_days, health_index, production_schedule):
    """
    OSA-CBM Layer 6: 정비 의사결정
    """
    if health_index < 0.3 or rul_days < 3:
        return {
            "action": "EMERGENCY_STOP",
            "priority": "CRITICAL",
            "message": f"즉시 정비 필요 (HI={health_index:.2f}, RUL={rul_days:.1f}일)"
        }
    elif rul_days < 7:
        # 생산 일정 고려한 정비 계획
        next_downtime = production_schedule.get_next_planned_downtime()
        return {
            "action": "SCHEDULE_MAINTENANCE",
            "priority": "HIGH",
            "recommended_date": next_downtime,
            "message": f"다음 계획 정지 시 정비 권고 (RUL={rul_days:.1f}일)"
        }
    elif rul_days < 30:
        return {
            "action": "ORDER_PARTS",
            "priority": "MEDIUM",
            "message": f"부품 주문 시작 (RUL={rul_days:.1f}일)"
        }
    else:
        return {
            "action": "CONTINUE_MONITORING",
            "priority": "LOW",
            "message": f"정상 모니터링 지속 (HI={health_index:.2f})"
        }

실무 구현 아키텍처: Python + MQTT + TimescaleDB

시스템 구성:

[센서] → [Edge Device (Layer 1-3)] → MQTT → [Cloud Server (Layer 4-6)]
                                              
                                        TimescaleDB (시계열 DB)
                                              
                                        Grafana Dashboard

Layer 1-3 (Edge):
– Raspberry Pi 4 + Python
– 실시간 데이터 수집 및 특징 추출 (10초 주기)
– MQTT로 경량 데이터 전송 (네트워크 대역폭 절약)

Layer 4-6 (Cloud):
– AWS EC2 + Docker
– TimescaleDB: 시계열 특징 저장 (압축률 95%)
– FastAPI: REST API 제공
– Celery: 비동기 RUL 계산 (1시간 주기)

데이터베이스 스키마 예시:

-- TimescaleDB Hypertable
CREATE TABLE equipment_features (
    time TIMESTAMPTZ NOT NULL,
    equipment_id INT,
    rms DOUBLE PRECISION,
    crest_factor DOUBLE PRECISION,
    kurtosis DOUBLE PRECISION,
    health_index DOUBLE PRECISION,
    rul_days DOUBLE PRECISION
);

SELECT create_hypertable('equipment_features', 'time');

ISO 13374 표준 준수 체크리스트

상호 운용성: 각 계층이 표준 인터페이스(JSON, Protobuf)로 통신
모듈성: Layer 3 알고리즘 교체 시 Layer 4-6 영향 없음
확장성: 새 센서 추가 시 Layer 1만 수정
추적성: 모든 데이터에 타임스탬프 + 메타데이터 포함
보안: MQTT TLS 암호화, DB 접근 제어

마무리

ISO 13374 기반 OSA-CBM 아키텍처는 예지정비 시스템의 산업 표준 설계 방법론입니다. 6단계 계층 구조는 복잡한 PHM 시스템을 명확하게 모듈화하여 개발·유지보수·확장을 용이하게 만듭니다.

핵심 요점:
– Layer 1-2는 데이터 품질 확보에 집중 (샘플링, 필터링)
– Layer 3은 도메인 지식 기반 특징 설계가 성능 결정
– Layer 4-5는 통계·ML 기법 선택이 예측 정확도 좌우
– Layer 6은 비즈니스 로직 통합으로 실질적 가치 창출

프로젝트 초기부터 이 표준을 따르면, 벤더 종속성을 피하고 장기적으로 유지 가능한 PHM 플랫폼을 구축할 수 있습니다. 특히 Edge-Cloud 하이브리드 구조로 설계하면 네트워크 비용을 줄이면서도 확장성을 확보할 수 있습니다.

Did you find this helpful?

☕ Buy me a coffee

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

TODAY 369 | TOTAL 2,592