test new version
This commit is contained in:
@@ -105,6 +105,10 @@ struct ProcessingLiveConfig {
|
||||
std::uint32_t sar3d_grid_nz = 160U;
|
||||
bool sar3d_use_compensation = true;
|
||||
bool sar3d_normalize_pairs = true;
|
||||
// Bottom-view projection angle around the vertical Y axis, degrees:
|
||||
// 0 = front view (X horizontal), 90 = side view (Z horizontal),
|
||||
// intermediate values project along the rotated horizontal direction.
|
||||
float sar3d_bottom_view_deg = 0.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.
|
||||
|
||||
@@ -396,6 +396,7 @@ void apply_legacy_gpr_algorithm_alias(ProcessingLiveConfig& config, const std::s
|
||||
std::pair{"sar3d_half_width_x_m", &config.sar3d_half_width_x_m},
|
||||
std::pair{"sar3d_half_width_y_m", &config.sar3d_half_width_y_m},
|
||||
std::pair{"sar3d_half_width_z_m", &config.sar3d_half_width_z_m},
|
||||
std::pair{"sar3d_bottom_view_deg", &config.sar3d_bottom_view_deg},
|
||||
}) {
|
||||
if (const auto found = root.find(key); found != root.end()) {
|
||||
if (!found->is_number()) {
|
||||
|
||||
@@ -457,6 +457,15 @@ auto Sar3dProcessor::process_collection(
|
||||
|
||||
// Finalization (port of gpr_core sar_finish_volume, minus smoothing):
|
||||
// |acc/(cnt+eps)|, ground-coordinate depth gate, normalization to peak.
|
||||
//
|
||||
// Two projections match the legacy render conventions (X across,
|
||||
// Z range/"вдаль", Y up):
|
||||
// - top view `sar3d_proj_xz`: max over Y, axes X (horizontal) / Z;
|
||||
// - bottom view `sar3d_proj_bottom`: vertical axis is always Y, the
|
||||
// horizontal axis u is the ground direction rotated by
|
||||
// `sar3d_bottom_view_deg` around Y: 0° = front view (u = X, max
|
||||
// along Z), 90° = side view (u = Z, max along X), intermediate
|
||||
// angles project along the rotated perpendicular.
|
||||
const int nx = volume.NX;
|
||||
const int ny = volume.NY;
|
||||
const int nz = volume.NZ;
|
||||
@@ -464,8 +473,36 @@ auto Sar3dProcessor::process_collection(
|
||||
const double cos_p = std::cos(pitch_rad);
|
||||
const double sin_p = std::sin(pitch_rad);
|
||||
|
||||
const double theta_deg = std::clamp(static_cast<double>(live_config.sar3d_bottom_view_deg), 0.0, 90.0);
|
||||
const double theta_rad = theta_deg * M_PI / 180.0;
|
||||
const double cos_t = std::cos(theta_rad);
|
||||
const double sin_t = std::sin(theta_rad);
|
||||
// Exact-axis fast paths keep the front/side views on the native grid.
|
||||
const bool front_view = theta_deg <= 1e-9;
|
||||
const bool side_view = theta_deg >= 90.0 - 1e-9;
|
||||
std::vector<double> u_axis{};
|
||||
if (front_view) {
|
||||
u_axis = grid.x;
|
||||
} else if (side_view) {
|
||||
u_axis = grid.z;
|
||||
} else {
|
||||
const double u_a = grid.x.front() * cos_t + grid.z.front() * sin_t;
|
||||
const double u_b = grid.x.front() * cos_t + grid.z.back() * sin_t;
|
||||
const double u_c = grid.x.back() * cos_t + grid.z.front() * sin_t;
|
||||
const double u_d = grid.x.back() * cos_t + grid.z.back() * sin_t;
|
||||
const double u_min = std::min(std::min(u_a, u_b), std::min(u_c, u_d));
|
||||
const double u_max = std::max(std::max(u_a, u_b), std::max(u_c, u_d));
|
||||
u_axis.resize(static_cast<std::size_t>(nx));
|
||||
for (int iu = 0; iu < nx; ++iu) {
|
||||
u_axis[static_cast<std::size_t>(iu)] = u_min + (u_max - u_min) * iu / static_cast<double>(nx - 1);
|
||||
}
|
||||
}
|
||||
const int nu = static_cast<int>(u_axis.size());
|
||||
const double u_start = u_axis.front();
|
||||
const double inv_du = nu > 1 ? static_cast<double>(nu - 1) / (u_axis.back() - u_start) : 0.0;
|
||||
|
||||
std::vector<float> projection_xz(static_cast<std::size_t>(nz) * nx, 0.0F);
|
||||
std::vector<float> projection_xy(static_cast<std::size_t>(ny) * nx, 0.0F);
|
||||
std::vector<float> projection_bottom(static_cast<std::size_t>(ny) * nu, 0.0F);
|
||||
float peak = 0.0F;
|
||||
for (int iy = 0; iy < ny; ++iy) {
|
||||
for (int iz = 0; iz < nz; ++iz) {
|
||||
@@ -475,6 +512,8 @@ auto Sar3dProcessor::process_collection(
|
||||
continue;
|
||||
}
|
||||
const std::size_t row = (static_cast<std::size_t>(iy) * nz + iz) * nx;
|
||||
const std::size_t bottom_row = static_cast<std::size_t>(iy) * nu;
|
||||
const double z_sin_t = grid.z[iz] * sin_t;
|
||||
for (int ix = 0; ix < nx; ++ix) {
|
||||
const std::size_t voxel = row + static_cast<std::size_t>(ix);
|
||||
const float value = std::abs(volume.acc[voxel]) /
|
||||
@@ -482,8 +521,16 @@ auto Sar3dProcessor::process_collection(
|
||||
peak = std::max(peak, value);
|
||||
auto& xz_cell = projection_xz[static_cast<std::size_t>(iz) * nx + ix];
|
||||
xz_cell = std::max(xz_cell, value);
|
||||
auto& xy_cell = projection_xy[static_cast<std::size_t>(iy) * nx + ix];
|
||||
xy_cell = std::max(xy_cell, value);
|
||||
int bin = ix;
|
||||
if (side_view) {
|
||||
bin = iz;
|
||||
} else if (!front_view) {
|
||||
const double u = grid.x[ix] * cos_t + z_sin_t;
|
||||
bin = static_cast<int>(std::lround((u - u_start) * inv_du));
|
||||
bin = std::clamp(bin, 0, nu - 1);
|
||||
}
|
||||
auto& bottom_cell = projection_bottom[bottom_row + static_cast<std::size_t>(bin)];
|
||||
bottom_cell = std::max(bottom_cell, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -491,7 +538,7 @@ auto Sar3dProcessor::process_collection(
|
||||
for (auto& value : projection_xz) {
|
||||
value /= peak;
|
||||
}
|
||||
for (auto& value : projection_xy) {
|
||||
for (auto& value : projection_bottom) {
|
||||
value /= peak;
|
||||
}
|
||||
}
|
||||
@@ -500,7 +547,7 @@ auto Sar3dProcessor::process_collection(
|
||||
build_image_payload("sar3d_proj_xz", grid.x, grid.z, std::move(projection_xz))
|
||||
);
|
||||
results.collection_payloads.push_back(
|
||||
build_image_payload("sar3d_proj_xy", grid.x, grid.y, std::move(projection_xy))
|
||||
build_image_payload("sar3d_proj_bottom", u_axis, grid.y, std::move(projection_bottom))
|
||||
);
|
||||
ipc::ResultPayload peak_payload{};
|
||||
peak_payload.processing_name = "sar3d_peak";
|
||||
|
||||
@@ -164,7 +164,11 @@ auto load_collection(
|
||||
return collection;
|
||||
}
|
||||
|
||||
void print_projection_argmax(const radar::ipc::ResultPayload& payload, const char* row_axis_name) {
|
||||
void print_projection_argmax(
|
||||
const radar::ipc::ResultPayload& payload,
|
||||
const char* col_axis_name,
|
||||
const char* row_axis_name
|
||||
) {
|
||||
std::size_t argmax = 0U;
|
||||
float best = -1.0F;
|
||||
for (std::size_t index = 0U; index < payload.image_values.size(); ++index) {
|
||||
@@ -177,9 +181,10 @@ void print_projection_argmax(const radar::ipc::ResultPayload& payload, const cha
|
||||
const auto col = argmax % nx;
|
||||
const auto row = argmax / nx;
|
||||
std::printf(
|
||||
"%s: max=%.6f at X=%.1f cm, %s=%.1f cm\n",
|
||||
"%s: max=%.6f at %s=%.1f cm, %s=%.1f cm\n",
|
||||
payload.processing_name.c_str(),
|
||||
static_cast<double>(best),
|
||||
col_axis_name,
|
||||
static_cast<double>(payload.image_x_axis[col]) * 100.0,
|
||||
row_axis_name,
|
||||
static_cast<double>(payload.image_y_axis[row]) * 100.0
|
||||
@@ -253,10 +258,26 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
for (const auto& payload : result.collection_payloads) {
|
||||
if (payload.kind != radar::ipc::ResultKind::ImageF32) {
|
||||
continue;
|
||||
if (payload.kind == radar::ipc::ResultKind::ImageF32 && payload.processing_name == "sar3d_proj_xz") {
|
||||
print_projection_argmax(payload, "X", "Z");
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom view across the selectable angles: the target's u coordinate must
|
||||
// move smoothly from its X (front, 0 deg) to its Z (side, 90 deg).
|
||||
const auto last_previous =
|
||||
std::span<const radar::ipc::PreprocessedCollection>(history.data(), history.size() - 1U);
|
||||
for (const float angle_deg : {0.0F, 30.0F, 60.0F, 90.0F}) {
|
||||
auto live_angle = live;
|
||||
live_angle.sar3d_bottom_view_deg = angle_deg;
|
||||
const auto angle_result =
|
||||
processor.process_collection(run_config, history.back(), last_previous, live_angle);
|
||||
for (const auto& payload : angle_result.collection_payloads) {
|
||||
if (payload.kind == radar::ipc::ResultKind::ImageF32 && payload.processing_name == "sar3d_proj_bottom") {
|
||||
std::printf("bottom @ %2.0f deg -> ", static_cast<double>(angle_deg));
|
||||
print_projection_argmax(payload, "u", "Y");
|
||||
}
|
||||
}
|
||||
print_projection_argmax(payload, payload.processing_name == "sar3d_proj_xz" ? "Z" : "Y");
|
||||
}
|
||||
std::printf("OK: sar3d processor path completed\n");
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user