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
26
27#include <VirtualRobot/MathTools.h>
28#include <VirtualRobot/Nodes/RobotNode.h>
29#include <VirtualRobot/RobotNodeSet.h>
30
32
34//#include <RobotComponents/components/MotionPlanning/Tasks/BiRRT/Task.h>
37
41
42namespace armarx
43{
44 GraspingTrajectory
45 PlannedMotionProvider::planMotion(const SimoxCSpaceBasePtr& cSpaceBase,
46 const SimoxCSpaceBasePtr& cSpacePlatformBase,
47 const MotionPlanningData& mpd,
48 const Ice::Current& c)
49 {
50 TrajectoryPtr jointTrajectory = calculateJointTrajectory(cSpaceBase, mpd, c);
51 TrajectoryPtr platformTrajectory = calculatePlatformTrajectory(cSpacePlatformBase, mpd, c);
52 return {platformTrajectory, jointTrajectory, mpd.rnsToUse, mpd.endeffector, mpd.grasp};
53 }
54
55 GraspingTrajectory
56 PlannedMotionProvider::planMotionParallel(const SimoxCSpaceBasePtr& cSpaceBase,
57 const SimoxCSpaceBasePtr& cSpacePlatformBase,
58 const MotionPlanningData& mpd,
59 const Ice::Current& c)
60 {
61 VectorXf startCfg, goalCfg, startPos, goalPos;
62 ScaledCSpacePtr scaledJointCSpace, scaledPlatformCSpace;
63 Eigen::Vector3f rpyAgent;
64 SimoxCSpacePtr cSpace = SimoxCSpacePtr::dynamicCast(cSpaceBase);
65 SimoxCSpacePtr cSpacePlatform = SimoxCSpacePtr::dynamicCast(cSpacePlatformBase);
66 prepareJointCSpace(cSpace, mpd, &startCfg, &goalCfg, &scaledJointCSpace);
67 preparePlatformCSpace(
68 cSpacePlatform, mpd, &startPos, &goalPos, &scaledPlatformCSpace, &rpyAgent);
69 ARMARX_INFO << "Starting BiRRT for Joints and Platform";
70 // TODO: This is not async. Why?? Are the tasks not started when they are enqueued?
72 startBiRRT(scaledJointCSpace, startCfg, goalCfg, 0.01);
74 startBiRRT(scaledPlatformCSpace, startPos, goalPos, 0.1);
75 ARMARX_INFO << "Collecting the jointTask";
76 Path jointTrajectoryPath = finishBiRRT(rspJointHandle, scaledJointCSpace, "Joint");
77 ARMARX_INFO << "Collecting the platformTask";
78 Path posTrajectoryPath = finishBiRRT(rspPlatformHandle, scaledPlatformCSpace, "Platform");
79 // BiRRTTask;
80
81 auto transformToGlobal = [&](armarx::VectorXf& pos2D)
82 {
83 Eigen::Vector2f globalPos =
84 Eigen::Rotation2Df(rpyAgent(2)) * Eigen::Vector2f(pos2D.at(0), pos2D.at(1));
85 pos2D.at(0) = globalPos[0] + cSpacePlatform->getAgent().agentPose->position->x;
86 pos2D.at(1) = globalPos[1] + cSpacePlatform->getAgent().agentPose->position->y;
87 pos2D.at(2) = math::MathUtils::angleModPI(pos2D.at(2) + rpyAgent(2));
88 };
89 for (auto& e : posTrajectoryPath.nodes)
90 {
91 transformToGlobal(e);
92 }
93 TrajectoryPtr jointTrajectory, platformTrajectory;
94 jointTrajectory = cSpace->pathToTrajectory(jointTrajectoryPath);
95 platformTrajectory = cSpacePlatform->pathToTrajectory(posTrajectoryPath);
96 return {platformTrajectory, jointTrajectory, mpd.rnsToUse, mpd.endeffector, mpd.grasp};
97 }
98
99 void
101 {
102 usingProxy("MotionPlanningServer");
103 usingProxy("RobotStateComponent");
104 maxPostProcessingSteps = 50;
105 }
106
107 void
109 {
110 getProxy(mps, "MotionPlanningServer");
111 getProxy(robotStateComponent, "RobotStateComponent");
112 localRobot = RemoteRobot::createLocalCloneFromFile(robotStateComponent,
113 VirtualRobot::RobotIO::eStructure);
114 }
115
116 void
118 {
119 planningTasks.clear();
120 }
121
122 void
126
133
134 TrajectoryBasePtr
135 PlannedMotionProvider::planJointMotion(const armarx::SimoxCSpaceBasePtr& cSpaceBase,
136 const armarx::MotionPlanningData& mpd,
137 const Ice::Current& c)
138 {
139 TrajectoryPtr trajectory = calculateJointTrajectory(cSpaceBase, mpd, c);
140 return TrajectoryBasePtr::dynamicCast(trajectory);
141 }
142
143 TrajectoryBasePtr
144 PlannedMotionProvider::planPlatformMotion(const armarx::SimoxCSpaceBasePtr& cSpacePlatformBase,
145 const armarx::MotionPlanningData& mpd,
146 const Ice::Current& c)
147 {
148 TrajectoryPtr trajectory = calculatePlatformTrajectory(cSpacePlatformBase, mpd, c);
149 return TrajectoryBasePtr::dynamicCast(trajectory);
150 }
151
153 PlannedMotionProvider::calculateJointTrajectory(const SimoxCSpaceBasePtr& cSpaceBase,
154 const MotionPlanningData& mpd,
155 const Ice::Current& c)
156 {
157 VectorXf startCfg;
158 VectorXf goalCfg;
159 ScaledCSpacePtr scaledJointCSpace;
160 SimoxCSpacePtr cSpace = SimoxCSpacePtr::dynamicCast(cSpaceBase);
161 prepareJointCSpace(cSpace, mpd, &startCfg, &goalCfg, &scaledJointCSpace);
163 startBiRRT(scaledJointCSpace, startCfg, goalCfg, 0.01);
164 Path jointTrajectoryPath = finishBiRRT(rspHandle, scaledJointCSpace, "Joint");
165 return cSpace->pathToTrajectory(jointTrajectoryPath);
166 }
167
169 PlannedMotionProvider::calculatePlatformTrajectory(const SimoxCSpaceBasePtr& cSpacePlatformBase,
170 const MotionPlanningData& mpd,
171 const Ice::Current& c)
172 {
173 VectorXf startPos;
174 VectorXf goalPos;
175 ScaledCSpacePtr scaledPlatformCSpace;
176 Eigen::Vector3f rpyAgent;
177 SimoxCSpacePtr cSpacePlatform = SimoxCSpacePtr::dynamicCast(cSpacePlatformBase);
178 preparePlatformCSpace(
179 cSpacePlatform, mpd, &startPos, &goalPos, &scaledPlatformCSpace, &rpyAgent);
180 // BiRRTTask;
181 RemoteHandle<MotionPlanningTaskControlInterfacePrx> rspHandle =
182 startBiRRT(scaledPlatformCSpace, startPos, goalPos, 0.1);
183 Path posTrajectoryPath = finishBiRRT(rspHandle, scaledPlatformCSpace, "Platform");
184
185 auto transformToGlobal = [&](armarx::VectorXf& pos2D)
186 {
187 Eigen::Vector2f globalPos =
188 Eigen::Rotation2Df(rpyAgent(2)) * Eigen::Vector2f(pos2D.at(0), pos2D.at(1));
189 pos2D.at(0) = globalPos[0] + cSpacePlatform->getAgent().agentPose->position->x;
190 pos2D.at(1) = globalPos[1] + cSpacePlatform->getAgent().agentPose->position->y;
191 pos2D.at(2) = math::MathUtils::angleModPI(pos2D.at(2) + rpyAgent(2));
192 };
193 for (auto& e : posTrajectoryPath.nodes)
194 {
195 transformToGlobal(e);
196 }
197
198 return cSpacePlatform->pathToTrajectory(posTrajectoryPath);
199 }
200
202 PlannedMotionProvider::startBiRRT(const ScaledCSpacePtr scaledCSpace,
203 const armarx::VectorXf startPos,
204 const armarx::VectorXf goalPos,
205 float dcdStep,
206 bool doRandomShortcutPostProcessing)
207 {
208 // BiRRTTask;
209 MotionPlanningTaskBasePtr taskRRT =
210 new BiRRTTask{scaledCSpace,
211 startPos,
212 goalPos,
213 getDefaultName() + ".birrt" + IceUtil::generateUUID(),
214 60,
215 dcdStep};
216 RemoteHandle<MotionPlanningTaskControlInterfacePrx> handle;
217 if (!doRandomShortcutPostProcessing)
218 {
219 handle = mps->enqueueTask(taskRRT);
220 }
221 else
222 {
223 handle = mps->enqueueTask(
225 "RRTSmoothing" + IceUtil::generateUUID(),
226 1,
227 dcdStep,
228 maxPostProcessingSteps));
229 }
230 planningTasks.push_back(handle);
231 return handle;
232 }
233
234 Path
235 PlannedMotionProvider::finishBiRRT(RemoteHandle<MotionPlanningTaskControlInterfacePrx> handle,
236 const ScaledCSpacePtr scaledCSpace,
237 const std::string roboPart)
238 {
240 handle->waitForFinishedRunning();
242 << roboPart + " trajectory planning took "
243 << IceUtil::Time::microSeconds(handle->getRunningTime()).toMilliSecondsDouble()
244 << " ms";
245
246 if (handle->getTaskStatus() == armarx::TaskStatus::ePlanningFailed)
247 {
248 throw RuntimeError(" Motion Planning failed!");
249 }
250
251 ARMARX_INFO << "RRTConnectTask Planning "
252 << ((bool)(handle->getTaskStatus() == armarx::TaskStatus::ePlanningFailed)
253 ? "failed"
254 : "succeeded");
255 ARMARX_INFO << "RRTConnectTask Planning status: " << handle->getTaskStatus();
256
257 auto posTrajectoryPath = handle->getPath();
258 ARMARX_CHECK_EXPRESSION(scaledCSpace);
259 scaledCSpace->unscalePath(posTrajectoryPath);
260 return posTrajectoryPath;
261 }
262
263 void
264 PlannedMotionProvider::preparePlatformCSpace(SimoxCSpacePtr cSpacePlatform,
265 const MotionPlanningData& mpd,
266 VectorXf* storeStart,
267 VectorXf* storeGoal,
268 ScaledCSpacePtr* storeScaledCSpace,
269 Eigen::Vector3f* storeRpyAgent)
270 {
271 cSpacePlatform->setStationaryObjectMargin(
272 getProperty<float>("PlatformMotionSafetyMargin").getValue());
273 ARMARX_CHECK_EXPRESSION(cSpacePlatform);
274
275 Eigen::Vector3f rpy, rpyAgent;
276 VirtualRobot::MathTools::eigen4f2rpy(PosePtr::dynamicCast(mpd.globalPoseStart)->toEigen(),
277 rpy);
278 VirtualRobot::MathTools::eigen4f2rpy(
279 PosePtr::dynamicCast(cSpacePlatform->getAgent().agentPose)->toEigen(), rpyAgent);
280 armarx::VectorXf startPos{
281 mpd.globalPoseStart->position->x - cSpacePlatform->getAgent().agentPose->position->x,
282 mpd.globalPoseStart->position->y - cSpacePlatform->getAgent().agentPose->position->y,
283 math::MathUtils::angleModPI(rpy(2) - rpyAgent(2))};
284
285 Eigen::Vector2f localStartPos =
286 Eigen::Rotation2Df(-rpyAgent(2)) * Eigen::Vector2f(startPos.at(0), startPos.at(1));
287 startPos.at(0) = localStartPos(0);
288 startPos.at(1) = localStartPos(1);
289 VirtualRobot::MathTools::eigen4f2rpy(PosePtr::dynamicCast(mpd.globalPoseGoal)->toEigen(),
290 rpy);
291 armarx::VectorXf goalPos{
292 mpd.globalPoseGoal->position->x - cSpacePlatform->getAgent().agentPose->position->x,
293 mpd.globalPoseGoal->position->y - cSpacePlatform->getAgent().agentPose->position->y,
294 math::MathUtils::angleModPI(rpy(2) - rpyAgent(2))};
295 Eigen::Vector2f localGoalPos =
296 Eigen::Rotation2Df(-rpyAgent(2)) * Eigen::Vector2f(goalPos.at(0), goalPos.at(1));
297 goalPos.at(0) = localGoalPos(0);
298 goalPos.at(1) = localGoalPos(1);
299
300 ARMARX_INFO << VAROUT(startPos) << VAROUT(goalPos);
301
302 ScaledCSpacePtr scaledPlatformCSpace = new ScaledCSpace(cSpacePlatform, {0.001, 0.001, 1});
303 scaledPlatformCSpace->scaleConfig(startPos);
304 scaledPlatformCSpace->scaleConfig(goalPos);
305 *storeStart = startPos;
306 *storeGoal = goalPos;
307 *storeScaledCSpace = scaledPlatformCSpace;
308 *storeRpyAgent = rpyAgent;
309 }
310
311 void
312 PlannedMotionProvider::prepareJointCSpace(SimoxCSpacePtr cSpace,
313 const MotionPlanningData& mpd,
314 VectorXf* storeStart,
315 VectorXf* storeGoal,
316 ScaledCSpacePtr* storeScaledCSpace)
317 {
318 cSpace->setStationaryObjectMargin(getProperty<float>("JointMotionSafetyMargin").getValue());
320 ARMARX_INFO << "Entered prepareJointCSpace";
321 Ice::FloatSeq cSpaceScaling;
322 for (VirtualRobot::RobotNodePtr node :
323 localRobot->getRobotNodeSet(mpd.rnsToUse)->getAllRobotNodes())
324 {
325 cSpaceScaling.push_back(node->isTranslationalJoint() ? 0.001f : 1.0f);
326 }
327 ARMARX_IMPORTANT << "Robot position: " << VAROUT(mpd.globalPoseStart->output())
328 << VAROUT(mpd.globalPoseGoal->output());
329
330 armarx::VectorXf startCfg = cSpace->jointMapToVector(mpd.configStart);
331 armarx::VectorXf goalCfg = cSpace->jointMapToVector(mpd.configGoal);
332
333 ARMARX_VERBOSE << VAROUT(startCfg) << VAROUT(goalCfg);
334 ScaledCSpacePtr scaledJointCSpace = new ScaledCSpace(cSpace, cSpaceScaling);
335 scaledJointCSpace->scaleConfig(startCfg);
336 scaledJointCSpace->scaleConfig(goalCfg);
337 *storeStart = startCfg;
338 *storeGoal = goalCfg;
339 *storeScaledCSpace = scaledJointCSpace;
340 }
341
343} // namespace armarx
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
#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)
Brief description of class PlannedMotionProvider.
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