목표 추적 : 회전 포탑을 가속 및 감속 할시기는 언제입니까?


24

움직이는 원형이 target다음과 같이 정의되어 있다고 가정 해보십시오 .

Vector2 position;
Vector2 velocity;
float radius;

그리고 회전 turret(어떤 종류의 움직이는 차량에 장착)은 다음과 같이 정의됩니다.

Vector2 position;
Vector2 velocity;
float angle; // radians
float angularVelocity; // radians per second
const float maxAngularVelocity; // radians per second
const float maxAngularAcceleration; // radians per second per second

(또는 그 선을 따라 무언가. 둘 다의 위치와 속도는 다른 곳에서 제어됩니다. 속도가 일정하고 속도에 따라 위치가 변경된다고 가정하십시오.)

주어진 프레임에서 결정하기 위해 두 가지 관련 AI 함수를 작성하려고합니다.

  • 포탑이 목표물을 가리 키도록 포탑 각도에 적용 할 각도 가속 (및 방향)은 무엇입니까?

  • 목표물이 현재 시야에 있다면, 목표물 (반지름 내의 모든 부분)을 x몇 초 동안 시야에 유지할 수 x있습니까? (또는 대안으로, 목표물이 실제로 "잠겨"있고 단순히 시력을 가로 질러 비행하는 것이 아닌 다른 전략이 있습니까?)

그리고 나는 도움을 사용할 수 있습니다 ...


1
실제 세계에서는 모터와 브레이크 중 하나 인 회전 가속 및 감속 값이 다를 수 있습니다.
e100

답변:


19

먼저 포탑 방향과 목표 방향 사이의 각도 차이를 결정해야합니다.

Vector2 turretToTarget = target.position - turret.position;
float desiredAngle = atan2(turretToTarget.y, turretToTarget.x);
float angleDiff = desiredAngle - turret.angle;

// Normalize angle to [-PI,PI] range. This ensures that the turret
// turns the shortest way.
while (angleDiff < -PI) angleDiff += 2*PI;
while (angleDiff >= PI) angleDiff -= 2*PI;

이 수량을 확보하면 터릿 각도에 대한 2 차 표현을 설정할 수 있습니다. 항상 최신 위치 및 속도 데이터를 사용하려면 각 업데이트에서이를 계산해야합니다.

// Compute angular acceleration.
const float C0 = // Must be determined.
const float C1 = // Must be determined.
float angularAcc = C0 * angleDiff - C1 * turret.angularVelocity;

여기서 가속도 표현의 첫 번째 항 (0도)은 터릿이 목표를 향해 회전하기 시작합니다. 그러나 정시에 멈추지 않고 오히려 앞뒤로 진동합니다. 정지시키기 위해서는 높은 가속도에 의해 높은 회전 속도가 반대되는 감쇠 제 2 항 (1도)이 필요합니다.

이제 양의 상수 (필수적으로 프로그램 상수는 아님)를 결정하고 시스템이 제대로 작동하도록 균형을 조정해야합니다. C0시스템 속도의 주요 제어입니다. 값이 높으면 C0선회 속도가 빠르고 값이 낮 으면 선회 속도가 느려집니다. 실제 값은 많은 요소에 따라 다르므로 여기에서 시행 착오를 사용해야합니다. C1댐핑 크기를 제어합니다. 이차 방정식 의 판별C1*C1 - 4*C0 >= 0비 진동 시스템을 가졌다 고 알려줍니다 .

// New definition.
const float C1 = 2*sqrt(C0); // Stabilizes the system.

C1숫자로 인해이 값보다 조금 더 큰 값을 선택해야 하지만 너무 크게 댐핑되지 않고 응답 속도가 느려질 수 있으므로 너무 크지 않아야합니다. 다시, 당신은 조정해야합니다.

또한이 코드는 각도 가속 만 계산한다는 점에 유의해야합니다. 각도와 각속도는 어떤 종류의 통합기를 사용하여 다른 곳에서 업데이트해야합니다. 질문에서 나는 이것이 커버되었다고 가정합니다.

마지막으로 빠른 목표물을 추적 할 때 포탑이 항상 뒤에 있기 때문에 지연에 대해 할 말이 있습니다. 이 문제를 해결하는 간단한 방법은 대상 위치에 선형 예측을 추가하는 것입니다. 즉, 항상 대상의 앞으로 방향을 약간 앞쪽으로 조준합니다.

// Improvement of the first lines above.
const float predictionTime = 1; // One second prediction, you need to experiment.
Vector2 turretToTarget = target.position + predictionTime * target.velocity - turret.position;
/// ...

포탑을 목표 반경 안에 일정 시간 유지하기 위해서는 이런 종류의 시스템에 직접 적용하기가 매우 어려울 수 있습니다. 이 컨트롤러는 항상 포탑이 목표물 (또는 예측 된 위치)을 목표로하도록 노력할 것입니다. 결과가 만족하지 밝혀 경우에 당신은 매개 변수를 수정해야 할 predictionTime, C0그리고 C1(안정의 범위 내에서).


