위성 궤도 데이터(TLE) 정규 표현식으로 유효성 검증하기

·2025년 2월 16일
4
post-thumbnail

개요

인공위성의 TLE를 업데이트하는 기능을 개발하며 유효성 검사를 진행해야 했으므로 근본적으로 TLE가 무엇인지 알아야 했습니다.
TLE는 위성의 궤도를 나타내는 데이터로, 이를 통해 위성의 위치와 이동 경로를 추적할 수 있습니다.
이번 글에서는 TLE가 무엇인지, 데이터가 어떻게 구성되어 있는지, 어떻게 유효성 검증을 진행하는지에 대해 살펴보도록 하겠습니다.

구현이 완료된 화면 예시

TLE

ISS (ZARYA)
1 25544U 98067A   25045.89486670  .00016158  00000-0  28923-3 0  9992
2 25544  51.6379 192.7304 0003914 317.8087 178.5772 15.50122294496197

국제우주정거장(ISS) TLE 예제

TLE(Two-Line Element Set)는 위성의 궤도 정보를 기술하는 형식입니다.
두 개의 텍스트 라인으로 이루어진 데이터이기 때문에 'Two-Line Element'라 부릅니다.
각 라인은 위성 궤도에 대한 중요한 정보를 포함하고 있으며, 이를 통해 위성의 위치, 속도, 궤도 주기 등을 추적할 수 있습니다.

TLE는 여러 기관과 웹사이트에서 제공하고 있습니다. 대표적으로는 다음과 같은 곳들이 있습니다.

  • CelesTrak : 다양한 위성의 TLE를 제공하며 위성 추적 및 궤도 분석을 위한 다양한 도구와 정보를 제공합니다.
  • Space-Track : 미국 정부가 운영하는 사이트로, TLE를 제공하지만 회원가입이 필요합니다.
  • N2YO : TLE를 제공하며, 실시간 위성 궤도 추적 기능도 존재합니다.

TLE 데이터 구조

미국 국립해양대기청(NOAA) TLE 구조 예시

TLE는 3줄로 구성되며 첫 줄은 위성 이름(생략 가능), 나머지 두 줄이 실제 궤도 데이터를 담고 있습니다.
69자 데이터 두 줄로 구성되며, 유효한 문자는 숫자 0-9, 대문자 A-Z, 마침표, 공백, 더하기 및 빼기 기호뿐으로 다른 문자는 유효하지 않습니다.
한 열에 이 모든 문자가 가능한 것은 아니며, 각 요소마다 유효한 문자가 다르게 적용됩니다.
각 줄의 첫 번째 요소는 해당 줄의 줄 번호를 나타냅니다. 지금부터 줄 번호를 제외한 각 요소의 의미와 정규식을 사용하여 검증하는 방법을 알아보도록 하겠습니다.

첫 번째 줄

위성 카탈로그 번호, 분류 (3~8번)

3~7번은 북미항공우주방위사령부(NORAD)에서 지구 궤도에 있는 모든 물체에 발사 또는 발견 순서대로 지정한 고유 식별 번호로, 위성 카탈로그 번호 또는 NORAD ID등으로 불립니다.

8번은 데이터의 보안 분류를 나타냅니다. 공개적으로 사용 가능한 모든 데이터에는 'U'로 작성되어 있으며 이것은 분류되지 않은 데이터를 나타냅니다.

  • U: 분류되지 않음(unclassified)
  • C: 분류됨(classified)
  • S: 비밀(secret)

이것을 종합하면, 5개의 숫자와 'U', 'C', 'S' 중 하나의 값으로 정규 표현식으로 작성하면 아래와 같습니다.

/\d{5}[UCS]/

국제 지정자 (10~17번)

국제 지정자는 국제 조약에 따라 로켓 및 위성을 위한 World Data Center-A(WDC-A-R&S)에서 지정한 식별자입니다.
WDC-AR&S는 이 값을 유지 관리하기 위해 NORAD 및 NASA의 국가 우주 과학 데이터 센터(NSSDC)와 협력합니다. 국제 지정자는 아래와 같이 구성됩니다.

  • 10~11번 : 각 객체에 대한 발사 연도 두 자리
  • 12~14번 : 그 해의 3자리 증가 발사 번호
  • 15~17번 : 발사체에서 분리된 위성의 순서를 나타내는 최대 3자리 코드(오른쪽 또는 왼쪽 정렬이 가능하지만 왼쪽 정렬을 선호)

예를 들어, 98067A 라면 98년도에 발사된, 67번째 로켓으로, 첫 번째 분리된 위성이라는 의미를 갖고 있습니다.
이 세 개의 필드는 비워둘 수 있지만, 비워둔다 해도 공백으로 모두 존재해야 합니다.

