Theo dõi mục tiêu: Khi nào cần tăng tốc và giảm tốc một tháp pháo quay?


24

Nói rằng tôi có một thông tư di chuyển targetđược định nghĩa là:

Vector2 position;
Vector2 velocity;
float radius;

Và một vòng quay turret(gắn trên một loại phương tiện di chuyển nào đó) được định nghĩa là:

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

(Hoặc một cái gì đó dọc theo các đường đó. Lưu ý rằng vị trí và vận tốc của cả hai được điều khiển ở nơi khác - giả sử vận ​​tốc là không đổi và thay đổi vị trí dựa trên vận tốc.)

Tôi đang cố gắng viết hai hàm AI liên quan để xác định, trên một khung nhất định:

  • Gia tốc góc nào (và theo hướng nào) để áp dụng cho góc của tháp pháo để giữ cho tháp pháo hướng vào mục tiêu?

  • Nếu mục tiêu hiện đang ở trong tầm nhìn, liệu nó (bất kỳ phần nào trong bán kính của nó) có thể được giữ trong tầm nhìn trong xvài giây, đâu xlà một phần của giây? (Alternatly: có một chiến lược khác để đảm bảo mục tiêu thực sự bị "khóa" và không chỉ đơn giản là bay qua các điểm tham quan?)

Và tôi có thể sử dụng một số trợ giúp ...


1
Bạn có thể có các giá trị khác nhau để tăng tốc và giảm tốc quay - trong thế giới thực, có lẽ một động cơ và một phanh khác.
e100

Câu trả lời:


19

Trước tiên, bạn cần xác định sự khác biệt về góc giữa hướng của tháp pháo và hướng tới mục tiêu.

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;

Khi bạn có các đại lượng này, bạn có thể thiết lập biểu thức bậc hai cho góc tháp pháo. Bạn cần tính toán điều này trên mỗi bản cập nhật để đảm bảo bạn luôn sử dụng dữ liệu mới nhất về vị trí và vận tốc.

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

Ở đây, thuật ngữ đầu tiên (độ không) trong biểu thức gia tốc sẽ khiến tháp pháo bắt đầu quay về phía mục tiêu. Tuy nhiên, nó sẽ không dừng lại theo thời gian mà thay vào đó dao động qua lại. Để làm cho nó dừng lại, chúng ta cần thuật ngữ thứ hai ẩm (độ thứ nhất) làm cho tốc độ quay cao bị phản đối bởi gia tốc cao.

Bây giờ các hằng số dương (không nhất thiết là hằng số chương trình) cần được xác định và cân bằng để làm cho hệ thống hoạt động tốt. C0là kiểm soát chính cho tốc độ của hệ thống. Giá trị cao C0sẽ cho tốc độ quay nhanh và giá trị thấp sẽ cho tốc độ quay thấp. Giá trị thực tế phụ thuộc vào nhiều yếu tố, vì vậy bạn nên sử dụng thử và lỗi tại đây. C1kiểm soát cường độ giảm xóc. Phân biệt của phương trình bậc hai cho chúng ta biết rằng nếu C1*C1 - 4*C0 >= 0chúng ta có một hệ không dao động.

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

Bạn có thể nên chọn C1lớn hơn một chút so với điều này vì lý do số, nhưng không quá lớn vì nó có thể trở nên quá ẩm ướt và chậm phản ứng thay thế. Một lần nữa, bạn cần phải điều chỉnh.

Ngoài ra, điều quan trọng cần lưu ý là mã này chỉ tính gia tốc góc. Tốc độ góc và tốc độ góc cần phải được cập nhật từ nơi này, sử dụng và tích hợp một số loại. Từ câu hỏi tôi cho rằng điều này đã được bảo hiểm.

Cuối cùng, có một cái gì đó để nói về độ trễ, bởi vì tháp pháo có thể sẽ luôn ở phía sau khi theo dõi mục tiêu nhanh. Một cách đơn giản để giải quyết vấn đề này là thêm dự đoán tuyến tính vào vị trí của mục tiêu, tức là luôn luôn hướng về phía trước theo hướng phía trước của mục tiêu.

// 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;
/// ...

Đối với việc giữ tháp pháo nhắm trong bán kính của mục tiêu trong một thời gian, đây có thể là một yêu cầu khó khăn để áp đặt trực tiếp lên loại hệ thống này. Bạn có thể chắc chắn rằng bộ điều khiển này sẽ cố gắng giữ cho tháp pháo nhắm vào mục tiêu (hay đúng hơn là vị trí dự đoán) mọi lúc. Nếu kết quả hóa ra không phải là thỏa đáng, bạn phải thay đổi các thông số predictionTime, C0C1(trong giới hạn ổn định).


Tôi không đủ điều kiện để nói nếu điều này đúng hay không, nhưng nghe có vẻ như một số công cụ thông minh! Tôi đã giải quyết các loại vấn đề này trong quá khứ bằng cách chuyển tiếp dự đoán ảnh hưởng của việc tăng tốc để giải quyết khi nào nên tăng tốc và khi nào nên "áp dụng các lần nghỉ". Điều đó có nghĩa là tôi đã làm sai?
Iain

Atan2 làm cho phương thức này khó thích ứng với hệ thống dự đoán do các tham số x và y thành atan2 trở nên phụ thuộc vào t.
Skizz

