[bug] Запросы рельефа голодают: часть направлений РЛС никогда не получает высоты #1

Closed
opened 2026-10-29 11:43:05 +00:00 by chexit · 1 comment
Owner

Проверено на 90379f6.

При повторном построении горизонта обход всегда начинается с первого луча. Ground::at() кладёт обновления старых известных колонок и новые колонки в одну очередь на 256 записей. При достаточном числе РЛС ранние колонки успевают устареть (>200 тиков) до полного обхода, вновь занимают бюджет и бесконечно вытесняют ещё неизвестные направления.

В изолированном тесте: 10 разнесённых РЛС дальнего обнаружения, 2500 тиков (125 игровых секунд), ответ высоты 200 на каждый запрос уже на следующем цикле. У каждой РЛС данные появляются только по 17 из 48 направлений; остальные остаются неизвестными. Неизвестный рельеф по текущей логике ничего не скрывает, поэтому это влияет на обнаружение целей за препятствиями.

Предложение: разделить очередь первичных запросов и обновлений, зарезервировать бюджет для неизвестных колонок и/или продолжать обход с сохранённого курсора. Проверить также конкуренцию с запросами высоты летящих дронов.

Код:

pub fn at(&mut self, p: DVec3, now: u64) -> Option<f64> {

Воспроизведено на настоящем коде sim и wave в отдельном native Rust crate (edition=2024, glam=0.30.10, cargo test --release). Движок и GPU не участвовали. Тест ниже проверяет ожидаемое исправленное поведение и сейчас падает; поместить в дочерний #[cfg(test)]-модуль соответствующего файла с use super::*;.

#[test]
fn terrain_queries_must_eventually_cover_all_radar_bearings() {
        let mut sim=Sim::new(1);
        for i in 0..10 {
            let id=sim.id();sim.sams.push(Sam::new(id,SamKind::Radar,DVec3::new(i as f64*5000.,70.,0.),0.));
        }
        let mut ground=Ground::default();
        for now in 1..=2500 {
            sim.tick=now;sim.update_sight(&mut ground);
            let answers=ground.take_wanted().into_iter().map(|(x,z)|(x,z,200)).collect();
            ground.answer(answers,now);
        }
        let visible:Vec<usize>=sim.horizons.values().map(|h|h.rays.iter().filter(|r|r.last().is_some_and(|v|v.is_finite())).count()).collect();
        eprintln!("radar terrain coverage after 125 seconds: {:?} / 48 bearings each",visible);
        assert!(visible.iter().all(|n|*n==48),"refreshes of early rays starve unknown terrain in later rays");
    }
Проверено на `90379f6`. При повторном построении горизонта обход всегда начинается с первого луча. `Ground::at()` кладёт обновления старых известных колонок и новые колонки в одну очередь на 256 записей. При достаточном числе РЛС ранние колонки успевают устареть (>200 тиков) до полного обхода, вновь занимают бюджет и бесконечно вытесняют ещё неизвестные направления. В изолированном тесте: 10 разнесённых РЛС дальнего обнаружения, 2500 тиков (125 игровых секунд), ответ высоты 200 на каждый запрос уже на следующем цикле. У каждой РЛС данные появляются только по 17 из 48 направлений; остальные остаются неизвестными. Неизвестный рельеф по текущей логике ничего не скрывает, поэтому это влияет на обнаружение целей за препятствиями. Предложение: разделить очередь первичных запросов и обновлений, зарезервировать бюджет для неизвестных колонок и/или продолжать обход с сохранённого курсора. Проверить также конкуренцию с запросами высоты летящих дронов. Код: https://gitea.maoniao.team/chexit/airdef/src/commit/90379f6/airdef-mod/src/sim/mod.rs#L181 Воспроизведено на настоящем коде `sim` и `wave` в отдельном native Rust crate (`edition=2024`, `glam=0.30.10`, `cargo test --release`). Движок и GPU не участвовали. Тест ниже проверяет ожидаемое исправленное поведение и сейчас падает; поместить в дочерний `#[cfg(test)]`-модуль соответствующего файла с `use super::*;`. ```rust #[test] fn terrain_queries_must_eventually_cover_all_radar_bearings() { let mut sim=Sim::new(1); for i in 0..10 { let id=sim.id();sim.sams.push(Sam::new(id,SamKind::Radar,DVec3::new(i as f64*5000.,70.,0.),0.)); } let mut ground=Ground::default(); for now in 1..=2500 { sim.tick=now;sim.update_sight(&mut ground); let answers=ground.take_wanted().into_iter().map(|(x,z)|(x,z,200)).collect(); ground.answer(answers,now); } let visible:Vec<usize>=sim.horizons.values().map(|h|h.rays.iter().filter(|r|r.last().is_some_and(|v|v.is_finite())).count()).collect(); eprintln!("radar terrain coverage after 125 seconds: {:?} / 48 bearings each",visible); assert!(visible.iter().all(|n|*n==48),"refreshes of early rays starve unknown terrain in later rays"); } ```
chexit added the area:simulationpriority:P1type:bug labels 2026-10-29 12:55:57 +00:00
Author
Owner

🤖 Agent: исправлено в https://gitea.maoniao.team/chexit/airdef/commit/e08fc65 (запушено в main).

🤖 Agent: исправлено в https://gitea.maoniao.team/chexit/airdef/commit/e08fc65 (запушено в main).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chexit/airdef#1