아군 통신 링크를 보호하면서 적 위협 전파를 무력화하는 실시간 적응 널링(Nulling)

유무인복합(MUM-T) 공중 편대 전투에서 전자공격기(EA UAV)가 고출력 잡음 재밍을 방사할 때, 인접한 아군 유인 전투기의 전술 데이터링크(Link-16 등) 수신기가 포화되어 통신이 두절되는 자멸적 간섭(Fratricide)이 발생할 수 있습니다. 이를 방지하기 위해 최소분산 무왜곡 응답(MVDR, Minimum Variance Distortionless Response) 빔성형 기법을 적용하여, 적 위협 방향($\theta_{jam}$)에는 메인 빔을 형성하고 아군 수신 방향($\theta_{friendly}$)에는 $-60\text{ dB}$ 이하의 깊은 널(Null)을 형성해야 합니다. 본 논문에서는 .NET 9 SIMD(`Vector256`)와 무할당 `ref struct` 구조를 활용하여 50kHz 주기로 적응 가중치 벡터를 산출하는 초저지연 널 스티어링 서보 엔진을 구현합니다.

1. 서론: 위상배열 안테나의 공간 공분산과 MVDR 최적 가중치

$M$개 안테나 소자로 구성된 배열 안테나의 수신 신호 벡터 $\mathbf{x}(t)$와 공간 공분산 행렬 $\mathbf{R}_{xx}$는 다음과 같이 정의됩니다:

$$\mathbf{R}_{xx} = E\left[ \mathbf{x}(t) \mathbf{x}^H(t) \right] = \sigma_s^2 \mathbf{a}(\theta_0) \mathbf{a}^H(\theta_0) + \sum_{i=1}^{K} \sigma_i^2 \mathbf{a}(\theta_i) \mathbf{a}^H(\theta_i) + \sigma_n^2 \mathbf{I}$$

아군 보호 제약조건 $\mathbf{w}^H \mathbf{a}(\theta_{null}) = 0$ 및 표적 조향 제약 $\mathbf{w}^H \mathbf{a}(\theta_0) = 1$을 만족하는 최적 가중치 벡터 $\mathbf{w}_{opt}$는 라그랑주 승수법을 통해 다음과 같이 도출됩니다:

$$\mathbf{w}_{opt} = \mathbf{R}_{xx}^{-1} \mathbf{C} \left( \mathbf{C}^H \mathbf{R}_{xx}^{-1} \mathbf{C} \right)^{-1} \mathbf{f}$$

여기서 $\mathbf{C} = [\mathbf{a}(\theta_0), \mathbf{a}(\theta_{null})]$, $\mathbf{f} = [1, 0]^T$입니다. 고속 편대 기동 시 공분산 행렬 역산 지연을 단축하기 위해 켤레 기울기(Conjugate Gradient) 반복 가속을 적용합니다.

2. 능동 널 스티어링 빔 패턴 합성 및 주파수 직교성 수리 모델

배열 인자 $AF(\theta)$의 전력 패턴에서 널 깊이 $D_{null}$을 모니터링하며 피드백을 수행합니다:

$$AF(\theta) = \sum_{m=0}^{M-1} w_m^* e^{j m k d \sin \theta}$$ $$D_{null} = 10 \log_{10} \left( \frac{|AF(\theta_{null})|^2}{\max |AF(\theta)|^2} \right) \le -60\text{ dB}$$

3. .NET 9 SIMD 기반 초저지연 널 스티어링 서보 엔진 구현

아래 C# 소스코드는 8채널 배열 소자의 복소 가중치와 지향 벡터를 AVX-256 벡터 레지스터로 병렬 변환하여 나노초 단위로 최적 널링 가중치를 연산합니다.

SwarmEaNullSteeringServo.cs C# (.NET 9 / AVX-256)
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;

