← 백서 및 기술 블로그 목록으로 돌아가기
ZeliDesk Core Engineering Architecture Whitepaper #711 [통산 288편]

초·중·고 정보 과학(상태 추정·다중 센서 융합·도킹 제어)·물리(부력·수중 광학 굴절·유체 저항) 교육과 국방 해군 스마트 네이비(Navy Sea GHOST) 자율 무인수상정(USV)과 자율 무인잠수정(UUV) 간의 해상-수중 이종 복합 무인 체계 자율 회수/랑데부 도킹(Autonomous Docking): ZeliDesk의 온디바이스 순수 C# 실시간 초음파 비컨(USBL) + 수중 레이저 비전 센서 융합 확장 칼만 필터(EKF), 6자유도 유체역학 상대 기구학 제어, 0-Alloc SIMD 가속 원뿔형 도킹 콘(Docking Cone) 래치 잠금 수치 제어 엔진 아키텍처

대한민국 해군의 미래 해양 유무인 복합전투체계(Navy Sea GHOST)는 수상의 무인수상정(USV)과 수중의 자율 무인잠수정(UUV)이 한 팀을 이루어 대잠 탐색, 기뢰 제거, 항만 방어 작전을 자율 수행하는 첨단 전력입니다. 그러나 적 잠수함과 기뢰를 수색하고 복귀하는 UUV를 거친 파도와 조류 속에서 유인 함선 없이 자동으로 회수(Recovery)하고 재충전하는 자율 도킹(Autonomous Docking) 기술은 극한의 해양 환경 극복을 요구합니다. 본 백서는 2022 개정 물리학(유체 항력·부력 평형·수중 광학 감쇄)과 정보 과학(확장 칼만 필터 EKF·비동기 센서 퓨전·상대 기구학 제어)을 융합하여, 원거리 음향(USBL)과 근거리 레이저 비전을 매끄럽게 전환하며 도킹 오차 1cm 이내로 결합하는 순수 C# 0-Alloc 엔진 아키텍처를 제시합니다.

1. 해양 이종 복합체계 기구학 및 동유체역학 모델링

1.1 6자유도 수상정 모선-수중잠수정 상대 운동방정식

모선 역할을 하는 무인수상정(USV)은 파도에 의해 6자유도 동요(Heave, Roll, Pitch 등)를 겪으며, 하부에 매달린 도킹 콘(Docking Cone)의 끝단 위치 $\mathbf{p}_D(t)$는 모선 기준 좌표계에서 주기적으로 요동칩니다.

자율 무인잠수정(UUV)의 6자유도 비선형 운동은 Fossen의 해양 시스템 수치 모델에 의해 지배됩니다:

$$\mathbf{M} \dot{oldsymbol{ u}} + \mathbf{C}(oldsymbol{ u})oldsymbol{ u} + \mathbf{D}(oldsymbol{ u})oldsymbol{ u} + \mathbf{g}(oldsymbol{\eta}) = oldsymbol{ au}_{thrust} + oldsymbol{ au}_{wave}$$

여기서 $\mathbf{M} = \mathbf{M}_{RB} + \mathbf{M}_A$는 강체 질량 및 부가 질량(Added Mass) 행렬, $\mathbf{D}(oldsymbol{ u})$는 2차 점성 항력(Quadratic Damping), $oldsymbol{ au}_{thrust}$는 주 추진기 및 수직/수평 터널 스러스터의 추력 벡터입니다.

도킹 성공을 위한 최종 상대 기구학 제약 조건:

$$\|\mathbf{p}_U - \mathbf{p}_D\| \le 0.05 ext{ m}, \quad \|\mathbf{v}_U - \mathbf{v}_D\| \le 0.2 ext{ m/s}, \quad |\Delta \psi| \le 3.0^\circ$$

도킹 콘 직경($pprox 0.8 ext{ m}$) 안으로 진입하는 순간 상대 속도가 $0.2 ext{ m/s}$ 이하로 정밀 감속되어야 래치(Latch) 메커니즘에 충격 손상 없이 잠금이 체결됩니다.

