@@ -25,12 +25,27 @@ two subclasses:
25
25
2 . ` prpy.planning.base.MetaPlanner ` : combines the output of multiple motion
26
26
planners, each of which is a ` BasePlanner ` or another ` MetaPlanner `
27
27
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.
34
49
35
50
For example, the following code will use OMPL to plan ` robot ` 's active DOFs
36
51
from their current values to to the ` goal_config ` configuration:
@@ -40,10 +55,10 @@ planner = OMPLPlanner('RRTConnect')
40
55
output_path = planner.PlanToConfiguration(robot, goal_config)
41
56
```
42
57
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.
47
62
48
63
See the following sub-sections for more information about the built-in planners
49
64
provided with PrPy, information about writing your own planner, and several
@@ -86,7 +101,7 @@ See the Python docstrings the above classes for more information.
86
101
87
102
### Common Planning Methods
88
103
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
90
105
have found these methods to be useful:
91
106
92
107
- ` PlanToConfiguration(robot, goal_config) ` : plan the robot's active DOFs from
@@ -112,25 +127,36 @@ of these methods accept planner-specific keyword arguments.
112
127
### Writing a Custom Planner
113
128
114
129
Implementing 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.
121
148
122
149
Please obey the following guidelines:
123
150
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__ ` .
127
153
- 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 .
129
155
- Each ` @PlanningMethod ` ** must** accept ` **kwargs ` to ignore arguments that
130
156
are not supported by the planner.
131
157
- 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
134
160
below.
135
161
- Raise a ` PlanningError ` to indicate an expected, but fatal, error (e.g.
136
162
timeout with no collision-free path).
0 commit comments