AIDT 온디바이스 국방 MUM-T 틸트로터 무인기(Tiltrotor UAV) 나셀 틸트 각도 변환 천이 회랑(Transition Corridor) 비선형 서보 엔진

헬리콥터 수직이착륙(VTOL)에서 고속 전진비행 천이 모드 전단 실속(Stall) 방지, 로터 추력-주익 양력 결합 분배, 10,000Hz C# 엔진

1. 개요

활주로가 없는 야전 및 함정 갑판에서 수직 이착륙(VTOL)하고, 순항 시에는 300노트 이상의 고속 비행을 달성하는 틸트로터 무인기(Tiltrotor UAV)는 헬리콥터 모드(나셀 90°)에서 고정익 비행기 모드(나셀 0°)로의 비행 모드 전환(천이 비행, Transition)을 수행합니다. 천이 비행 구간에서는 로터의 수직 추력이 주익의 공기역학적 양력으로 점진 이전되는데, 나셀 틸트 속도가 비행 속도 증가율보다 너무 빠르면 주익이 실속(Wing Stall)에 빠져 급격한 고도 강하가 발생하고, 너무 느리면 로터 과회전 및 블레이드 플래핑 플러터(Flapping Flutter)가 유발됩니다. 따라서 허용 비행 속도와 나셀 각도 간의 안전 마진을 규정하는 '천이 회랑(Transition Corridor)' 내부를 밀리초 단위로 추종하며 로터 총피치와 조종익면을 재분배해야 합니다. 본 고에서는 10,000Hz 주기로 비행 회랑 경계를 계산하고 나셀 서보 액추에이터를 구동하는 0-Alloc C# 엔진을 구현합니다.

2. 수학적 모델링 및 지배 방정식

천이 비행 구간에서의 수직 및 수평 합성 힘 평형 방정식은 다음과 같습니다:

\[ F_z = 2 T_{rotor} \sin(\beta_n + \alpha) + \frac{1}{2} \rho V^2 S_w C_L(\alpha, \beta_n) = m g \]
\[ F_x = 2 T_{rotor} \cos(\beta_n + \alpha) - \left( \frac{1}{2}\rho V^2 S_w C_D(\alpha) + D_{fuselage} \right) = m \dot{V} \]

나셀 틸트각 \(\beta_n\)에 따른 천이 비행 회랑(Transition Corridor) 하한 실속 속도 및 상한 구조한계 속도식은 다음과 같습니다:

\[ V_{min}(\beta_n) = \sqrt{\frac{2(mg - 2 T_{max} \sin\beta_n)}{\rho S_w C_{L,max}}}, \quad V_{max}(\beta_n) = V_{aero\_limit}(\beta_n) \]

천이 회랑 중심 궤적 추종을 위한 최적 나셀 틸트 각속도 비선형 서보식은 다음과 같습니다:

\[ \dot{\beta}_n^{cmd} = -K_v \left( V_{pitot} - V_{ref}(\beta_n) \right) - K_\alpha (\alpha_{curr} - \alpha_{trim}) \quad (|\dot{\beta}_n| \le 8^\circ/\text{s}) \]

3. 실시간 C# 서보 제어기 구현

다음은 피토관 대기속도 및 받음각 센서 데이터를 10,000Hz 주기로 분석하여 유압 나셀 틸트 액추에이터와 플래퍼론 각도를 제어하는 0-Alloc C# 엔진 구현체입니다:

TiltrotorNacelleTransitionServoEngine.cs
using System;
using System.Runtime.CompilerServices;

