io.h
Go to the documentation of this file.
1/**
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include <string>
20
22{
24 {
25 /**
26 * Distance to obstacles [mm] the optimizer aims for.
27 *
28 * This is a target, not a limit: the obstacle barrier falls to zero here, so the
29 * smoother has no reason to seek more room than this and a growing reason to seek more
30 * as it drops below. Raising it pushes paths further from furniture.
31 */
32 double clearance = 75.0;
33
34 /**
35 * Distance to obstacles [mm] below which a path is actually refused.
36 *
37 * Kept separate from `clearance` because the two answer different questions. The
38 * target says where the smoother should try to be; this says what is unsafe. Enforcing
39 * the target as the limit throws away paths that are perfectly drivable -- the costmap
40 * already has the robot's radius subtracted, so a path measured at 30 mm still clears
41 * obstacles by 30 mm of real air, and refusing it means falling back to the unsmoothed
42 * path, which is rougher and no safer.
43 *
44 * Its real job is to stop the smoother trading clearance for smoothness without bound:
45 * straightening a corner is worth more to the cost function than the room it gives up,
46 * so without a floor a path would cut corners into obstacles outright.
47 *
48 * Note the costmap is sampled at cell centres and read by nearest cell, so a reported
49 * distance carries up to about half a cell diagonal of error -- 70 mm at the default
50 * 100 mm cells. A limit far below that is being enforced within the noise of the
51 * measurement rather than on the geometry.
52 */
53 double min_clearance = 25.0;
54
55 // Width [mm] of the obstacle influence band beyond the clearance. The cost falls to
56 // exactly zero at `clearance + obs_max_distance` and also sets how sharply penetration
57 // into the clearance is punished.
58 double obs_max_distance = 300.0;
59
60 /**
61 * Spacing [mm] of the obstacle samples along a segment.
62 *
63 * Must be no coarser than the trajectory checker's own sampling, or the optimizer is
64 * judged at points it never evaluated: a segment can pass every sample the cost
65 * function looks at and still dip below the clearance between two of them. This was a
66 * fixed count of 3 per segment regardless of length, which matched the checker only
67 * while segments happened to be about 200 mm long.
68 */
70
71 /**
72 * Judge a path against what it was given, when the input is already inside the limit.
73 *
74 * The limit below is an absolute floor, and on a request whose own start, goal or
75 * route already sits inside it the floor cannot be met by anything -- so the smoothed
76 * path is refused and the unsmoothed one is driven instead. That trade is not a safety
77 * decision. Measured over the requests it applies to, the path handed back is *the same
78 * distance from obstacles* as the smoothed one would have been, and considerably
79 * rougher; the rejection buys nothing at all.
80 *
81 * With this on, the floor for such a request becomes the clearance its own input
82 * already had, so the smoother is required not to make the worst point worse rather
83 * than to fix something it cannot reach. Requests whose input clears the limit are
84 * unaffected -- for them the floor is the limit, exactly as before.
85 */
87
88 /**
89 * Scale the tracking weight by the clearance at each waypoint's reference position.
90 *
91 * Strong where clearance is scarce, fading to nothing where it is plentiful. The soft
92 * counterpart to pinning: it discourages a tight waypoint from wandering without
93 * removing its freedom, so it cannot create the half-constrained segments that pinning
94 * does.
95 */
97
98 /// Clearance [mm] at which the leash starts to relax.
100
101 /// Clearance [mm] beyond which tracking is off entirely.
103
104 /**
105 * Hold interior waypoints below `obstacle_freeze_threshold` fixed during the solve.
106 *
107 * The intent is robustness: a waypoint already close to an obstacle is one the
108 * optimizer could only make worse. Measure before enabling -- see the threshold below.
109 */
111
112 /**
113 * Clearance [mm] at or below which an interior waypoint is pinned.
114 *
115 * Pinning a waypoint makes both segments adjoining it half-constrained, which is
116 * exactly the structure that produces the rejections this smoother already has at its
117 * commanded endpoints: the checker samples those segments, and with one end immovable
118 * the optimizer often cannot lift a dip out of them. Freezing turns every tight
119 * waypoint into another such endpoint, and it does so precisely where clearance is
120 * already scarce.
121 */
123
124 /// Lower bound on the samples per segment, so a short segment is still evaluated.
126
127 /// Upper bound, so a long segment cannot make the problem huge.
129
130 // Pass 1: smooth near original path
131 double pass1_w_obs = 100.0;
133 double pass1_w_spacing = 0.001;
134 double pass1_w_tracking = 0.2;
136
137 // Pass 2: push away from obstacles
138 double pass2_w_obs = 500.0;
139 double pass2_w_pose_smooth = 15.0;
140 double pass2_w_spacing = 0.001;
141 double pass2_w_tracking = 0.1;
143
144 // Pass 3: final polish
145 double pass3_w_obs = 1000.0;
146 double pass3_w_pose_smooth = 25.0;
147 double pass3_w_spacing = 0.0;
148 double pass3_w_tracking = 0.05;
150
151 // Repair pass (used if collisions remain after pass 3)
152 double repair_w_obs = 2000.0;
153 double repair_w_pose_smooth = 30.0;
154 double repair_w_spacing = 0.0;
155 double repair_w_tracking = 0.2;
158
159 // Bounded tracking to safe (hill-climbed) path.
160 // The hard deviation limit is also the maximum allowed movement from the
161 // original SPFA path.
162 double tracking_deadzone = 25.0;
165 double w_tracking_hard = 10000.0;
166
167 // Ceres solver
168 int max_iterations = 150;
169 int num_threads = 4;
173 };
174
176 loadSmoothingParams(const std::string& filePath = "algorithms/spfa-smoothing.cfg");
177
178} // namespace armarx::navigation::algorithms::spfa::smoothing::io
SmoothingParams loadSmoothingParams(const std::string &filePath)
Definition io.cpp:29
double min_clearance
Distance to obstacles [mm] below which a path is actually refused.
Definition io.h:53
double tracking_fade_end_clearance
Clearance [mm] beyond which tracking is off entirely.
Definition io.h:102
bool use_obstacle_freeze
Hold interior waypoints below obstacle_freeze_threshold fixed during the solve.
Definition io.h:110
double clearance
Distance to obstacles [mm] the optimizer aims for.
Definition io.h:32
double tracking_fade_start_clearance
Clearance [mm] at which the leash starts to relax.
Definition io.h:99
bool use_tracking_clearance_adaptive
Scale the tracking weight by the clearance at each waypoint's reference position.
Definition io.h:96
double segment_sample_spacing
Spacing [mm] of the obstacle samples along a segment.
Definition io.h:69
bool allow_degraded_input
Judge a path against what it was given, when the input is already inside the limit.
Definition io.h:86
double obstacle_freeze_threshold
Clearance [mm] at or below which an interior waypoint is pinned.
Definition io.h:122
int max_segment_obstacle_samples
Upper bound, so a long segment cannot make the problem huge.
Definition io.h:128
int segment_obstacle_samples
Lower bound on the samples per segment, so a short segment is still evaluated.
Definition io.h:125