Đây chính xác là giải pháp tôi đã gợi ý trong câu trả lời của tôi dưới đây. Tuyệt vời chi tiết và trình bày!
drxzcl

@Iain: Không có đúng sai ở đây. Mặc dù tôi đoán phương pháp của bạn sẽ có hai trạng thái riêng biệt: tăng tốc / giảm tốc, phương pháp này được lấy cảm hứng từ một bộ điều chỉnh từ lý thuyết điều khiển, điều chỉnh gia tốc để tạo ra phản ứng nhanh trong khi giảm quá mức và dao động.
Staffan E

1
Cũng như các ý kiến ​​khác, điều này sẽ hoạt động cho một mục tiêu đứng yên nhưng có thể sẽ không được chấp nhận cho bất kỳ mục tiêu di chuyển nào. Các thuật ngữ C0 và C1 là các công cụ lò xo ẩm truyền thống, trong đó C0 đại diện cho sức mạnh của mùa xuân (thường được gọi là k) và C1 là hệ số giảm xóc (thường được gọi là 'B' hoặc 'c'). Vì vậy, có, bạn có thể giảm thiểu dao động bằng cách tăng giảm xóc nhưng vấn đề là điều này không cố gắng dự đoán mục tiêu sẽ ở đâu, do đó, sẽ bị tiêu diệt để đạt được mục tiêu mong muốn.
dash-tom-bang

3

Những gì bạn có ở đây là một vấn đề kiểm soát cơ bản . Tháp pháo là hệ thống, gia tốc là điều khiển và cảm biến đo vị trí / vận tốc. Có nhiều cách để giải quyết những vấn đề này, vì đó là một vấn đề được nghiên cứu rất kỹ trong kỹ thuật.

Key đang kết thúc với một hệ thống ổn định, tức là một hệ thống không tạo ra dao động. Điều này thường được thực hiện bằng cách thêm giảm xóc. Trang wikipedia sẽ giúp bạn bắt đầu.


2

Trước hết, tính toán vectơ từ tháp pháo đến mục tiêu. Sau đó so sánh điều này với vector hiện tại của tháp pháo. Sau đó, sử dụng sự khác biệt giữa hai để tìm ra gia tốc góc và tốc độ góc cần thiết để đưa tháp pháo quay về điểm đúng hướng trong một thời gian nhất định.

OK, điều đó có vẻ đơn giản. Tuy nhiên, bạn thực sự nên cố gắng dự đoán vị trí của mục tiêu vì mục tiêu sẽ di chuyển theo thời gian bạn xoay tháp pháo. Để làm điều này:-

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

Trong đó P là vị trí và V là vận tốc và chỉ số là d cho đích (đích) và s cho nguồn (tháp pháo), cung cấp một vectơ chỉ hướng: -

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

Trong đó D là vectơ chỉ phương và Dsd 'là hướng yêu cầu tại thời điểm t. Bây giờ, hãy tìm ra hướng của tháp pháo dựa trên vị trí hiện tại, vận tốc và gia tốc tối đa trong một thời gian nhất định: -

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

Ds và Ds 'là hướng nguồn và R là tốc độ quay. Với tất cả những điều đó, bạn muốn tìm t khi Dsd '== Ds' và do đó, tốc độ quay yêu cầu. Đừng quên rằng tất cả các P, D và V đều có các thành phần x và y.

Tôi chưa tính đến việc tăng tốc ở đây - điều đó làm tăng thêm sự phức tạp. Khi bạn đã có R và t, bạn có thể ước chừng một par par R (tức là tăng tốc và giảm tốc) để có được kết quả tương tự.


Đây có vẻ là một câu trả lời tốt cho tính toán đánh chặn, nhưng thật không may, có một khoảng cách lớn giữa những người có thể đọc loại ký hiệu toán học đó và biến nó thành mã chương trình, và hầu hết những người làm trò chơi chưa biết câu trả lời câu hỏi. Nói cách khác, tôi nghĩ rằng các nhà phát triển trò chơi có thể đọc ký hiệu toán học đó, có lẽ đã có thể tìm ra cách lập trình giải pháp bắn. Nó sẽ giúp tôi hiểu các công thức của bạn nếu bạn giải thích các điều khoản của bạn có nghĩa là gì.
Dronz

2

Những gì bạn có thể đang tìm kiếm ở đây là Bộ điều khiển PID , tương tự như câu trả lời được chấp nhận cho câu hỏi SO này

Ban đầu tôi đã trả lời câu hỏi đó bằng cách "tự lăn" nhưng câu trả lời này đầy đủ và thanh lịch hơn đáng kể.


0

Điều đầu tiên cần làm là tính toán góc giữa dòng chảy và đối tượng được theo dõi.
Điều tiếp theo là kiểm tra xem sử dụng tốc độ torrent hiện tại và áp dụng gia tốc tối đa ngược (dừng torrent) thì torrent sẽ dừng trước hay sau đối tượng được theo dõi.
Nếu câu trả lời là torrent sẽ dừng trước đối tượng được theo dõi, hãy áp dụng gia tốc tối đa về phía trước (tăng tốc độ).
Nếu câu trả lời là torrent sẽ dừng sau đối tượng được theo dõi, hãy áp dụng gia tốc tối đa về phía sau (dừng torrent).
Bằng cách này, torrent sẽ alwais đến nhanh nhất và sẽ dừng lại ở đúng điểm (hoặc một phần sau).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.