이것을 종합하면, 5자리 숫자와 한 개의 알파벳 + 공백 아니면, 두 개의 알파벳 | 5자리 숫자와 공백 또는 알파벳 (오른쪽 정렬이 가능하므로) | 공백 8개의 조건으로 정규 표현식으로 작성하면 아래와 같습니다.

/(\d{5}[A-Z][ A-Z]{2}|\d{5}[ A-Z]{2}[A-Z]| {8})/

Epoch (19~32번)

에포크는 특정한 기준 시간(기점)부터 경과한 시간을 나타내는 방식으로, 위성이 기준이 되는 시간에 어떤 위치에 있었는지를 나타내며 아래와 같이 구성됩니다.

  • 19~20번 : 두 자리 숫자의 연도
  • 21~32번 : 해당 연도의 날짜 및 시간

예를 들어, 25045.89486670 라면, 25년도의 45번째 날(2월 14일) 21시 29분(아래 계산 참고) 을 기점으로 위성의 궤도 값을 나타내는 것을 알 수 있습니다.

0.89486670 × 24시간 ≈ 21.48시간
0.48시간 × 60분 = 28.8분
∴ 0.89486670 ≈ 21시 29분

이것을 종합하면, 5자리 숫자, 점(.), 8자리 숫자 값으로 정규 표현식으로 작성하면 아래와 같습니다.

/\d{5}\.\d{8}/

평균 운동의 1차 미분 (34~43번)

평균 운동의 1차 미분은 위성이 1일 동안 하는 회전(궤도) 횟수의 일일 변화율을 2로 나눈 값입니다.
이는 위성이 얼마나 많은 각도를 이동하는지를 나타내어, 공기 저항을 뚫고 얼마나 잘 나아갈 수 있는지를 수치화한 값입니다.
첫 번째 요소에는 공백이나, 빼기, 더하기 기호가 들어갈 수 있으며 그다음으로는 점(.)과 8자리 숫자가 이어집니다. 정규 표현식으로 작성하면 아래와 같습니다.

/[ \-+]\.\d{8}/

평균 운동의 2차 미분 (45~52번)

평균 운동의 2차 미분은 1차 도함수가 시간이 지나면서 얼마나 변화하는지를 나타냅니다. 즉, 평균 운동의 변화율이 점점 증가하는지, 감소하는지를 나타냅니다.
속도 변화의 가속도를 나타내며, 위성 궤도가 시간이 지남에 따라 어떻게 변하는지 분석하는 데 유용합니다.
지수 표기법을 사용하여 00000-000000×10^−0 을 의미합니다.
또한 비어 있을 수 있으며, 이는 값 0에 해당합니다.

±NNNNN±N과 같은 형식으로 이루어지거나, 빈 값이므로 정규 표현식으로 작성하면 아래와 같습니다.

/[ \-+]\d{5}[-+]\d| {8}/

BSTAR 항력 계수 (54~61번)

BSTAR 항력 계수는 공기 저항을 반영한 계수로, 물체가 항력에 얼마나 취약한지를 나타내며 28923-328923×10^-3을 의미합니다.
평균 운동의 2차 미분과 동일하게 지수 표기법으로 ±NNNNN±N과 같은 형식으로 이루어지거나, 빈 값이므로 정규 표현식으로 작성하면 아래와 같습니다.

/[ \-+]\d{5}[-+]\d| {8}/

에페메리스 유형 (63번)

에페메리스 유형은 데이터를 생성하는 데 사용된 궤도 모델을 나타냅니다.
TLE에는 "0"을 사용하며, 이는 SGP4/SDP4 궤도 모델 기반으로 예측됨을 의미합니다.

/[0]/

요소 집합 번호 (65~68번)

일반적으로 요소 집합 번호는 개체에 대해 새 TLE가 생성될 때 증가합니다. 그러나, 기본공간제어센터와 백업공간제어센터 간의 작업이 전환될 때 요소 집합 번호가 동기화되지 않아 일부 번호는 재사용되고 다른 번호는 건너뛰는 경우가 있습니다. 999를 초과할 때까지 증가하며 초과하면 1로 돌아갑니다.
따라서 마지막 자리는 숫자여야 하고, 앞의 세 자릿수는 공백이거나 숫자 형식으로 이루어져 있으므로 정규 표현식으로 작성하면 아래와 같습니다.

/[ \d]{3}\d/

체크섬 (69번)

