Task.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2017, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX
19 * @author Mirko Waechter( mirko.waechter at kit dot edu)
20 * @date 2017
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#include "Task.h"
25
26#include <SimoxUtility/algorithm/string/string_tools.h>
27
29
31
33#include "../../util/Metrics.h"
34#include <MotionPlanning/CSpace/CSpacePath.h>
35#include <MotionPlanning/CSpace/CSpaceSampled.h> // IWYU pragma: keep
36#include <MotionPlanning/Planner/BiRrt.h>
37#include <MotionPlanning/PostProcessing/ShortcutProcessor.h>
38
40{
41
42 Task::Task(const CSpaceBasePtr& cspace,
43 const VectorXf& startCfg,
44 const VectorXf& goalCfg,
45 const std::string& taskName,
46 Ice::Long maximalPlanningTimeInSeconds,
47 float dcdStep)
48 {
49 this->cspace = cspace->clone();
50 this->startCfg = startCfg;
51 this->goalCfg = goalCfg;
52 this->dcdStep = dcdStep;
53 this->maximalPlanningTimeInSeconds = maximalPlanningTimeInSeconds;
54 this->taskName = taskName;
55
56 if (startCfg.size() != goalCfg.size() ||
57 startCfg.size() != static_cast<std::size_t>(this->cspace->getDimensionality()))
58 {
59 throw std::invalid_argument{
60 "start and goal have to be the size of the cspace's dimensionality"};
61 }
62 }
63
64 void
65 Task::abortTask(const ::Ice::Current&)
66 {
67 }
68
69 Path
70 Task::getPath(const ::Ice::Current&) const
71 {
72 std::lock_guard<std::mutex> lock{mtx};
73 return solution;
74 }
75
76 void
77 Task::run(const RemoteObjectNodePrxList&, const ::Ice::Current&)
78 {
79
80 auto failureOutput = [this]
81 {
82 SimoxCSpacePtr origCSpace = getOriginalCSpace();
83 ARMARX_CHECK_EXPRESSION(origCSpace);
84
85 std::stringstream ss;
86 for (auto set : origCSpace->getCD().getSceneObjectSets())
87 {
88 if (origCSpace->getCD().isInCollision(set))
89 {
90 std::string name = set->getName();
91 Ice::StringSeq names;
92 if (name.empty())
93 {
95 for (auto e : set->getSceneObjects())
96 {
97 names.push_back(e->getName());
98 }
99 }
100 else
101 {
102 names.push_back(name);
103 }
104
105 ss << "scene object set consisting of " << simox::alg::join(names, ", ")
106 << " is in collision\n";
107 }
108 }
109 return ss.str();
110 };
111
112
113 setTaskStatus(TaskStatus::ePlanning);
115 //check trivial cases
116 cspace->initCollisionTest();
117
118 const auto startIsCollisionFree =
119 cspace->isCollisionFree(std::pair<const Ice::Float*, const Ice::Float*>{
120 startCfg.data(), startCfg.data() + startCfg.size()});
121 if (!startIsCollisionFree)
122 {
123 ARMARX_WARNING << "BiRRT failed trivially: start config is in collision: " << startCfg
124 << " Collisions:\n"
125 << failureOutput();
126
127 setTaskStatus(TaskStatus::ePlanningFailed);
128 return;
129 }
130 const auto goalIscollisionFree =
131 cspace->isCollisionFree(std::pair<const Ice::Float*, const Ice::Float*>{
132 goalCfg.data(), goalCfg.data() + goalCfg.size()});
133 if (!goalIscollisionFree)
134 {
135 ARMARX_WARNING << "BiRRT failed trivially: goal config is in collision" << goalCfg
136 << " Collisions:\n"
137 << failureOutput();
138 setTaskStatus(TaskStatus::ePlanningFailed);
139 return;
140 }
141
142 SimoxCSpacePtr origCSpace = getOriginalCSpace();
143 ARMARX_CHECK_EXPRESSION(origCSpace);
144 ARMARX_INFO << "RobotConfig: "
145 << origCSpace->getAgentSceneObj()->getConfig()->getRobotNodeJointValueMap();
146 Saba::CSpaceSampledPtr sampledcSpace = getOriginalCSpace()->createSimoxCSpace();
147 ARMARX_CHECK_EXPRESSION(sampledcSpace);
148 IceUtil::Time start = IceUtil::Time::now();
150 {
151 ARMARX_INFO << "BiRRT took : " << (IceUtil::Time::now() - start).toMilliSecondsDouble()
152 << " ms";
153 };
154
155 ScaledCSpacePtr scaledCSpace = ScaledCSpacePtr::dynamicCast(cspace);
156 if (scaledCSpace)
157 {
158 ARMARX_VERBOSE << "unscaling configs " << VAROUT(startCfg) << VAROUT(goalCfg);
159 scaledCSpace->unscaleConfig(startCfg);
160 scaledCSpace->unscaleConfig(goalCfg);
161 sampledcSpace->setMetricWeights(
162 Eigen::Map<Eigen::VectorXf>(scaledCSpace->getScalingFactors().data(),
163 scaledCSpace->getScalingFactors().size()));
164 ARMARX_VERBOSE << "unscaled configs " << VAROUT(startCfg) << VAROUT(goalCfg);
165 }
166
167 const auto distStartEnd =
168 euclideanDistance(startCfg.begin(), startCfg.end(), goalCfg.begin());
169
170 if (distStartEnd <= dcdStep)
171 {
172 setTaskStatus(TaskStatus::eDone);
173 solution.nodes.emplace_back(startCfg);
174 solution.nodes.emplace_back(goalCfg);
175 return;
176 }
177
178
179 Saba::Rrt::RrtMethod mode;
180 mode = Saba::Rrt::eExtend;
182 ARMARX_INFO << "CSpace type : " << cspace->ice_id();
183
184
185 ARMARX_INFO << "Created simox cspace";
186 // float samplingSize = 0.04f;
187 // sampledcSpace->setSamplingSize(samplingSize);
188 sampledcSpace->setSamplingSizeDCD(dcdStep);
189 ARMARX_INFO << "SamplingSizeDCD: " << sampledcSpace->getSamplingSizeDCD();
190 Saba::BiRrtPtr rrt(new Saba::BiRrt(sampledcSpace, mode /*, mode2, samplingSize*/));
191
192
193 rrt->setStart(Eigen::Map<Eigen::ArrayXf>(startCfg.data(), startCfg.size()));
194 rrt->setGoal(Eigen::Map<Eigen::ArrayXf>(goalCfg.data(), goalCfg.size()));
195
196 bool planningSucceeded = rrt->plan();
197 if (planningSucceeded)
198 {
199 ARMARX_VERBOSE << "BiRRT succeeded! ";
200 Saba::CSpacePathPtr tmpSolution = rrt->getSolution();
201 ARMARX_INFO << "waypoints: " << tmpSolution->getPoints().size();
202
203
204 TIMING_START(ShortCutter);
205 ARMARX_INFO << "Shortcutting!";
206 Saba::ShortcutProcessor shortcutter(tmpSolution, sampledcSpace);
207 tmpSolution = shortcutter.shortenSolutionRandom(100, 200);
208 ARMARX_INFO << "Shortcutting resulted into " << tmpSolution->getPoints().size();
209 TIMING_END(ShortCutter);
210 for (auto& vec : tmpSolution->getPoints())
211 {
212 this->solution.nodes.push_back(VectorXf{vec.data(), vec.data() + vec.rows()});
213 }
215 if (scaledCSpace)
216 {
217 scaledCSpace->scalePath(solution);
218 }
219 // auto from = *solution.nodes.begin();
220 // int i = 1;
221 // for (auto& to : solution.nodes)
222 // {
223 // bool collisionFree = dcdIsPathCollisionFree(
224 // from, to, dcdStep,
225 // [this](const VectorXf & cfg)
226 // {
227 // return cspace->isCollisionFree({cfg.data(), cfg.data() + cfg.size()});
228 // },
229 // false
230 // );
231 // if (!collisionFree)
232 // {
233 // ARMARX_ERROR << "Collision in path at node: " << i << " Collisions:\n" << failureOutput();
234 // setTaskStatus(TaskStatus::ePlanningFailed);
235 // return;
236 // }
237 // from = to;
238 // i++;
239 // }
240
241 setTaskStatus(TaskStatus::eDone);
242 return;
243 }
244
245 else
246 {
247 setTaskStatus(TaskStatus::ePlanningFailed);
248 return;
249 }
250 }
251
254 {
255 SimoxCSpacePtr origCSpace;
256 if (cspace->ice_isA(CSpaceAdaptorBase::ice_staticId()))
257 {
258 origCSpace = SimoxCSpacePtr::dynamicCast(
259 CSpaceAdaptorBasePtr::dynamicCast(cspace)->getOriginalCSpace());
260
261 // sampledcSpace = ScaledCSpacePtr::dynamicCast(cspace)->getOriginal()->createSimoxCSpace();
262 }
263 else
264 {
265 origCSpace = SimoxCSpacePtr::dynamicCast(cspace);
266 }
267 return origCSpace;
268 }
269
270
271} // namespace armarx::birrt
#define VAROUT(x)
bool setTaskStatus(TaskStatus::Status newTaskStatus, const Ice::Current &=Ice::emptyCurrent) override
void abortTask(const ::Ice::Current &) override
Definition Task.cpp:65
void run(const RemoteObjectNodePrxList &, const ::Ice::Current &) override
Definition Task.cpp:77
Path getPath(const ::Ice::Current &) const override
Definition Task.cpp:70
std::mutex mtx
Definition Task.h:59
SimoxCSpacePtr getOriginalCSpace() const
Definition Task.cpp:253
#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_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define ARMARX_ON_SCOPE_EXIT
Executes given code when the enclosing scope is left.
#define TIMING_START(name)
Helper macro to do timing tests.
Definition TimeUtil.h:289
#define TIMING_END(name)
Prints duration.
Definition TimeUtil.h:306
IceInternal::Handle< ScaledCSpace > ScaledCSpacePtr
An ice handle to a ScaledCSpace.
float euclideanDistance(IteratorType1 first1, IteratorType1 last1, IteratorType2 first2)
Returns the euclidean distance.
Definition Metrics.h:104
IceInternal::Handle< SimoxCSpace > SimoxCSpacePtr
An ice handle for a SimoxCSpace.
Definition SimoxCSpace.h:56