포스트

(C++) 3채널 레이다 센서로 물체 운동의 스핀축 계산하기

위상차 이용 스핀축 계산 원리

(C++) 3채널 레이다 센서로 물체 운동의 스핀축 계산하기

내용

3채널 레이다 센서로 물체 운동의 스핀축 계산하기

3개 채널의 레이다 센서 수신부(RX)를 ‘ㄴ’ 형태로 배치하고, 위 아래 채널 두 개로 상하 위상차를 구하고, 좌우 채널 두 개로 좌우 위상차를 구한 뒤, 해당 상하 위상차와 좌우 위상차 데이터를 이용해 스핀축을 계산하는 원리를 정리한다.

레이다 시리즈 7장의 각도 계산을 두 축으로 확장한 것이다. 위상차를 채널에서 뽑아내는 부분 — 같은 도플러 빈에서 켤레곱으로 위상차를 구하고 채널 간 오프셋을 빼는 절차 — 은 7장에 있고, 여기서는 그렇게 얻은 $\phi_v$와 $\phi_h$가 이미 있다고 두고 시작한다.


레이다 센서 배치 및 위상차 측정

3개의 레이다 센서를 ‘ㄴ’ 형태로 배치한다. 두 개의 RX 센서를 위와 아래에 배치하여 수직 위상차($\phi_v$)를 측정하고, 두 개의 RX 센서를 좌우에 배치하여 수평 위상차($\phi_h$)를 측정한다.

수직 위상차($\phi_v$)와 수평 위상차($\phi_h$)는 각각 수직 및 수평 방향에서의 공의 움직임에 따른 위상 차이를 나타내며, 안테나 간 거리와 파장을 사용하여 각도로 변환할 수 있다.


변수의 의미

  1. lambda ($\lambda$): 파장
    • lambda는 레이다 신호의 파장을 나타낸다. 파장은 주파수와 속도의 관계를 나타내며, 특정 주파수의 신호가 공기 중에서 진행될 때의 거리이다.
    • 파장 $\lambda$는 주파수 $f$와 다음 관계를 가진다:

      \[\lambda = \frac{c}{f}\]

      여기서 $c$는 신호가 전파되는 매질의 속도 (예: 공기 중에서의 빛의 속도)이다.

  2. d: 안테나 간 거리
    • d는 위상차를 측정하는 두 수신 안테나(RX) 사이의 간격을 나타낸다. 이 거리는 위상차를 기반으로 각도를 계산하는 데 필수적인 요소이다.
    • 안테나 간 거리가 커질수록 위상차의 변화를 더 뚜렷하게 감지할 수 있다.


간격을 키우면 정밀도와 시야를 맞바꾼다. 위상차가 $\lvert\phi\rvert \le \pi$ 안에 있어야 각도가 하나로 정해지므로, 유일하게 풀리는 구간은 $\pm\arcsin(\lambda/2d)$다. 예컨대 $\lambda = 0.03$ m(10 GHz), $d = 0.1$ m이면 $d/\lambda = 3.33$이라 정밀도는 좋지만 유일 구간이 ±8.6°밖에 안 된다. 그 밖에서 들어온 표적은 접힌 각도로 읽힌다.

시야 전체를 유일하게 풀려면 $d \le \lambda/2$여야 한다. 어느 쪽을 고를지는 표적이 들어오는 원뿔이 얼마나 좁은지가 정한다. 같은 상충을 숫자로 펼친 것이 6장에 있다.


동작 원리

‘ㄴ’ 배열에서 두 위상차는 도래 방향 단위벡터의 기선 방향 성분(방향 코사인)에 비례한다.

\[\phi_h = \frac{2\pi d}{\lambda}\sin\theta_h, \qquad \phi_v = \frac{2\pi d}{\lambda}\sin\theta_v\]

수평 기선은 $\sin\theta_h$를 재는 자이고, 수직 기선은 $\sin\theta_v$를 재는 자다. 시선에 수직인 평면에서 표적 방향의 기울기는 두 성분의 비로 정해진다.

\[\theta_{\text{spin}} = \operatorname{atan2}(\sin\theta_v,\ \sin\theta_h) = \operatorname{atan2}(\phi_v,\ \phi_h)\]