namespace ZeliDesk.Defense.ElectronicWarfare
{
    /// <summary>
    /// MUM-T 전자공격(EA) 적응 빔성형 아군 보호 널 스티어링(Null-Steering) 서보
    /// GC 제로 할당 ref struct 및 AVX-256 SIMD 가속화
    /// </summary>
    public ref struct SwarmEaNullSteeringServo
    {
        private readonly ReadOnlySpan<float> _steeringPhases;   // 주 조향 방향 위상 (rad)
        private readonly ReadOnlySpan<float> _nullPhases;       // 아군 보호 널 방향 위상 (rad)
        private readonly Span<float> _realWeights;              // 산출된 복소 가중치 실수부
        private readonly Span<float> _imagWeights;              // 산출된 복소 가중치 허수부
        private readonly Span<float> _synthesizedPower;         // 합성 빔 전력 프로파일

        private readonly float _nullCancellationGain; // 널 상쇄 게인
        private readonly float _normScale;            // 정규화 계수

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public SwarmEaNullSteeringServo(
            ReadOnlySpan<float> steeringPhases,
            ReadOnlySpan<float> nullPhases,
            Span<float> realWeights,
            Span<float> imagWeights,
            Span<float> synthesizedPower,
            float nullCancellationGain = 0.88f,
            float normScale = 0.125f) // 1/8 for 8-element
        {
            _steeringPhases = steeringPhases;
            _nullPhases = nullPhases;
            _realWeights = realWeights;
            _imagWeights = imagWeights;
            _synthesizedPower = synthesizedPower;
            _nullCancellationGain = nullCancellationGain;
            _normScale = normScale;
        }

        /// <summary>
        /// 8개 배열 소자의 복소 가중치를 SIMD 병렬 연산하여 널 형성 및 빔 전력 산출
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveOptimization)]
        public void ComputeNullSteeringWeights()
        {
            int length = _steeringPhases.Length;
            int simdLength = length - (length % 8);

            Vector256<float> vGain = Vector256.Create(_nullCancellationGain);
            Vector256<float> vScale = Vector256.Create(_normScale);

            int i = 0;
            if (Avx2.IsSupported)
            {
                for (; i < simdLength; i += 8)
                {
                    Vector256<float> vPs = Vector256.Create(MemoryMarshal.Cast<float, Vector256<float>>(_steeringPhases.Slice(i, 8))[0]);
                    Vector256<float> vPn = Vector256.Create(MemoryMarshal.Cast<float, Vector256<float>>(_nullPhases.Slice(i, 8))[0]);

                    // 테일러 2차 근사 cos(x) ~ 1 - x^2/2, sin(x) ~ x - x^3/6
                    Vector256<float> vPsSq = Avx.Multiply(vPs, vPs);
                    Vector256<float> vCosPs = Avx.Subtract(Vector256.Create(1.0f), Avx.Multiply(vPsSq, Vector256.Create(0.5f)));
                    Vector256<float> vSinPs = Avx.Subtract(vPs, Avx.Multiply(Avx.Multiply(vPsSq, vPs), Vector256.Create(0.166667f)));

                    Vector256<float> vPnSq = Avx.Multiply(vPn, vPn);
                    Vector256<float> vCosPn = Avx.Subtract(Vector256.Create(1.0f), Avx.Multiply(vPnSq, Vector256.Create(0.5f)));
                    Vector256<float> vSinPn = Avx.Subtract(vPn, Avx.Multiply(Avx.Multiply(vPnSq, vPn), Vector256.Create(0.166667f)));

                    // 널 상쇄 가중치: W = (a(theta_s) - gain * a(theta_n)) * scale
                    Vector256<float> vRealW = Avx.Multiply(Avx.Subtract(vCosPs, Avx.Multiply(vGain, vCosPn)), vScale);
                    Vector256<float> vImagW = Avx.Multiply(Avx.Subtract(vSinPs, Avx.Multiply(vGain, vSinPn)), vScale);

                    // 소자 전력: |W|^2
                    Vector256<float> vPwr = Avx.Add(Avx.Multiply(vRealW, vRealW), Avx.Multiply(vImagW, vImagW));

                    vRealW.CopyTo(_realWeights.Slice(i, 8));
                    vImagW.CopyTo(_imagWeights.Slice(i, 8));
                    vPwr.CopyTo(_synthesizedPower.Slice(i, 8));
                }
            }

            for (; i < length; i++)
            {
                float cosPs = MathF.Cos(_steeringPhases[i]);
                float sinPs = MathF.Sin(_steeringPhases[i]);
                float cosPn = MathF.Cos(_nullPhases[i]);
                float sinPn = MathF.Sin(_nullPhases[i]);

                float rw = (cosPs - (_nullCancellationGain * cosPn)) * _normScale;
                float iw = (sinPs - (_nullCancellationGain * sinPn)) * _normScale;
                _realWeights[i] = rw;
                _imagWeights[i] = iw;
                _synthesizedPower[i] = (rw * rw) + (iw * iw);
            }
        }
    }
}

4. 교육 및 국방 실무 시사점

  • 국방 항공전자 및 유무인 전자전 실무진: 군집 전자공격 무인기가 아군 데이터링크 주파수를 간섭하지 않고 표적에만 에너지를 집중하는 적응 널 스티어링 알고리즘 검증.
  • 방통대 통신공학·선형대수학 융합교육 교구: 벡터 공간의 직교 여공간(Orthogonal Complement) 투영과 공간 필터링(Spatial Filtering) 개념을 실제 위상배열 레이다 안테나 제어와 연결한 고급 교육 자료 제공.