PlannedMotionProvider.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 RobotComponents::ArmarXObjects::PlannedMotionProvider
17 * @author Adrian Knobloch ( adrian dot knobloch at student dot kit dot edu )
18 * @date 2017
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <VirtualRobot/MathTools.h>
26#include <VirtualRobot/Nodes/RobotNode.h>
27#include <VirtualRobot/RobotNodeSet.h>
28
30
32//#include <RobotComponents/components/MotionPlanning/Tasks/BiRRT/Task.h>
35
39
40namespace armarx
41{
42 GraspingTrajectory
43 PlannedMotionProvider::planMotion(const SimoxCSpaceBasePtr& cSpaceBase,
44 const SimoxCSpaceBasePtr& cSpacePlatformBase,
45 const MotionPlanningData& mpd,
46 const Ice::Current& c)
47 {
48 TrajectoryPtr jointTrajectory = calculateJointTrajectory(cSpaceBase, mpd, c);
49 TrajectoryPtr platformTrajectory = calculatePlatformTrajectory(cSpacePlatformBase, mpd, c);
50 return {platformTrajectory, jointTrajectory, mpd.rnsToUse, mpd.endeffector, mpd.grasp};
51 }
52
53 GraspingTrajectory
54 PlannedMotionProvider::planMotionParallel(const SimoxCSpaceBasePtr& cSpaceBase,
55 const SimoxCSpaceBasePtr& cSpacePlatformBase,
56 const MotionPlanningData& mpd,
57 const Ice::Current& c)
58 {
59 VectorXf startCfg, goalCfg, startPos, goalPos;
60 ScaledCSpacePtr scaledJointCSpace, scaledPlatformCSpace;
61 Eigen::Vector3f rpyAgent;
62 SimoxCSpacePtr cSpace = SimoxCSpacePtr::dynamicCast(cSpaceBase);
63 SimoxCSpacePtr cSpacePlatform = SimoxCSpacePtr::dynamicCast(cSpacePlatformBase);
64 prepareJointCSpace(cSpace, mpd, &startCfg, &goalCfg, &scaledJointCSpace);
65 preparePlatformCSpace(
66 cSpacePlatform, mpd, &startPos, &goalPos, &scaledPlatformCSpace, &rpyAgent);
67 ARMARX_INFO << "Starting BiRRT for Joints and Platform";
68 // TODO: This is not async. Why?? Are the tasks not started when they are enqueued?
70 startBiRRT(scaledJointCSpace, startCfg, goalCfg, 0.01);
72 startBiRRT(scaledPlatformCSpace, startPos, goalPos, 0.1);
73 ARMARX_INFO << "Collecting the jointTask";
74 Path jointTrajectoryPath = finishBiRRT(rspJointHandle, scaledJointCSpace, "Joint");
75 ARMARX_INFO << "Collecting the platformTask";
76 Path posTrajectoryPath = finishBiRRT(rspPlatformHandle, scaledPlatformCSpace, "Platform");
77 // BiRRTTask;
78
79 auto transformToGlobal = [&](armarx::VectorXf& pos2D)
80 {
81 Eigen::Vector2f globalPos =
82 Eigen::Rotation2Df(rpyAgent(2)) * Eigen::Vector2f(pos2D.at(0), pos2D.at(1));
83 pos2D.at(0) = globalPos[0] + cSpacePlatform->getAgent().agentPose->position->x;
84 pos2D.at(1) = globalPos[1] + cSpacePlatform->getAgent().agentPose->position->y;
85 pos2D.at(2) = math::MathUtils::angleModPI(pos2D.at(2) + rpyAgent(2));
86 };
87 for (auto& e : posTrajectoryPath.nodes)
88 {
89 transformToGlobal(e);
90 }
91 TrajectoryPtr jointTrajectory, platformTrajectory;
92 jointTrajectory = cSpace->pathToTrajectory(jointTrajectoryPath);
93 platformTrajectory = cSpacePlatform->pathToTrajectory(posTrajectoryPath);
94 return {platformTrajectory, jointTrajectory, mpd.rnsToUse, mpd.endeffector, mpd.grasp};
95 }
96
97 void
99 {
100 usingProxy("MotionPlanningServer");
101 usingProxy("RobotStateComponent");
102 maxPostProcessingSteps = 50;
103 }
104
105 void
107 {
108 getProxy(mps, "MotionPlanningServer");
109 getProxy(robotStateComponent, "RobotStateComponent");
110 localRobot = RemoteRobot::createLocalCloneFromFile(robotStateComponent,
111 VirtualRobot::RobotIO::eStructure);
112 }
113
114 void
116 {
117 planningTasks.clear();
118 }
119
120 void
124
131
132 TrajectoryBasePtr
133 PlannedMotionProvider::planJointMotion(const armarx::SimoxCSpaceBasePtr& cSpaceBase,
134 const armarx::MotionPlanningData& mpd,
135 const Ice::Current& c)
136 {
137 TrajectoryPtr trajectory = calculateJointTrajectory(cSpaceBase, mpd, c);
138 return TrajectoryBasePtr::dynamicCast(trajectory);
139 }
140
141 TrajectoryBasePtr
142 PlannedMotionProvider::planPlatformMotion(const armarx::SimoxCSpaceBasePtr& cSpacePlatformBase,
143 const armarx::MotionPlanningData& mpd,
144 const Ice::Current& c)
145 {
146 TrajectoryPtr trajectory = calculatePlatformTrajectory(cSpacePlatformBase, mpd, c);
147 return TrajectoryBasePtr::dynamicCast(trajectory);
148 }
149
151 PlannedMotionProvider::calculateJointTrajectory(const SimoxCSpaceBasePtr& cSpaceBase,
152 const MotionPlanningData& mpd,
153 const Ice::Current& c)
154 {
155 VectorXf startCfg;
156 VectorXf goalCfg;
157 ScaledCSpacePtr scaledJointCSpace;
158 SimoxCSpacePtr cSpace = SimoxCSpacePtr::dynamicCast(cSpaceBase);
159 prepareJointCSpace(cSpace, mpd, &startCfg, &goalCfg, &scaledJointCSpace);
161 startBiRRT(scaledJointCSpace, startCfg, goalCfg, 0.01);
162 Path jointTrajectoryPath = finishBiRRT(rspHandle, scaledJointCSpace, "Joint");
163 return cSpace->pathToTrajectory(jointTrajectoryPath);
164 }
165
167 PlannedMotionProvider::calculatePlatformTrajectory(const SimoxCSpaceBasePtr& cSpacePlatformBase,
168 const MotionPlanningData& mpd,
169 const Ice::Current& c)
170 {
171 VectorXf startPos;
172 VectorXf goalPos;
173 ScaledCSpacePtr scaledPlatformCSpace;
174 Eigen::Vector3f rpyAgent;
175 SimoxCSpacePtr cSpacePlatform = SimoxCSpacePtr::dynamicCast(cSpacePlatformBase);
176 preparePlatformCSpace(
177 cSpacePlatform, mpd, &startPos, &goalPos, &scaledPlatformCSpace, &rpyAgent);
178 // BiRRTTask;
179 RemoteHandle<MotionPlanningTaskControlInterfacePrx> rspHandle =
180 startBiRRT(scaledPlatformCSpace, startPos, goalPos, 0.1);
181 Path posTrajectoryPath = finishBiRRT(rspHandle, scaledPlatformCSpace, "Platform");
182
183 auto transformToGlobal = [&](armarx::VectorXf& pos2D)
184 {
185 Eigen::Vector2f globalPos =
186 Eigen::Rotation2Df(rpyAgent(2)) * Eigen::Vector2f(pos2D.at(0), pos2D.at(1));
187 pos2D.at(0) = globalPos[0] + cSpacePlatform->getAgent().agentPose->position->x;
188 pos2D.at(1) = globalPos[1] + cSpacePlatform->getAgent().agentPose->position->y;
189 pos2D.at(2) = math::MathUtils::angleModPI(pos2D.at(2) + rpyAgent(2));
190 };
191 for (auto& e : posTrajectoryPath.nodes)
192 {
193 transformToGlobal(e);
194 }
195
196 return cSpacePlatform->pathToTrajectory(posTrajectoryPath);
197 }
198
200 PlannedMotionProvider::startBiRRT(const ScaledCSpacePtr scaledCSpace,
201 const armarx::VectorXf startPos,
202 const armarx::VectorXf goalPos,
203 float dcdStep,
204 bool doRandomShortcutPostProcessing)
205 {
206 // BiRRTTask;
207 MotionPlanningTaskBasePtr taskRRT =
208 new BiRRTTask{scaledCSpace,
209 startPos,
210 goalPos,
211 getDefaultName() + ".birrt" + IceUtil::generateUUID(),
212 60,
213 dcdStep};
214 RemoteHandle<MotionPlanningTaskControlInterfacePrx> handle;
215 if (!doRandomShortcutPostProcessing)
216 {
217 handle = mps->enqueueTask(taskRRT);
218 }
219 else
220 {
221 handle = mps->enqueueTask(
223 "RRTSmoothing" + IceUtil::generateUUID(),
224 1,
225 dcdStep,
226 maxPostProcessingSteps));
227 }
228 planningTasks.push_back(handle);
229 return handle;
230 }
231
232 Path
233 PlannedMotionProvider::finishBiRRT(RemoteHandle<MotionPlanningTaskControlInterfacePrx> handle,
234 const ScaledCSpacePtr scaledCSpace,
235 const std::string roboPart)
236 {
238 handle->waitForFinishedRunning();
240 << roboPart + " trajectory planning took "
241 << IceUtil::Time::microSeconds(handle->getRunningTime()).toMilliSecondsDouble()
242 << " ms";
243
244 if (handle->getTaskStatus() == armarx::TaskStatus::ePlanningFailed)
245 {
246 throw RuntimeError(" Motion Planning failed!");
247 }
248
249 ARMARX_INFO << "RRTConnectTask Planning "
250 << ((bool)(handle->getTaskStatus() == armarx::TaskStatus::ePlanningFailed)
251 ? "failed"
252 : "succeeded");
253 ARMARX_INFO << "RRTConnectTask Planning status: " << handle->getTaskStatus();
254
255 auto posTrajectoryPath = handle->getPath();
256 ARMARX_CHECK_EXPRESSION(scaledCSpace);
257 scaledCSpace->unscalePath(posTrajectoryPath);
258 return posTrajectoryPath;
259 }
260
261 void
262 PlannedMotionProvider::preparePlatformCSpace(SimoxCSpacePtr cSpacePlatform,
263 const MotionPlanningData& mpd,
264 VectorXf* storeStart,
265 VectorXf* storeGoal,
266 ScaledCSpacePtr* storeScaledCSpace,
267 Eigen::Vector3f* storeRpyAgent)
268 {
269 cSpacePlatform->setStationaryObjectMargin(
270 getProperty<float>("PlatformMotionSafetyMargin").getValue());
271 ARMARX_CHECK_EXPRESSION(cSpacePlatform);
272
273 Eigen::Vector3f rpy, rpyAgent;
274 VirtualRobot::MathTools::eigen4f2rpy(PosePtr::dynamicCast(mpd.globalPoseStart)->toEigen(),
275 rpy);
276 VirtualRobot::MathTools::eigen4f2rpy(
277 PosePtr::dynamicCast(cSpacePlatform->getAgent().agentPose)->toEigen(), rpyAgent);
278 armarx::VectorXf startPos{
279 mpd.globalPoseStart->position->x - cSpacePlatform->getAgent().agentPose->position->x,
280 mpd.globalPoseStart->position->y - cSpacePlatform->getAgent().agentPose->position->y,
281 math::MathUtils::angleModPI(rpy(2) - rpyAgent(2))};
282
283 Eigen::Vector2f localStartPos =
284 Eigen::Rotation2Df(-rpyAgent(2)) * Eigen::Vector2f(startPos.at(0), startPos.at(1));
285 startPos.at(0) = localStartPos(0);
286 startPos.at(1) = localStartPos(1);
287 VirtualRobot::MathTools::eigen4f2rpy(PosePtr::dynamicCast(mpd.globalPoseGoal)->toEigen(),
288 rpy);
289 armarx::VectorXf goalPos{
290 mpd.globalPoseGoal->position->x - cSpacePlatform->getAgent().agentPose->position->x,
291 mpd.globalPoseGoal->position->y - cSpacePlatform->getAgent().agentPose->position->y,
292 math::MathUtils::angleModPI(rpy(2) - rpyAgent(2))};
293 Eigen::Vector2f localGoalPos =
294 Eigen::Rotation2Df(-rpyAgent(2)) * Eigen::Vector2f(goalPos.at(0), goalPos.at(1));
295 goalPos.at(0) = localGoalPos(0);
296 goalPos.at(1) = localGoalPos(1);
297
298 ARMARX_INFO << VAROUT(startPos) << VAROUT(goalPos);
299
300 ScaledCSpacePtr scaledPlatformCSpace = new ScaledCSpace(cSpacePlatform, {0.001, 0.001, 1});
301 scaledPlatformCSpace->scaleConfig(startPos);
302 scaledPlatformCSpace->scaleConfig(goalPos);
303 *storeStart = startPos;
304 *storeGoal = goalPos;
305 *storeScaledCSpace = scaledPlatformCSpace;
306 *storeRpyAgent = rpyAgent;
307 }
308
309 void
310 PlannedMotionProvider::prepareJointCSpace(SimoxCSpacePtr cSpace,
311 const MotionPlanningData& mpd,
312 VectorXf* storeStart,
313 VectorXf* storeGoal,
314 ScaledCSpacePtr* storeScaledCSpace)
315 {
316 cSpace->setStationaryObjectMargin(getProperty<float>("JointMotionSafetyMargin").getValue());
318 ARMARX_INFO << "Entered prepareJointCSpace";
319 Ice::FloatSeq cSpaceScaling;
320 for (VirtualRobot::RobotNodePtr node :
321 localRobot->getRobotNodeSet(mpd.rnsToUse)->getAllRobotNodes())
322 {
323 cSpaceScaling.push_back(node->isTranslationalJoint() ? 0.001f : 1.0f);
324 }
325 ARMARX_IMPORTANT << "Robot position: " << VAROUT(mpd.globalPoseStart->output())
326 << VAROUT(mpd.globalPoseGoal->output());
327
328 armarx::VectorXf startCfg = cSpace->jointMapToVector(mpd.configStart);
329 armarx::VectorXf goalCfg = cSpace->jointMapToVector(mpd.configGoal);
330
331 ARMARX_VERBOSE << VAROUT(startCfg) << VAROUT(goalCfg);
332 ScaledCSpacePtr scaledJointCSpace = new ScaledCSpace(cSpace, cSpaceScaling);
333 scaledJointCSpace->scaleConfig(startCfg);
334 scaledJointCSpace->scaleConfig(goalCfg);
335 *storeStart = startCfg;
336 *storeGoal = goalCfg;
337 *storeScaledCSpace = scaledJointCSpace;
338 }
339} // namespace armarx
#define VAROUT(x)
constexpr T c
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
GraspingTrajectory planMotion(const SimoxCSpaceBasePtr &cSpaceBase, const SimoxCSpaceBasePtr &cSpacePlatformBase, const MotionPlanningData &mpd, const Ice::Current &c=Ice::emptyCurrent) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
TrajectoryBasePtr planPlatformMotion(const SimoxCSpaceBasePtr &cSpacePlatformBase, const MotionPlanningData &mpd, const Ice::Current &c=Ice::emptyCurrent) override
TrajectoryBasePtr planJointMotion(const SimoxCSpaceBasePtr &cSpaceBase, const MotionPlanningData &mpd, const Ice::Current &c=Ice::emptyCurrent) override
GraspingTrajectory planMotionParallel(const SimoxCSpaceBasePtr &cSpaceBase, const SimoxCSpaceBasePtr &cSpacePlatformBase, const MotionPlanningData &mpd, const Ice::Current &c) override
std::string getDefaultName() const override
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
The RemoteHandle class wrapps a ClientSideRemoteHandleControlBlock and can be used just as a Ice prox...
static VirtualRobot::RobotPtr createLocalCloneFromFile(RobotStateComponentInterfacePrx robotStatePrx, VirtualRobot::RobotIO::RobotDescription loadMode=VirtualRobot::RobotIO::eFull)
This is a convenience function for createLocalClone, which automatically gets the filename from the R...
static float angleModPI(float value)
Definition MathUtils.h:173
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
T getValue(nlohmann::json &userConfig, nlohmann::json &defaultConfig, const std::string &entryName)
Definition utils.h:80
std::vector< Pose > Path
Definition basic_types.h:46
This file offers overloads of toIce() and fromIce() functions for STL container types.
birrt::Task BiRRTTask
Definition Task.h:72
IceInternal::Handle< ScaledCSpace > ScaledCSpacePtr
An ice handle to a ScaledCSpace.
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition Trajectory.h:52
rngshortcut::Task RandomShortcutPostprocessorTask
Definition Task.h:128
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
IceInternal::Handle< SimoxCSpace > SimoxCSpacePtr
An ice handle for a SimoxCSpace.
Definition SimoxCSpace.h:56