GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#include <hpp/fcl/BVH/BVH_model.h> |
||
2 |
#include <hpp/fcl/mesh_loader/assimp.h> |
||
3 |
|||
4 |
#include <hpp/pinocchio/urdf/util.hh> |
||
5 |
#include <hpp/rbprm/contact_generation/kinematics_constraints.hh> |
||
6 |
#include <hpp/rbprm/rbprm-device.hh> |
||
7 |
#include <hpp/rbprm/rbprm-fullbody.hh> |
||
8 |
#include <pinocchio/multibody/geometry.hpp> |
||
9 |
#include <pinocchio/parsers/utils.hpp> |
||
10 |
#include <pinocchio/utils/file-explorer.hpp> |
||
11 |
|||
12 |
namespace hpp { |
||
13 |
namespace rbprm { |
||
14 |
namespace reachability { |
||
15 |
|||
16 |
typedef fcl::BVHModel<fcl::OBBRSS> PolyhedronType; |
||
17 |
typedef fcl::shared_ptr<PolyhedronType> PolyhedronPtrType; |
||
18 |
|||
19 |
1166 |
VectorX triangleNormal(const PolyhedronPtrType& obj, size_t index) { |
|
20 |
✓✗ | 2332 |
VectorX normal(3); |
21 |
// access a vertice of faceId with : obj->vertices[obj->tri_indices[index](i)] |
||
22 |
// outward normal of triangle : (tri.p2 - tri.p1).cross(tri.p3 - tri.p1); |
||
23 |
/*hppDout(notice,"Face : "<<index); |
||
24 |
hppDout(notice,"0 - "<<obj->vertices[obj->tri_indices[index][0]]); |
||
25 |
hppDout(notice,"1 - "<<obj->vertices[obj->tri_indices[index][1]]); |
||
26 |
hppDout(notice,"2 - "<<obj->vertices[obj->tri_indices[index][2]]); |
||
27 |
*/ |
||
28 |
✓✗ | 1166 |
normal = (obj->vertices[obj->tri_indices[index][1]] - |
29 |
1166 |
obj->vertices[obj->tri_indices[index][0]]) |
|
30 |
✓✗✓✗ |
1166 |
.cross(obj->vertices[obj->tri_indices[index][2]] - |
31 |
✓✗ | 2332 |
obj->vertices[obj->tri_indices[index][0]]); |
32 |
✓✗ | 2332 |
return normal.normalized(); |
33 |
} |
||
34 |
|||
35 |
VectorX triangleNormalTransform(const PolyhedronPtrType& obj, size_t index, |
||
36 |
fcl::Transform3f T) { |
||
37 |
VectorX normal(3); |
||
38 |
// access a vertice of faceId with : obj->vertices[obj->tri_indices[index](i)] |
||
39 |
// outward normal of triangle : (tri.p2 - tri.p1).cross(tri.p3 - tri.p1); |
||
40 |
/*hppDout(notice,"Face : "<<index); |
||
41 |
hppDout(notice,"0 - "<<obj->vertices[obj->tri_indices[index][0]]); |
||
42 |
hppDout(notice,"1 - "<<obj->vertices[obj->tri_indices[index][1]]); |
||
43 |
hppDout(notice,"2 - "<<obj->vertices[obj->tri_indices[index][2]]); |
||
44 |
*/ |
||
45 |
fcl::Vec3f t0, t1, t2; |
||
46 |
t0 = T.transform(obj->vertices[obj->tri_indices[index][0]]); |
||
47 |
t1 = T.transform(obj->vertices[obj->tri_indices[index][1]]); |
||
48 |
t2 = T.transform(obj->vertices[obj->tri_indices[index][2]]); |
||
49 |
normal = (t1 - t0).cross(t2 - t0); |
||
50 |
return normal.normalized(); |
||
51 |
} |
||
52 |
|||
53 |
} // namespace reachability |
||
54 |
} // namespace rbprm |
||
55 |
} // namespace hpp |
||
56 |
|||
57 |
std::pair<hpp::rbprm::MatrixX3, hpp::rbprm::MatrixX3> |
||
58 |
10 |
hpp::rbprm::reachability::loadConstraintsFromObj(const std::string& fileName, |
|
59 |
double minDistance) { |
||
60 |
hppDout(notice, "Load constraints for filename : " << fileName); |
||
61 |
|||
62 |
✓✗ | 20 |
std::vector<std::string> package_dirs = ::pinocchio::rosPaths(); |
63 |
std::string meshPath = |
||
64 |
✓✗ | 20 |
::pinocchio::retrieveResourcePath(fileName, package_dirs); |
65 |
✗✓ | 10 |
if (meshPath == "") { |
66 |
hppDout(warning, "Unable to load kinematics constraints : " |
||
67 |
<< "Mesh " << fileName << " could not be found."); |
||
68 |
return std::pair<hpp::rbprm::MatrixX3, hpp::rbprm::MatrixX3>(); |
||
69 |
} |
||
70 |
|||
71 |
// pinocchio::urdf::Parser parser("anchor",pinocchio::DevicePtr_t()); |
||
72 |
hpp::rbprm::reachability::PolyhedronPtrType polyhedron( |
||
73 |
✓✗✓✗ ✓✗ |
20 |
new hpp::rbprm::reachability::PolyhedronType); |
74 |
// name is stored in link->name |
||
75 |
try { |
||
76 |
✓✗✓✗ |
10 |
fcl::loadPolyhedronFromResource(meshPath, hpp::rbprm::Vector3(1, 1, 1), |
77 |
polyhedron); |
||
78 |
} catch (std::runtime_error e) { |
||
79 |
hppDout(warning, "Unable to load kinematics constraints : " << e.what()); |
||
80 |
return std::pair<hpp::rbprm::MatrixX3, hpp::rbprm::MatrixX3>(); |
||
81 |
} |
||
82 |
|||
83 |
// iterate over all faces : for each faces add a line in A : normal and a |
||
84 |
// value in b : position of a vertice.dot(normal) |
||
85 |
10 |
size_t numFaces = polyhedron->num_tris; |
|
86 |
hppDout(notice, "Num faces : " << numFaces); |
||
87 |
10 |
size_t numIneq = numFaces; |
|
88 |
✓✗ | 10 |
if (minDistance > 0) { |
89 |
10 |
numIneq++; |
|
90 |
} |
||
91 |
✓✗ | 20 |
hpp::rbprm::MatrixX3 N(numIneq, 3); |
92 |
✓✗ | 20 |
hpp::rbprm::MatrixX3 V(numIneq, 3); |
93 |
|||
94 |
✓✗✓✗ |
20 |
hpp::rbprm::VectorX n, v; |
95 |
✓✓ | 1176 |
for (size_t fId = 0; fId < numFaces; ++fId) { |
96 |
// hppDout(notice,"For face : "<<fId); |
||
97 |
✓✗ | 1166 |
n = hpp::rbprm::reachability::triangleNormal(polyhedron, fId); |
98 |
✓✗ | 1166 |
v = polyhedron->vertices[polyhedron->tri_indices[fId][0]]; |
99 |
// hppDout(notice,"normal : "<<n.transpose()); |
||
100 |
// hppDout(notice,"vertice: "<<v.transpose()); |
||
101 |
✓✗✓✗ |
1166 |
N.block<1, 3>(fId, 0) = n; |
102 |
✓✗✓✗ |
1166 |
V.block<1, 3>(fId, 0) = v; |
103 |
} |
||
104 |
|||
105 |
✓✗ | 10 |
if (minDistance > 0) { |
106 |
✓✗✓✗ ✓✗ |
10 |
N.block<1, 3>(numIneq - 1, 0) = hpp::rbprm::Vector3(0, 0, -1); |
107 |
✓✗✓✗ ✓✗ |
10 |
V.block<1, 3>(numIneq - 1, 0) = hpp::rbprm::Vector3(0, 0, minDistance); |
108 |
} |
||
109 |
hppDout(notice, "End of loading kinematic constraints : "); |
||
110 |
// hppDout(notice,"N : "<<N); |
||
111 |
// hppDout(notice,"v : "<<V); |
||
112 |
|||
113 |
✓✗ | 10 |
return std::make_pair(N, V); |
114 |
} |
||
115 |
|||
116 |
namespace hpp { |
||
117 |
namespace rbprm { |
||
118 |
namespace reachability { |
||
119 |
std::pair<MatrixX3, VectorX> computeAllKinematicsConstraints( |
||
120 |
const RbPrmFullBodyPtr_t& fullBody, |
||
121 |
const pinocchio::ConfigurationPtr_t& configuration) { |
||
122 |
fullBody->device_->currentConfiguration(*configuration); |
||
123 |
fullBody->device_->computeForwardKinematics(); |
||
124 |
// first loop to compute size required : |
||
125 |
size_t numIneq = 0; |
||
126 |
for (CIT_Limb lit = fullBody->GetLimbs().begin(); |
||
127 |
lit != fullBody->GetLimbs().end(); ++lit) { |
||
128 |
numIneq += lit->second->kinematicConstraints_.first.rows(); |
||
129 |
} |
||
130 |
MatrixX3 A(numIneq, 3); |
||
131 |
VectorX b(numIneq); |
||
132 |
std::pair<MatrixX3, VectorX> Ab_limb; |
||
133 |
size_t currentId = 0; |
||
134 |
for (CIT_Limb lit = fullBody->GetLimbs().begin(); |
||
135 |
lit != fullBody->GetLimbs().end(); ++lit) { |
||
136 |
if (lit->second->kinematicConstraints_.first.size() > 0) { |
||
137 |
Ab_limb = getInequalitiesAtTransform( |
||
138 |
lit->second->kinematicConstraints_, |
||
139 |
lit->second->effector_.currentTransformation()); |
||
140 |
A.block(currentId, 0, Ab_limb.first.rows(), 3) = Ab_limb.first; |
||
141 |
b.segment(currentId, Ab_limb.first.rows()) = Ab_limb.second; |
||
142 |
currentId += Ab_limb.first.rows(); |
||
143 |
} |
||
144 |
} |
||
145 |
|||
146 |
return std::make_pair(A, b); |
||
147 |
} |
||
148 |
|||
149 |
32 |
std::pair<MatrixX3, VectorX> computeKinematicsConstraintsForState( |
|
150 |
const RbPrmFullBodyPtr_t& fullBody, const State& state) { |
||
151 |
✓✗✓✗ |
32 |
fullBody->device_->currentConfiguration(state.configuration_); |
152 |
✓✗ | 32 |
fullBody->device_->computeForwardKinematics(); |
153 |
hppDout(notice, "Compute kinematics constraints :"); |
||
154 |
// first loop to compute size required : |
||
155 |
32 |
size_t numIneq = 0; |
|
156 |
64 |
for (std::map<std::string, bool>::const_iterator cit = |
|
157 |
32 |
state.contacts_.begin(); |
|
158 |
✓✓ | 160 |
cit != state.contacts_.end(); ++cit) { |
159 |
✓✗ | 64 |
if (cit->second) { // limb with name cit->first is in contact |
160 |
64 |
numIneq += |
|
161 |
✓✗✓✗ ✓✗ |
64 |
fullBody->GetLimb(cit->first)->kinematicConstraints_.first.rows(); |
162 |
hppDout(notice, "Limb : " << cit->first << " is in contact."); |
||
163 |
} |
||
164 |
} |
||
165 |
✓✗ | 64 |
MatrixX3 A(numIneq, 3); |
166 |
✓✗ | 64 |
VectorX b(numIneq); |
167 |
✓✗ | 64 |
std::pair<MatrixX3, VectorX> Ab_limb; |
168 |
32 |
size_t currentId = 0; |
|
169 |
32 |
RbPrmLimbPtr_t limb; |
|
170 |
64 |
for (std::map<std::string, bool>::const_iterator cit = |
|
171 |
32 |
state.contacts_.begin(); |
|
172 |
✓✓ | 160 |
cit != state.contacts_.end(); ++cit) { |
173 |
✓✗ | 64 |
if (cit->second) { // limb with name cit->first is in contact |
174 |
✓✗✓✗ |
64 |
limb = fullBody->GetLimb(cit->first); |
175 |
✓✗ | 128 |
Ab_limb = getInequalitiesAtTransform( |
176 |
✓✗✓✗ |
128 |
limb->kinematicConstraints_, limb->effector_.currentTransformation()); |
177 |
✓✗✓✗ ✓✗ |
64 |
A.block(currentId, 0, Ab_limb.first.rows(), 3) = Ab_limb.first; |
178 |
✓✗✓✗ ✓✗ |
64 |
b.segment(currentId, Ab_limb.first.rows()) = Ab_limb.second; |
179 |
✓✗ | 64 |
currentId += Ab_limb.first.rows(); |
180 |
} |
||
181 |
} |
||
182 |
hppDout(notice, "End of kinematics constraints, A size : (" |
||
183 |
<< A.rows() << "," << A.cols() << ")"); |
||
184 |
✓✗ | 64 |
return std::make_pair(A, b); |
185 |
} |
||
186 |
|||
187 |
std::pair<MatrixX3, VectorX> computeKinematicsConstraintsForLimb( |
||
188 |
const RbPrmFullBodyPtr_t& fullBody, const State& state, |
||
189 |
const std::string& limbName) { |
||
190 |
fullBody->device_->currentConfiguration(state.configuration_); |
||
191 |
fullBody->device_->computeForwardKinematics(); |
||
192 |
hppDout(notice, "Compute kinematics constraints for limb :" << limbName); |
||
193 |
// first loop to compute size required : |
||
194 |
if (state.contacts_.find(limbName) == state.contacts_.end()) { |
||
195 |
hppDout(warning, "No Limbs in contact found with name :" << limbName); |
||
196 |
return std::pair<MatrixX3, VectorX>(); |
||
197 |
} |
||
198 |
if (!state.contacts_.at(limbName)) { |
||
199 |
hppDout(warning, |
||
200 |
"Limb " << limbName << " is not in contact for current state"); |
||
201 |
return std::pair<MatrixX3, VectorX>(); |
||
202 |
} |
||
203 |
|||
204 |
RbPrmLimbPtr_t limb = fullBody->GetLimb(limbName); |
||
205 |
return getInequalitiesAtTransform(limb->kinematicConstraints_, |
||
206 |
limb->effector_.currentTransformation()); |
||
207 |
} |
||
208 |
|||
209 |
64 |
std::pair<MatrixX3, VectorX> getInequalitiesAtTransform( |
|
210 |
const std::pair<MatrixX3, MatrixX3>& NV, |
||
211 |
const hpp::pinocchio::Transform3f& transformPin) { |
||
212 |
128 |
fcl::Transform3f transform(transformPin.rotation(), |
|
213 |
✓✗✓✗ ✓✗ |
64 |
transformPin.translation()); |
214 |
✓✗ | 64 |
size_t numIneq = NV.first.rows(); |
215 |
✓✗ | 128 |
MatrixX3 A(numIneq, 3); |
216 |
✓✗ | 128 |
VectorX b(numIneq); |
217 |
✓✗✓✗ |
128 |
VectorX n, v; |
218 |
✓✓ | 9280 |
for (size_t i = 0; i < numIneq; ++i) { |
219 |
✓✗✓✗ ✓✗✓✗ |
9216 |
n = transform.getRotation() * (NV.first.block<1, 3>(i, 0).transpose()); |
220 |
✓✗✓✗ ✓✗✓✗ |
9216 |
v = transform.transform(NV.second.block<1, 3>(i, 0).transpose()); |
221 |
✓✗✓✗ |
9216 |
A.block<1, 3>(i, 0) = n; |
222 |
✓✗✓✗ |
9216 |
b[i] = v.dot(n); |
223 |
} |
||
224 |
// hppDout(notice,"Transform : "<<transform); |
||
225 |
// hppDout(notice,"A : "<<A); |
||
226 |
// hppDout(notice,"b : "<<b); |
||
227 |
✓✗ | 128 |
return std::make_pair(A, b); |
228 |
} |
||
229 |
|||
230 |
bool verifyKinematicConstraints(const std::pair<MatrixX3, MatrixX3>& NV, |
||
231 |
const hpp::pinocchio::Transform3f& transform, |
||
232 |
const fcl::Vec3f& point) { |
||
233 |
return verifyKinematicConstraints(getInequalitiesAtTransform(NV, transform), |
||
234 |
point); |
||
235 |
} |
||
236 |
|||
237 |
bool verifyKinematicConstraints(const std::pair<MatrixX3, VectorX>& Ab, |
||
238 |
const fcl::Vec3f& point) { |
||
239 |
hppDout(notice, "verify kinematic constraints : point = " << point); |
||
240 |
for (size_type i = 0; i < Ab.second.size(); ++i) { |
||
241 |
hppDout(notice, "for i = " << i); |
||
242 |
hppDout(notice, "A = " << (Ab.first.block<1, 3>(i, 0))); |
||
243 |
hppDout(notice, "b = " << Ab.second[i]); |
||
244 |
if (Ab.first.block<1, 3>(i, 0).dot(point) > Ab.second[i]) { |
||
245 |
hppDout(notice, "Constraint not verified !"); |
||
246 |
return false; |
||
247 |
} |
||
248 |
} |
||
249 |
return true; |
||
250 |
} |
||
251 |
|||
252 |
bool verifyKinematicConstraints(const RbPrmFullBodyPtr_t& fullbody, |
||
253 |
const State& state, fcl::Vec3f point) { |
||
254 |
return verifyKinematicConstraints( |
||
255 |
computeKinematicsConstraintsForState(fullbody, state), point); |
||
256 |
} |
||
257 |
|||
258 |
} // namespace reachability |
||
259 |
} // namespace rbprm |
||
260 |
} // namespace hpp |
Generated by: GCOVR (Version 4.2) |