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. C0
là kiểm soát chính cho tốc độ của hệ thống. Giá trị cao C0
sẽ 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. C1
kiể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 >= 0
chú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 C1
lớ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
, C0
và C1
(trong giới hạn ổn định).