체크섬(Checksum)은 데이터의 무결성을 검증하기 위한 간단한 수학적 기법입니다.
이 값은 데이터가 전송되거나 저장되는 과정에서 오류가 발생했는지 확인하는 용도로 사용되며 아래와 같은 규칙으로 값이 정해집니다.

  • 숫자(0~9) : 모두 더하기
  • 빼기 기호 : 1로 간주해서 더하기
  • 공백, 마침표, 더하기 기호, 기타 문자 : 0으로 간주(무시)

이렇게 더한 총합을 10으로 나눈 나머지 값이 체크섬이 됩니다.
이러한 계산 로직을 함수로 작성하면 아래와 같이 작성할 수 있습니다.

const computeChecksum = (line: string) => {
  let sum = 0
  for (let i = 0; i < 68; i++) {
    const char = line[i]
    const val = parseInt(char)
    if (!isNaN(val)) {
      sum += val
    } else if (char === '-') {
      sum += 1
    }
  }
  return sum % 10
}

두 번째 줄

위성 카탈로그 번호 (3~7번)

첫 번째 줄과 동일하게 위성 카탈로그 번호를 나타냅니다.

경사도 (9~16번)

경사도는 적도와 궤도면 사이의 각도를 말합니다. 도 단위이며 0도에서 180도까지만 가능합니다.
따라서 아래와 같은 규칙으로 정규 표현식을 적용할 수 있습니다.

  • (?:0?\d{1,2}| ?\d{1,2}|1[0-7]\d)\.\d{4}$|180\.0000
    • 0?\d{1,2} : (선택적 0) 0~99
    • ?\d{1,2} : (선택적 공백) 0~99
    • 1[0-7]\d : 100~179
    • \.\d{4} : 소수점 네 자리 숫자 (.0000 ~ .9999)
  • 180\.0000 : 180.0000
/^(?:0?\d{1,2}|  ?\d{1,2}|1[0-7]\d)\.\d{4}$|180\.0000$/

승교점 경도 (18~25번)