namespace ZeliDesk.Defense.Tiltrotor
{
    public readonly ref struct TiltrotorAirFrame
    {
        public readonly double AirspeedKnots;
        public readonly double CurrentNacelleAngleDegrees; // 90 = Helicopter mode, 0 = Airplane mode
        public readonly double AngleOfAttackDegrees;
        public readonly double AltitudeMeters;
        public readonly double RotorCollectiveThrustNewtons;

        public TiltrotorAirFrame(
            double airspeedKnots,
            double currentNacelleAngleDegrees,
            double angleOfAttackDegrees,
            double altitudeMeters,
            double rotorCollectiveThrustNewtons)
        {
            AirspeedKnots = airspeedKnots;
            CurrentNacelleAngleDegrees = currentNacelleAngleDegrees;
            AngleOfAttackDegrees = angleOfAttackDegrees;
            AltitudeMeters = altitudeMeters;
            RotorCollectiveThrustNewtons = rotorCollectiveThrustNewtons;
        }
    }

    public ref struct TiltrotorControlCommand
    {
        public double NacelleRateDegSec; // Positive: tilt forward towards airplane mode
        public double ElevonPitchTrimDegrees;
        public double TransitionCorridorMarginKnots;
        public bool IsInsideTransitionCorridor;
        public bool IsConversionCompleted;
    }

    public ref struct TiltrotorNacelleTransitionServoEngine
    {
        private const double MaxNacelleRateDegSec = 8.0;
        private readonly double _kpSpeed;
        private readonly double _kpAlpha;
        private readonly double _dt;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public TiltrotorNacelleTransitionServoEngine(double kpSpeed, double kpAlpha, double dt)
        {
            _kpSpeed = kpSpeed;
            _kpAlpha = kpAlpha;
            _dt = dt;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void ComputeTransitionServo(in TiltrotorAirFrame frame, out TiltrotorControlCommand cmd)
        {
            cmd = default;
            double nacelle = frame.CurrentNacelleAngleDegrees;

            // Transition schedule: Airspeed as function of nacelle angle
            // At 90 deg (Helo): 0~40 kts, At 0 deg (Airplane): 120~280 kts
            double fraction = (90.0 - nacelle) / 90.0; // 0 (helo) to 1 (airplane)
            double vMinCorridor = 30.0 + (fraction * 70.0);  // 30 -> 100 kts
            double vMaxCorridor = 70.0 + (fraction * 150.0); // 70 -> 220 kts
            double vTarget = 0.5 * (vMinCorridor + vMaxCorridor);

            double speedErr = frame.AirspeedKnots - vTarget;
            bool isInsideCorridor = frame.AirspeedKnots >= vMinCorridor && frame.AirspeedKnots <= vMaxCorridor;

            // Nacelle rate command
            double nacelleRate = _kpSpeed * (frame.AirspeedKnots - vMinCorridor) - (_kpAlpha * (frame.AngleOfAttackDegrees - 4.0));
            nacelleRate = Math.Clamp(nacelleRate, -MaxNacelleRateDegSec, MaxNacelleRateDegSec);

            // Don't tilt forward if below stall speed
            if (frame.AirspeedKnots < vMinCorridor)
            {
                nacelleRate = Math.Min(0.0, nacelleRate); // Only allow tilting back to helicopter
            }

            // Stop when completed
            if (nacelle <= 0.0 && nacelleRate > 0)
            {
                nacelleRate = 0.0;
            }

            double elevonTrim = (4.0 - frame.AngleOfAttackDegrees) * 1.5;
            elevonTrim = Math.Clamp(elevonTrim, -15.0, 15.0);

            cmd.NacelleRateDegSec = nacelleRate;
            cmd.ElevonPitchTrimDegrees = elevonTrim;
            cmd.TransitionCorridorMarginKnots = frame.AirspeedKnots - vMinCorridor;
            cmd.IsInsideTransitionCorridor = isInsideCorridor;
            cmd.IsConversionCompleted = nacelle <= 0.5;
        }
    }
}

4. 교육 및 실무 적용 방안

  • 육군/해병대 항공단 및 항공우주연구원(KARI): 틸트로터 공력 전환 비행동역학 및 천이 회랑 자동제어 이론 교육.
  • 차세대 사단급/함상용 틸트로터 무인기 사업: 실속 방지 및 자동 모드 전환 비선형 온디바이스 비행제어기 탑재.