NavigatingSkillHelper.cpp
Go to the documentation of this file.
2
3#include <memory>
4#include <mutex>
5#include <optional>
6#include <string>
7
8#include <Eigen/Core>
9#include <Eigen/Geometry>
10
11#include <range/v3/range/conversion.hpp>
12#include <range/v3/view/transform.hpp>
13
17#include <ArmarXCore/interface/core/UserException.h>
19
31#include <armarx/navigation/skills/aron/NavigatingSkillParams.aron.generated.h>
34
36{
37
39 const Services& srv) :
40 properties_(properties)
41 {
42 srv_.emplace(srv);
43 }
44
45 namespace
46 {
47
48 void
49 instantiateGlobalPlannerParams(
50 std::unique_ptr<armarx::navigation::global_planning::GlobalPlannerParams>& params,
51 const arondto::NavigatingSkillParams& skillParams)
52 {
53 switch (skillParams.globalPlanningAlgorithm.value)
54 {
55 case arondto::GlobalPlanningAlgorithm::ImplEnum::AStar:
56 ARMARX_INFO << "Using " << VAROUT("AStarParams")
57 << " global planning strategy.";
58 params = std::make_unique<armarx::navigation::global_planning::AStarParams>();
59 break;
60 case arondto::GlobalPlanningAlgorithm::ImplEnum::AStarWithOrientation:
61 ARMARX_INFO << "Using " << VAROUT("AStarWithOrientationParams")
62 << " global planning strategy.";
63 params = std::make_unique<
65 break;
66 case arondto::GlobalPlanningAlgorithm::ImplEnum::Point2Point:
67 {
68 ARMARX_INFO << "Using " << VAROUT("Point2Point")
69 << " global planning strategy.";
70
73 skillParams.p2pCheckCollisionsAlongTrajectory;
74
75 params =
76 std::make_unique<armarx::navigation::global_planning::Point2PointParams>(p);
77 break;
78 }
79 case arondto::GlobalPlanningAlgorithm::ImplEnum::SPFA:
80 ARMARX_INFO << "Using " << VAROUT("SPFA") << " global planning strategy.";
81 params = std::make_unique<armarx::navigation::global_planning::SPFAParams>();
82 break;
83 default:
84 ARMARX_ERROR << "Algorithm selection incomplete";
85 throw armarx::InvalidArgumentException(
86 "Tried to instantiate global planner but parameter selection logic is "
87 "missing the planner type");
88 break;
89 }
90 }
91 } // namespace
92
93 void
94 NavigatingSkillHelper::init(const arondto::NavigatingSkillParams& params, const std::string& id)
95 {
96 //armarx::navigation::global_planning::AStarWithOrientationParams globalPlannerParams{};
97 std::unique_ptr<armarx::navigation::global_planning::GlobalPlannerParams>
98 globalPlannerParams;
99 instantiateGlobalPlannerParams(globalPlannerParams, params);
100
103 {
104 ARMARX_CHECK_NOT_NULL(properties_.safetyGuardParamsMutex);
105 std::lock_guard g{*properties_.safetyGuardParamsMutex};
106 if (properties_.safetyGuardParams != nullptr)
107 {
108 safetyGuardParams = *properties_.safetyGuardParams;
109 }
110 }
111 safetyGuardParams.ignoredRegions =
112 params.safetyGuardIgnoredRegions |
113 ranges::views::transform(
114 [](const core::arondto::BoundingBox2D& bbDto) -> Eigen::AlignedBox2f
115 {
116 Eigen::AlignedBox2f bbBo;
117 core::fromAron(bbDto, bbBo);
118 return bbBo;
119 }) |
120 ranges::to_vector;
121
122
123 core::GeneralConfig generalParams{};
124 // load defaults from skill provider
125 generalParams = properties_.defaultGeneralConfig;
126
127 // ramping
128 if (params.enableRampingStart.has_value())
129 {
130 generalParams.enableRampingStart = params.enableRampingStart.value();
131 }
132 if (params.enableRampingEnd.has_value())
133 {
134 generalParams.enableRampingEnd = params.enableRampingEnd.value();
135 }
136 if (params.enableRampingCorners.has_value())
137 {
138 generalParams.enableRampingCorners = params.enableRampingCorners.value();
139 }
140 if (params.rampLength.has_value())
141 {
142 generalParams.rampLength = params.rampLength.value();
143 }
144 if (params.cornerVelocity.has_value())
145 {
146 generalParams.cornerVelocity = params.cornerVelocity.value();
147 }
148 if (params.boundaryVelocity.has_value())
149 {
150 generalParams.boundaryVelocity = params.boundaryVelocity.value();
151 }
152 if (params.cornerLimit.has_value())
153 {
154 generalParams.cornerLimit = params.cornerLimit.value();
155 }
156
158 params.inCollisionDistanceThresholdForRecovery;
159 ARMARX_INFO << "Collision recovery threshold: "
160 << generalParams.inCollisionDistanceThresholdForRecovery << " mm";
161
162 generalParams.navigateCloseAsPossible = params.navigateCloseAsPossible;
163 ARMARX_INFO << "Navigate close as possible: "
164 << (generalParams.navigateCloseAsPossible ? "enabled" : "disabled");
165
166 if (generalParams.enableRampingStart or generalParams.enableRampingEnd or
167 generalParams.enableRampingCorners)
168 {
169 ARMARX_INFO << "Velocity ramping is enabled (start=" << generalParams.enableRampingStart
170 << "; end=" << generalParams.enableRampingEnd
171 << "; corners=" << generalParams.enableRampingCorners
172 << "; rampLength=" << generalParams.rampLength
173 << "; cornerVelocity=" << generalParams.cornerVelocity
174 << "; boundaryVelocity=" << generalParams.boundaryVelocity
175 << "; cornerLimit=" << generalParams.cornerLimit << ").";
176 }
177
178 if (params.velocityLimitLinear.has_value())
179 {
180 generalParams.maxVel.linear = params.velocityLimitLinear.value();
181 }
182 if (params.velocityLimitAngular.has_value())
183 {
184 generalParams.maxVel.angular = params.velocityLimitAngular.value();
185 }
186
187 ARMARX_INFO << "Configuring navigator to respect the velocity limits:";
188 ARMARX_INFO << "linear: " << generalParams.maxVel.linear;
189 ARMARX_INFO << "angular: " << generalParams.maxVel.angular;
190
191 // parameterize the navigation stack
193 cfg.general(generalParams);
194 cfg.globalPlanner(*globalPlannerParams);
195
196 if (params.enableLocalPlanning)
197 {
198 cfg.localPlanner(localPlannerParams);
199 }
200
201 if (params.enableSafetyGuard)
202 {
203 cfg.safetyGuard(safetyGuardParams);
204 }
205
206 // goal reached config - optional override from skill params
207 if (params.goalReachedThresholds.has_value())
208 {
209 core::GoalReachedConfig goalReachedCfg;
210 goalReachedCfg.posTh = params.goalReachedThresholds->posTh;
211 goalReachedCfg.oriTh = params.goalReachedThresholds->oriTh;
212 goalReachedCfg.linearVelTh = params.goalReachedThresholds->linearVelTh;
213 goalReachedCfg.angularVelTh = params.goalReachedThresholds->angularVelTh;
214 goalReachedCfg.filterCount = 5; // Use default filter count
215
216 ARMARX_INFO << "Goal reached config override: posTh=" << goalReachedCfg.posTh
217 << "mm, oriTh=" << goalReachedCfg.oriTh << "rad, linearVelTh="
218 << goalReachedCfg.linearVelTh << "mm/s, angularVelTh="
219 << goalReachedCfg.angularVelTh << "rad/s";
220
221 cfg.goalReached(goalReachedCfg);
222 }
223
224 // configure the `navigator` which provides a simplified and typed interface to the navigation server
226 memorySubscriber.reset();
227
229 memorySubscriber.emplace(id, srv_->memoryNameSystem);
230
231 // register our config
232 ARMARX_INFO << "Registering config";
233 iceNavigator = srv_->iceNavigatorFactory.createConfig(cfg, id);
234
235 navigator.emplace(client::Navigator::InjectedServices{
236 .navigator = iceNavigator.get(), .subscriber = &memorySubscriber.value()});
237 }
238
239 std::optional<client::Navigator>&
241 {
242 return navigator;
243 }
244
245 arondto::NavigatingSkillParams
247 {
248 arondto::NavigatingSkillParams defaultParameters;
249
250 defaultParameters.enableRampingStart = std::nullopt;
251 defaultParameters.enableRampingEnd = std::nullopt;
252 defaultParameters.enableRampingCorners = std::nullopt;
253 defaultParameters.rampLength = std::nullopt;
254 defaultParameters.cornerVelocity = std::nullopt;
255 defaultParameters.boundaryVelocity = std::nullopt;
256 defaultParameters.cornerLimit = std::nullopt;
257
258 defaultParameters.inCollisionDistanceThresholdForRecovery = 150.0F;
259
260 defaultParameters.navigateCloseAsPossible = false;
261
262 defaultParameters.enableLocalPlanning = false;
263 defaultParameters.enableSafetyGuard = true;
264 defaultParameters.safetyGuardIgnoredRegions =
265 std::vector<armarx::navigation::core::arondto::BoundingBox2D>();
266 defaultParameters.velocityLimitAngular = std::nullopt;
267 defaultParameters.velocityLimitLinear = std::nullopt;
268 defaultParameters.globalPlanningAlgorithm = arondto::GlobalPlanningAlgorithm::SPFA;
269 defaultParameters.p2pCheckCollisionsAlongTrajectory = false;
270
271 // Goal reached thresholds - optional, defaults to nullopt (use component defaults)
272 defaultParameters.goalReachedThresholds = std::nullopt;
273
274 return defaultParameters;
275 }
276} // namespace armarx::navigation::skills
#define VAROUT(x)
NavigationStackConfig & goalReached(const core::GoalReachedConfig &cfg)
NavigationStackConfig & safetyGuard(const safety_guard::SafetyGuardParams &params)
NavigationStackConfig & localPlanner(const local_planning::LocalPlannerParams &params)
NavigationStackConfig & globalPlanner(const global_planning::GlobalPlannerParams &params)
NavigationStackConfig & general(const core::GeneralConfig &cfg)
std::optional< client::Navigator > & getNavigator()
NavigatingSkillHelper(const Properties &properties, const Services &srv)
void init(const arondto::NavigatingSkillParams &params, const std::string &id)
static arondto::NavigatingSkillParams DefaultSkillDescription()
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
void fromAron(const arondto::GlobalTrajectoryPoint &dto, GlobalTrajectoryPoint &bo)
float inCollisionDistanceThresholdForRecovery
Maximum distance [mm] to search for a valid recovery position when robot starts in collision.
#define ARMARX_TRACE
Definition trace.h:77