ManagerNode.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 <mutex>
27 #include <atomic>
28 #include <thread>
29 #include <condition_variable>
30 
32 
33 
35 
36 #include "../../util/PlanningUtil.h"
37 #include <RobotComponents/interface/components/MotionPlanning/Tasks/AdaptiveDynamicDomainInformedRRTStar/ManagerNode.h>
38 #include <RobotComponents/interface/components/MotionPlanning/Tasks/AdaptiveDynamicDomainInformedRRTStar/WorkerNode.h>
39 
40 #include "Tree.h"
41 
42 namespace armarx
43 {
44  template <class IceBaseClass, class DerivedClass> class GenericFactory;
45 }
46 namespace armarx::addirrtstar
47 {
48  class ManagerNode;
49  /**
50  * @brief An ice handle for a ManagerNode.
51  */
53 
54  /**
55  * @brief Manages the planning of the addirrt* algorithm.
56  * Starts workers and checks whether the planning should end.
57  */
58  class ManagerNode:
59  virtual public ManagerNodeBase,
60  virtual public ManagedIceObject
61  {
62  /**
63  * @brief The clock used to meassure durations.
64  */
65  using ClockType = std::chrono::system_clock;
66  public:
67  /**
68  * @brief Ctor.
69  * @param task The manager node's task. The manager will store its result in it.
70  * @param remoteObjectNodes RemoteObjectNodes used for parallelization.
71  * @param initialWorkerCount The initial worker count.
72  * @param maximalWorkerCount The maximal worker count.
73  * @param planningComputingPowerRequestStrategy The used cprs.
74  * @param dcdStep The dcd step size.
75  * @param maximalPlanningTimeInSeconds The maximal planning time in seconds. Planning will end after this time.
76  * @param batchSize The size of a batch.
77  * @param nodeCountDeltaForGoalConnectionTries deprecated
78  * @param cspace The used planning cspace.
79  * @param startCfg The start configuration.
80  * @param goalCfg The goal configuration.
81  * @param addParams Parameters for adaptive dynamic domain.
82  * @param targetCost The target cost. Planning will end after shorter path was found..
83  */
85  TaskBasePrx task,
86  RemoteObjectNodePrxList remoteObjectNodes,
87  //management
88  Ice::Long initialWorkerCount,
89  Ice::Long maximalWorkerCount,
90  const cprs::ComputingPowerRequestStrategyBasePtr& planningComputingPowerRequestStrategy,
91  //general
92  float dcdStep,
93  Ice::Long maximalPlanningTimeInSeconds,
94  Ice::Long batchSize,
95  Ice::Long nodeCountDeltaForGoalConnectionTries,
96  //problem
97  CSpaceBasePtr cspace,
98  VectorXf startCfg,
99  VectorXf goalCfg,
100  AdaptiveDynamicDomainParameters addParams,
101  float targetCost
102  ):
103  ManagerNodeBase
104  (
105  task, remoteObjectNodes,
106  initialWorkerCount, maximalWorkerCount, planningComputingPowerRequestStrategy,
107  dcdStep, maximalPlanningTimeInSeconds,
108  cspace,
109  startCfg, goalCfg,
110  addParams, targetCost, batchSize, nodeCountDeltaForGoalConnectionTries
111  )
112  {
113  //other variables get initialized in onInitComponent
114  }
115 
116  /**
117  * @brief dtor.
118  * asserts the manager thread was joined.
119  */
120  ~ManagerNode() override
121  {
122 #pragma GCC diagnostic push
123 #pragma GCC diagnostic ignored "-Wterminate"
125 #pragma GCC diagnostic pop
126  }
127 
128  //from managedIceObject
129  /**
130  * @brief Initializes the tree and sampler.
131  * Starts the manager thread.
132  */
133  void onInitComponent() override;
134  /**
135  * @brief noop. (debug output)
136  */
137  void onConnectComponent() override;
138 
139  /**
140  * @brief noop. (debug output)
141  */
142  void onDisconnectComponent() override
143  {
144  ARMARX_VERBOSE_S << "armarx::addirrtstar::ManagerNode::onDisconnectComponent()";
145  }
146  /**
147  * @brief Stopps planning and joins the manager thread.
148  */
149  void onExitComponent() override;
150  /**
151  * @return The components default name.
152  */
153  std::string getDefaultName() const override
154  {
155  return "ADDIRRTStarManagerNode";
156  }
157 
158  //from ManagerNodeBase
159  /**
160  * @brief Sets the flag to stop planning
161  */
162  void kill(const Ice::Current& = Ice::emptyCurrent) override
163  {
164  killRequest = true;
165  }
166 
167  /**
168  * @return The shortest found path. (with its cost)
169  */
170  PathWithCost getBestPath(const Ice::Current& = Ice::emptyCurrent) const override;
171  /**
172  * @return The number of found paths.
173  */
174  Ice::Long getPathCount(const Ice::Current& = Ice::emptyCurrent) const override;
175  /**
176  * @param index The index.
177  * @return The path at the given index.
178  */
179  PathWithCost getNthPathWithCost(Ice::Long n, const Ice::Current& = Ice::emptyCurrent) const override;
180  /**
181  * @return All found paths.
182  */
183  PathWithCostSeq getAllPathsWithCost(const Ice::Current& = Ice::emptyCurrent) const override;
184 
185  /**
186  * @param workerId The updates worker id.
187  * @param updateId The updates sub id.
188  * @return The requested update. If the update is not cached it will be fetched from the corresponding worker.
189  */
190  Update getUpdate(Ice::Long workerId, Ice::Long updateId, const Ice::Current& = Ice::emptyCurrent) const override;
191  /**
192  * @return The current tree with all updates applied.
193  */
194  FullIceTree getTree(const Ice::Current& = Ice::emptyCurrent) const override;
195 
196  /**
197  * @brief Used by workers to inform the manager about their number of updates before exiting.
198  * Used by the manager to fetch all remaining updates before exiting.
199  * @param workerId The worker.
200  * @param finalUpdateId Its final update id.
201  */
202  void setWorkersFinalUpdateId(Ice::Long workerId, Ice::Long finalUpdateId, const Ice::Current&) override;
203 
204  //from TreeUpdateInterface
205  /**
206  * @brief Adds the given update to the queue of pending updates.
207  * @param u The update.
208  */
209  void updateTree(const Update& u, const Ice::Current& = Ice::emptyCurrent) override;
210 
211  /**
212  * @brief Sents the manager's collected test data to the task.
213  */
214  void sendManagerNodeData() const;
215  /**
216  * @return The RRT's node count.
217  */
218  Ice::Long getNodeCount(const Ice::Current& = Ice::emptyCurrent) const override;
219 
220  // ResourceManagementInterface interface
221  void setMaxCpus(Ice::Int maxCpus, const Ice::Current& = Ice::emptyCurrent) override;
222 
223  Ice::Int getMaxCpus(const Ice::Current& = Ice::emptyCurrent) const override;
224 
225  protected:
226  friend class GenericFactory<ManagerNodeBase, ManagerNode>;
227  /**
228  * @brief Ctor used by ice factories.
229  */
230  ManagerNode() = default;
231 
232  /**
233  * @brief Creates a new worker on the given remote object node.
234  * @param remoteObjectNodeIndex The remote object node's index.
235  */
236  void createNewWorkerOn(std::size_t remoteObjectNodeIndex);
237 
238  /**
239  * @brief The managet task.checkedCastIt checks whether new workers are required and starts them if this is the case.
240  * Ith checks whether planing has finished.
241  */
242  void managerTask();
243 
244  //not threadsafe! use only when holding updateMutex
245  /**
246  * @brief Returns whether the given update is cached. (requires the caller to hold the updateMutex)
247  * @param workerId The updates worker id.
248  * @param updateId The updates sub id.
249  * @return Whether the given update is cached.
250  */
251  bool hasLocalUpdateRequiresUpdateMutex(std::size_t workerId, std::size_t updateId) const;
252  //not threadsafe! use only when holding updateMutex
253  /**
254  * @brief Returns the requested update from the cache. (requires the caller to hold the updateMutex)
255  * @param workerId The updates worker id.
256  * @param updateId The updates sub id.
257  * @return The requested update from the cache.
258  */
259  const Update& getLocalUpdateRequiresUpdateMutex(std::size_t workerId, std::size_t updateId) const;
260  //not threadsafe! use only when holding updateMutex
261  /**
262  * @brief Returns the requested update fetched from the corresponding worker. (requires the caller to hold the updateMutex)
263  * @param workerId The updates worker id.
264  * @param updateId The updates sub id.
265  * @return The requested update fetched from the corresponding worker.
266  */
267  Update getRemoteUpdate(std::size_t workerId, std::size_t updateId) const;
268 
269  /**
270  * @brief Applies all pending updates. (requires the user to hold update and tree mutex)
271  * @param updateLock Lock for the update mutex. it will be unlocked when getting a remote update.
272  */
273  void applyUpdatesNotThreadSafe(std::unique_lock<std::mutex>& updateLock);
274  /**
275  * @brief Creates a new worker. (the remote object node is selected automatically)
276  */
277  void createNewWorker();
278  /**
279  * @brief Shuts down and removes all workers. (Their newest data is fetched before destruction.)
280  */
281  void cleanupAllWorkers();
282 
283  /**
284  * @brief Stores the given applied update to the cache. (requires the caller to hold the updateMutex)
285  * @param u The update.
286  */
287  void cacheAppliedUpdateRequiresUpdateMutex(Update&& u);
288 
289  /**
290  * @return Whether planning is done.
291  */
292  bool isPlanningDone();
293 
294  /**
295  * @return Whether planning has failed.
296  */
297  bool hasTimeRunOut();
298 
299 
300  /**
301  * @brief getActiveWorkerCount returns the number of currently active workers.
302  * @return
303  */
304  std::size_t getActiveWorkerCount() const
305  {
306  return activeWorkerCount;
307  }
308 
309  /**
310  * @brief Returns the number of currently available workers (both active and paused).
311  * @return
312  */
313  std::size_t getWorkerCount() const
314  {
315  return workers.size();
316  }
317 
318  //management
319  /**
320  * @brief Flag to signal the manager thread to exit.
321  */
322  std::atomic_bool killRequest;
323  /**
324  * @brief The tread executing \ref managerTask.
325  */
326  std::thread managerThread;
327  /**
328  * @brief currentlyActiveWorkers the index of the newest planning process in the workers vector (is <= workers.size()).
329  */
330  std::atomic_size_t activeWorkerCount;
331  /**
332  * @brief Worker proxies.
333  * worker[i][j] is the j-th worker on the remote object node remoteObjectNodes[i]
334  */
335  std::vector<RemoteHandle<WorkerNodeBasePrx>> workers;
336  /**
337  * @brief How many workers are started on each remote object node.
338  */
339  std::vector<std::size_t> workersPerRemoteObjectNode;
340  /**
341  * @brief How many workers are maximal allowed on each remote object node.
342  */
343  std::vector<std::size_t> maxWorkersPerRemoteObjectNode;
344  /**
345  * @brief used to lock access to the vector workers
346  */
347  mutable std::mutex workerMutex;
348 
349  //updates
350  /**
351  * @brief Protects the update section of the tree and the update cache of the manager
352  */
353  mutable std::mutex updateMutex;
354  /**
355  * @brief The update topic's prefix. (to ensure unique names.)
356  */
357  std::string updateTopicPrefix;
358  /**
359  * @brief All applied updates. (per worker)
360  */
361  std::vector<std::deque<Update>> appliedUpdates;
362 
363  /**
364  * @brief Used when shutting down to ensure all updates were applied before destroying the nodes remote object.
365  */
366  std::vector<Ice::Long> workersFinalUpdateId;
367  //rrt
368  /**
369  * @brief protects the tree data
370  */
371  mutable std::mutex treeMutex;
372  /**
373  * @brief CV used by the manager thread to wait for new updates.
374  */
375  std::condition_variable managerEvent;
376  /**
377  * @brief The RRT
378  */
380 
381  /**
382  * @brief The rotation matrix used by the informed samplers.
383  */
384  Ice::FloatSeq rotationMatrix;
385 
386  /**
387  * @brief Timepoint when the manager node started planning.
388  * Used to check whether the maximal planning time was exceeded.
389  */
390  ClockType::time_point timepointStart;
391 
392  /**
393  *@brief required for static factory methode create
394  */
395  friend class ManagedIceObject;
396  };
397 }
398 
armarx::addirrtstar::ManagerNode::treeMutex
std::mutex treeMutex
protects the tree data
Definition: ManagerNode.h:371
armarx::addirrtstar::ManagerNode::getBestPath
PathWithCost getBestPath(const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:113
armarx::addirrtstar::ManagerNode::workersPerRemoteObjectNode
std::vector< std::size_t > workersPerRemoteObjectNode
How many workers are started on each remote object node.
Definition: ManagerNode.h:339
armarx::addirrtstar::ManagerNode::onInitComponent
void onInitComponent() override
Initializes the tree and sampler.
Definition: ManagerNode.cpp:38
armarx::addirrtstar::ManagerNode::setMaxCpus
void setMaxCpus(Ice::Int maxCpus, const Ice::Current &=Ice::emptyCurrent) override
Definition: ManagerNode.cpp:556
armarx::addirrtstar::ManagerNode::getWorkerCount
std::size_t getWorkerCount() const
Returns the number of currently available workers (both active and paused).
Definition: ManagerNode.h:313
armarx::addirrtstar::ManagerNode::getTree
FullIceTree getTree(const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:167
armarx::addirrtstar::ManagerNode::getNodeCount
Ice::Long getNodeCount(const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:538
RemoteHandle.h
armarx::addirrtstar::ManagerNode::createNewWorkerOn
void createNewWorkerOn(std::size_t remoteObjectNodeIndex)
Creates a new worker on the given remote object node.
Definition: ManagerNode.cpp:335
armarx::addirrtstar::ManagerNode::getMaxCpus
Ice::Int getMaxCpus(const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:561
armarx::addirrtstar::ManagerNode
Manages the planning of the addirrt* algorithm.
Definition: ManagerNode.h:58
armarx::addirrtstar::ManagerNode::onDisconnectComponent
void onDisconnectComponent() override
noop.
Definition: ManagerNode.h:142
armarx::addirrtstar::ManagerNode::updateTopicPrefix
std::string updateTopicPrefix
The update topic's prefix.
Definition: ManagerNode.h:357
Tree.h
armarx::addirrtstar::ManagerNode::hasLocalUpdateRequiresUpdateMutex
bool hasLocalUpdateRequiresUpdateMutex(std::size_t workerId, std::size_t updateId) const
Returns whether the given update is cached.
Definition: ManagerNode.cpp:403
armarx::addirrtstar::ManagerNode::managerEvent
std::condition_variable managerEvent
CV used by the manager thread to wait for new updates.
Definition: ManagerNode.h:375
armarx::addirrtstar::ManagerNode::rotationMatrix
Ice::FloatSeq rotationMatrix
The rotation matrix used by the informed samplers.
Definition: ManagerNode.h:384
armarx::addirrtstar::ManagerNode::managerThread
std::thread managerThread
The tread executing managerTask.
Definition: ManagerNode.h:326
armarx::addirrtstar::ManagerNode::maxWorkersPerRemoteObjectNode
std::vector< std::size_t > maxWorkersPerRemoteObjectNode
How many workers are maximal allowed on each remote object node.
Definition: ManagerNode.h:343
armarx::addirrtstar::ManagerNode::getAllPathsWithCost
PathWithCostSeq getAllPathsWithCost(const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:133
armarx::addirrtstar::ManagerNode::~ManagerNode
~ManagerNode() override
dtor.
Definition: ManagerNode.h:120
IceInternal::Handle
Definition: forward_declarations.h:8
armarx::addirrtstar::ManagerNode::hasTimeRunOut
bool hasTimeRunOut()
Definition: ManagerNode.cpp:550
armarx::addirrtstar::ManagerNode::sendManagerNodeData
void sendManagerNodeData() const
Sents the manager's collected test data to the task.
armarx::addirrtstar::ManagerNode::getRemoteUpdate
Update getRemoteUpdate(std::size_t workerId, std::size_t updateId) const
Returns the requested update fetched from the corresponding worker.
Definition: ManagerNode.cpp:395
armarx::addirrtstar::ManagerNode::updateTree
void updateTree(const Update &u, const Ice::Current &=Ice::emptyCurrent) override
Adds the given update to the queue of pending updates.
Definition: ManagerNode.cpp:435
armarx::addirrtstar::ManagerNode::setWorkersFinalUpdateId
void setWorkersFinalUpdateId(Ice::Long workerId, Ice::Long finalUpdateId, const Ice::Current &) override
Used by workers to inform the manager about their number of updates before exiting.
Definition: ManagerNode.cpp:422
ManagedIceObject.h
armarx::addirrtstar::ManagerNode::kill
void kill(const Ice::Current &=Ice::emptyCurrent) override
Sets the flag to stop planning.
Definition: ManagerNode.h:162
armarx::addirrtstar::ManagerNode::getPathCount
Ice::Long getPathCount(const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:120
armarx::addirrtstar::ManagerNode::killRequest
std::atomic_bool killRequest
Flag to signal the manager thread to exit.
Definition: ManagerNode.h:322
armarx::addirrtstar::ManagerNode::updateMutex
std::mutex updateMutex
Protects the update section of the tree and the update cache of the manager.
Definition: ManagerNode.h:353
armarx::addirrtstar::ManagerNode::ManagerNode
ManagerNode()=default
Ctor used by ice factories.
armarx::addirrtstar::ManagerNode::onExitComponent
void onExitComponent() override
Stopps planning and joins the manager thread.
Definition: ManagerNode.cpp:104
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
armarx::addirrtstar::ManagerNode::managerTask
void managerTask()
The managet task.checkedCastIt checks whether new workers are required and starts them if this is the...
Definition: ManagerNode.cpp:176
armarx::addirrtstar::ManagerNode::workersFinalUpdateId
std::vector< Ice::Long > workersFinalUpdateId
Used when shutting down to ensure all updates were applied before destroying the nodes remote object.
Definition: ManagerNode.h:366
armarx::addirrtstar::ManagerNode::workers
std::vector< RemoteHandle< WorkerNodeBasePrx > > workers
Worker proxies.
Definition: ManagerNode.h:335
armarx::addirrtstar::ManagerNode::cleanupAllWorkers
void cleanupAllWorkers()
Shuts down and removes all workers.
Definition: ManagerNode.cpp:442
armarx::addirrtstar::ManagerNode::getActiveWorkerCount
std::size_t getActiveWorkerCount() const
getActiveWorkerCount returns the number of currently active workers.
Definition: ManagerNode.h:304
armarx::addirrtstar::ManagerNode::cacheAppliedUpdateRequiresUpdateMutex
void cacheAppliedUpdateRequiresUpdateMutex(Update &&u)
Stores the given applied update to the cache.
Definition: ManagerNode.cpp:523
armarx::addirrtstar::ManagerNode::appliedUpdates
std::vector< std::deque< Update > > appliedUpdates
All applied updates.
Definition: ManagerNode.h:361
armarx::addirrtstar::ManagerNode::tree
Tree tree
The RRT.
Definition: ManagerNode.h:379
armarx::addirrtstar::ManagerNode::applyUpdatesNotThreadSafe
void applyUpdatesNotThreadSafe(std::unique_lock< std::mutex > &updateLock)
Applies all pending updates.
Definition: ManagerNode.cpp:504
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::ManagerNode::getNthPathWithCost
PathWithCost getNthPathWithCost(Ice::Long n, const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:125
armarx::addirrtstar::ManagerNode::getUpdate
Update getUpdate(Ice::Long workerId, Ice::Long updateId, const Ice::Current &=Ice::emptyCurrent) const override
Definition: ManagerNode.cpp:148
armarx::addirrtstar::ManagerNode::ManagerNode
ManagerNode(TaskBasePrx task, RemoteObjectNodePrxList remoteObjectNodes, Ice::Long initialWorkerCount, Ice::Long maximalWorkerCount, const cprs::ComputingPowerRequestStrategyBasePtr &planningComputingPowerRequestStrategy, float dcdStep, Ice::Long maximalPlanningTimeInSeconds, Ice::Long batchSize, Ice::Long nodeCountDeltaForGoalConnectionTries, CSpaceBasePtr cspace, VectorXf startCfg, VectorXf goalCfg, AdaptiveDynamicDomainParameters addParams, float targetCost)
Ctor.
Definition: ManagerNode.h:84
armarx::addirrtstar::ManagerNode::createNewWorker
void createNewWorker()
Creates a new worker.
Definition: ManagerNode.cpp:375
armarx::addirrtstar::ManagerNode::workerMutex
std::mutex workerMutex
used to lock access to the vector workers
Definition: ManagerNode.h:347
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
armarx::addirrtstar::ManagerNode::isPlanningDone
bool isPlanningDone()
Definition: ManagerNode.cpp:544
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:200
armarx::addirrtstar::ManagerNode::getLocalUpdateRequiresUpdateMutex
const Update & getLocalUpdateRequiresUpdateMutex(std::size_t workerId, std::size_t updateId) const
Returns the requested update from the cache.
Definition: ManagerNode.cpp:409
armarx::GenericFactory
Definition: FactoryCollectionBase.h:51
armarx::addirrtstar::ManagerNode::getDefaultName
std::string getDefaultName() const override
Definition: ManagerNode.h:153
armarx::addirrtstar::ManagerNode::onConnectComponent
void onConnectComponent() override
noop.
Definition: ManagerNode.cpp:96
armarx::addirrtstar::ManagerNode::timepointStart
ClockType::time_point timepointStart
Timepoint when the manager node started planning.
Definition: ManagerNode.h:390
armarx::addirrtstar::ManagerNode::activeWorkerCount
std::atomic_size_t activeWorkerCount
currentlyActiveWorkers the index of the newest planning process in the workers vector (is <= workers....
Definition: ManagerNode.h:330
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::addirrtstar
Definition: ManagerNode.cpp:35