In real life modern IR homing missiles use infrared imaging to detect and see targets. Coupled with the IR sensor is a small computer that applies various computer vision algorithms to detect and track targets as well as rejecting decoys and other false targets.
Problem is in War Thunder such a system cannot be realistically implemented because of the nature of the medium. War Thunder is a realtime multiplayer game and the hardware needed to simulate even one such missile operating in real time is too expensive. Because of this we need to approximate this expensive simulation, like it is done with many other mechanics already in the game.
In order to understand how an approximation makes this system faster we need to walk thought a “realistic” implementation first.
The algorithm of it would look something like this.
(I don’t know how Gaijin architectured their code this is just an assumption)
fun updateSeekerIIR() {
// get a infrared image from the sensor
// this would render the game world from the seeker perspective in the IR spectrum
// very expensive
std::vector<uint8_t> ir_image = this.seeker.render_view(SPECTRUM_IR);
// we send this image to a CV algorithm to detect features (targets, decoys...)
// also very expensive
std::vector<IIR_feature> features = IIR_detect_feautes(ir_image);
// selects the best target while ignoring false targets
// cheap
target_t best_target = IIR_select_best_target(features)
// set our target for the guidance system
this.set_target(best_target);
}
// then the guidance part guides the missiles to the target
In the “realistic” simulation we would have to both render the game world from the missiles perspective (something you get for free in reality since it just like taking a picture) and then also run an expensive computer vision algorithm to figure out what exactly is on the captured image. IRL missiles have special hardware (like a GPU) for this task but our game servers don’t. In order for this to be done each server would need to have powerful GPUs for both rendering the IR images and then to run the CV algorithm which is simply impossible to do at scale.
We can skip both rendering and feature detection with a bit of precomputation. Let me elaborate.
Classifications our CV algorithm produces are going to be based on few things like distance to the target, shape of the target, temperature across the target (think colors from the image it gets from the sensor), and lastly the direction the target is facing in relation to the sensor.
For example it could be harder for the missile to detect a target at longer range if the target is presenting a small profile but putting it’s wingtips in line with the direction from which the camera is looking.
While the results of the algorithm are going to be very different for very different combinations of parameters (think close range top down shot seeing the entire plane vs long range shot seeing only the profile) similar (close) combinations of parameters are going to get similar results (600 meters from the target and 570 meters from the target from the same angle are going to be similar).
What this means is that if we precompute the results of the CV algorithm for a large enough number of parameter combinations we can always select one most similar to our current state and use that instead of running the CV.
We run the CV for:
- Different airframes. Similar airframes are treated the same.
- * Different aspects (target orientation). Let’s say a 100
- Different distances. Let’s say 50 steps (every 100 meters assuming 5km range on the seeker idk)
- Different engine output. 10 steps for example
* We would evenly distribute 100 points on a sphere and use that as the start of the direction vector
We would also run the CV for various decoys like flares (and whatever else Gaijin may introduce) with similar settings.
Let’s say we have M combinations total for our CV precomputed structure.
Using this for approximating the CV algo we can rewrite our function a little like this
fun updateSeekerIIR() {
// grab the objects that are in our seekers field of view
// very fast
std::vector<IR_object> objects = this.seeker.collect();
// very fast lookup. at worst O(logM)
std::vector<IIR_features> = CVApproxMap(objects);
// same things as before. fast
target_t best_target = IIR_select_best_target(features)
// set our target for the guidance system
this.set_target(best_target);
}
// then the guidance part guides the missiles to the target
If there are any devs here on the forum I would love to hear your opinion on this.