web UI added and refactoring done
This commit is contained in:
@@ -76,6 +76,12 @@ struct ProcessingLiveConfig {
|
||||
float legacy_gpr_min_visible_pair_count = 0.0F;
|
||||
std::uint32_t gpr_max_detected_objects_to_draw = 0;
|
||||
std::uint32_t gpr_draw_top_m_objects = 0;
|
||||
// Visible X/Z window (metres). The locator clips broadcast objects to this
|
||||
// window so the socket emits only what the desktop plot actually shows.
|
||||
float gpr_visible_x_min_m = -2.0F;
|
||||
float gpr_visible_x_max_m = 2.0F;
|
||||
float gpr_visible_z_min_m = 0.0F;
|
||||
float gpr_visible_z_max_m = 14.0F;
|
||||
// When true, the data_processor ignores socket-supplied `vlc` updates and
|
||||
// keeps using `gpr_speed_m_s` from this file. Mirrored from the GUI's
|
||||
// "ignore socket speed" checkbox.
|
||||
|
||||
@@ -64,6 +64,7 @@ void DataProcessor::run(const std::atomic<bool>& stop_requested) {
|
||||
std::uint64_t last_replayed_revision = live_config_loader_.revision();
|
||||
std::uint64_t last_applied_history_command_seq = 0;
|
||||
std::uint64_t error_count = 0;
|
||||
std::uint64_t consecutive_errors = 0;
|
||||
// Fix #55: track the socket-fed speed used for the last reprocess so a change
|
||||
// arriving without a live-config revision bump still triggers a reprocess of
|
||||
// the current result (gated below by reprocess_current_result).
|
||||
@@ -143,6 +144,7 @@ void DataProcessor::run(const std::atomic<bool>& stop_requested) {
|
||||
);
|
||||
publish_result_collection(result_collection, results_ring_);
|
||||
publish_locator(result_collection, live_config);
|
||||
consecutive_errors = 0; // made progress; reset the escalation counter
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -155,14 +157,23 @@ void DataProcessor::run(const std::atomic<bool>& stop_requested) {
|
||||
throw;
|
||||
}
|
||||
// A single bad collection (torn ring slot, decode/processing error) must
|
||||
// not kill the long-running processor: drop it and keep going. Throttle
|
||||
// logging and pause briefly so a persistent error cannot busy-spin/flood.
|
||||
if (error_count % 100 == 0) {
|
||||
std::cerr << "data_processor: dropped collection after error (count="
|
||||
<< (error_count + 1) << "): " << exc.what() << '\n';
|
||||
}
|
||||
// not kill the long-running processor: drop it and keep going.
|
||||
++error_count;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(config_.runtime.idle_sleep_ms));
|
||||
++consecutive_errors;
|
||||
// Escalate a PERSISTENT failure (a deterministic config error drops every
|
||||
// collection forever): log it loudly and distinctly — not buried in the
|
||||
// every-100 throttle — so liveness-only supervision still surfaces it.
|
||||
if (consecutive_errors % 500 == 0) {
|
||||
std::cerr << "data_processor: " << consecutive_errors
|
||||
<< " consecutive failures — likely a permanent configuration error: "
|
||||
<< exc.what() << '\n';
|
||||
} else if (error_count % 100 == 1) {
|
||||
std::cerr << "data_processor: dropped collection after error (count="
|
||||
<< error_count << "): " << exc.what() << '\n';
|
||||
}
|
||||
// Back-off (floored at 1ms even if idle_sleep_ms==0) so a persistent error
|
||||
// cannot busy-spin a core or flood the log.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(std::max<int>(1, config_.runtime.idle_sleep_ms)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,6 +232,14 @@ auto DataProcessor::build_locator_filter(const ProcessingLiveConfig& live_config
|
||||
live_config.processor_mode.empty() ? default_processor_mode_ : live_config.processor_mode;
|
||||
|
||||
radar::locator::FilterParams filter{};
|
||||
// Clip broadcast objects to the same visible X/Z window the desktop plot uses,
|
||||
// so the socket emits only the objects the operator actually sees.
|
||||
filter.visible_bounds = radar::locator::VisibleBounds{
|
||||
.x_min = live_config.gpr_visible_x_min_m,
|
||||
.x_max = live_config.gpr_visible_x_max_m,
|
||||
.z_min = live_config.gpr_visible_z_min_m,
|
||||
.z_max = live_config.gpr_visible_z_max_m,
|
||||
};
|
||||
if (requested_mode == "legacy_gpr") {
|
||||
filter.min_score = live_config.legacy_gpr_min_visible_pair_count;
|
||||
// The GUI deliberately disables the "draw top N" capping for legacy
|
||||
|
||||
@@ -348,6 +348,19 @@ void apply_legacy_gpr_algorithm_alias(ProcessingLiveConfig& config, const std::s
|
||||
}
|
||||
config.gpr_min_visible_score = static_cast<float>(found->get<double>());
|
||||
}
|
||||
for (const auto& [key, target] : {
|
||||
std::pair{"gpr_visible_x_min_m", &config.gpr_visible_x_min_m},
|
||||
std::pair{"gpr_visible_x_max_m", &config.gpr_visible_x_max_m},
|
||||
std::pair{"gpr_visible_z_min_m", &config.gpr_visible_z_min_m},
|
||||
std::pair{"gpr_visible_z_max_m", &config.gpr_visible_z_max_m},
|
||||
}) {
|
||||
if (const auto found = root.find(key); found != root.end()) {
|
||||
if (!found->is_number()) {
|
||||
throw std::runtime_error(std::string("processing.") + key + " must be number");
|
||||
}
|
||||
*target = static_cast<float>(found->get<double>());
|
||||
}
|
||||
}
|
||||
if (const auto found = root.find("legacy_gpr_min_visible_pair_count"); found != root.end()) {
|
||||
if (!found->is_number()) {
|
||||
throw std::runtime_error("processing.legacy_gpr_min_visible_pair_count must be number");
|
||||
|
||||
@@ -511,8 +511,16 @@ void TcpServer::acceptor_loop() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
// Listening socket closed during shutdown produces EBADF/EINVAL; bail.
|
||||
break;
|
||||
// Shutdown closes the listening socket (EBADF/EINVAL) -> bail. But an
|
||||
// unexpected errno on a still-running server (e.g. EPERM from a firewall
|
||||
// rule) must NOT kill the acceptor and silently stop serving new clients:
|
||||
// log, back off, and keep accepting.
|
||||
if (!running_.load(std::memory_order_acquire)) {
|
||||
break;
|
||||
}
|
||||
std::cerr << "locator: accept() failed (errno=" << errno << "); retrying\n";
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
reap_finished_clients();
|
||||
|
||||
Reference in New Issue
Block a user