이것이 옳은지 아닌지는 말할 수 없지만 자격이있는 것 같습니다! 과거에 이러한 유형의 문제를 해결하여 가속 시간이 언제 가속을 적용하고 언제 "휴식을 적용"해야하는지 알아낼 수있었습니다. 그것은 내가 잘못하고 있다는 것을 의미합니까?
Iain

atan2는 atan2에 대한 x 및 y 매개 변수가 t에 종속되기 때문에이 방법을 예측 시스템에 적용하기 어렵게 만듭니다.
Skizz

이것은 정확히 아래 답변에서 암시하는 해결책입니다. 뛰어난 디테일과 프레젠테이션!
drxzcl

@Iain : 옳고 그름은 없습니다. 귀하의 방법은 가속 / 감속의 두 가지 이산 상태를 가질 것이라고 생각하지만,이 방법은 제어 이론의 조절기에서 영감을 얻어 가속도를 조정하여 오버 슈트 및 진동을 줄이면서 빠른 응답을 얻습니다.
Staffan E

1
다른 의견들과 마찬가지로, 이것은 고정 목표물에 대해서는 효과가 있지만 움직이는 목표물에는 적합하지 않을 수 있습니다. C0 및 C1 항은 전통적인 댐핑 스프링 재료이며, 여기서 C0은 스프링의 강도 (보통 k)를 나타내고 C1은 댐핑 팩터 (보통 'B'또는 'c')입니다. 그래서 그래, 당신은 댐핑 그러나 문제는이 대상이 어디에 예측하려고하지 않는다는 것입니다 본격 의한 진동 최소화 할 수있는 때문에 원하는 목표를 지연 할 운명 일 수 있습니다.
dash-tom-bang

3

여기있는 것은 기본 제어 문제 입니다. 터릿은 시스템이고 가속은 제어이며 센서는 위치 / 속도를 측정합니다. 공학에서 매우 잘 연구 된 문제이기 때문에 이러한 문제를 해결하는 방법에는 여러 가지가 있습니다.

키는 안정적인 시스템, 즉 진동을 생성하지 않는 시스템으로 끝납니다. 이것은 일반적으로 댐핑을 추가하여 수행됩니다. Wikipedia 페이지가 시작됩니다.


2

먼저 터릿에서 대상까지의 벡터를 계산하십시오. 그런 다음 이것을 터릿의 현재 벡터와 비교하십시오. 그런 다음 둘 사이의 차이를 사용하여 주어진 시간 내에 터렛이 올바른 방향으로 회전하도록하는 데 필요한 각가속도와 각속도를 계산하십시오.

좋아, 그것은 간단 해 보였다. 그러나 포탑을 돌릴 때 목표물이 움직이기 때문에 목표물 위치를 예상해야합니다. 이것을하기 위해:-

Pd' = Pd + t.Vd
Ps' = Ps + t.Vs

여기서 P는 위치이고 V는 속도이고 아래 첨자는 대상 (대상)의 경우 d이고 소스 (터릿)의 경우 s이며 방향 벡터를 제공합니다.

Dsd' = Pd' - Ps' = Pd + t.Vd - (Ps + t.Vs) = Pd - Ps + (Vd - Vs).t

여기서 D는 방향 벡터이고 Dsd '는 시간 t에서 필요한 방향입니다. 이제 주어진 시간 t 동안 현재 위치와 최대 속도 및 가속도를 기준으로 터릿 방향을 계산하십시오

Ds' = t.Ds.Rs -> this is a vector rotation

Ds와 Ds '는 소스 방향이고 Rs는 회전 속도입니다. 이 모든 것에서, 당신은 Dsd '== Ds'일 때 t와 필요한 회전 속도 인 Rs를 찾고자합니다. 모든 P, D 및 V에는 x 및 y 성분이 있다는 것을 잊지 마십시오.

여기서 가속을 고려하지 않았습니다. 복잡성이 훨씬 더 커집니다. Rs와 t를 얻은 후에는 동일한 결과를 얻기 위해 포물선 Rs (예 : 가속 및 감속)를 근사 할 수 있습니다.


이것은 가로 채기 계산에 대한 좋은 해답처럼 보이지만 불행히도 이런 종류의 수학 표기법을 읽고 그것을 프로그램 코드로 변환 할 수있는 사람들과 대부분의 사람들이 질문. 다시 말해, 수학 표기법을 읽을 수있는 게임 개발자는 아마도 발사 솔루션을 프로그래밍하는 방법을 이미 알고있을 것입니다. 용어의 의미를 설명하면 수식을 이해하는 데 도움이됩니다.
Dronz


0

가장 먼저 할 일은 터 렌트와 추적 된 오브젝트 사이의 각도를 계산하는 것입니다.
다음으로 현재 토렌트 속도를 사용하고 최대 가속도를 거꾸로 적용 (토렌트 정지)하면 추적 된 오브젝트 전후에 토렌트가 중지됩니다.
답이 추적 된 물체보다 먼저 토렌트가 멈추는 것이라면 최대 가속을 앞으로 적용하십시오 (증가 속도).
답은 추적 된 물체 이후에 토렌트가 멈추는 것이라면 최대 가속을 뒤로 적용하십시오 (토렌트를 멈추십시오).
이렇게하면 급류가 가장 빨리 도착하여 올바른 지점 (또는 그 이후 부분)에서 멈출 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.