승교점은 위성이 적도를 넘어 올라가는 지점의 위치(적경)를 나타냅니다. 도 단위이며 0도에서 360도까지 가능합니다.
따라서 아래와 같은 규칙으로 정규 표현식을 적용할 수 있습니다.

  • `(?:0?\d{1,2}| ?\d{1,2}|1[0-9]{1,2}|2[0-9]{1,2}|3[0-5]\d).\d{4}|360.0000
    • 0?\d{1,2}: (선택적 0) 0~99
    • ?\d{1,2}: (선택적 공백) 0~99
    • 1[0-9]{1,2}: 100~199
    • 2[0-9]{1,2}: 200~299
    • 3[0-5]\d: 300~359
    • \.\d{4}: 소수점 네 자리 숫자 (.0000 ~ .9999)
  • 360\.0000: 360.0000
/^(?:0?\d{1,2}|  ?\d{1,2}|1[0-9]{1,2}|2[0-9]{1,2}|3[0-5]\d)\.\d{4}|360\.0000$/

이심률 (27~33번)

출처 : 위키백과

이심률은 궤도의 타원 형태를 나타내며, 값이 0에 가까울수록 원형 궤도입니다.
소수점 이하의 단위 값으로 예를 들어, 1234567의 값은 0.1234567을 의미합니다.
따라서 아래와 같이 정규 표현식을 작성할 수 있습니다.

/\d{7}/

근점 편각 (35~42번)

근점 편각은 궤도의 승교점부터 궤도에서 가장 낮은 점(근지점)까지의 각도를 나타냅니다.
도 단위이며 0도에서 360도까지 가능하므로 승교점 경도와 같은 정규 표현식으로 나타낼 수 있습니다.

/^(?:0?\d{1,2}|  ?\d{1,2}|1[0-9]{1,2}|2[0-9]{1,2}|3[0-5]\d)\.\d{4}|360\.0000$/

평균 근점 이각 (44~51번)

출처 : 위키백과

평균 근점 이각은 위성이 주어진 시간에 궤도를 따라 얼마나 이동했는지를 나타내는 각도입니다.
도 단위이며 0도에서 360도까지 가능하므로 승교점 경도, 근점 편각과 같은 정규 표현식으로 나타낼 수 있습니다.

/^(?:0?\d{1,2}|  ?\d{1,2}|1[0-9]{1,2}|2[0-9]{1,2}|3[0-5]\d)\.\d{4}|360\.0000$/

평균 운동 (53~63번)

평균 운동은 하루 동안 위성이 몇 바퀴 공전하는지를 나타냅니다.

  • n : 평균 운동 (단위: 회전/일)
  • T : 공전 주기 (단위: 초)
  • 86400 : 하루(24시간)의 초 단위 변환 값

최대 두자리 정수 뒤 소수점 8자리로 표현하여 아래와 같은 정규 표현식을 사용할 수 있습니다.

/[ \d]{2}\.\d{8}/

Epoch 기준 공전 횟수 (64~68번)

Epoch 기준 공전 횟수는 TLE에 기록된 에포크 시간까지 위성이 몇 바퀴를 돌았는지 나타내는 값입니다.
위성이 궤도의 상승 노드(위성이 지구를 돌면서 적도와 궤도면이 교차하는 지점)에 있을 때 회전이 시작되며, 발사 후 첫 번째 상승 노드까지의 주기는 회전 0으로 간주되고, 첫 번째 상승 노드에 도달하면 회전 1로 간주됩니다.
이를 최대 네 자릿수 숫자로 표현하여 아래와 같은 정규 표현식을 사용할 수 있습니다.

/[ \d]{4}\d/

체크섬 (69번)

첫 번째 줄과 동일하게 마지막은 체크섬을 나타냅니다.

종합

지금까지 알아본 TLE의 값을 요약하면 아래와 같은 형식이 구성됩니다.

1 NNNNNC NNNNNAAA NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN 
2 NNNNN NNN.NNNN NNN.NNNN NNNNNNN NNN.NNNN NNN.NNNN NN.NNNNNNNNNNNNNN
  • 공백이나 마침표가 있는 열에는 다른 문자를 사용할 수 없습니다.
  • 'N'이 있는 열에는 0-9의 숫자나 경우에 따라 공백을 사용할 수 있습니다.
  • 'A'가 있는 열에는 A-Z 문자나 공백을 사용할 수 있습니다.
  • 'C'가 있는 열에는 요소 집합의 분류를 나타내는 문자만 사용할 수 있습니다.
  • 일반적으로 분류되지 않은 데이터의 경우 'U' 또는 비밀 데이터의 경우 'S'입니다.
  • '+'가 있는 열에는 더하기 기호, 빼기 기호 또는 공백을 사용할 수 있으며 '-'가 있는 열에는 더하기 또는 빼기 기호를 사용할 수 있습니다(나머지 필드가 비어 있지 않은 경우)

또한 지금까지 알아본 TLE 데이터의 의미를 통해 다음과 같은 정보를 얻을 수 있습니다.

  • 위성이 현재 어느 위치에 있는지
  • 위성이 언제 어디를 통과할 것인지 예측
  • 위성의 고도, 속도, 궤도 형태 분석
  • 특정 지역에서 위성이 관측 가능한지 등...

번외

북미항공우주방위사령부(NORAD)의 산타 추적

위성 카탈로그 번호를 부여하는 NORAD는 매년 크리스마스 기념 이벤트로 산타를 추적하는 이벤트 페이지를 제공합니다.
1955년 미국 콜로라도의 한 백화점이 '산타에게 전화를 걸어보세요'라는 광고를 그만 NORAD 대륙공방위사령부의 전화번호로 잘 못 작성한 일이 있었습니다.
결국 어린이들의 전화가 군으로 걸려왔고 동심을 깨고 싶지 않았던 당시 담당자는 '직원들에게 산타가 북극에서 남하하는 징후가 있는지 레이더를 확인해보라고 지시했다'고 응대합니다. 이렇게 탄생한 산타 추적 전통은 매년 이어지고 있습니다.

마무리

const lineOneRegexes: ValidationRule = {
  catalogNumber: {
    regex: /\d{5}[CSU]/,
    slice: [2, 8],
    message: 'Fix catalog number',
  },
  internationalDesignator: {
    regex: / (\d{5}[A-Z][ A-Z]{2}|\d{5}[ A-Z]{2}[A-Z]| {8})/,
    slice: [8, 17],
    message: 'Fix international designator or leave it blank',
  },
  ...
}

지금까지 작성한 정규 표현식을 객체로 표현하여, 각각의 오류에 따른 에러 메시지를 하단에 표출되도록 작업을 진행했습니다.
처음에는 라이브러리를 활용해서 유효성 검증을 할까 생각도 했지만, TLE 유효성 검증만 진행하는 라이브러리가 없기도 했고 이참에 TLE에 대해 공부해 보면 좋을 것 같다는 생각이 들어 여러 문서를 찾아가며 글을 작성했습니다. 이 글이 TLE를 이해하는 데 도움이 되었으면 좋겠습니다!

참고 자료

profile
FE ✨

4개의 댓글

comment-user-thumbnail
2025년 2월 22일

너무 재미있는 글이네요! 잘 읽었습니다!

1개의 답글
comment-user-thumbnail
2025년 3월 12일

네???

1개의 답글

관련 채용 정보