PlanMotionBase.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotSkillTemplates::MotionPlanningGroup
17 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * @date 2016
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include "PlanMotionBase.h"
24
26
30
31using namespace armarx;
32using namespace MotionPlanningGroup;
33
34// DO NOT EDIT NEXT LINE
35PlanMotionBase::SubClassRegistry PlanMotionBase::Registry(PlanMotionBase::GetName(),
37
38void
40{
41 resetTask();
42 //called prior to any locking of a mutex -> no deadlock
44 {
45 resetTask();
46 };
47
48 //setup cspace
49 SimoxCSpacePtr cspaceSimox;
50 if (in.getPlanPlatformMovement())
51 {
52 SimoxCSpaceWith2DPosePtr cspaceSimox2d =
53 new SimoxCSpaceWith2DPose{getWorkingMemory()->getCommonStorage()};
54 if (!in.isCSpacePlatformMovementBoundsMinSet())
55 {
57 << "platform movement should be planned, but the min movement bounds were not set.";
58 emitFailure();
59 return;
60 }
61 if (!in.isCSpacePlatformMovementBoundsMaxSet())
62 {
64 << "platform movement should be planned, but the max movement bounds were not set.";
65 emitFailure();
66 return;
67 }
68 cspaceSimox = cspaceSimox2d;
69 Vector3fRange movBounds;
70 movBounds.min.e0 = in.getCSpacePlatformMovementBoundsMin()->x;
71 movBounds.min.e1 = in.getCSpacePlatformMovementBoundsMin()->y;
72 movBounds.min.e2 = in.getCSpacePlatformMovementBoundsMin()->z;
73 movBounds.max.e0 = in.getCSpacePlatformMovementBoundsMax()->x;
74 movBounds.max.e1 = in.getCSpacePlatformMovementBoundsMax()->y;
75 movBounds.max.e2 = in.getCSpacePlatformMovementBoundsMax()->z;
76 cspaceSimox2d->setPoseBounds(movBounds);
77 }
78 else
79 {
80 cspaceSimox = new SimoxCSpace{getWorkingMemory()->getCommonStorage()};
81 }
82
83 //agent
84 AgentPlanningInformation agent;
85 agent.agentProjectNames = in.getAgentProjectName();
86 agent.agentRelativeFilePath = in.getAgentRelativeFilePath();
87
88 if (in.isCSpaceKinemaicChainNamesSet())
89 {
90 agent.kinemaicChainNames = in.getCSpaceKinemaicChainNames();
91 }
92 if (in.isCSpaceAdditionalJointsForPlanningSet())
93 {
94 agent.additionalJointsForPlanning = in.getCSpaceAdditionalJointsForPlanning();
95 }
96 if (in.isCSpaceJointsExcludedFromPlanningSet())
97 {
98 agent.jointsExcludedFromPlanning = in.getCSpaceJointsExcludedFromPlanning();
99 }
100
101 agent.collisionSetNames = in.getCollisionSetNames();
102 if (in.isInitialJointValuesSet())
103 {
104 agent.initialJointValues = in.getInitialJointValues();
105 }
106 agent.agentPose = in.getInitialAgentPose();
107
108 if (agent.kinemaicChainNames.empty() && agent.additionalJointsForPlanning.empty())
109 {
110 ARMARX_ERROR_S << "no joints set for planning! (define CSpaceAdditionalJointsForPlanning "
111 "and/or CSpaceKinemaicChainNames)";
112 emitFailure();
113 return;
114 }
115
116 ARMARX_VERBOSE_S << "Loading agent from project '" << agent.agentProjectName << "' and path '"
117 << agent.agentRelativeFilePath << "'";
118
119 cspaceSimox->setAgent(agent);
120 //objects
121 cspaceSimox->addObjectsFromWorkingMemory(getWorkingMemory());
122 cspaceSimox->setStationaryObjectMargin(in.getStationaryObjectMargin());
123 VectorXf start = cspaceSimox->jointMapToVector(in.getConfigStart());
124 if (start.size() != static_cast<std::size_t>(cspaceSimox->getDimensionality()))
125 {
126 ARMARX_ERROR_S << "the start config has " << start.size()
127 << "demensions, but the cspace has " << cspaceSimox->getDimensionality()
128 << " dimensions.";
129 emitFailure();
130 return;
131 }
132
133 VectorXf stop = cspaceSimox->jointMapToVector(in.getConfigStop());
134 if (stop.size() != static_cast<std::size_t>(cspaceSimox->getDimensionality()))
135 {
136 ARMARX_ERROR_S << "the stop config has " << stop.size() << "demensions, but the cspace has "
137 << cspaceSimox->getDimensionality() << " dimensions.";
138 emitFailure();
139 return;
140 }
141 ARMARX_IMPORTANT_S << "planned joints: " << cspaceSimox->getAgentJointNames();
142
143 CSpaceBasePtr cspace = cspaceSimox;
144 ScaledCSpacePtr scaledCspace;
145 if (in.getPlanPlatformMovement())
146 {
147 //we need scaling
148 VectorXf scale = {0.005, 0.005, 1};
149 scale.resize(cspaceSimox->getDimensionality(), 1);
150 scaledCspace = new ScaledCSpace{cspaceSimox, scale};
151 scaledCspace->scaleConfig(start);
152 scaledCspace->scaleConfig(stop);
153 cspace = scaledCspace;
154 }
155
156 float dcdStepSize = 0.1;
157
158 std::lock_guard<std::mutex> lock{taskMutex};
159 assert(!task);
160 task = getMotionPlanningServer()->enqueueTask(new RandomShortcutPostprocessorTask{
161 new RRTConnectTask{cspace,
162 start,
163 stop,
164 "Statechart.PlanMotionBase.RRT",
165 in.getPlanningTimeInSeconds(),
166 dcdStepSize},
167 "Statechart.PlanMotionBase.PostProcess",
168 in.getTrajectoryOptimizationTimeout() //max time spend for postprocessing
169 });
170
171 //wait for the task to finish (we can't call wait, since we may want to abort)
172 while (!isRunningTaskStopped() && !task->finishedRunning())
173 {
174 //time does not need to respect the time server (this is just polling for a result)
175 std::this_thread::sleep_for(std::chrono::milliseconds(20));
176 }
177 if (TaskStatus::eDone == task->getTaskStatus())
178 {
179 //found a path!
180 PathWithCost p = task->getPathWithCost();
181 if (scaledCspace)
182 {
183 //we planned movement->we need to unscale the path
184 scaledCspace->unscalePath(p.nodes);
185 }
186 TrajectoryPtr trajectory = cspaceSimox->pathToTrajectory(
187 p); // new Trajectory{p.nodes, Ice::DoubleSeq{}, cspaceSimox->getAgentJointNames()};
188 ARMARX_INFO_S << "Traj: " << trajectory->output();
189 setOutput("Trajectory", trajectory);
190 emitSuccess();
191 return;
192 }
193 //no path was found!
194 emitFailure();
195}
196
197void
199{
200 std::lock_guard<std::mutex> lock{taskMutex};
201 if (task)
202 {
203 task->abortTask();
204 task = nullptr;
205 }
206}
207
208// DO NOT EDIT NEXT FUNCTION
PlanMotionBase(const XMLStateConstructorParams &stateData)
RandomShortcutPostprocessorTaskHandle task
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Takes an other cspace and scales its' dimensions.
Similar to SimoxCSpace, but prepends dimensions for translation in x and y and a rotation around z.
The SimoxCSpace contains a set of stationary obstacles and an agent.
Definition SimoxCSpace.h:67
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_VERBOSE_S
Definition Logging.h:207
#define ARMARX_IMPORTANT_S
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:210
#define ARMARX_ON_SCOPE_EXIT
Executes given code when the enclosing scope is left.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< ScaledCSpace > ScaledCSpacePtr
An ice handle to a ScaledCSpace.
IceInternal::Handle< SimoxCSpaceWith2DPose > SimoxCSpaceWith2DPosePtr
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition Trajectory.h:52
rngshortcut::Task RandomShortcutPostprocessorTask
Definition Task.h:128
rrtconnect::Task RRTConnectTask
Definition Task.h:120
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition XMLState.h:64
IceInternal::Handle< SimoxCSpace > SimoxCSpacePtr
An ice handle for a SimoxCSpace.
Definition SimoxCSpace.h:56