GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
// |
||
2 |
// Copyright (c) 2019-2022 CNRS INRIA |
||
3 |
// |
||
4 |
|||
5 |
#ifndef __pinocchio_algorithm_model_hxx__ |
||
6 |
#define __pinocchio_algorithm_model_hxx__ |
||
7 |
|||
8 |
#include <algorithm> |
||
9 |
|||
10 |
namespace pinocchio |
||
11 |
{ |
||
12 |
namespace details |
||
13 |
{ |
||
14 |
|||
15 |
// Retrieve the joint id in model_out, given the info of model_in. |
||
16 |
// If the user change all the joint names, the universe name won't correspond to the first joint in the tree when searching by name. |
||
17 |
// We thus need to retrieve it with other means, e.g. checking the index of the joints. |
||
18 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl> |
||
19 |
203 |
JointIndex getJointId(const ModelTpl<Scalar,Options,JointCollectionTpl> & model_in, |
|
20 |
const ModelTpl<Scalar,Options,JointCollectionTpl> & model_out, |
||
21 |
const std::string & joint_name_in_model_in) |
||
22 |
{ |
||
23 |
203 |
const JointIndex joint_id = model_in.getJointId(joint_name_in_model_in); |
|
24 |
✗✓ | 203 |
assert(joint_id < model_in.joints.size()); |
25 |
✗✓✗✗ ✗✓ |
203 |
if(joint_id == 0 && model_in.parents[0] == 0) // This is the universe, maybe renamed. |
26 |
return model_out.getJointId(model_out.names[0]); |
||
27 |
else |
||
28 |
203 |
return model_out.getJointId(joint_name_in_model_in); |
|
29 |
} |
||
30 |
|||
31 |
// Retrieve the frame id in model_out, given the info of model_in. |
||
32 |
// If the user change all the frame names, the universe name won't correspond to the first frame in the tree when searching by name. |
||
33 |
// We thus need to retrieve it with other means, e.g. checking the fields of the frames. |
||
34 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl> |
||
35 |
✓✗ | 536 |
FrameIndex getFrameId(const ModelTpl<Scalar,Options,JointCollectionTpl> & model_in, |
36 |
const ModelTpl<Scalar,Options,JointCollectionTpl> & model_out, |
||
37 |
const std::string & frame_name_in_model_in, |
||
38 |
const FrameType & type) |
||
39 |
{ |
||
40 |
✓✗ | 536 |
const FrameIndex frame_id = model_in.getFrameId(frame_name_in_model_in); |
41 |
✗✓ | 536 |
assert(frame_id < model_in.frames.size()); |
42 |
✓✓✓✗ ✓✗✓✓ |
536 |
if(frame_id == 0 && model_in.frames[0].previousFrame == 0 && model_in.frames[0].parent == 0) // This is the universe, maybe renamed. |
43 |
3 |
return model_out.getFrameId(model_out.frames[0].name,type); |
|
44 |
else |
||
45 |
533 |
return model_out.getFrameId(frame_name_in_model_in,type); |
|
46 |
} |
||
47 |
|||
48 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl> |
||
49 |
14 |
void appendUniverseToModel(const ModelTpl<Scalar,Options,JointCollectionTpl> & modelAB, |
|
50 |
const GeometryModel & geomModelAB, |
||
51 |
FrameIndex parentFrame, |
||
52 |
const SE3Tpl<Scalar, Options> & pfMAB, |
||
53 |
ModelTpl<Scalar,Options,JointCollectionTpl> & model, |
||
54 |
GeometryModel & geomModel) |
||
55 |
{ |
||
56 |
typedef ModelTpl<Scalar,Options,JointCollectionTpl> Model; |
||
57 |
typedef typename Model::Frame Frame; |
||
58 |
|||
59 |
✗✓✗✗ |
14 |
PINOCCHIO_THROW(parentFrame < model.frames.size(), |
60 |
std::invalid_argument, |
||
61 |
"parentFrame is greater than the size of the frames vector."); |
||
62 |
|||
63 |
14 |
const Frame & pframe = model.frames[parentFrame]; |
|
64 |
14 |
JointIndex jid = pframe.parent; |
|
65 |
✗✓ | 14 |
assert(jid < model.joints.size()); |
66 |
|||
67 |
// If inertia is not NaN, add it. |
||
68 |
✓✗ | 14 |
if (modelAB.inertias[0] == modelAB.inertias[0]) |
69 |
✓✗ | 14 |
model.appendBodyToJoint (jid, modelAB.inertias[0], pframe.placement * pfMAB); |
70 |
|||
71 |
// Add all frames whose parent is this joint. |
||
72 |
✓✓ | 483 |
for (FrameIndex fid = 1; fid < modelAB.frames.size(); ++fid) |
73 |
{ |
||
74 |
✓✗ | 938 |
Frame frame = modelAB.frames[fid]; |
75 |
✓✓ | 469 |
if (frame.parent == 0) |
76 |
{ |
||
77 |
✓✗✗✓ ✗✗ |
6 |
PINOCCHIO_CHECK_INPUT_ARGUMENT(!model.existFrame(frame.name, frame.type), |
78 |
"The two models have conflicting frame names."); |
||
79 |
|||
80 |
6 |
frame.parent = jid; |
|
81 |
✓✓ | 6 |
if (frame.previousFrame != 0) |
82 |
{ |
||
83 |
✓✗ | 5 |
frame.previousFrame = getFrameId(modelAB,model,modelAB.frames[frame.previousFrame].name, |
84 |
5 |
modelAB.frames[frame.previousFrame].type); |
|
85 |
} |
||
86 |
else |
||
87 |
{ |
||
88 |
1 |
frame.previousFrame = parentFrame; |
|
89 |
} |
||
90 |
|||
91 |
// Modify frame placement |
||
92 |
✓✗✓✗ |
6 |
frame.placement = pframe.placement * pfMAB * frame.placement; |
93 |
✓✗ | 6 |
model.addFrame (frame); |
94 |
} |
||
95 |
} |
||
96 |
|||
97 |
// Add all geometries whose parent is this joint. |
||
98 |
✓✓ | 89 |
for (GeomIndex gid = 0; gid < geomModelAB.geometryObjects.size(); ++gid) |
99 |
{ |
||
100 |
✓✗ | 150 |
GeometryObject go = geomModelAB.geometryObjects[gid]; |
101 |
✓✓ | 75 |
if (go.parentJoint == 0) |
102 |
{ |
||
103 |
1 |
go.parentJoint = jid; |
|
104 |
✓✗ | 1 |
if (go.parentFrame != 0) |
105 |
{ |
||
106 |
✓✗ | 1 |
go.parentFrame = getFrameId(modelAB,model,modelAB.frames[go.parentFrame].name, |
107 |
1 |
modelAB.frames[go.parentFrame].type); |
|
108 |
} |
||
109 |
else |
||
110 |
{ |
||
111 |
go.parentFrame = parentFrame; |
||
112 |
} |
||
113 |
✓✗✓✗ |
1 |
go.placement = pframe.placement * pfMAB * go.placement; |
114 |
✓✗ | 1 |
geomModel.addGeometryObject (go); |
115 |
} |
||
116 |
} |
||
117 |
14 |
} |
|
118 |
|||
119 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl> |
||
120 |
struct AppendJointOfModelAlgoTpl |
||
121 |
: public fusion::JointUnaryVisitorBase< AppendJointOfModelAlgoTpl<Scalar,Options,JointCollectionTpl> > |
||
122 |
{ |
||
123 |
|||
124 |
typedef ModelTpl<Scalar,Options,JointCollectionTpl> Model; |
||
125 |
typedef typename Model::Frame Frame; |
||
126 |
|||
127 |
typedef boost::fusion::vector< |
||
128 |
const Model &, |
||
129 |
const GeometryModel&, |
||
130 |
JointIndex, |
||
131 |
const typename Model::SE3 &, |
||
132 |
Model &, |
||
133 |
GeometryModel& > ArgsType; |
||
134 |
|||
135 |
template <typename JointModel> |
||
136 |
434 |
static void algo (const JointModelBase<JointModel> & jmodel_in, |
|
137 |
const Model & modelAB, |
||
138 |
const GeometryModel & geomModelAB, |
||
139 |
JointIndex parent_id, |
||
140 |
const typename Model::SE3 & pMi, |
||
141 |
Model & model, |
||
142 |
GeometryModel & geomModel) |
||
143 |
{ |
||
144 |
// If old parent is universe, use what's provided in the input. |
||
145 |
// otherwise, get the parent from modelAB. |
||
146 |
434 |
const JointIndex joint_id_in = jmodel_in.id(); |
|
147 |
✓✓ | 434 |
if (modelAB.parents[joint_id_in] > 0) |
148 |
406 |
parent_id = getJointId(modelAB,model,modelAB.names[modelAB.parents[joint_id_in]]); |
|
149 |
|||
150 |
✗✓✗✗ |
434 |
PINOCCHIO_CHECK_INPUT_ARGUMENT(!model.existJointName(modelAB.names[joint_id_in]), |
151 |
"The two models have conflicting joint names."); |
||
152 |
|||
153 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
3038 |
JointIndex joint_id_out = model.addJoint(parent_id, |
154 |
jmodel_in, |
||
155 |
434 |
pMi * modelAB.jointPlacements[joint_id_in], |
|
156 |
434 |
modelAB.names[joint_id_in], |
|
157 |
✓✗ | 434 |
jmodel_in.jointVelocitySelector(modelAB.effortLimit), |
158 |
✓✗ | 434 |
jmodel_in.jointVelocitySelector(modelAB.velocityLimit), |
159 |
✓✗ | 434 |
jmodel_in.jointConfigSelector(modelAB.lowerPositionLimit), |
160 |
✓✗ | 434 |
jmodel_in.jointConfigSelector(modelAB.upperPositionLimit), |
161 |
✓✗ | 434 |
jmodel_in.jointVelocitySelector(modelAB.friction), |
162 |
434 |
jmodel_in.jointVelocitySelector(modelAB.damping)); |
|
163 |
✗✓ | 434 |
assert(joint_id_out < model.joints.size()); |
164 |
|||
165 |
✓✗ | 434 |
model.appendBodyToJoint(joint_id_out, modelAB.inertias[joint_id_in]); |
166 |
|||
167 |
434 |
const typename Model::JointModel & jmodel_out = model.joints[joint_id_out]; |
|
168 |
✓✗✓✗ |
434 |
jmodel_out.jointVelocitySelector(model.rotorInertia) = jmodel_in.jointVelocitySelector(modelAB.rotorInertia); |
169 |
✓✗✓✗ |
434 |
jmodel_out.jointVelocitySelector(model.rotorGearRatio) = jmodel_in.jointVelocitySelector(modelAB.rotorGearRatio); |
170 |
|||
171 |
// Add all frames whose parent is this joint. |
||
172 |
✓✓ | 23036 |
for (FrameIndex fid = 1; fid < modelAB.frames.size(); ++fid) |
173 |
{ |
||
174 |
✓✗ | 45204 |
Frame frame = modelAB.frames[fid]; |
175 |
✓✗✓✓ |
22602 |
if (frame.parent == jmodel_in.id()) |
176 |
{ |
||
177 |
✓✗✗✓ ✗✗ |
926 |
PINOCCHIO_CHECK_INPUT_ARGUMENT(!model.existFrame(frame.name, frame.type), |
178 |
"The two models have conflicting frame names."); |
||
179 |
|||
180 |
926 |
frame.parent = joint_id_out; |
|
181 |
✓✓✗✓ |
926 |
assert (frame.previousFrame > 0 || frame.type == JOINT); |
182 |
✓✓ | 926 |
if (frame.previousFrame != 0) |
183 |
{ |
||
184 |
✓✗ | 902 |
frame.previousFrame = getFrameId(modelAB,model,modelAB.frames[frame.previousFrame].name,modelAB.frames[frame.previousFrame].type); |
185 |
} |
||
186 |
|||
187 |
✓✗ | 926 |
model.addFrame(frame); |
188 |
} |
||
189 |
} |
||
190 |
// Add all geometries whose parent is this joint. |
||
191 |
✓✓ | 3798 |
for(GeomIndex gid = 0; gid < geomModelAB.geometryObjects.size(); ++gid) |
192 |
{ |
||
193 |
✓✗ | 6728 |
GeometryObject go = geomModelAB.geometryObjects[gid]; |
194 |
✓✓ | 3364 |
if(go.parentJoint == joint_id_in) |
195 |
{ |
||
196 |
148 |
go.parentJoint = joint_id_out; |
|
197 |
✗✓ | 148 |
assert(go.parentFrame > 0); |
198 |
✓✗✓✓ ✓✓ |
148 |
if(go.parentFrame != 0 && go.parentFrame < modelAB.frames.size()) |
199 |
{ |
||
200 |
✓✗ | 144 |
go.parentFrame = getFrameId(modelAB,model,modelAB.frames[go.parentFrame].name,modelAB.frames[go.parentFrame].type); |
201 |
} |
||
202 |
✓✗ | 148 |
geomModel.addGeometryObject(go); |
203 |
} |
||
204 |
} |
||
205 |
} |
||
206 |
}; |
||
207 |
|||
208 |
} // namespace details |
||
209 |
|||
210 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl> |
||
211 |
void |
||
212 |
4 |
appendModel(const ModelTpl<Scalar,Options,JointCollectionTpl> & modelA, |
|
213 |
const ModelTpl<Scalar,Options,JointCollectionTpl> & modelB, |
||
214 |
const FrameIndex frameInModelA, |
||
215 |
const SE3Tpl<Scalar, Options> & aMb, |
||
216 |
ModelTpl<Scalar,Options,JointCollectionTpl> & model) |
||
217 |
{ |
||
218 |
✓✗✓✗ ✓✗ |
8 |
GeometryModel geomModelA, geomModelB, geomModel; |
219 |
|||
220 |
✓✗ | 4 |
appendModel(modelA, modelB, geomModelA, geomModelB, frameInModelA, aMb, |
221 |
model, geomModel); |
||
222 |
4 |
} |
|
223 |
|||
224 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl> |
||
225 |
void |
||
226 |
7 |
appendModel(const ModelTpl<Scalar,Options,JointCollectionTpl> & modelA, |
|
227 |
const ModelTpl<Scalar,Options,JointCollectionTpl> & modelB, |
||
228 |
const GeometryModel& geomModelA, |
||
229 |
const GeometryModel& geomModelB, |
||
230 |
const FrameIndex frameInModelA, |
||
231 |
const SE3Tpl<Scalar, Options>& aMb, |
||
232 |
ModelTpl<Scalar,Options,JointCollectionTpl>& model, |
||
233 |
GeometryModel& geomModel) |
||
234 |
{ |
||
235 |
typedef details::AppendJointOfModelAlgoTpl<Scalar, Options, JointCollectionTpl> AppendJointOfModelAlgo; |
||
236 |
typedef typename AppendJointOfModelAlgo::ArgsType ArgsType; |
||
237 |
|||
238 |
✗✓✗✗ |
7 |
PINOCCHIO_CHECK_INPUT_ARGUMENT((bool)(frameInModelA < (FrameIndex) modelA.nframes), |
239 |
"frameInModelA is an invalid Frame index, greater than the number of frames contained in modelA."); |
||
240 |
|||
241 |
typedef ModelTpl<Scalar,Options,JointCollectionTpl> Model; |
||
242 |
typedef typename Model::SE3 SE3; |
||
243 |
typedef typename Model::Frame Frame; |
||
244 |
|||
245 |
7 |
const Frame & frame = modelA.frames[frameInModelA]; |
|
246 |
✓✓✓✗ ✓✗✗✗ |
7 |
static const SE3 id = SE3::Identity(); |
247 |
|||
248 |
7 |
int njoints = modelA.njoints + modelB.njoints - 1; |
|
249 |
7 |
model.names .reserve ((size_t)njoints); |
|
250 |
7 |
model.joints .reserve ((size_t)njoints); |
|
251 |
7 |
model.jointPlacements .reserve ((size_t)njoints); |
|
252 |
7 |
model.parents .reserve ((size_t)njoints); |
|
253 |
7 |
model.inertias .reserve ((size_t)njoints); |
|
254 |
7 |
int nframes = modelA.nframes + modelB.nframes - 1; |
|
255 |
7 |
model.frames .reserve ((size_t)nframes); |
|
256 |
|||
257 |
7 |
geomModel.geometryObjects.reserve (geomModelA.ngeoms + geomModelB.ngeoms); |
|
258 |
|||
259 |
// Copy modelA joints until frame.parentJoint |
||
260 |
7 |
details::appendUniverseToModel (modelA, geomModelA, 0, id, model, geomModel); |
|
261 |
✓✓ | 58 |
for (JointIndex jid = 1; jid <= frame.parent; ++jid) |
262 |
{ |
||
263 |
✓✗ | 51 |
ArgsType args (modelA, geomModelA, 0, id, model, geomModel); |
264 |
✓✗✓✗ |
51 |
AppendJointOfModelAlgo::run (modelA.joints[jid], args); |
265 |
} |
||
266 |
|||
267 |
// Copy modelB joints |
||
268 |
7 |
details::appendUniverseToModel (modelB, geomModelB, |
|
269 |
7 |
details::getFrameId(modelA,model,frame.name,frame.type), aMb, model, geomModel); |
|
270 |
✓✓ | 44 |
for (JointIndex jid = 1; jid < modelB.joints.size(); ++jid) |
271 |
{ |
||
272 |
✓✓✓✗ ✓✗ |
37 |
SE3 pMi = (jid == 1 ? frame.placement * aMb : id); |
273 |
✓✗ | 37 |
ArgsType args (modelB, geomModelB, frame.parent, pMi, model, geomModel); |
274 |
✓✗✓✗ |
37 |
AppendJointOfModelAlgo::run (modelB.joints[jid], args); |
275 |
} |
||
276 |
|||
277 |
// Copy remaining joints of modelA |
||
278 |
✓✓ | 136 |
for (JointIndex jid = frame.parent+1; jid < modelA.joints.size(); ++jid) |
279 |
{ |
||
280 |
✓✗ | 129 |
ArgsType args (modelA, geomModelA, 0, id, model, geomModel); |
281 |
✓✗✓✗ |
129 |
AppendJointOfModelAlgo::run (modelA.joints[jid], args); |
282 |
} |
||
283 |
|||
284 |
#ifdef PINOCCHIO_WITH_HPP_FCL |
||
285 |
// Add collision pairs of geomModelA and geomModelB |
||
286 |
7 |
geomModel.collisionPairs.reserve(geomModelA.collisionPairs.size() |
|
287 |
7 |
+ geomModelB.collisionPairs.size() |
|
288 |
7 |
+ geomModelA.geometryObjects.size() * geomModelB.geometryObjects.size()); |
|
289 |
|||
290 |
✓✓ | 701 |
for (std::size_t icp = 0; icp < geomModelA.collisionPairs.size(); ++icp) |
291 |
{ |
||
292 |
694 |
const CollisionPair& cp = geomModelA.collisionPairs[icp]; |
|
293 |
694 |
GeomIndex go1 = geomModel.getGeometryId(geomModelA.geometryObjects[cp.first ].name); |
|
294 |
694 |
GeomIndex go2 = geomModel.getGeometryId(geomModelA.geometryObjects[cp.second].name); |
|
295 |
✓✗ | 694 |
geomModel.addCollisionPair (CollisionPair (go1, go2)); |
296 |
} |
||
297 |
|||
298 |
✓✓ | 35 |
for (std::size_t icp = 0; icp < geomModelB.collisionPairs.size(); ++icp) |
299 |
{ |
||
300 |
28 |
const CollisionPair & cp = geomModelB.collisionPairs[icp]; |
|
301 |
28 |
GeomIndex go1 = geomModel.getGeometryId(geomModelB.geometryObjects[cp.first ].name); |
|
302 |
28 |
GeomIndex go2 = geomModel.getGeometryId(geomModelB.geometryObjects[cp.second].name); |
|
303 |
✓✗ | 28 |
geomModel.addCollisionPair (CollisionPair (go1, go2)); |
304 |
} |
||
305 |
|||
306 |
// add the collision pairs between geomModelA and geomModelB. |
||
307 |
✓✓ | 68 |
for (Index i = 0; i < geomModelA.geometryObjects.size(); ++i) |
308 |
{ |
||
309 |
61 |
GeomIndex go1 = geomModel.getGeometryId(geomModelA.geometryObjects[i].name); |
|
310 |
✓✓ | 399 |
for (Index j = 0; j < geomModelB.geometryObjects.size(); ++j) |
311 |
{ |
||
312 |
338 |
GeomIndex go2 = geomModel.getGeometryId(geomModelB.geometryObjects[j].name); |
|
313 |
338 |
if ( geomModel.geometryObjects[go1].parentJoint |
|
314 |
✓✗ | 338 |
!= geomModel.geometryObjects[go2].parentJoint) |
315 |
✓✗ | 338 |
geomModel.addCollisionPair(CollisionPair(go1, go2)); |
316 |
} |
||
317 |
} |
||
318 |
#endif |
||
319 |
7 |
} |
|
320 |
|||
321 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl, typename ConfigVectorType> |
||
322 |
void |
||
323 |
15 |
buildReducedModel(const ModelTpl<Scalar,Options,JointCollectionTpl> & input_model, |
|
324 |
std::vector<JointIndex> list_of_joints_to_lock, |
||
325 |
const Eigen::MatrixBase<ConfigVectorType> & reference_configuration, |
||
326 |
ModelTpl<Scalar,Options,JointCollectionTpl> & reduced_model) |
||
327 |
{ |
||
328 |
✓✗✗✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ |
15 |
PINOCCHIO_CHECK_ARGUMENT_SIZE(reference_configuration.size(), input_model.nq, |
329 |
"The configuration vector is not of right size"); |
||
330 |
✗✓✗✗ |
15 |
PINOCCHIO_CHECK_INPUT_ARGUMENT(list_of_joints_to_lock.size() <= (size_t)input_model.njoints, |
331 |
"The number of joints to lock is greater than the total of joints in the reduced_model"); |
||
332 |
|||
333 |
typedef ModelTpl<Scalar,Options,JointCollectionTpl> Model; |
||
334 |
typedef typename Model::JointModel JointModel; |
||
335 |
typedef typename Model::JointData JointData; |
||
336 |
typedef typename Model::Frame Frame; |
||
337 |
typedef typename Model::SE3 SE3; |
||
338 |
|||
339 |
// Sort indexes |
||
340 |
✓✗ | 15 |
std::sort(list_of_joints_to_lock.begin(),list_of_joints_to_lock.end()); |
341 |
|||
342 |
// Check that they are not two identical elements |
||
343 |
✓✓ | 31 |
for(size_t id = 1; id < list_of_joints_to_lock.size(); ++id) |
344 |
{ |
||
345 |
✗✓✗✗ |
16 |
PINOCCHIO_CHECK_INPUT_ARGUMENT(list_of_joints_to_lock[id-1] < list_of_joints_to_lock[id], |
346 |
"The input list_of_joints_to_lock contains two identical indexes."); |
||
347 |
} |
||
348 |
|||
349 |
// Reserve memory |
||
350 |
15 |
const Eigen::DenseIndex njoints = input_model.njoints - (Eigen::DenseIndex)list_of_joints_to_lock.size(); |
|
351 |
✓✗ | 15 |
reduced_model.names .reserve((size_t)njoints); |
352 |
✓✗ | 15 |
reduced_model.joints .reserve((size_t)njoints); |
353 |
✓✗ | 15 |
reduced_model.jointPlacements .reserve((size_t)njoints); |
354 |
✓✗ | 15 |
reduced_model.parents .reserve((size_t)njoints); |
355 |
|||
356 |
✓✗ | 15 |
reduced_model.names[0] = input_model.names[0]; |
357 |
✓✗ | 15 |
reduced_model.joints[0] = input_model.joints[0]; |
358 |
✓✗ | 15 |
reduced_model.jointPlacements[0] = input_model.jointPlacements[0]; |
359 |
15 |
reduced_model.parents[0] = input_model.parents[0]; |
|
360 |
✓✗ | 15 |
reduced_model.inertias[0] = input_model.inertias[0]; |
361 |
|||
362 |
✓✗ | 15 |
reduced_model.name = input_model.name; |
363 |
✓✗ | 15 |
reduced_model.gravity = input_model.gravity; |
364 |
|||
365 |
15 |
size_t current_index_to_lock = 0; |
|
366 |
|||
367 |
✓✓ | 312 |
for(JointIndex joint_id = 1; joint_id < (JointIndex)input_model.njoints; ++joint_id) |
368 |
{ |
||
369 |
✓✓ | 297 |
const JointIndex joint_id_to_lock = (current_index_to_lock < list_of_joints_to_lock.size()) ? list_of_joints_to_lock[current_index_to_lock] : 0; |
370 |
|||
371 |
297 |
const JointIndex input_parent_joint_index = input_model.parents[joint_id]; |
|
372 |
297 |
const std::string & joint_name = input_model.names[joint_id]; |
|
373 |
297 |
const JointModel & joint_input_model = input_model.joints[joint_id]; |
|
374 |
|||
375 |
// retrieve the closest joint parent in the new kinematic tree |
||
376 |
297 |
const std::string & parent_joint_name = input_model.names[input_parent_joint_index]; |
|
377 |
✓✗ | 297 |
const bool exist_parent_joint = reduced_model.existJointName(parent_joint_name); |
378 |
|||
379 |
✓✓ | 297 |
const JointIndex reduced_parent_joint_index |
380 |
= exist_parent_joint |
||
381 |
✓✓✓✗ |
320 |
? reduced_model.getJointId(parent_joint_name) |
382 |
✓✗ | 23 |
: reduced_model.frames[reduced_model.getFrameId(parent_joint_name)].parent; |
383 |
|||
384 |
✓✓✓✗ |
297 |
const SE3 parent_frame_placement |
385 |
= exist_parent_joint |
||
386 |
? SE3::Identity() |
||
387 |
✓✗✓✗ |
23 |
: reduced_model.frames[reduced_model.getFrameId(parent_joint_name)].placement; |
388 |
|||
389 |
✓✓ | 297 |
const FrameIndex reduced_previous_frame_index |
390 |
= exist_parent_joint |
||
391 |
✓✓✓✗ |
297 |
? 0 |
392 |
: reduced_model.getFrameId(parent_joint_name); |
||
393 |
|||
394 |
✓✓ | 297 |
if(joint_id == joint_id_to_lock) |
395 |
{ |
||
396 |
// the joint should not be added to the Model but aggragated to its parent joint |
||
397 |
|||
398 |
// Compute the new placement of the joint with respect to its parent joint in the new kinematic tree. |
||
399 |
✓✗ | 54 |
JointData joint_data = joint_input_model.createData(); |
400 |
✓✗ | 27 |
joint_input_model.calc(joint_data,reference_configuration); |
401 |
✓✗✓✗ ✓✗ |
27 |
const SE3 liMi = parent_frame_placement * input_model.jointPlacements[joint_id] * joint_data.M(); |
402 |
|||
403 |
✓✗ | 27 |
Frame frame = Frame(joint_name, |
404 |
reduced_parent_joint_index, reduced_previous_frame_index, |
||
405 |
liMi, |
||
406 |
FIXED_JOINT, |
||
407 |
27 |
input_model.inertias[joint_id]); |
|
408 |
|||
409 |
✓✗ | 27 |
FrameIndex frame_id = reduced_model.addFrame(frame); |
410 |
27 |
reduced_model.frames[frame_id].previousFrame = frame_id; // a bit weird, but this is a solution for missing parent frame |
|
411 |
|||
412 |
27 |
current_index_to_lock++; |
|
413 |
} |
||
414 |
else |
||
415 |
{ |
||
416 |
// the joint should be added to the Model as it is |
||
417 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
1890 |
JointIndex reduced_joint_id = reduced_model.addJoint(reduced_parent_joint_index, |
418 |
joint_input_model, |
||
419 |
270 |
parent_frame_placement * input_model.jointPlacements[joint_id], |
|
420 |
joint_name, |
||
421 |
✓✗ | 270 |
joint_input_model.jointVelocitySelector(input_model.effortLimit), |
422 |
✓✗ | 270 |
joint_input_model.jointVelocitySelector(input_model.velocityLimit), |
423 |
✓✗ | 270 |
joint_input_model.jointConfigSelector(input_model.lowerPositionLimit), |
424 |
✓✗ | 270 |
joint_input_model.jointConfigSelector(input_model.upperPositionLimit), |
425 |
✓✗ | 270 |
joint_input_model.jointVelocitySelector(input_model.friction), |
426 |
✓✗ | 270 |
joint_input_model.jointVelocitySelector(input_model.damping)); |
427 |
// Append inertia |
||
428 |
✓✗✓✗ |
540 |
reduced_model.appendBodyToJoint(reduced_joint_id, |
429 |
270 |
input_model.inertias[joint_id], |
|
430 |
SE3::Identity()); |
||
431 |
|||
432 |
// Copy other kinematics and dynamics properties |
||
433 |
270 |
const typename Model::JointModel & jmodel_out = reduced_model.joints[reduced_joint_id]; |
|
434 |
270 |
jmodel_out.jointVelocitySelector(reduced_model.rotorInertia) |
|
435 |
✓✗✓✗ ✓✗ |
270 |
= joint_input_model.jointVelocitySelector(input_model.rotorInertia); |
436 |
270 |
jmodel_out.jointVelocitySelector(reduced_model.rotorGearRatio) |
|
437 |
✓✗✓✗ ✓✗ |
270 |
= joint_input_model.jointVelocitySelector(input_model.rotorGearRatio); |
438 |
} |
||
439 |
} |
||
440 |
|||
441 |
// Retrieve and extend the reference configurations |
||
442 |
typedef typename Model::ConfigVectorMap ConfigVectorMap; |
||
443 |
20 |
for(typename ConfigVectorMap::const_iterator config_it = input_model.referenceConfigurations.begin(); |
|
444 |
✓✓ | 25 |
config_it != input_model.referenceConfigurations.end(); ++config_it) |
445 |
{ |
||
446 |
5 |
const std::string & config_name = config_it->first; |
|
447 |
5 |
const typename Model::ConfigVectorType & input_config_vector = config_it->second; |
|
448 |
|||
449 |
✓✗ | 5 |
typename Model::ConfigVectorType reduced_config_vector(reduced_model.nq); |
450 |
5 |
for(JointIndex reduced_joint_id = 1; |
|
451 |
✓✓ | 146 |
reduced_joint_id < reduced_model.joints.size(); |
452 |
++reduced_joint_id) |
||
453 |
{ |
||
454 |
✓✗ | 141 |
const JointIndex input_joint_id = input_model.getJointId(reduced_model.names[reduced_joint_id]); |
455 |
141 |
const JointModel & input_joint_model = input_model.joints[input_joint_id]; |
|
456 |
141 |
const JointModel & reduced_joint_model = reduced_model.joints[reduced_joint_id]; |
|
457 |
|||
458 |
✓✗✓✗ ✓✗ |
141 |
reduced_joint_model.jointConfigSelector(reduced_config_vector) = input_joint_model.jointConfigSelector(input_config_vector); |
459 |
} |
||
460 |
|||
461 |
✓✗✓✗ |
5 |
reduced_model.referenceConfigurations.insert(std::make_pair(config_name, reduced_config_vector)); |
462 |
} |
||
463 |
|||
464 |
// Add all frames |
||
465 |
15 |
typename Model::FrameVector::const_iterator frame_it = input_model.frames.begin(); |
|
466 |
✓✓ | 696 |
for(++frame_it;frame_it != input_model.frames.end(); ++frame_it) |
467 |
{ |
||
468 |
681 |
const Frame & input_frame = *frame_it; |
|
469 |
681 |
const std::string & support_joint_name = input_model.names[input_frame.parent]; |
|
470 |
|||
471 |
✓✗ | 681 |
std::vector<JointIndex>::const_iterator support_joint_it = std::find(list_of_joints_to_lock.begin(), |
472 |
list_of_joints_to_lock.end(), |
||
473 |
681 |
input_frame.parent); |
|
474 |
|||
475 |
✓✓ | 681 |
if(support_joint_it != list_of_joints_to_lock.end()) |
476 |
{ |
||
477 |
✓✓ | 78 |
if( input_frame.type == JOINT |
478 |
✓✗✓✗ |
27 |
&& reduced_model.existFrame(input_frame.name) |
479 |
✓✓✓✗ ✓✓ |
105 |
&& support_joint_name == input_frame.name) |
480 |
27 |
continue; // this means that the Joint is now fixed and has been replaced by a Frame. No need to add a new one. |
|
481 |
|||
482 |
// The joint has been removed and replaced by a Frame |
||
483 |
✓✗ | 51 |
const FrameIndex joint_frame_id = reduced_model.getFrameId(support_joint_name); |
484 |
51 |
const Frame & joint_frame = reduced_model.frames[joint_frame_id]; |
|
485 |
✓✗ | 102 |
Frame reduced_frame = input_frame; |
486 |
✓✗ | 51 |
reduced_frame.placement = joint_frame.placement * input_frame.placement; |
487 |
51 |
reduced_frame.parent = joint_frame.parent; |
|
488 |
✓✗✓✗ |
51 |
reduced_frame.previousFrame = reduced_model.getFrameId(input_model.frames[input_frame.previousFrame].name); |
489 |
✓✗ | 51 |
reduced_model.addFrame(reduced_frame, false); |
490 |
} |
||
491 |
else |
||
492 |
{ |
||
493 |
✓✗ | 1206 |
Frame reduced_frame = input_frame; |
494 |
✓✗ | 603 |
reduced_frame.parent = reduced_model.getJointId(input_model.names[input_frame.parent]); |
495 |
✓✗✓✗ |
603 |
reduced_frame.previousFrame = reduced_model.getFrameId(input_model.frames[input_frame.previousFrame].name); |
496 |
✓✗ | 603 |
reduced_model.addFrame(reduced_frame, false); |
497 |
} |
||
498 |
} |
||
499 |
15 |
} |
|
500 |
|||
501 |
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl, typename ConfigVectorType> |
||
502 |
void |
||
503 |
3 |
buildReducedModel(const ModelTpl<Scalar,Options,JointCollectionTpl> & input_model, |
|
504 |
const GeometryModel & input_geom_model, |
||
505 |
const std::vector<JointIndex> & list_of_joints_to_lock, |
||
506 |
const Eigen::MatrixBase<ConfigVectorType> & reference_configuration, |
||
507 |
ModelTpl<Scalar,Options,JointCollectionTpl> & reduced_model, |
||
508 |
GeometryModel & reduced_geom_model) |
||
509 |
{ |
||
510 |
|||
511 |
✓✗ | 6 |
const std::vector<GeometryModel> temp_input_geoms(1,input_geom_model); |
512 |
6 |
std::vector<GeometryModel> temp_reduced_geom_models; |
|
513 |
|||
514 |
✓✗ | 3 |
buildReducedModel(input_model, temp_input_geoms, list_of_joints_to_lock, |
515 |
reference_configuration, reduced_model, |
||
516 |
temp_reduced_geom_models); |
||
517 |
✓✗ | 3 |
reduced_geom_model = temp_reduced_geom_models.front(); |
518 |
3 |
} |
|
519 |
|||
520 |
template <typename Scalar, int Options, |
||
521 |
template <typename, int> class JointCollectionTpl, |
||
522 |
typename GeometryModelAllocator, |
||
523 |
typename ConfigVectorType> |
||
524 |
9 |
void buildReducedModel( |
|
525 |
const ModelTpl<Scalar, Options, JointCollectionTpl> &input_model, |
||
526 |
const std::vector<GeometryModel,GeometryModelAllocator> &list_of_geom_models, |
||
527 |
const std::vector<JointIndex> &list_of_joints_to_lock, |
||
528 |
const Eigen::MatrixBase<ConfigVectorType> &reference_configuration, |
||
529 |
ModelTpl<Scalar, Options, JointCollectionTpl> &reduced_model, |
||
530 |
std::vector<GeometryModel,GeometryModelAllocator> &list_of_reduced_geom_models) { |
||
531 |
|||
532 |
typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; |
||
533 |
✓✗ | 9 |
buildReducedModel(input_model, list_of_joints_to_lock, reference_configuration, reduced_model); |
534 |
|||
535 |
// for all GeometryModels |
||
536 |
✓✓ | 24 |
for (size_t gmi = 0; gmi < list_of_geom_models.size(); ++gmi) { |
537 |
15 |
const GeometryModel &input_geom_model = list_of_geom_models[gmi]; |
|
538 |
✓✗ | 30 |
GeometryModel reduced_geom_model; |
539 |
|||
540 |
// Add all the geometries |
||
541 |
typedef GeometryModel::GeometryObject GeometryObject; |
||
542 |
typedef GeometryModel::GeometryObjectVector GeometryObjectVector; |
||
543 |
224 |
for(GeometryObjectVector::const_iterator it = input_geom_model.geometryObjects.begin(); |
|
544 |
✓✓ | 433 |
it != input_geom_model.geometryObjects.end(); ++it) |
545 |
{ |
||
546 |
209 |
const GeometryModel::GeometryObject & geom = *it; |
|
547 |
|||
548 |
209 |
const JointIndex joint_id_in_input_model = geom.parentJoint; |
|
549 |
✗✓✗✗ ✗✗ |
209 |
_PINOCCHIO_CHECK_INPUT_ARGUMENT_2((joint_id_in_input_model < (JointIndex)input_model.njoints), |
550 |
"Invalid joint parent index for the geometry with name " + geom.name); |
||
551 |
209 |
const std::string & parent_joint_name = input_model.names[joint_id_in_input_model]; |
|
552 |
|||
553 |
209 |
JointIndex reduced_joint_id = (JointIndex)-1; |
|
554 |
typedef typename Model::SE3 SE3; |
||
555 |
✓✗ | 209 |
SE3 relative_placement = SE3::Identity(); |
556 |
✓✗✓✓ |
209 |
if(reduced_model.existJointName(parent_joint_name)) |
557 |
{ |
||
558 |
✓✗ | 175 |
reduced_joint_id = reduced_model.getJointId(parent_joint_name); |
559 |
} |
||
560 |
else // The joint is now a frame |
||
561 |
{ |
||
562 |
✓✗ | 34 |
const FrameIndex reduced_frame_id = reduced_model.getFrameId(parent_joint_name); |
563 |
34 |
reduced_joint_id = reduced_model.frames[reduced_frame_id].parent; |
|
564 |
✓✗ | 34 |
relative_placement = reduced_model.frames[reduced_frame_id].placement; |
565 |
} |
||
566 |
|||
567 |
✓✗ | 418 |
GeometryObject reduced_geom(geom); |
568 |
209 |
reduced_geom.parentJoint = reduced_joint_id; |
|
569 |
418 |
reduced_geom.parentFrame = reduced_model.getBodyId( |
|
570 |
✓✗ | 209 |
input_model.frames[geom.parentFrame].name); |
571 |
✓✗ | 209 |
reduced_geom.placement = relative_placement * geom.placement; |
572 |
✓✗ | 209 |
reduced_geom_model.addGeometryObject(reduced_geom); |
573 |
} |
||
574 |
|||
575 |
#ifdef PINOCCHIO_WITH_HPP_FCL |
||
576 |
// Add all the collision pairs - the index of the geometry objects should have not changed |
||
577 |
|||
578 |
typedef GeometryModel::CollisionPairVector CollisionPairVector; |
||
579 |
15 |
for(CollisionPairVector::const_iterator it = input_geom_model.collisionPairs.begin(); |
|
580 |
✗✓ | 15 |
it != input_geom_model.collisionPairs.end(); ++it) |
581 |
{ |
||
582 |
const CollisionPair & cp = *it; |
||
583 |
reduced_geom_model.addCollisionPair(cp); |
||
584 |
} |
||
585 |
#endif |
||
586 |
|||
587 |
✓✗ | 15 |
list_of_reduced_geom_models.push_back(reduced_geom_model); |
588 |
} |
||
589 |
9 |
} |
|
590 |
|||
591 |
} // namespace pinocchio |
||
592 |
|||
593 |
#endif // ifndef __pinocchio_algorithm_model_hxx__ |
Generated by: GCOVR (Version 4.2) |