RoomScene.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 <cstddef>
20#include <filesystem>
21#include <optional>
22#include <random>
23#include <string>
24#include <vector>
25
26#include <Eigen/Core>
27
29
31
33{
34
35 /// A pose from the room's navigation graph, kept with its name so a failing request can be
36 /// reported as something a reader recognises rather than a pair of coordinates.
37 struct NamedPose
38 {
39 std::string name;
40
42 };
43
44 /// Whether a point lies within the bounds, edges included.
45 bool contains(const algorithms::SceneBounds& bounds, const Eigen::Vector2f& point);
46
47 /// The room as the planner sees it, assembled from PriorKnowledgeData.
48 struct RoomScene
49 {
50 /// The first `roomWallCount` obstacles are always the room walls, which is what lets
51 /// the synthetic scenes below strip the furniture and keep the room.
53
54 /// Poses from `navigation-graphs/<room>/locations.json`.
55 std::vector<NamedPose> locations;
56
57 /// Import problems: objects and locations dropped, and objects kept with an
58 /// approximated footprint. Reported so a reader knows what is actually in the costmap.
59 std::vector<std::string> importWarnings;
60
61 /// Set when the scene is a corridor, so requests can be drawn as exits from it.
62 std::optional<algorithms::SceneBounds> corridor;
63 };
64
65 /// Number of wall boxes `buildRoomScene` puts at the front of the obstacle list.
66 inline constexpr std::size_t roomWallCount = 4;
67
68 /**
69 * @brief Build the scene for a room from PriorKnowledgeData.
70 *
71 * Each object's oriented bounding box is transformed by the object's pose and projected to
72 * the ground plane. Room walls come from the room polygon's axis-aligned bounds.
73 *
74 * @param priorKnowledge Root of the PriorKnowledgeData `data/PriorKnowledgeData` directory.
75 * @param room Room path within the scene collections, e.g. `50_19/R007`.
76 * @param sceneFiles Scene descriptions to merge, e.g. `static_scene`, `mobile_kitchen`.
77 * @param wallThickness Thickness [mm] of the boxes standing in for the room walls.
78 */
79 RoomScene buildRoomScene(const std::filesystem::path& priorKnowledge,
80 const std::string& room,
81 const std::vector<std::string>& sceneFiles,
82 float wallThickness = 200.F);
83
85 {
86 /// Boxes to add. R007 is 6 x 14 m, so a few dozen already makes it hard.
87 int count{40};
88
89 float minExtent{300.F};
90
91 float maxExtent{900.F};
92
93 /**
94 * Gap [mm] a new box must leave to every obstacle already placed.
95 *
96 * This is the knob that makes the scene difficult, and it is deliberately expressed
97 * as a gap rather than as a density. Set a little above the robot's diameter it
98 * produces passages the robot only just fits through, which is the regime where the
99 * smoother has to thread a path rather than merely shorten one. Set below the
100 * diameter it produces dead ends, which tests the planner rather than the smoother.
101 */
102 float minGap{750.F};
103
104 /// Attempts per box before giving up, so a saturated room terminates.
105 int maxAttempts{400};
106 };
107
108 /**
109 * @brief Scatter boxes through the room to create tight passages.
110 *
111 * Seeded from the caller's generator, so a cluttered sweep is as reproducible as a plain
112 * one. Returns the number actually placed, which falls short of `count` once the room
113 * saturates.
114 */
115 int addClutter(analysis::Scene& scene, const ClutterParameters& parameters, std::mt19937& rng);
116
118 {
119 /// Clear width [mm] between the corridor walls.
120 float width{900.F};
121
122 /// How far the corridor runs into the room [mm].
123 float length{5000.F};
124
125 float wallThickness{200.F};
126 };
127
128 /**
129 * @brief A dead-end corridor opening into the rest of the room.
130 *
131 * Models the case the serpentine does not: the robot starts *inside* tight space and has to
132 * get out. The difference matters because the optimizer holds the start fixed, so a start
133 * deep in a corridor constrains the path in a way a start in open space never does -- the
134 * first segments have one free endpoint each and no room either side.
135 *
136 * Removes the furniture, keeping only the room walls.
137 *
138 * @return The region the corridor occupies, so requests can be drawn as exits from it.
139 */
141 const CorridorParameters& parameters);
142
144 {
145 /// Width [mm] of every opening. Exact by construction, which is the point: random
146 /// clutter cannot guarantee a passage is traversable, and a scene whose passages are
147 /// narrower than the checker's clearance measures its own geometry rather than the
148 /// planner.
149 float passageWidth{1000.F};
150
151 /// Number of transverse walls. Each one adds an opening the path must thread and a
152 /// direction change, which is what actually loads the smoother.
153 int walls{6};
154
155 float wallThickness{200.F};
156 };
157
158 /**
159 * @brief Replace the room's contents with transverse walls whose openings alternate sides.
160 *
161 * Forces a serpentine path: every wall is a tight passage followed by a reversal, so a
162 * single request exercises threading and turning repeatedly. Furniture is removed rather
163 * than added to, so the passage width is the only thing constraining the path and the
164 * scene stays interpretable.
165 *
166 * @return The narrowest clearance [mm] the scene offers a robot of the given radius, so
167 * the caller can refuse to run a sweep that is unwinnable by construction.
168 */
169 float makeSerpentine(analysis::Scene& scene,
170 const SerpentineParameters& parameters,
171 float robotRadius);
172
173} // namespace armarx::navigation::evaluation
Eigen::Isometry3f Pose
Definition basic_types.h:31
This file is part of ArmarX.
Definition Metrics.cpp:30
bool contains(const algorithms::SceneBounds &bounds, const Eigen::Vector2f &point)
Whether a point lies within the bounds, edges included.
Definition RoomScene.cpp:99
algorithms::SceneBounds makeCorridor(analysis::Scene &scene, const CorridorParameters &parameters)
A dead-end corridor opening into the rest of the room.
float makeSerpentine(analysis::Scene &scene, const SerpentineParameters &parameters, const float robotRadius)
Replace the room's contents with transverse walls whose openings alternate sides.
RoomScene buildRoomScene(const std::filesystem::path &priorKnowledge, const std::string &room, const std::vector< std::string > &sceneFiles, const float wallThickness)
Build the scene for a room from PriorKnowledgeData.
int addClutter(analysis::Scene &scene, const ClutterParameters &parameters, std::mt19937 &rng)
Scatter boxes through the room to create tight passages.
constexpr std::size_t roomWallCount
Number of wall boxes buildRoomScene puts at the front of the obstacle list.
Definition RoomScene.h:66
The synthetic scene: what the world looks like, independent of the planner.
Definition Scene.h:60
int maxAttempts
Attempts per box before giving up, so a saturated room terminates.
Definition RoomScene.h:105
float minGap
Gap [mm] a new box must leave to every obstacle already placed.
Definition RoomScene.h:102
int count
Boxes to add. R007 is 6 x 14 m, so a few dozen already makes it hard.
Definition RoomScene.h:87
float length
How far the corridor runs into the room [mm].
Definition RoomScene.h:123
float width
Clear width [mm] between the corridor walls.
Definition RoomScene.h:120
A pose from the room's navigation graph, kept with its name so a failing request can be reported as s...
Definition RoomScene.h:38
The room as the planner sees it, assembled from PriorKnowledgeData.
Definition RoomScene.h:49
std::vector< NamedPose > locations
Poses from navigation-graphs/<room>/locations.json.
Definition RoomScene.h:55
std::optional< algorithms::SceneBounds > corridor
Set when the scene is a corridor, so requests can be drawn as exits from it.
Definition RoomScene.h:62
analysis::Scene scene
The first roomWallCount obstacles are always the room walls, which is what lets the synthetic scenes ...
Definition RoomScene.h:52
std::vector< std::string > importWarnings
Import problems: objects and locations dropped, and objects kept with an approximated footprint.
Definition RoomScene.h:59
float passageWidth
Width [mm] of every opening.
Definition RoomScene.h:149