WorkerNode.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package RobotComponents
19 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
20 * @date 2015
21 * @copyright http://www.gnu.org/licenses/gpl.txt
22 * GNU General Public License
23 */
24#pragma once
25
26#include <atomic>
27#include <deque>
28#include <mutex>
29#include <thread>
30#include <unordered_map>
31#include <utility>
32#include <vector>
33
35
36#include <RobotComponents/interface/components/MotionPlanning/Tasks/AdaptiveDynamicDomainInformedRRTStar/WorkerNode.h>
37
38#include "../../util/Metrics.h"
40#include "../../util/Samplers.h"
41#include "Tree.h"
42
43namespace armarx
44{
45 template <class IceBaseClass, class DerivedClass>
46 class GenericFactory;
47}
48
49namespace armarx::addirrtstar
50{
51 class WorkerNode;
52 /**
53 * @brief An ice handle for a WorkerNode of the addirrt* algorithm
54 */
56
57 /**
58 * @brief Implements the worker side of the batch distributed adaptive dynamic domain informed rrt* planner.
59 *
60 * This algorithm has two variants for selecting nodes for rewiring.
61 * (see doi> 10.1177/0278364911406761)
62 * One using k-Nearest-Neighbours with:
63 * - k(#nodes)= kRRT * log(#nodes)
64 * - kRRT > 2^(dimensions+1) * e (1 + 1/dimensions)
65 *
66 * One using Nearest-Neighbours with a radius:
67 * - r(#nodes)= min{γRRT( log(#nodes) / #nodes )^(1/dimensions) , η}
68 * - γRRT =(2 ( 1 + 1/dimensions))^(1/d) *(μ(Xfree) / ζd)^(1/dimensions)
69 * - η = maximal step size during 1 extend (+inf in this implementation)
70 * - μ(Xfree) = Lebesgue measure of the obstacle-free space
71 * - ζd = volume of the d-dimensional unit ball in Euclidean space
72 *
73 * since μ(Xfree) can only be estimated the k-NN version is used.
74 */
75 class WorkerNode : virtual public ManagedIceObject, virtual public WorkerNodeBase
76 {
77 public:
78 /**
79 * @brief Type of a configuration.
80 */
82
83 static_assert(std::numeric_limits<Ice::Float>::has_infinity,
84 "requires inf in current implementation");
85
86 /**
87 * @brief ctor
88 * @param cspace The palnning cspace.
89 * @param startCfg The start configuration.
90 * @param goalCfg The goal configuration.
91 * @param DCDStepSize The dcd step size.
92 * @param addParams The adaptive dynamic domain parameters.
93 * @param manager A proxy to the manager node.
94 * @param workerId The worker's id.
95 * @param batchSize The batch size.
96 * @param nodeCountDeltaForGoalConnectionTries Number of nodes created (by a worker) before a connect to the goal node is tried (by this worker).
97 * @param topicPrefix The used topic prefix. (for the topic name to distribute updates)
98 * @param rotationMatrix The rotation matrix for the informed ellipsoid.
99 */
100 WorkerNode(const CSpaceBasePtr& cspace,
101 const VectorXf& startCfg,
102 const VectorXf& goalCfg,
103 Ice::Float DCDStepSize,
104 AdaptiveDynamicDomainParameters addParams,
105 const ManagerNodeBasePrx& manager,
106 Ice::Long workerId,
107 Ice::Long batchSize,
108 Ice::Long nodeCountDeltaForGoalConnectionTries,
109 const std::string& topicPrefix,
110 const Ice::FloatSeq& rotationMatrix
111
112 ) :
113 WorkerNodeBase(cspace,
114 startCfg,
115 goalCfg,
116 DCDStepSize,
117 addParams,
118 manager,
119 workerId,
120 batchSize,
121 nodeCountDeltaForGoalConnectionTries,
122 topicPrefix,
123 rotationMatrix),
125 {
126 }
127
128 /**
129 * @brief dtor. Asserts the worker thread was joined.
130 */
131 ~WorkerNode() override
132 {
133#pragma GCC diagnostic push
134#pragma GCC diagnostic ignored "-Wterminate"
136#pragma GCC diagnostic pop
137 }
138
139 //from managedIceObject
140 /**
141 * @brief Initializes the worker and starts the worker thread.
142 */
143 void onInitComponent() override;
144 /**
145 * @brief Gets a proxy to the topic.
146 */
147 void onConnectComponent() override;
148
149 /**
150 * @brief noop
151 */
152 void
154 {
155 }
156
157 /**
158 * @brief Kills the worker thread (if it is still running) and joins it.
159 */
160 void onExitComponent() override;
161
162 /**
163 * @return The component's default name.
164 */
165 std::string
166 getDefaultName() const override
167 {
168 return "ADDIRRTStarWorkerNode";
169 }
170
171 //from WorkerNodeBase
172 /**
173 * @brief Signals the worker thread to exit.
174 */
175 void
176 killWorker(const Ice::Current& = Ice::emptyCurrent) override
177 {
178 killRequest = true;
179 }
180
181 void
182 pauseWorker(bool pauseFlag, const Ice::Current& = Ice::emptyCurrent) override
183 {
184 workerPaused = pauseFlag;
185 }
186
187 /**
188 * @param updateId The updates id.
189 * @return This workers update with the given id.
190 */
191 Update getUpdate(Ice::Long updateId,
192 const Ice::Current& = Ice::emptyCurrent) const override;
193
194
195 //from WorkerUpdateInterface
196 /**
197 * @brief Receives an update from other workers and adds it to the queue of pending updates.
198 * @param u the update.
199 */
200 void updateTree(const Update& u, const Ice::Current& = Ice::emptyCurrent) override;
201
202 //from ice
203 /**
204 * @brief noop
205 */
206 void
208 {
209 }
210
211 /**
212 * @brief Calculates the euclidian distance between from and to.
213 * @param from First vector.
214 * @param to Second vector.
215 * @return The euclidian distance between from and to.
216 */
217 static float
218 distance(const ConfigType& from, const ConfigType& to)
219 {
220 ARMARX_CHECK_EXPRESSION(from.size() == to.size());
221 return euclideanDistance(from.data(), from.data() + from.size(), to.data());
222 }
223
224 protected:
225 friend class GenericFactory<WorkerNodeBase, WorkerNode>;
226
227 /**
228 * @brief Only used when transmitting through ice.
229 */
230 WorkerNode() = default;
231
232 /**
233 * @param workerNodeId The update's worker id.
234 * @param updateSubId The update's sub id.
235 * @return The update fetched from the manager node.
236 */
237 Update getRemoteUpdate(Ice::Long workerNodeId, Ice::Long updateSubId);
238
239 /**
240 * @brief The worker task.
241 * It performs all planning.
242 */
243 void workerTask();
244
245 /**
246 * @brief initializes the tree by getting the current tree from the manager
247 */
248 void
250 {
251 tree.init(manager->getTree(), addParams, workerId);
252 }
253
254 /**
255 * @brief Does a linear interpolation from from to to and checks the path per DCD.
256 * @param from starting point for the interpolation. (assumed to be collision free)
257 * @param to end point for the interpolation.
258 * @return The point furthest away from from (but collision free reachable from from)
259 * on the line from->to.
260 * If from->to is collision free the return value is identical to to (no floating point error).
261 * If the first step on the path from->to has a collision the return value is identical to from (no floating point error).
262 */
263 ConfigType steer(const ConfigType& from, const ConfigType& to);
264 /**
265 * @param cfg The configuration.
266 * @return Whether the given configuration is collision free.
267 */
268 bool isCollisionFree(const ConfigType& cfg);
269 /**
270 * @param from The start configuration.
271 * @param to The goal configuration.
272 * @return Whether the path from from to to is colliswion free.
273 */
274 bool isPathCollisionFree(const ConfigType& from, const ConfigType& to);
275
276 /**
277 * @return The cspace's dimensionality
278 */
279 std::size_t
281 {
282 return cspace->getDimensionality();
283 }
284
285 /**
286 * @return Number of neighbours currently considered as parent.
287 */
288 std::size_t getK();
289
290 /**
291 * @brief The RRT tree
292 */
294
295 /**
296 * @brief Wheether the node should shut down.
297 */
298 std::atomic_bool killRequest;
299
300 /**
301 * @brief workerPaused is true if the worker is currently on hold and does not perform any calculations.
302 */
303 std::atomic_bool workerPaused;
304
305 /**
306 * @brief Mutex protecting the update structures.
307 */
308 mutable std::mutex updateMutex;
309
310 /**
311 * @brief Thread executing the worker task.
312 */
313 std::thread workerThread;
314
315 /**
316 * @brief The update topic's name.
317 */
318 std::string updateTopicName;
319 /**
320 * @brief Proxy used to write to the update topic.
321 */
322 TreeUpdateInterfacePrx globalWorkers;
323 /**
324 * @brief A string representation of the worker id.
325 * Used for output.
326 */
327 std::string workerIdSring;
328
329 /**
330 * @brief The index one past the last node that was considered to be connected to the goal configuration.
331 */
333
334 /**
335 * @brief Stores the sampler.
336 *
337 * A pointer is used, since the sampler ctor requires space information and in case of default construction
338 * the information is not available. (the default ctor is used when transmitting this object per ice.)
339 * The pointer gets set during construction or post unmarshalling.
340 */
341 std::unique_ptr<InformedSampler> sampler;
342
343 /**
344 *@brief required for static factory methode create
345 */
346 friend class ManagedIceObject;
347
348 /**
349 * @brief Searches the optimal parent for a configuration.
350 * Used by the rrt* component.
351 * @param nodeNearestId The id of the nearest node.
352 * @param cfgReached The reached configuration.
353 * @param outNodeBestId Output parameter: The id of the optimal parent.
354 * @param outCostReachedToNodeBest Output parameter: The distance of reached and the optimal parent.
355 * @param outKNearestIdsAndDistances Output parameter: The k nearest nodes and their distance to reached.
356 * @param outIsCollisionFreeCache Output parameter: Cache storing collision checks for paths between nodes from knearest and reached.
357 */
358 void findBestParent(const NodeId& nodeNearestId,
359 const ConfigType& cfgReached,
360 NodeId& outNodeBestId,
361 float& outCostReachedToNodeBest,
362 std::vector<std::pair<NodeId, float>>& outKNearestIdsAndDistances,
363 std::map<NodeId, bool>& outIsCollisionFreeCache);
364
365 /**
366 * @brief The rewire operation of the rrt* algorithm.
367 * It optimizes path lengths.
368 * @param nodeId The root node's id
369 * @param kNearestIdsAndDistances The k nearest nodes and their distance to the root node.
370 * @param isCollisionFreeCache Cache storing collision checks for paths between nodes from knearest and the root node..
371 */
372 void rewire(const NodeId& nodeId,
373 const std::vector<std::pair<NodeId, float>>& kNearestIdsAndDistances,
374 const std::map<NodeId, bool>& isCollisionFreeCache);
375
376 /**
377 * @brief Adds a configuration to the tree.
378 * The configurations best parent is searched and rewiring is performed fot it.
379 * @param cfgReached The configuration.
380 * @param nodeNearestId The nearest node's id.
381 */
382 void addAndRewireConfig(const ConfigType& cfgReached, const NodeId& nodeNearestId);
383
384 /**
385 * @brief Executes one iteration of a batch.
386 */
387 void doBatchIteration();
388
389 /**
390 * @brief Executes a batch.
391 */
392 void doBatch();
393
394 /**
395 * @brief Applies all pending updates to the tree.
396 */
397 void applyPendingUpdates();
398
399 private:
400 /**
401 * @brief Buffer for the range used by the collision check.
402 */
403 std::pair<const float*, const float*> bufferCDRange;
404 };
405} // namespace armarx::addirrtstar
A structure holding and managing all data connected to the tree used in the ADDIRRT* algorithm.
Definition Tree.h:50
VectorXf ConfigType
The type of configurations.
Definition Tree.h:56
Implements the worker side of the batch distributed adaptive dynamic domain informed rrt* planner.
Definition WorkerNode.h:76
void updateTree(const Update &u, const Ice::Current &=Ice::emptyCurrent) override
Receives an update from other workers and adds it to the queue of pending updates.
std::size_t onePastLastGoalConnect
The index one past the last node that was considered to be connected to the goal configuration.
Definition WorkerNode.h:332
void findBestParent(const NodeId &nodeNearestId, const ConfigType &cfgReached, NodeId &outNodeBestId, float &outCostReachedToNodeBest, std::vector< std::pair< NodeId, float > > &outKNearestIdsAndDistances, std::map< NodeId, bool > &outIsCollisionFreeCache)
Searches the optimal parent for a configuration.
void onInitComponent() override
Initializes the worker and starts the worker thread.
void ice_postUnmarshal() override
noop
Definition WorkerNode.h:207
WorkerNode(const CSpaceBasePtr &cspace, const VectorXf &startCfg, const VectorXf &goalCfg, Ice::Float DCDStepSize, AdaptiveDynamicDomainParameters addParams, const ManagerNodeBasePrx &manager, Ice::Long workerId, Ice::Long batchSize, Ice::Long nodeCountDeltaForGoalConnectionTries, const std::string &topicPrefix, const Ice::FloatSeq &rotationMatrix)
ctor
Definition WorkerNode.h:100
void applyPendingUpdates()
Applies all pending updates to the tree.
void workerTask()
The worker task.
void onDisconnectComponent() override
noop
Definition WorkerNode.h:153
std::string updateTopicName
The update topic's name.
Definition WorkerNode.h:318
void doBatch()
Executes a batch.
std::thread workerThread
Thread executing the worker task.
Definition WorkerNode.h:313
TreeUpdateInterfacePrx globalWorkers
Proxy used to write to the update topic.
Definition WorkerNode.h:322
std::atomic_bool killRequest
Wheether the node should shut down.
Definition WorkerNode.h:298
Update getUpdate(Ice::Long updateId, const Ice::Current &=Ice::emptyCurrent) const override
friend class ManagedIceObject
required for static factory methode create
Definition WorkerNode.h:346
std::mutex updateMutex
Mutex protecting the update structures.
Definition WorkerNode.h:308
void addAndRewireConfig(const ConfigType &cfgReached, const NodeId &nodeNearestId)
Adds a configuration to the tree.
std::unique_ptr< InformedSampler > sampler
Stores the sampler.
Definition WorkerNode.h:341
void initTree()
initializes the tree by getting the current tree from the manager
Definition WorkerNode.h:249
void onConnectComponent() override
Gets a proxy to the topic.
static float distance(const ConfigType &from, const ConfigType &to)
Calculates the euclidian distance between from and to.
Definition WorkerNode.h:218
void pauseWorker(bool pauseFlag, const Ice::Current &=Ice::emptyCurrent) override
Definition WorkerNode.h:182
std::string workerIdSring
A string representation of the worker id.
Definition WorkerNode.h:327
Tree::ConfigType ConfigType
Type of a configuration.
Definition WorkerNode.h:81
Update getRemoteUpdate(Ice::Long workerNodeId, Ice::Long updateSubId)
void doBatchIteration()
Executes one iteration of a batch.
std::atomic_bool workerPaused
workerPaused is true if the worker is currently on hold and does not perform any calculations.
Definition WorkerNode.h:303
bool isPathCollisionFree(const ConfigType &from, const ConfigType &to)
ConfigType steer(const ConfigType &from, const ConfigType &to)
Does a linear interpolation from from to to and checks the path per DCD.
void rewire(const NodeId &nodeId, const std::vector< std::pair< NodeId, float > > &kNearestIdsAndDistances, const std::map< NodeId, bool > &isCollisionFreeCache)
The rewire operation of the rrt* algorithm.
void onExitComponent() override
Kills the worker thread (if it is still running) and joins it.
WorkerNode()=default
Only used when transmitting through ice.
bool isCollisionFree(const ConfigType &cfg)
std::string getDefaultName() const override
Definition WorkerNode.h:166
void killWorker(const Ice::Current &=Ice::emptyCurrent) override
Signals the worker thread to exit.
Definition WorkerNode.h:176
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
IceInternal::Handle< WorkerNode > WorkerNodePtr
An ice handle for a WorkerNode of the addirrt* algorithm.
Definition WorkerNode.h:55
This file offers overloads of toIce() and fromIce() functions for STL container types.
float euclideanDistance(IteratorType1 first1, IteratorType1 last1, IteratorType2 first2)
Returns the euclidean distance.
Definition Metrics.h:104