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