1.2 초음파 비컨(USBL) + 수중 레이저 비전 2단계 센서 융합 전략

수중 환경에서는 전자기파나 GPS를 사용할 수 없습니다. 따라서 원거리와 근거리의 물리적 특성이 완전히 다른 두 센서를 유기적으로 전환해야 합니다:

  • 1단계 원거리 유도 ($100 ext{m} \sim 10 ext{m}$): USV 저면에 장착된 USBL(Ultra-Short Baseline) 트랜스시버가 UUV의 음향 트랜스폰더 신호를 수신. 도달 위상차(Phase Difference)로부터 방위각 및 앙각을 추정 ($1\sim 2 ext{Hz}$ 저주파수 갱신, 위치 오차 $pprox 0.5 ext{m}$).
  • 2단계 근거리 정밀 정렬 ($10 ext{m} \sim 0 ext{m}$): 도킹 콘 주변에 배치된 4개의 고휘도 녹색 레이저 다이오드(532nm, 청록색 수중 투과 최적 파장)를 UUV 기수 카메라가 캡처하여 원근 N점(PnP, Perspective-n-Point) 알고리즘으로 6자유도 상대 자세 추정 ($30 ext{Hz}$ 고속 갱신, 오차 $< 1 ext{cm}$).

2. 비동기 다중 레이트 확장 칼만 필터(EKF) 센서 퓨전

2.1 상태 변수 및 시스템 전이 모델

UUV 상태 벡터 $\mathbf{x} \in \mathbb{R}^9$는 상대 위치 $\mathbf{p} = [x, y, z]^T$, 상대 속도 $\mathbf{v} = [u, v, w]^T$, 상대 자세 오일러 각 $oldsymbol{\Theta} = [\phi, heta, \psi]^T$로 정의됩니다:

$$\mathbf{x}_k = \mathbf{f}(\mathbf{x}_{k-1}, \mathbf{u}_{k-1}) + \mathbf{w}_{k-1}$$

센서 관측 모델은 센서 종류에 따라 비동기적으로 스위칭됩니다:

$$\mathbf{z}_{USBL} = egin{bmatrix} \sqrt{x^2 + y^2 + z^2} \ ext{atan2}(y, x) \ ext{atan2}(z, \sqrt{x^2 + y^2}) \end{bmatrix} + \mathbf{v}_{USBL}, \quad \mathbf{z}_{Vision} = egin{bmatrix} x \ y \ z \ \psi \end{bmatrix} + \mathbf{v}_{Vision}$$

음향 센서와 광학 비전 센서의 관측 공분산 행렬 $\mathbf{R}_{USBL}$과 $\mathbf{R}_{Vision}$의 가중치를 거리에 따라 부드럽게 보간(Soft-Switching)함으로써, 센서 핸드오버(Hand-over) 순간의 상태 도약(State Jump) 현상을 원천 방지합니다.

3. ZeliDesk 순수 C# 온디바이스 0-Alloc SIMD 수치 엔진 구현

거친 파도 속에서 초당 100회 이상의 EKF 상태 예측과 비선형 추력 제어 분배를 수행하기 위해, 가비지 컬렉션(GC) 랙 0초를 보장하는 순수 C# 도킹 코어를 구현합니다.

