@@ -25,12 +25,27 @@ two subclasses:
25252 . ` prpy.planning.base.MetaPlanner ` : combines the output of multiple motion
2626 planners, each of which is a ` BasePlanner ` or another ` MetaPlanner `
2727
28- Each planner has one or more * planning methods* , annotated with the
29- ` @PlanningMethod ` decorator, that look like ordinary functions. However, unlike
30- an ordinary function, calling a planning method clones the robot's environment
31- into a * planning environment* associated with the planner. Planning occurs in
32- the cloned environment to allow PrPy to run multiple planners in parallel and
33- to paralellize planning and execution.
28+ Each planner has one or more * planning methods* , annotated with either the
29+ ` @LockedPlanningMethod ` or `@ClonedPlanningMethod decorator, that look like
30+ ordinary functions. Using these decorators makes other PrPy components
31+ aware that these methods exist and follow a particular specification that
32+ allows them to be composed with other PrPy objects automatically. For
33+ example, ` MetaPlanner ` s will report that they can perform planning methods
34+ that their child motion planners have enumerated via ` @PlanningMethod `
35+ decorators.
36+
37+ ` @PlanningMethod ` decorators also make sure that calls to planning code are
38+ executed in a thread-safe manner. In the case of ` @LockedPlanningMethod ` ,
39+ this is enforced by locking the calling environment until the planning method
40+ has completed. In the case of ` @ClonedPlanningMethod ` , this is enforced by
41+ cloning the calling environment, and calling the wrapped method with references
42+ to the cloned environment. The result of the method is then copied back to the
43+ calling environment. ` @ClonedPlanningMethod ` s can be used to run multiple
44+ planners in parallel and to parallelize planning and execution.
45+
46+ In general, ** locked** planning methods are used for calls that will terminate
47+ extremely quickly, while ** cloned** planning methods are used for calls that
48+ might take a significant amount of time.
3449
3550For example, the following code will use OMPL to plan ` robot ` 's active DOFs
3651from their current values to to the ` goal_config ` configuration:
@@ -40,10 +55,10 @@ planner = OMPLPlanner('RRTConnect')
4055output_path = planner.PlanToConfiguration(robot, goal_config)
4156```
4257
43- First , ` robot.GetEnv() ` is cloned into the the ` planner.env ` planning
44- environment. Next, planning occurs in the cloned environment. Finally, the
45- output path is cloned back into ` robot.GetEnv() ` and is returned by the
46- planner.
58+ As this is a ` @ClonedPlanningMethod ` , ` robot.GetEnv() ` is cloned into the
59+ the ` planner.env ` planning environment. Planning occurs within this cloned
60+ environment. Finally, the output path is cloned back into ` robot.GetEnv() `
61+ and is returned by the planner.
4762
4863See the following sub-sections for more information about the built-in planners
4964provided with PrPy, information about writing your own planner, and several
@@ -86,7 +101,7 @@ See the Python docstrings the above classes for more information.
86101
87102### Common Planning Methods
88103
89- There is no formal list of ` @PlanningMethod ` s or their arguments. However, we
104+ There is no formal list of ` @* PlanningMethod ` s or their arguments. However, we
90105have found these methods to be useful:
91106
92107- ` PlanToConfiguration(robot, goal_config) ` : plan the robot's active DOFs from
@@ -112,25 +127,36 @@ of these methods accept planner-specific keyword arguments.
112127### Writing a Custom Planner
113128
114129Implementing a custom planner requires extending the ` BasePlanner ` class and
115- decorating one or more methods with the ` @PlanningMethod ` decorator. Extending
116- the ` BasePlanner ` class constructs the planning environment ` self.env ` and
117- allows PrPy to identify your planner as a base planner class, as opposed to a
118- meta-planner. The ` @PlanningMethod ` decorator handles environment cloning and
119- allows meta-planners to query the list of planning methods that the planner
120- supports (e.g. to generate docstrings).
130+ decorating one or more methods with the ` @LockedPlanningMethod ` or
131+ ` @ClonedPlanningMethod ` decorator.
132+
133+ Extending the ` BasePlanner ` class allows PrPy to identify your planner as a
134+ base planner class, as opposed to a meta-planner. The ` @PlanningMethod `
135+ decorators handle environment cloning or locking and allows meta-planners to
136+ query the list of planning methods that the planner supports (e.g. to generate
137+ docstrings).
138+
139+ Each instance of a ` BasePlanner ` -derived class constructs a planning
140+ environment ` self.env ` . This environment is uniquely associated with each
141+ instance of the planner and is what will be used in ` @ClonedPlanningMethod `
142+ calls. Since this environment is persistent and unique, it can also be used
143+ as a place to cache data or pre-load plugins for planners that have heavyweight
144+ initialization steps. However, because of this, each planning instance can
145+ only execute one ` @ClonedPlanningMethod ` at a time. It can still execute
146+ arbitrary ` @LockedPlanningMethod ` calls, as long as they are referring to
147+ robots in different environments.
121148
122149Please obey the following guidelines:
123150
124- - Assume that the cloned environment is locked during the entire call.
125- - Subclass constructor ** must** call ` BasePlanner.__init__ ` .
126- - A ` @PlanningMethod ` ** must not** call another ` @PlanningMethod ` .
151+ - Assume that the planning environment is locked during the entire call.
152+ - Subclass constructors ** must** call ` BasePlanner.__init__ ` .
127153- Each ` @PlanningMethod ` ** must** accept the first argument ` robot ` , which is a
128- robot in the cloned environment.
154+ robot in the environment it should be using to perform planning .
129155- Each ` @PlanningMethod ` ** must** accept ` **kwargs ` to ignore arguments that
130156 are not supported by the planner.
131157- Each ` @PlanningMethod ` ** must** return a ` Trajectory ` which was created in
132- the cloned environment.
133- - When possible, use one of the defacto-standard ` @PlanningMethod ` names listed
158+ the same environment as the robot it was passed (e.g. ` robot.GetEnv() ` ) .
159+ - When possible, use one of the defacto-standard ` @* PlanningMethod ` names listed
134160 below.
135161- Raise a ` PlanningError ` to indicate an expected, but fatal, error (e.g.
136162 timeout with no collision-free path).
0 commit comments