ReUseX
0.0.5
3D Point Cloud Processing for Building Reuse
Toggle main menu visibility
Loading...
Searching...
No Matches
optimize_stage.hpp
Go to the documentation of this file.
1
// SPDX-FileCopyrightText: 2026 Povl Filip Sonne-Frederiksen
2
//
3
// SPDX-License-Identifier: GPL-3.0-or-later
4
5
#pragma once
6
7
// The in-process `optimize` stage and the executor that adds it to
8
// default_stage_executor(), shared by every in-process job runner: the Qt
9
// client (rux) and the web GUI (ruxd).
10
//
11
// LAYERING: reusex_pipeline does not link reusex_slam (GTSAM, #464), so this
12
// header is deliberately HEADER-ONLY and compiled into its consumers, which
13
// must link both modules (the `reusex` umbrella does). It is the same
14
// arrangement as geometry/component_persistence.hpp. Including it from
15
// reusex_pipeline itself, or from ruxd_api_lib, would be a link error.
16
17
#include <reusex/core/ProjectDB.hpp>
18
#include <reusex/pipeline/stages.hpp>
19
#include <reusex/slam/PlaneGraphOptimizer.hpp>
20
#include <reusex/slam/optimize_parameters.hpp>
21
22
#include <fmt/format.h>
23
24
#include <exception>
25
#include <utility>
26
27
namespace
reusex::pipeline
{
28
32
inline
StageResult
run_optimize_stage
(
ProjectDB
&db,
const
StageContext
&ctx) {
33
geometry::PlaneGraphOptions
options;
34
bool
dry_run =
false
;
35
try
{
36
geometry::apply_optimize_parameters
(options, dry_run, ctx.
parameters
);
37
}
catch
(
const
std::exception &e) {
38
return
StageResult::invalid
(e.what());
39
}
40
41
try
{
42
auto
result =
geometry::optimize_sensor_poses
(db, options, dry_run);
43
44
if
(result.landmarks == 0 && result.loop_edges == 0)
45
return
StageResult::success
(
46
fmt::format(
"no plane landmarks reached min_observations={} and no "
47
"loop edges present; poses left unchanged"
,
48
options.
min_landmark_observations
));
49
50
if
(!result.converged)
51
return
StageResult::failure
(
52
"factor-graph optimizer failed to produce a solution; poses left "
53
"unchanged"
);
54
55
if
(dry_run)
56
return
StageResult::success
(
57
fmt::format(
"dry run: {} frames, {} landmarks, {:.4f} -> {:.4f} "
58
"error, max shift {:.4f} m (poses not written)"
,
59
result.frames, result.landmarks, result.initial_error,
60
result.final_error, result.max_pose_shift));
61
62
return
StageResult::success
(
63
fmt::format(
"{} frames, {} landmarks, {:.4f} -> {:.4f} error, max "
64
"shift {:.4f} m"
,
65
result.frames, result.landmarks, result.initial_error,
66
result.final_error, result.max_pose_shift),
67
// `sensor_frames` is the artifact optimized poses are written into.
68
{{
"table"
,
"sensor_frames"
, static_cast<int64_t>(result.frames)}});
69
}
catch
(
const
std::exception &e) {
70
return
StageResult::failure
(
71
fmt::format(
"pose optimization failed: {}"
, e.what()));
72
}
73
}
74
77
inline
StageExecutor
stage_executor_with_optimize
() {
78
auto
default_exec =
default_stage_executor
();
79
return
[default_exec =
80
std::move(default_exec)](
const
StageContext
&ctx) ->
StageResult
{
81
if
(ctx.stage ==
JobStage::optimize
) {
82
try
{
83
ProjectDB
db(ctx.project,
/*readOnly=*/
false
);
84
return
run_optimize_stage
(db, ctx);
85
}
catch
(
const
std::exception &e) {
86
return
StageResult::failure
(fmt::format(
87
"could not open project '{}': {}"
, ctx.project.string(), e.what()));
88
}
89
}
90
return
default_exec(ctx);
91
};
92
}
93
94
}
// namespace reusex::pipeline
reusex::ProjectDB
Definition
ProjectDB.hpp:45
reusex::geometry::optimize_sensor_poses
PlaneGraphResult optimize_sensor_poses(ProjectDB &db, const PlaneGraphOptions &options, bool dry_run=false)
High-level entry point: extract surfels for every sensor frame in db, globally optimize their poses v...
reusex::geometry::apply_optimize_parameters
void apply_optimize_parameters(PlaneGraphOptions &options, bool &dry_run, std::string_view parameters)
Apply the optimize stage's parameter JSON to options and dry_run.
reusex::pipeline
Definition
job_types.hpp:24
reusex::pipeline::run_optimize_stage
StageResult run_optimize_stage(ProjectDB &db, const StageContext &ctx)
Run optimize on an open project: the library defaults (which the rux optimize flags mirror) plus the ...
Definition
optimize_stage.hpp:32
reusex::pipeline::JobStage::optimize
@ optimize
refine per-frame sensor poses via plane-landmark pose graph
Definition
stages.hpp:49
reusex::pipeline::default_stage_executor
StageExecutor default_stage_executor()
The executor that actually runs the pipeline (a thin wrap of run_stage).
reusex::pipeline::StageExecutor
std::function< StageResult(const StageContext &)> StageExecutor
Stage execution strategy.
Definition
stages.hpp:148
reusex::pipeline::stage_executor_with_optimize
StageExecutor stage_executor_with_optimize()
default_stage_executor() plus optimize (run_optimize_stage on a read-write open of the job's project)...
Definition
optimize_stage.hpp:77
reusex::geometry::PlaneGraphOptions
Parameters for plane-landmark pose-graph optimization.
Definition
PlaneGraphOptimizer.hpp:172
reusex::geometry::PlaneGraphOptions::min_landmark_observations
int min_landmark_observations
landmark must be seen by >= this many frames
Definition
PlaneGraphOptimizer.hpp:186
reusex::pipeline::StageContext
Everything a stage execution needs, independent of any HTTP/CLI front end.
Definition
stages.hpp:116
reusex::pipeline::StageContext::parameters
std::string parameters
Stage parameters as a JSON object (empty string = all defaults).
Definition
stages.hpp:124
reusex::pipeline::StageResult
Outcome of one stage execution.
Definition
stages.hpp:92
reusex::pipeline::StageResult::success
static StageResult success(std::string message={})
reusex::pipeline::StageResult::failure
static StageResult failure(std::string message)
reusex::pipeline::StageResult::invalid
static StageResult invalid(std::string message)
libs
reusex
include
pipeline
optimize_stage.hpp
Generated by
1.18.0