GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
// Copyright (c) 2014, LAAS-CNRS |
||
2 |
// Authors: Steve Tonneau (steve.tonneau@laas.fr) |
||
3 |
// |
||
4 |
// This file is part of hpp-rbprm. |
||
5 |
// hpp-rbprm is free software: you can redistribute it |
||
6 |
// and/or modify it under the terms of the GNU Lesser General Public |
||
7 |
// License as published by the Free Software Foundation, either version |
||
8 |
// 3 of the License, or (at your option) any later version. |
||
9 |
// |
||
10 |
// hpp-rbprm is distributed in the hope that it will be |
||
11 |
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
||
12 |
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
13 |
// General Lesser Public License for more details. You should have |
||
14 |
// received a copy of the GNU Lesser General Public License along with |
||
15 |
// hpp-rbprm. If not, see <http://www.gnu.org/licenses/>. |
||
16 |
|||
17 |
#include <hpp/fcl/BVH/BVH_model.h> |
||
18 |
#include <hpp/fcl/collision_object.h> |
||
19 |
|||
20 |
#include <Eigen/Geometry> |
||
21 |
#include <hpp/core/collision-validation-report.hh> |
||
22 |
#include <hpp/core/collision-validation.hh> |
||
23 |
#include <hpp/core/configuration-shooter/uniform.hh> |
||
24 |
#include <hpp/core/problem.hh> |
||
25 |
#include <hpp/pinocchio/configuration.hh> |
||
26 |
#include <hpp/pinocchio/liegroup-element.hh> |
||
27 |
#include <hpp/pinocchio/liegroup-space.hh> |
||
28 |
#include <hpp/rbprm/rbprm-shooter.hh> |
||
29 |
#include <hpp/rbprm/rbprm-validation-report.hh> |
||
30 |
#include <hpp/util/timer.hh> |
||
31 |
#include <pinocchio/algorithm/joint-configuration.hpp> |
||
32 |
|||
33 |
namespace hpp { |
||
34 |
using namespace core; |
||
35 |
using namespace fcl; |
||
36 |
namespace { |
||
37 |
static const int SIZE_EULER = 6; |
||
38 |
typedef fcl::BVHModel<OBBRSS> BVHModelOB; |
||
39 |
typedef fcl::shared_ptr<const BVHModelOB> BVHModelOBConst_Ptr_t; |
||
40 |
|||
41 |
47226 |
BVHModelOBConst_Ptr_t GetModel( |
|
42 |
const pinocchio::FclConstCollisionObjectPtr_t object) { |
||
43 |
✓✗✗✓ |
47226 |
if (object->collisionGeometry()->getNodeType() != BV_OBBRSS) { |
44 |
hppDout(warning, |
||
45 |
"Collision geometry in shooter is not a BV_OBBRSS, cannot get the " |
||
46 |
"model."); |
||
47 |
return BVHModelOBConst_Ptr_t(); |
||
48 |
} |
||
49 |
// assert(object->collisionGeometry()->getNodeType() == BV_OBBRSS); |
||
50 |
const BVHModelOBConst_Ptr_t model = |
||
51 |
94452 |
static_pointer_cast<const BVHModelOB>(object->collisionGeometry()); |
|
52 |
// assert(model->getModelType() == BVH_MODEL_TRIANGLES); |
||
53 |
✗✓ | 47226 |
if (model->getModelType() != BVH_MODEL_TRIANGLES) { |
54 |
hppDout(warning, "Collision model is not of type BVH_MODEL_TRIANGLES."); |
||
55 |
return BVHModelOBConst_Ptr_t(); |
||
56 |
} |
||
57 |
47226 |
return model; |
|
58 |
} |
||
59 |
|||
60 |
174 |
double TriangleArea(rbprm::TrianglePoints& tri) { |
|
61 |
double a, b, c; |
||
62 |
✓✗ | 174 |
a = (tri.p1 - tri.p2).norm(); |
63 |
✓✗ | 174 |
b = (tri.p2 - tri.p3).norm(); |
64 |
✓✗ | 174 |
c = (tri.p3 - tri.p1).norm(); |
65 |
174 |
double s = 0.5 * (a + b + c); |
|
66 |
174 |
return sqrt(s * (s - a) * (s - b) * (s - c)); |
|
67 |
} |
||
68 |
|||
69 |
48395 |
std::vector<double> getTranslationBounds( |
|
70 |
const pinocchio::RbPrmDevicePtr_t robot) { |
||
71 |
✓✗ | 96790 |
const JointPtr_t root = robot->Device::rootJoint(); |
72 |
48395 |
std::vector<double> res; |
|
73 |
✓✓ | 193580 |
for (std::size_t i = 0; i < 3; ++i) { |
74 |
✓✗✓✗ |
145185 |
if (root->isBounded(i)) { |
75 |
✓✗✓✗ |
145185 |
res.push_back(root->lowerBound(i)); |
76 |
✓✗✓✗ |
145185 |
res.push_back(root->upperBound(i)); |
77 |
} else { |
||
78 |
res.push_back(-std::numeric_limits<double>::max()); |
||
79 |
res.push_back(std::numeric_limits<double>::max()); |
||
80 |
} |
||
81 |
} |
||
82 |
96790 |
return res; |
|
83 |
} |
||
84 |
|||
85 |
1132 |
void SetConfigTranslation(const pinocchio::RbPrmDevicePtr_t robot, |
|
86 |
Configuration_t& config, const Vec3f& translation) { |
||
87 |
✓✗ | 2264 |
std::vector<double> bounds = getTranslationBounds(robot); |
88 |
✓✓ | 4528 |
for (std::size_t i = 0; i < 3; ++i) { |
89 |
✓✗ | 3396 |
config(i) = |
90 |
✓✗ | 6792 |
std::min(bounds[2 * i + 1], std::max(bounds[2 * i], translation[i])); |
91 |
} |
||
92 |
1132 |
} |
|
93 |
|||
94 |
47263 |
void Translate(const pinocchio::RbPrmDevicePtr_t robot, Configuration_t& config, |
|
95 |
const Vec3f& translation) { |
||
96 |
// bound to positions limits |
||
97 |
✓✗ | 94526 |
std::vector<double> bounds = getTranslationBounds(robot); |
98 |
✓✓ | 189052 |
for (int i = 0; i < 3; ++i) { |
99 |
✓✗ | 283578 |
config(i) = std::min(bounds[2 * i + 1], |
100 |
✓✗✓✗ |
425367 |
std::max(bounds[2 * i], config(i) + translation[i])); |
101 |
} |
||
102 |
47263 |
} |
|
103 |
|||
104 |
/*void SampleRotationRec(ConfigurationPtr_t config, JointVector_t& jv, |
||
105 |
std::size_t& current) |
||
106 |
{ |
||
107 |
JointPtr_t joint = jv[current++]; |
||
108 |
std::size_t rank = joint->rankInConfiguration (); |
||
109 |
const hpp::pinocchio::LiegroupSpacePtr_t jm = joint->configurationSpace(); |
||
110 |
jm->neutral().setNeutral(); setRandom (); |
||
111 |
hpp::pinocchio::LiegroupSpace toto; |
||
112 |
//toto/ |
||
113 |
joint->jointModel()-> configuration ()->uniformlySample (rank, *config); |
||
114 |
if(current<jv.size()) |
||
115 |
SampleRotationRec(config,jv,current); |
||
116 |
}*/ |
||
117 |
|||
118 |
1132 |
void SampleRotation(const std::vector<double>& so3, Configuration_t& config) { |
|
119 |
✗✓ | 1132 |
if (so3.empty()) return; |
120 |
✗✓ | 1132 |
assert(so3.size() == SIZE_EULER); |
121 |
✓✗ | 1132 |
Eigen::Vector3d rot; |
122 |
✓✓ | 4528 |
for (int i = 0; i < 6; i += 2) { |
123 |
✓✗ | 3396 |
rot[i / 2] = so3[i] + (so3[i + 1] - so3[i]) * rand() / RAND_MAX; |
124 |
// std::cout << "rot i " << rot [i/2] << " i " << i/2 << std::endl; |
||
125 |
} |
||
126 |
|||
127 |
✓✗✓✗ ✓✗✓✗ |
1132 |
Eigen::Quaterniond qt = Eigen::AngleAxisd(rot(0), Eigen::Vector3d::UnitZ()) * |
128 |
✓✗✓✗ ✓✗ |
1132 |
Eigen::AngleAxisd(rot(1), Eigen::Vector3d::UnitY()) * |
129 |
✓✗✓✗ ✓✗✓✗ |
2264 |
Eigen::AngleAxisd(rot(2), Eigen::Vector3d::UnitX()); |
130 |
1132 |
std::size_t rank = 3; |
|
131 |
/*for(std::size_t i = 0; i <4; ++i) |
||
132 |
{ |
||
133 |
config(rank+i) = qt.coeffs()(i); |
||
134 |
}*/ |
||
135 |
✓✗✓✗ |
1132 |
config.segment<4>(rank) = qt.coeffs(); |
136 |
} |
||
137 |
|||
138 |
/*void SampleRotation(pinocchio::DevicePtr_t so3, ConfigurationPtr_t config, |
||
139 |
JointVector_t& jv) |
||
140 |
{ |
||
141 |
std::size_t id = 1; |
||
142 |
if(so3->rootJoint()) |
||
143 |
{ |
||
144 |
Eigen::Matrix <value_type, 3, 1> confso3; |
||
145 |
id+=1; |
||
146 |
pinocchio::JointPtr_t joint = so3->rootJoint(); |
||
147 |
for(int i =0; i <3; ++i) |
||
148 |
{ |
||
149 |
joint->configuration()->uniformlySample (i, confso3); |
||
150 |
joint = joint->numberChildJoints() > 0 ? joint->childJoint(0) : 0; |
||
151 |
} |
||
152 |
Eigen::Quaterniond qt = Eigen::AngleAxisd(confso3(0), |
||
153 |
Eigen::Vector3d::UnitZ()) |
||
154 |
* Eigen::AngleAxisd(confso3(1), Eigen::Vector3d::UnitY()) |
||
155 |
* Eigen::AngleAxisd(confso3(2), Eigen::Vector3d::UnitX()); |
||
156 |
std::size_t rank = 3; |
||
157 |
(*config)(rank+0) = qt.w(); |
||
158 |
(*config)(rank+1) = qt.x(); |
||
159 |
(*config)(rank+2) = qt.y(); |
||
160 |
(*config)(rank+3) = qt.z(); |
||
161 |
} |
||
162 |
if(id < jv.size()) |
||
163 |
SampleRotationRec(config,jv,id); |
||
164 |
}*/ |
||
165 |
|||
166 |
/*std::vector<double> initSo3() |
||
167 |
{ |
||
168 |
std::vector<double> res; |
||
169 |
int sign = -1; |
||
170 |
for (int i =0; i<6; ++i) |
||
171 |
{ |
||
172 |
res.push_back(sign * std::numeric_limits<double>::infinity()); |
||
173 |
sign *= -1; |
||
174 |
} |
||
175 |
//DevicePtr_t so3Robot = pinocchio::Device::create("so3Robot"); |
||
176 |
//so3Robot->rootJoint(0); |
||
177 |
return res; |
||
178 |
}*/ |
||
179 |
|||
180 |
37 |
void seRotationtLimits(std::vector<double>& so3Robot, |
|
181 |
const std::vector<double>& limitszyx) { |
||
182 |
✗✓ | 37 |
assert(SIZE_EULER == limitszyx.size()); |
183 |
37 |
so3Robot = limitszyx; |
|
184 |
/*pinocchio::Joint* previous = so3Robot->rootJoint(); |
||
185 |
if(previous == 0) |
||
186 |
{ |
||
187 |
// init joints |
||
188 |
previous = new pinocchio::jointRotation::Bounded(fcl::Transform3f()); |
||
189 |
pinocchio::Joint * jy = new |
||
190 |
pinocchio::jointRotation::Bounded(fcl::Transform3f()); pinocchio::Joint * jx = |
||
191 |
new pinocchio::jointRotation::Bounded(fcl::Transform3f()); |
||
192 |
so3Robot->rootJoint(previous); |
||
193 |
previous->addChildJoint (jy); |
||
194 |
jy->addChildJoint (jx); |
||
195 |
previous->name("so3z"); |
||
196 |
jy->name("so3y"); |
||
197 |
jx->name("so3x"); |
||
198 |
} |
||
199 |
// set limits pinocchio::JointPtr_t |
||
200 |
assert(limitszyx.size() == 6); |
||
201 |
int i = 0; |
||
202 |
pinocchio::JointPtr_t current = previous; |
||
203 |
for(std::vector<double>::const_iterator cit = limitszyx.begin(); |
||
204 |
cit != limitszyx.end(); ++cit, ++i) |
||
205 |
{ |
||
206 |
if(i % 2 == 0) |
||
207 |
{ |
||
208 |
current->lowerBound(0, *cit); |
||
209 |
} |
||
210 |
else |
||
211 |
{ |
||
212 |
current->upperBound(0, *cit); |
||
213 |
current = current->numberChildJoints() > 0 ? current->childJoint(0) : |
||
214 |
0; |
||
215 |
} |
||
216 |
}*/ |
||
217 |
37 |
} |
|
218 |
|||
219 |
} // namespace |
||
220 |
|||
221 |
namespace rbprm { |
||
222 |
|||
223 |
37 |
RbPrmShooterPtr_t RbPrmShooter::create( |
|
224 |
const pinocchio::RbPrmDevicePtr_t& robot, |
||
225 |
const ObjectStdVector_t& geometries, const affMap_t& affordances, |
||
226 |
const std::vector<std::string>& filter, |
||
227 |
const std::map<std::string, std::vector<std::string> >& affFilters, |
||
228 |
const std::size_t shootLimit, const std::size_t displacementLimit) { |
||
229 |
37 |
unsigned int seed = (unsigned int)(time(NULL)); |
|
230 |
37 |
srand(seed); |
|
231 |
hppDout(notice, "&&&&&& SEED = " << seed); |
||
232 |
RbPrmShooter* ptr = |
||
233 |
new RbPrmShooter(robot, geometries, affordances, filter, affFilters, |
||
234 |
✓✗ | 37 |
shootLimit, displacementLimit); |
235 |
|||
236 |
37 |
RbPrmShooterPtr_t shPtr(ptr); |
|
237 |
✓✗ | 37 |
ptr->init(shPtr); |
238 |
37 |
return shPtr; |
|
239 |
} |
||
240 |
|||
241 |
37 |
void RbPrmShooter::init(const RbPrmShooterPtr_t& self) { |
|
242 |
37 |
ConfigurationShooter::init(self); |
|
243 |
37 |
weak_ = self; |
|
244 |
37 |
} |
|
245 |
|||
246 |
37 |
void RbPrmShooter::BoundSO3(const std::vector<double>& limitszyx) { |
|
247 |
37 |
seRotationtLimits(eulerSo3_, limitszyx); |
|
248 |
37 |
} |
|
249 |
|||
250 |
/** |
||
251 |
* @brief getUsedSurfaces produce a list of CollisionObject from the affordances |
||
252 |
* list : use all objects corresponding to at least one affordance filter set. |
||
253 |
* @param affordances |
||
254 |
* @param affFilters |
||
255 |
* @return |
||
256 |
*/ |
||
257 |
37 |
hpp::core::ObjectStdVector_t getUsedSurfaces( |
|
258 |
const affMap_t& affordances, |
||
259 |
const std::map<std::string, std::vector<std::string> >& affFilters) { |
||
260 |
37 |
core::ObjectStdVector_t surfaces; |
|
261 |
74 |
std::set<std::string> addedTypes; |
|
262 |
hppDout(notice, "Begin getUsedSurfaces from affordances"); |
||
263 |
82 |
for (std::map<std::string, std::vector<std::string> >::const_iterator |
|
264 |
37 |
itFilter = affFilters.begin(); |
|
265 |
✓✓ | 201 |
itFilter != affFilters.end(); ++itFilter) { // for each roms |
266 |
hppDout(notice, "For rom : " << itFilter->first); |
||
267 |
82 |
for (std::vector<std::string>::const_iterator itType = |
|
268 |
82 |
itFilter->second.begin(); |
|
269 |
✓✓ | 246 |
itType != itFilter->second.end(); ++itType) { |
270 |
hppDout(notice, "aff type : " << *itType); |
||
271 |
✓✓✗✓ |
127 |
if (addedTypes.empty() || |
272 |
✓✗✓✓ |
127 |
(addedTypes.find(*itType) == addedTypes.end())) { |
273 |
hppDout(notice, |
||
274 |
"new type of affordance, add corresponding collision objects " |
||
275 |
"to the list"); |
||
276 |
✓✗ | 37 |
addedTypes.insert(*itType); |
277 |
✓✗✓✗ |
37 |
if (affordances.map.find(*itType) != affordances.map.end()) { |
278 |
✓✗ | 37 |
affMap_t::const_iterator itAff = affordances.map.find(*itType); |
279 |
87 |
for (AffordanceObjects_t::const_iterator itObj = |
|
280 |
37 |
itAff->second.begin(); |
|
281 |
✓✓ | 211 |
itObj != itAff->second.end(); ++itObj) { |
282 |
✓✗ | 87 |
surfaces.push_back(itObj->second); |
283 |
} |
||
284 |
} |
||
285 |
} |
||
286 |
} |
||
287 |
} |
||
288 |
hppDout(notice, "final size of surfaces list : " << surfaces.size()); |
||
289 |
74 |
return surfaces; |
|
290 |
} |
||
291 |
|||
292 |
// TODO: outward |
||
293 |
|||
294 |
37 |
RbPrmShooter::RbPrmShooter( |
|
295 |
const pinocchio::RbPrmDevicePtr_t& robot, |
||
296 |
const hpp::core::ObjectStdVector_t& geometries, const affMap_t& affordances, |
||
297 |
const std::vector<std::string>& filter, |
||
298 |
const std::map<std::string, std::vector<std::string> >& affFilters, |
||
299 |
37 |
const std::size_t shootLimit, const std::size_t displacementLimit) |
|
300 |
: shootLimit_(shootLimit), |
||
301 |
displacementLimit_(displacementLimit), |
||
302 |
filter_(filter), |
||
303 |
weights_(), |
||
304 |
triangles_(), |
||
305 |
robot_(robot), |
||
306 |
37 |
validator_(rbprm::RbPrmValidation::create(robot_, filter, affFilters, |
|
307 |
affordances, geometries)), |
||
308 |
uniformShooter_(core::configurationShooter::Uniform::create(robot)), |
||
309 |
✓✗✓✗ ✓✗ |
37 |
ratioWeighted_(0.3) { |
310 |
469 |
for (hpp::core::ObjectStdVector_t::const_iterator cit = geometries.begin(); |
|
311 |
✓✓ | 469 |
cit != geometries.end(); ++cit) { |
312 |
✓✗ | 432 |
validator_->addObstacle(*cit); |
313 |
} |
||
314 |
✓✗✓✗ |
37 |
this->InitWeightedTriangles(getUsedSurfaces(affordances, affFilters)); |
315 |
37 |
} |
|
316 |
|||
317 |
37 |
void RbPrmShooter::InitWeightedTriangles( |
|
318 |
const core::ObjectStdVector_t& geometries) { |
||
319 |
37 |
double sum = 0; |
|
320 |
124 |
for (core::ObjectStdVector_t::const_iterator objit = geometries.begin(); |
|
321 |
✓✓ | 211 |
objit != geometries.end(); ++objit) { |
322 |
✓✗ | 87 |
const pinocchio::FclConstCollisionObjectPtr_t colObj = (*objit)->fcl(); |
323 |
✓✗ | 174 |
BVHModelOBConst_Ptr_t model = GetModel(colObj); // TODO NOT TRIANGLES |
324 |
✓✓ | 261 |
for (int i = 0; i < model->num_tris; ++i) { |
325 |
✓✗ | 174 |
TrianglePoints tri; |
326 |
174 |
Triangle fcltri = model->tri_indices[i]; |
|
327 |
✓✗✓✗ |
174 |
tri.p1 = colObj->getRotation() * model->vertices[fcltri[0]] + |
328 |
✓✗ | 348 |
colObj->getTranslation(); |
329 |
✓✗✓✗ |
174 |
tri.p2 = colObj->getRotation() * model->vertices[fcltri[1]] + |
330 |
✓✗ | 348 |
colObj->getTranslation(); |
331 |
✓✗✓✗ |
174 |
tri.p3 = colObj->getRotation() * model->vertices[fcltri[2]] + |
332 |
✓✗ | 348 |
colObj->getTranslation(); |
333 |
✓✗ | 174 |
double weight = TriangleArea(tri); |
334 |
hppDout(notice, "Area of triangle = " << weight); |
||
335 |
174 |
sum += weight; |
|
336 |
✓✗ | 174 |
weights_.push_back(weight); |
337 |
✓✗✓✗ ✓✗ |
174 |
fcl::Vec3f normal = (tri.p2 - tri.p1).cross(tri.p3 - tri.p1); |
338 |
✓✗ | 174 |
normal.normalize(); |
339 |
✓✗✓✗ |
174 |
triangles_.push_back(std::make_pair(normal, tri)); |
340 |
} |
||
341 |
} |
||
342 |
37 |
double previousWeight = 0; |
|
343 |
hppDout(notice, "Sum of all areas of triangles : " << sum); |
||
344 |
211 |
for (std::vector<double>::iterator wit = weights_.begin(); |
|
345 |
✓✓ | 211 |
wit != weights_.end(); ++wit) { |
346 |
174 |
previousWeight += (*wit) / sum; |
|
347 |
174 |
(*wit) = previousWeight; |
|
348 |
hppDout(notice, "current weight = " << previousWeight); |
||
349 |
} |
||
350 |
hppDout(notice, "number of triangle for the shooter : " << triangles_.size()); |
||
351 |
37 |
} |
|
352 |
|||
353 |
697 |
const RbPrmShooter::T_TriangleNormal& RbPrmShooter::RandomPointIntriangle() |
|
354 |
const { |
||
355 |
697 |
return triangles_[rand() % triangles_.size()]; |
|
356 |
} |
||
357 |
|||
358 |
297 |
const RbPrmShooter::T_TriangleNormal& RbPrmShooter::WeightedTriangle() const { |
|
359 |
297 |
double r = ((double)rand() / (RAND_MAX)); |
|
360 |
297 |
std::vector<T_TriangleNormal>::const_iterator trit = triangles_.begin(); |
|
361 |
1770 |
for (std::vector<double>::const_iterator wit = weights_.begin(); |
|
362 |
✓✗ | 3243 |
wit != weights_.end(); ++wit, ++trit) { |
363 |
✓✓ | 1770 |
if (*wit >= r) return *trit; |
364 |
} |
||
365 |
return triangles_[triangles_.size() - 1]; // not supposed to happen |
||
366 |
} |
||
367 |
|||
368 |
1132 |
void RbPrmShooter::randConfigAtPos(const pinocchio::RbPrmDevicePtr_t robot, |
|
369 |
const std::vector<double>& eulerSo3, |
||
370 |
Configuration_t& config, |
||
371 |
const Vec3f p) const { |
||
372 |
1132 |
uniformShooter_->shoot(config); |
|
373 |
✓✗ | 1132 |
SetConfigTranslation(robot, config, p); |
374 |
1132 |
SampleRotation(eulerSo3, config); |
|
375 |
1132 |
} |
|
376 |
|||
377 |
47139 |
fcl::Vec3f normalFromTriangleContact( |
|
378 |
const Contact& c, hpp::core::CollisionObjectConstPtr_t colObj) { |
||
379 |
47139 |
int i = c.b2; |
|
380 |
✓✗ | 47139 |
TrianglePoints tri; |
381 |
✓✗✓✗ |
94278 |
BVHModelOBConst_Ptr_t model = GetModel(colObj->fcl()); // TODO NOT TRIANGLES |
382 |
✓✗ | 47139 |
fcl::Vec3f normal; |
383 |
✓✗ | 47139 |
if (model) { |
384 |
47139 |
Triangle fcltri = model->tri_indices[i]; |
|
385 |
✓✗✓✗ ✓✗ |
47139 |
tri.p1 = colObj->fcl()->getRotation() * model->vertices[fcltri[0]] + |
386 |
✓✗✓✗ |
94278 |
colObj->fcl()->getTranslation(); |
387 |
✓✗✓✗ ✓✗ |
47139 |
tri.p2 = colObj->fcl()->getRotation() * model->vertices[fcltri[1]] + |
388 |
✓✗✓✗ |
94278 |
colObj->fcl()->getTranslation(); |
389 |
✓✗✓✗ ✓✗ |
47139 |
tri.p3 = colObj->fcl()->getRotation() * model->vertices[fcltri[2]] + |
390 |
✓✗✓✗ |
94278 |
colObj->fcl()->getTranslation(); |
391 |
✓✗✓✗ ✓✗ |
47139 |
normal = (tri.p2 - tri.p1).cross(tri.p3 - tri.p1); |
392 |
} else { |
||
393 |
hppDout(warning, |
||
394 |
"In shooter : cannot get contact normal, use z axis by default."); |
||
395 |
normal = fcl::Vec3f(0, 0, 1); |
||
396 |
} |
||
397 |
✓✗ | 94278 |
return normal.normalized(); |
398 |
} |
||
399 |
|||
400 |
431 |
void RbPrmShooter::impl_shoot(hpp::core::Configuration_t& config) const { |
|
401 |
hppDout(notice, "!!! Random shoot"); |
||
402 |
HPP_DEFINE_TIMECOUNTER(SHOOT_COLLISION); |
||
403 |
431 |
uniformShooter_->shoot(config); |
|
404 |
431 |
std::size_t limit = shootLimit_; |
|
405 |
431 |
bool found(false); |
|
406 |
✓✗✓✓ |
1425 |
while (limit > 0 && !found) { |
407 |
// pick one triangle randomly |
||
408 |
994 |
const T_TriangleNormal* sampled(0); |
|
409 |
994 |
double r = ((double)rand() / (RAND_MAX)); |
|
410 |
✓✓ | 994 |
if (r > ratioWeighted_) |
411 |
✓✗ | 697 |
sampled = &RandomPointIntriangle(); |
412 |
else |
||
413 |
✓✗ | 297 |
sampled = &WeightedTriangle(); |
414 |
994 |
const TrianglePoints& tri = sampled->second; |
|
415 |
// http://stackoverflow.com/questions/4778147/sample-random-point-in-triangle |
||
416 |
double r1, r2; |
||
417 |
994 |
r1 = ((double)rand() / (RAND_MAX)); |
|
418 |
994 |
r2 = ((double)rand() / (RAND_MAX)); |
|
419 |
✓✗✓✗ ✓✗✓✗ |
994 |
Vec3f p = (1 - sqrt(r1)) * tri.p1 + (sqrt(r1) * (1 - r2)) * tri.p2 + |
420 |
✓✗✓✗ |
1988 |
(sqrt(r1) * r2) * tri.p3; |
421 |
994 |
const Vec3f& n = sampled->first; |
|
422 |
|||
423 |
// set configuration position to sampled point |
||
424 |
✓✗✓✗ |
994 |
randConfigAtPos(robot_, eulerSo3_, config, p); |
425 |
// rotate and translate randomly until valid configuration found or |
||
426 |
// no obstacle is reachable |
||
427 |
✓✗✓✗ ✓✗ |
994 |
ValidationReportPtr_t reportShPtr(new RbprmValidationReport); |
428 |
994 |
std::size_t limitDis = displacementLimit_; |
|
429 |
✓✗ | 994 |
Vec3f lastDirection = n; |
430 |
✓✓✓✓ |
48564 |
while (!found && limitDis > 0) { |
431 |
HPP_START_TIMECOUNTER(SHOOT_COLLISION); |
||
432 |
✓✗ | 47671 |
found = validator_->validate(config, reportShPtr, filter_); |
433 |
RbprmValidationReportPtr_t report = |
||
434 |
47671 |
dynamic_pointer_cast<RbprmValidationReport>(reportShPtr); |
|
435 |
✓✓✓✓ |
47671 |
bool valid = found || !report->trunkInCollision; |
436 |
HPP_STOP_TIMECOUNTER(SHOOT_COLLISION); |
||
437 |
|||
438 |
✓✓ | 47671 |
if (valid & !found) { |
439 |
// try to rotate to reach rom |
||
440 |
✓✗✓✓ ✓✓ |
253 |
for (; limitDis > 0 && !found && valid; --limitDis) { |
441 |
// SampleRotation(eulerSo3_, config); |
||
442 |
✓✗✓✗ |
138 |
randConfigAtPos(robot_, eulerSo3_, config, p); |
443 |
HPP_START_TIMECOUNTER(SHOOT_COLLISION); |
||
444 |
✓✗ | 138 |
found = validator_->validate(config, reportShPtr, filter_); |
445 |
HPP_STOP_TIMECOUNTER(SHOOT_COLLISION); |
||
446 |
✓✓ | 138 |
if (!found) { |
447 |
✓✗✓✗ |
124 |
Translate(robot_, config, |
448 |
✓✗✓✗ ✓✗ |
248 |
-lastDirection * 0.2 * ((double)rand() / (RAND_MAX))); |
449 |
} |
||
450 |
HPP_START_TIMECOUNTER(SHOOT_COLLISION); |
||
451 |
✓✗ | 138 |
found = validator_->validate(config, reportShPtr, filter_); |
452 |
138 |
report = dynamic_pointer_cast<RbprmValidationReport>(reportShPtr); |
|
453 |
✓✓✓✓ |
138 |
valid = found || !report->trunkInCollision; |
454 |
// found = validator_->validate(config, filter_); |
||
455 |
HPP_STOP_TIMECOUNTER(SHOOT_COLLISION); |
||
456 |
} |
||
457 |
✓✓ | 115 |
if (!found) break; |
458 |
✓✓ | 47556 |
} else if (!valid) // move out of collision |
459 |
{ |
||
460 |
// retrieve Contact information |
||
461 |
47139 |
report = dynamic_pointer_cast<RbprmValidationReport>(reportShPtr); |
|
462 |
✓✗✓✗ |
94278 |
lastDirection = normalFromTriangleContact(report->result.getContact(0), |
463 |
94278 |
report->object2); |
|
464 |
✓✗✓✗ |
94278 |
Translate( |
465 |
47139 |
robot_, config, |
|
466 |
lastDirection * |
||
467 |
✓✗✓✗ |
47139 |
(std::abs(report->result.getContact(0).penetration_depth) + |
468 |
0.03)); |
||
469 |
47139 |
limitDis--; |
|
470 |
} |
||
471 |
} |
||
472 |
994 |
limit--; |
|
473 |
} |
||
474 |
✗✓ | 431 |
if (!found) std::cout << "no config found" << std::endl; |
475 |
hppDout(info, "shoot : " << pinocchio::displayConfig(config)); |
||
476 |
HPP_DISPLAY_TIMECOUNTER(SHOOT_COLLISION); |
||
477 |
431 |
} |
|
478 |
|||
479 |
void RbPrmShooter::sampleExtraDOF(bool sampleExtraDOF) { |
||
480 |
uniformShooter_->sampleExtraDOF(sampleExtraDOF); |
||
481 |
} |
||
482 |
|||
483 |
3 |
HPP_START_PARAMETER_DECLARATION(RbprmShooter) |
|
484 |
✓✗✓✗ ✓✗✓✗ |
3 |
Problem::declareParameter(core::ParameterDescription( |
485 |
core::Parameter::FLOAT, "RbprmShooter/ratioWeighted", |
||
486 |
"The ratio used to select a random triangle with a weight proportional to " |
||
487 |
"it's area. " |
||
488 |
"Otherwise the triangles are choosed uniformly. ", |
||
489 |
✓✗ | 6 |
core::Parameter(0.3))); |
490 |
3 |
HPP_END_PARAMETER_DECLARATION(RbprmShooter) |
|
491 |
|||
492 |
} // namespace rbprm |
||
493 |
} // namespace hpp |
Generated by: GCOVR (Version 4.2) |