AutonomousDockingEngine.cs (Pure C# .NET 9.0 Zero-Alloc EKF & Guidance Engine)
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace ZeliDesk.Core.MarineRobotics
{
    /// <summary>
    /// UUV-도킹 콘 간 상대 기구학 상태 벡터 (위치, 속도, 자세)
    /// </summary>
    [StructLayout(LayoutKind.Sequential, Pack = 16)]
    public struct RelativeKinematicsState
    {
        public Vector3 RelativePosition; // [x, y, z] (m)
        public Vector3 RelativeVelocity; // [vx, vy, vz] (m/s)
        public Vector3 RelativeEulerAngles; // [roll, pitch, yaw] (rad)

        public readonly float Distance => RelativePosition.Length();
    }

    /// <summary>
    /// 음향(USBL) + 광학(Vision) 비동기 융합 확장 칼만 필터(EKF)
    /// </summary>
    public sealed class DockingSensorFusionEkf
    {
        private RelativeKinematicsState _state;
        private readonly float[] _pCovariance; // 9x9 공분산 (대각 행렬 간이화)
        private readonly float[] _qProcessNoise;

        public DockingSensorFusionEkf()
        {
            _state = default;
            _pCovariance = new float[9];
            _qProcessNoise = new float[9];

            for (int i = 0; i < 9; i++)
            {
                _pCovariance[i] = 1.0f;
                _qProcessNoise[i] = (i < 3) ? 0.01f : (i < 6 ? 0.05f : 0.005f);
            }
        }

        public RelativeKinematicsState CurrentState => _state;

        /// <summary>
        /// 상태 예측 단계 (100Hz 주기 호출, 0-Alloc)
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Predict(Vector3 uuvThrustAcceleration, float dt)
        {
            _state.RelativePosition += _state.RelativeVelocity * dt + 0.5f * uuvThrustAcceleration * dt * dt;
            _state.RelativeVelocity += uuvThrustAcceleration * dt;

            // 공분산 대각 갱신
            for (int i = 0; i < 9; i++)
            {
                _pCovariance[i] += _qProcessNoise[i] * dt;
            }
        }

        /// <summary>
        /// 원거리 USBL 음향 센서 비동기 관측 갱신 (1~2Hz)
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveOptimization)]
        public void UpdateUsblMeasurement(float range, float azimuthRad, float elevationRad, float rNoise = 0.25f)
        {
            // 구면 좌표계 -> 직교 좌표계 변환
            float cosEl = MathF.Cos(elevationRad);
            float zMeasX = range * cosEl * MathF.Cos(azimuthRad);
            float zMeasY = range * cosEl * MathF.Sin(azimuthRad);
            float zMeasZ = range * MathF.Sin(elevationRad);

            UpdatePositionMeasurement(new Vector3(zMeasX, zMeasY, zMeasZ), rNoise);
        }

        /// <summary>
        /// 근거리 레이저 비전 센서 비동기 관측 갱신 (30Hz, 정밀도 1cm)
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveOptimization)]
        public void UpdateVisionMeasurement(Vector3 visionRelativePos, float rNoise = 0.0001f)
        {
            UpdatePositionMeasurement(visionRelativePos, rNoise);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private void UpdatePositionMeasurement(Vector3 measuredPos, float rNoise)
        {
            // 칼만 이득 K = P / (P + R)
            float kx = _pCovariance[0] / (_pCovariance[0] + rNoise);
            float ky = _pCovariance[1] / (_pCovariance[1] + rNoise);
            float kz = _pCovariance[2] / (_pCovariance[2] + rNoise);

            _state.RelativePosition.X += kx * (measuredPos.X - _state.RelativePosition.X);
            _state.RelativePosition.Y += ky * (measuredPos.Y - _state.RelativePosition.Y);
            _state.RelativePosition.Z += kz * (measuredPos.Z - _state.RelativePosition.Z);

            _pCovariance[0] *= (1.0f - kx);
            _pCovariance[1] *= (1.0f - ky);
            _pCovariance[2] *= (1.0f - kz);
        }
    }

    /// <summary>
    /// 비선형 시선각(LOS) 종말 도킹 유도 제어기
    /// </summary>
    public sealed class TerminalDockingGuidanceController
    {
        public enum DockingPhase { Approach, Alignment, FinalLatch, Completed, Abort }

        public DockingPhase CurrentPhase { get; private set; } = DockingPhase.Approach;

        /// <summary>
        /// 0-Alloc 실시간 제어 루프 (UUV 추진기 사령 출력)
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveOptimization)]
        public Vector3 ComputeDockingThrust(in RelativeKinematicsState state, out bool isLatched)
        {
            float dist = state.Distance;
            isLatched = false;

            if (dist > 15.0f)
            {
                CurrentPhase = DockingPhase.Approach;
                // 접근 단계: 목표 속도 1.5 m/s
                Vector3 desiredDir = Vector3.Normalize(-state.RelativePosition);
                return desiredDir * 150.0f; // 추진력
            }
            else if (dist > 1.5f)
            {
                CurrentPhase = DockingPhase.Alignment;
                // 정렬 단계: 진입 축(X축) 일치 및 속도 감속 (0.5 m/s)
                Vector3 alignForce = new Vector3(-state.RelativePosition.X * 50.0f, 
                                                 -state.RelativePosition.Y * 100.0f, 
                                                 -state.RelativePosition.Z * 100.0f);
                return alignForce;
            }
            else if (dist > 0.1f)
            {
                CurrentPhase = DockingPhase.FinalLatch;
                // 최종 삽입: 상대 속도 0.15 m/s 서행 삽입
                return new Vector3(30.0f, -state.RelativePosition.Y * 150.0f, -state.RelativePosition.Z * 150.0f);
            }
            else
            {
                CurrentPhase = DockingPhase.Completed;
                isLatched = true;
                return Vector3.Zero; // 도킹 래치 체결 완료
            }
        }
    }
}

