Skip to content

Commit 037ce0a

Browse files
author
Chien-Liang Fok
committed
Adds ability to clone RigidBodyTree.
1 parent 7b7387d commit 037ce0a

File tree

5 files changed

+445
-4
lines changed

5 files changed

+445
-4
lines changed

drake/multibody/BUILD

+15
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,21 @@ drake_cc_googletest(
181181
],
182182
)
183183

184+
drake_cc_googletest(
185+
name = "rigid_body_tree_clone_test",
186+
srcs = ["test/rigid_body_tree/rigid_body_tree_clone_test.cc"],
187+
data = [
188+
":test_models",
189+
"//drake/automotive:models",
190+
"//drake/examples/Atlas:models",
191+
"//drake/examples/Valkyrie:models",
192+
],
193+
deps = [
194+
":rigid_body_tree",
195+
"//drake/multibody/parsers",
196+
],
197+
)
198+
184199
drake_cc_googletest(
185200
name = "rigid_body_tree_creation_test",
186201
srcs = ["test/rigid_body_tree/rigid_body_tree_creation_test.cc"],

drake/multibody/rigid_body_tree.cc

+304-2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,298 @@ RigidBodyTree<T>::RigidBodyTree(void)
124124
template <typename T>
125125
RigidBodyTree<T>::~RigidBodyTree(void) {}
126126

127+
// For an explanation of why these SWIG preprocessor commands are needed, see
128+
// the comment immediately above the declaration of RigidBodyTree::Clone() in
129+
// rigid_body_tree.h.
130+
#ifndef SWIG
131+
template <>
132+
unique_ptr<RigidBodyTree<double>> RigidBodyTree<double>::Clone() const {
133+
auto clone = make_unique<RigidBodyTree<double>>();
134+
135+
clone->joint_limit_min = this->joint_limit_min;
136+
clone->joint_limit_max = this->joint_limit_max;
137+
clone->a_grav = this->a_grav;
138+
clone->B = this->B;
139+
clone->num_positions_ = this->num_positions_;
140+
clone->num_velocities_ = this->num_velocities_;
141+
clone->num_model_instances_ = this->num_model_instances_;
142+
clone->initialized_ = this->initialized_;
143+
144+
// Clones the rigid bodies.
145+
for (const auto& body : bodies) {
146+
if (body->get_name() != std::string(RigidBodyTreeConstants::kWorldName)) {
147+
clone->bodies.push_back(body->Clone());
148+
}
149+
}
150+
151+
// Clones the joints and adds them to the cloned RigidBody objects.
152+
for (const auto& original_body : bodies) {
153+
if (original_body->get_name() ==
154+
std::string(RigidBodyTreeConstants::kWorldName)) {
155+
continue;
156+
}
157+
158+
const int original_body_index =
159+
this->FindBodyIndex(original_body->get_name(),
160+
original_body->get_model_instance_id());
161+
const int cloned_body_index =
162+
clone->FindBodyIndex(original_body->get_name(),
163+
original_body->get_model_instance_id());
164+
DRAKE_DEMAND(original_body_index == cloned_body_index);
165+
166+
RigidBody<double>* cloned_body = clone->get_mutable_body(cloned_body_index);
167+
DRAKE_DEMAND(cloned_body != nullptr);
168+
169+
const RigidBody<double>* original_body_parent = original_body->get_parent();
170+
DRAKE_DEMAND(original_body_parent != nullptr);
171+
172+
const int original_body_parent_index =
173+
this->FindBodyIndex(original_body_parent->get_name(),
174+
original_body_parent->get_model_instance_id());
175+
const int cloned_body_parent_index =
176+
clone->FindBodyIndex(original_body_parent->get_name(),
177+
original_body_parent->get_model_instance_id());
178+
DRAKE_DEMAND(original_body_parent_index == cloned_body_parent_index);
179+
180+
RigidBody<double>* cloned_body_parent =
181+
clone->get_mutable_body(cloned_body_parent_index);
182+
DRAKE_DEMAND(cloned_body_parent != nullptr);
183+
184+
cloned_body->add_joint(cloned_body_parent,
185+
original_body->getJoint().Clone());
186+
}
187+
188+
for (const auto& original_frame : frames) {
189+
const RigidBody<double>& original_frame_body =
190+
original_frame->get_rigid_body();
191+
const int cloned_frame_body_index =
192+
clone->FindBodyIndex(original_frame_body.get_name(),
193+
original_frame_body.get_model_instance_id());
194+
RigidBody<double>* cloned_frame_body =
195+
clone->get_mutable_body(cloned_frame_body_index);
196+
DRAKE_DEMAND(cloned_frame_body != nullptr);
197+
std::shared_ptr<RigidBodyFrame<double>> cloned_frame =
198+
original_frame->Clone(cloned_frame_body);
199+
clone->frames.push_back(cloned_frame);
200+
}
201+
202+
// Adds joints to the cloned RigidBodyFrame objects.
203+
for (const auto& original_frame : frames) {
204+
std::shared_ptr<RigidBodyFrame<double>> cloned_frame =
205+
clone->findFrame(original_frame->get_name(),
206+
original_frame->get_model_instance_id());
207+
DRAKE_DEMAND(cloned_frame != nullptr);
208+
const RigidBody<double>& original_frame_body =
209+
original_frame->get_rigid_body();
210+
const int cloned_frame_body_index =
211+
clone->FindBodyIndex(original_frame_body.get_name(),
212+
original_frame_body.get_model_instance_id());
213+
RigidBody<double>* cloned_frame_body =
214+
clone->get_mutable_body(cloned_frame_body_index);
215+
DRAKE_DEMAND(cloned_frame_body != nullptr);
216+
cloned_frame->set_rigid_body(cloned_frame_body);
217+
}
218+
219+
for (const auto& actuator : actuators) {
220+
RigidBody<double>* cloned_body =
221+
clone->FindBody(actuator.body_->get_name(), "" /* model_name */,
222+
actuator.body_->get_model_instance_id());
223+
DRAKE_DEMAND(cloned_body != nullptr);
224+
clone->actuators.emplace_back(
225+
actuator.name_, cloned_body, actuator.reduction_,
226+
actuator.effort_limit_min_, actuator.effort_limit_max_);
227+
}
228+
229+
for (const auto& loop : loops) {
230+
std::shared_ptr<RigidBodyFrame<double>> frame_a =
231+
clone->findFrame(loop.frameA_->get_name(),
232+
loop.frameA_->get_model_instance_id());
233+
std::shared_ptr<RigidBodyFrame<double>> frame_b =
234+
clone->findFrame(loop.frameB_->get_name(),
235+
loop.frameB_->get_model_instance_id());
236+
clone->loops.emplace_back(frame_a, frame_b, loop.axis_);
237+
}
238+
239+
return clone;
240+
}
241+
#endif
242+
243+
template<>
244+
bool RigidBodyTree<double>::CompareToClone(const RigidBodyTree<double>& other)
245+
const {
246+
if (this->get_num_model_instances() != other.get_num_model_instances()) {
247+
drake::log()->debug(
248+
"RigidBodyTree::CompareToClone(): num model instances mismatch:\n"
249+
" - this: {}\n"
250+
" - other: {}",
251+
this->get_num_model_instances(),
252+
other.get_num_model_instances());
253+
return false;
254+
}
255+
if (this->get_num_bodies() != other.get_num_bodies()) {
256+
drake::log()->debug(
257+
"RigidBodyTree::CompareToClone(): num bodies mismatch:\n"
258+
" - this: {}\n"
259+
" - other: {}",
260+
this->get_num_bodies(),
261+
other.get_num_bodies());
262+
return false;
263+
}
264+
if (this->get_num_frames() != other.get_num_frames()) {
265+
drake::log()->debug(
266+
"RigidBodyTree::CompareToClone(): num bodies mismatch:\n"
267+
" - this: {}\n"
268+
" - other: {}",
269+
this->get_num_frames(),
270+
other.get_num_frames());
271+
return false;
272+
}
273+
if (this->get_num_positions() != other.get_num_positions()) {
274+
drake::log()->debug(
275+
"RigidBodyTree::CompareToClone(): num positions mismatch:\n"
276+
" - this: {}\n"
277+
" - other: {}",
278+
this->get_num_positions(),
279+
other.get_num_positions());
280+
return false;
281+
}
282+
if (this->get_num_velocities() != other.get_num_velocities()) {
283+
drake::log()->debug(
284+
"RigidBodyTree::CompareToClone(): num velocities mismatch:\n"
285+
" - this: {}\n"
286+
" - other: {}",
287+
this->get_num_velocities(),
288+
other.get_num_velocities());
289+
return false;
290+
}
291+
if (this->get_num_actuators() != other.get_num_actuators()) {
292+
drake::log()->debug(
293+
"RigidBodyTree::CompareToClone(): num velocities mismatch:\n"
294+
" - this: {}\n"
295+
" - other: {}",
296+
this->get_num_actuators(),
297+
other.get_num_actuators());
298+
return false;
299+
}
300+
for (int i = 0; i < this->get_num_bodies(); ++i) {
301+
if (!this->bodies.at(i)->CompareToClone(*other.bodies.at(i))) {
302+
drake::log()->debug(
303+
"RigidBodyTree::CompareToClone(): bodies mismatch at index {}.", i);
304+
return false;
305+
}
306+
}
307+
for (int i = 0; i < this->get_num_frames(); ++i) {
308+
if (!this->frames.at(i)->CompareToClone(*other.frames.at(i))) {
309+
drake::log()->debug(
310+
"RigidBodyTree::CompareToClone(): frames mismatch at index {}.", i);
311+
return false;
312+
}
313+
}
314+
for (int i = 0; i < this->get_num_actuators(); ++i) {
315+
const RigidBodyActuator* this_actuator = &actuators.at(i);
316+
const RigidBodyActuator* other_actuator = &other.actuators.at(i);
317+
if (this_actuator->name_ != other_actuator->name_) {
318+
drake::log()->debug(
319+
"RigidBodyTree::CompareToClone(): actuators mismatch at index {}. "
320+
"Names do not match:\n"
321+
" - this: {}\n"
322+
" - other: {}",
323+
i, this_actuator->name_, other_actuator->name_);
324+
return false;
325+
}
326+
if (!this_actuator->body_->CompareToClone(*other_actuator->body_)) {
327+
drake::log()->debug(
328+
"RigidBodyTree::CompareToClone(): actuator mismatch at index {}. "
329+
"Bodies do not match.", i);
330+
return false;
331+
}
332+
if (this_actuator->reduction_ != other_actuator->reduction_) {
333+
drake::log()->debug(
334+
"RigidBodyTree::CompareToClone(): actuator mismatch at index {}. "
335+
"Reductions do not match:\n"
336+
" - this: {}\n"
337+
" - other: {}",
338+
i, this_actuator->reduction_, other_actuator->reduction_);
339+
return false;
340+
}
341+
if (this_actuator->effort_limit_min_ != other_actuator->effort_limit_min_) {
342+
drake::log()->debug(
343+
"RigidBodyTree::CompareToClone(): actuator mismatch at index {}. "
344+
"Minimum effort limits do not match:\n"
345+
" - this: {}\n"
346+
" - other: {}",
347+
i, this_actuator->effort_limit_min_,
348+
other_actuator->effort_limit_min_);
349+
return false;
350+
}
351+
if (this_actuator->effort_limit_max_ != other_actuator->effort_limit_max_) {
352+
drake::log()->debug(
353+
"RigidBodyTree::CompareToClone(): actuator mismatch at index {}. "
354+
"Maximum effort limits do not match:\n"
355+
" - this: {}\n"
356+
" - other: {}",
357+
i, this_actuator->effort_limit_max_,
358+
other_actuator->effort_limit_max_);
359+
return false;
360+
}
361+
}
362+
for (int i = 0; i < static_cast<int>(this->loops.size()); ++i) {
363+
const RigidBodyLoop<double>* this_loop = &loops.at(i);
364+
const RigidBodyLoop<double>* other_loop = &other.loops.at(i);
365+
if (!this_loop->frameA_->CompareToClone(*other_loop->frameA_)) {
366+
drake::log()->debug(
367+
"RigidBodyTree::CompareToClone(): loop mismatch at index {}. "
368+
"FrameAs do not match.", i);
369+
return false;
370+
}
371+
if (!this_loop->frameB_->CompareToClone(*other_loop->frameB_)) {
372+
drake::log()->debug(
373+
"RigidBodyTree::CompareToClone(): loop mismatch at index {}. "
374+
"FrameBs do not match.", i);
375+
return false;
376+
}
377+
if (!this_loop->axis_.isApprox(other_loop->axis_,
378+
std::numeric_limits<double>::epsilon())) {
379+
drake::log()->debug(
380+
"RigidBodyTree::CompareToClone(): loop mismatch at index {}. "
381+
"Axes do not match:\n"
382+
" - this: {}\n"
383+
" - other: {}",
384+
i, this_loop->axis_.transpose(),
385+
other_loop->axis_.transpose());
386+
return false;
387+
}
388+
}
389+
if (this->a_grav != other.a_grav) {
390+
drake::log()->debug(
391+
"RigidBodyTree::CompareToClone(): gravity vector mismatch:\n"
392+
" - this: {}\n"
393+
" - other: {}",
394+
this->a_grav,
395+
other.a_grav);
396+
return false;
397+
}
398+
if (this->B != other.B) {
399+
drake::log()->debug(
400+
"RigidBodyTree::CompareToClone(): B matrix mismatch:\n"
401+
" - this:\n{}\n"
402+
" - other:\n{}",
403+
this->B,
404+
other.B);
405+
return false;
406+
}
407+
if (this->initialized_ != other.initialized_) {
408+
drake::log()->debug(
409+
"RigidBodyTree::CompareToClone(): initialized_ mismatch:\n"
410+
" - this:\n{}\n"
411+
" - other:\n{}",
412+
this->initialized_,
413+
other.initialized_);
414+
return false;
415+
}
416+
return true;
417+
}
418+
127419
template <typename T>
128420
bool RigidBodyTree<T>::transformCollisionFrame(
129421
RigidBody<T>* body, const Eigen::Isometry3d& displace_transform) {
@@ -2760,11 +3052,16 @@ int RigidBodyTree<T>::FindIndexOfChildBodyOfJoint(const std::string& joint_name,
27603052

27613053
template <typename T>
27623054
const RigidBody<T>& RigidBodyTree<T>::get_body(int body_index) const {
2763-
DRAKE_DEMAND(body_index >= 0 &&
2764-
body_index < get_num_bodies());
3055+
DRAKE_DEMAND(body_index >= 0 && body_index < get_num_bodies());
27653056
return *bodies[body_index].get();
27663057
}
27673058

3059+
template <typename T>
3060+
RigidBody<T>* RigidBodyTree<T>::get_mutable_body(int body_index) {
3061+
DRAKE_DEMAND(body_index >= 0 && body_index < get_num_bodies());
3062+
return bodies[body_index].get();
3063+
}
3064+
27683065
template <typename T>
27693066
int RigidBodyTree<T>::get_num_bodies() const {
27703067
return static_cast<int>(bodies.size());
@@ -2776,6 +3073,11 @@ int RigidBodyTree<T>::get_number_of_bodies() const {
27763073
return get_num_bodies();
27773074
}
27783075

3076+
template <typename T>
3077+
int RigidBodyTree<T>::get_num_frames() const {
3078+
return static_cast<int>(frames.size());
3079+
}
3080+
27793081
// TODO(liang.fok) Remove this method prior to Release 1.0.
27803082
template <typename T>
27813083
RigidBody<T>* RigidBodyTree<T>::findJoint(const std::string& joint_name,

0 commit comments

Comments
 (0)