두 기선의 $d$와 $\lambda$가 같으면 공통 인수 $\lambda/2\pi d$가 약분되어 위상차를 그대로 넣으면 된다. 각도로 되돌리는 $\arcsin$이 계산 경로에 아예 등장하지 않는다는 것이 요점이다. 개별 각도가 따로 필요할 때만 $\theta = \arcsin(\phi\lambda/2\pi d)$로 복원한다.


계산 코드

1
2
3
4
5
6
7
8
9
#include <cmath>

// phaseV, phaseH : [rad], 켤레곱으로 구해 (−π, π] 로 접힌 값 (7장)
// 두 기선의 d 와 λ 가 같다는 전제. 다르면 각 위상차를 자기 d 로 나눠 맞춘 뒤 넣는다.
double calculateSpinAxisAngle(double phaseV, double phaseH)
{
    // 위상차가 방향 코사인에 비례하므로 비를 취하면 λ/(2πd) 가 약분된다
    return std::atan2(phaseV, phaseH) * 180.0 / M_PI;
}

부호와 축 방향은 안테나를 실제로 어느 쪽에 붙였는지에 따라 달라진다. 알려진 방향으로 회전하는 표적을 놓고 한 번 확인하고 부호를 고정하는 편이 안전하다.


틀리기 쉬운 합성 두 가지

같은 재료를 다르게 합성하면 그럴듯해 보이지만 틀린다. 첫 번째는 이 글의 초판이 실제로 썼던 방식이다(전체 이력은 git에 있다).

각도를 3차원 단위벡터로 펼쳐 합성하면 수직 정보가 소멸한다. $V_z = \sin\theta_v$, $V_x = \cos\theta_v\cos\theta_h$, $V_y = \cos\theta_v\sin\theta_h$로 단위벡터를 만들고 $\operatorname{atan2}(V_y, V_x)$를 취하는 방식이다. 대입해 보면 문제가 바로 보인다.

\[\operatorname{atan2}(V_y,\,V_x) = \operatorname{atan2}\big(\cos\theta_v \sin\theta_h,\; \cos\theta_v \cos\theta_h\big) = \theta_h\]

$\theta_v$는 $\arcsin$의 출력이라 항상 $\lvert\theta_v\rvert \le 90°$이고 따라서 $\cos\theta_v \ge 0$이다. 양수인 공통 인수는 $\operatorname{atan2}$에서 그대로 약분되므로, 돌려받는 값은 수평 각도 $\theta_h$ 그 자체다. 수직 위상차를 재려고 채널을 하나 더 놓은 의미가 사라진다.

각도로 바꾼 뒤 각도끼리 합성하는 것은 근사다. $\arcsin$을 거친 $\operatorname{atan2}(\theta_v, \theta_h)$는 소각에서만 방향 코사인 비와 일치하고, 각도가 커질수록 $\arcsin$의 비선형이 왜곡으로 들어온다. 게다가 $\arcsin$은 잡음이나 캘리브레이션 오차로 인자가 1을 조금만 넘어도 NaN을 내고, NaN은 이후 계산으로 조용히 전파된다. 개별 각도를 보고할 일이 있으면 std::asin(std::clamp(k, -1.0, 1.0))처럼 인자를 먼저 묶어야 한다. 위 계산 코드처럼 위상차 비로 바로 가면 두 문제 모두 생기지 않는다.


이 각도를 ‘스핀축’이라 부르려면

위 함수가 주는 것은 위상차 한 쌍을 시선에 수직인 평면에서 합성한 방향이다. 그 자체는 도래각 계산이지 스핀축이 아니고, 무엇의 위상차를 넣느냐가 물리적 의미를 정한다.

  • 주 도플러 피크 빈의 위상차를 넣으면 나오는 것은 그 시점 위상 중심의 각위치이고, 프레임 간 변화를 이으면 궤적의 진행 방향이다.
  • 스핀 자체는 6장에서 본 대로 주 피크 양옆의 측대역(백스핀 2,700 rpm에서 ±966 Hz)에 실린다. 스핀축을 직접 겨냥하려면 측대역 성분의 도래각까지 봐야 한다.

그래서 이 함수를 쓰는 코드에는 입력이 어느 빈에서 나온 위상차인지를 함께 적어 두어야 한다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.