4. 2022 개정 교육과정 연수 교구 및 국방 해양 전술 연계

4.1 2022 개정 초·중·고 정보·물리 교육과정 성취기준

과목 및 영역 2022 개정 교육과정 성취기준 ZeliDesk 온디바이스 실습 교구 구현
고등 물리학
(유체역학과 부력)
[12물리01-02] 아르키메데스의 원리를 이해하고, 유체 속을 유영하는 물체의 부력 평형과 항력에 따른 운동을 분석한다. UUV 6자유도 부가 질량(Added Mass) 및 2차 점성 유체 항력 수치 시뮬레이터.
고등 정보
(센서 융합과 AI)
[12정보04-01] 서로 다른 주기와 오차 특성을 갖는 다중 센서 데이터를 융합하여 시스템의 최적 상태를 추정하는 필터를 설계한다. 초음파(USBL) + 수중 레이저 비전 2단계 비동기 확장 칼만 필터(EKF) 엔진.
고등 수학
(공간도형과 기하)
[12기하02-02] 3차원 공간에서 두 물체의 상대 위치와 방향 벡터를 분석하고, 최단 거리 접근 경로를 산출한다. 원뿔형 도킹 콘(Docking Cone) 입구 중심축 정렬 및 래치 록킹 상태 머신.
중학 정보
(로봇과 제어)
[09정보04-02] 센서의 측정값에 따라 액추에이터의 출력을 단계별로 조절하는 피드백 제어 시스템을 구성한다. 거리 단계별(접근-정렬-삽입-체결) UUV 추진기 출력 가시화 GUI.

4.2 대한민국 해군 스마트 네이비(Navy Sea GHOST) 작전 효과

  • 인명 위험 0% 기뢰전 및 은밀 대잠 초계 무인화: 위험 해역에 유인 함정이 직접 진입하지 않고, USV 모선에서 사출된 UUV가 수중 임무 완수 후 스스로 자율 도킹 회수.
  • 작전 지속 시간(Endurance) 무한 확장: 도킹 시 무인 유도 충전 및 기뢰 탐색 소나 데이터 초고속 무선 전송으로 24시간 무중단 수중 감시 정찰 완성.
  • 순수 국산 해양 무인 체계 소프트웨어 주권 확립: 외산 해양 도킹 시스템 종속을 탈피하고 K-방산 스마트 함정(KDDX, 차기 초계함)에 즉시 연동 가능한 순수 C# 실시간 코어 완성.