Skip to content

Commit 58a50b8

Browse files
committed
Break dependency loop and fix existing tests
1 parent 2cafe01 commit 58a50b8

10 files changed

+341
-279
lines changed

multibody/plant/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ drake_cc_library(
9393
"discrete_step_memory.cc",
9494
"discrete_update_manager.cc",
9595
"dummy_physical_model.cc",
96+
"element_collection.cc",
9697
"force_density_field_declare_system_resources.cc",
9798
"geometry_contact_data.cc",
9899
"make_discrete_update_manager.cc",

multibody/plant/deformable_body.cc

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ MultibodyConstraintId DeformableBody<T>::AddFixedConstraint(
7777
auto query =
7878
scene_graph.get_query_output_port().Eval<geometry::QueryObject<double>>(
7979
*context);
80-
const VectorX<T>& p_WPi = reference_positions_;
80+
const VectorX<double>& p_WPi = reference_positions_;
8181
for (int vertex_index = 0; vertex_index < fem_model_->num_nodes();
8282
++vertex_index) {
8383
/* The vertex position in the deformable body's geometry frame. */
@@ -169,28 +169,33 @@ void DeformableBody<T>::Enable(systems::Context<T>* context) const {
169169
}
170170

171171
template <typename T>
172-
DeformableBody<T>::DeformableBody(DeformableBodyIndex index,
173-
DeformableBodyId id, GeometryId geometry_id,
174-
ModelInstanceIndex model_instance,
175-
const VolumeMesh<double>& mesh_G,
176-
const math::RigidTransform<double>& X_WG,
177-
const fem::DeformableBodyConfig<T>& config,
178-
const MultibodyPlant<T>* plant)
172+
DeformableBody<T>::DeformableBody(
173+
DeformableBodyIndex index, DeformableBodyId id, std::string name,
174+
GeometryId geometry_id, ModelInstanceIndex model_instance,
175+
const VolumeMesh<double>& mesh_G, const math::RigidTransform<double>& X_WG,
176+
const fem::DeformableBodyConfig<T>& config, const MultibodyPlant<T>* plant)
179177
: index_(index),
180178
id_(id),
179+
name_(std::move(name)),
181180
geometry_id_(geometry_id),
182181
model_instance_(model_instance),
182+
mesh_G_(mesh_G),
183183
X_WG_(X_WG),
184184
config_(config),
185185
plant_(plant) {
186-
DRAKE_DEMAND(plant_ != nullptr);
187-
DRAKE_DEMAND(!plant->is_finalized());
188-
geometry::VolumeMesh<double> mesh_W = mesh_G;
189-
mesh_W.TransformVertices(X_WG);
190-
BuildLinearVolumetricModel(mesh_W, config);
191-
reference_positions_.resize(3 * mesh_W.num_vertices());
192-
for (int v = 0; v < mesh_W.num_vertices(); ++v) {
193-
reference_positions_.template segment<3>(3 * v) = mesh_W.vertex(v);
186+
if constexpr (std::is_same_v<T, double>) {
187+
DRAKE_DEMAND(plant_ != nullptr);
188+
DRAKE_DEMAND(!plant->is_finalized());
189+
geometry::VolumeMesh<double> mesh_W = mesh_G;
190+
mesh_W.TransformVertices(X_WG);
191+
BuildLinearVolumetricModel(mesh_W, config);
192+
reference_positions_.resize(3 * mesh_W.num_vertices());
193+
for (int v = 0; v < mesh_W.num_vertices(); ++v) {
194+
reference_positions_.template segment<3>(3 * v) = mesh_W.vertex(v);
195+
}
196+
} else {
197+
throw std::runtime_error(
198+
"DeformableBody<T>::DeformableBody(): T must be double.");
194199
}
195200
}
196201

@@ -208,7 +213,9 @@ void DeformableBody<T>::SetExternalForces(
208213
}
209214

210215
template <typename T>
211-
void DeformableBody<T>::BuildLinearVolumetricModel(
216+
template <typename T1>
217+
typename std::enable_if_t<std::is_same_v<T1, double>, void>
218+
DeformableBody<T>::BuildLinearVolumetricModel(
212219
const VolumeMesh<double>& mesh,
213220
const fem::DeformableBodyConfig<T>& config) {
214221
switch (config.material_model()) {
@@ -232,8 +239,9 @@ void DeformableBody<T>::BuildLinearVolumetricModel(
232239
}
233240

234241
template <typename T>
235-
template <template <class> class Model>
236-
void DeformableBody<T>::BuildLinearVolumetricModelHelper(
242+
template <template <typename> class Model, typename T1>
243+
typename std::enable_if_t<std::is_same_v<T1, double>, void>
244+
DeformableBody<T>::BuildLinearVolumetricModelHelper(
237245
const VolumeMesh<double>& mesh,
238246
const fem::DeformableBodyConfig<T>& config) {
239247
constexpr int kNaturalDimension = 3;
@@ -275,7 +283,8 @@ void DeformableBody<T>::BuildLinearVolumetricModelHelper(
275283
fem_model_ = std::move(concrete_fem_model);
276284
}
277285

278-
template class DeformableBody<double>;
279-
280286
} // namespace multibody
281287
} // namespace drake
288+
289+
DRAKE_DEFINE_CLASS_TEMPLATE_INSTANTIATIONS_ON_DEFAULT_SCALARS(
290+
class ::drake::multibody::DeformableBody);

multibody/plant/deformable_body.h

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <memory>
4+
#include <string>
45
#include <vector>
56

67
#include "drake/common/drake_copyable.h"
@@ -19,22 +20,18 @@
1920
namespace drake {
2021
namespace multibody {
2122

23+
// TODO(xuchenhan-tri): Derive from MultibodyElement.
2224
template <typename T>
2325
class DeformableBody {
2426
public:
25-
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(DeformableBody);
26-
2727
/** Returns this element's unique index. */
2828
DeformableBodyIndex index() const { return index_; }
2929

3030
/** Returns the unique body id. */
3131
DeformableBodyId body_id() const { return id_; }
3232

33-
/** Returns physical parameters of this deformable body. */
34-
const fem::DeformableBodyConfig<T>& config() const { return config_; }
35-
36-
/** Returns the number of degrees of freedom (DoFs) of this body. */
37-
int num_dofs() const { return fem_model_->num_dofs(); }
33+
/** Returns the name of the body. */
34+
const std::string& name() const { return name_; }
3835

3936
/** Returns the geometry id of the deformable geometry used to simulate this
4037
deformable body. */
@@ -43,13 +40,21 @@ class DeformableBody {
4340
/** Returns the model instance index of this deformable body. */
4441
ModelInstanceIndex model_instance() const { return model_instance_; }
4542

43+
/** Returns physical parameters of this deformable body. */
44+
const fem::DeformableBodyConfig<T>& config() const { return config_; }
45+
46+
/** Returns the number of degrees of freedom (DoFs) of this body. */
47+
int num_dofs() const { return fem_model_->num_dofs(); }
48+
4649
/** Returns the reference positions of the vertices of the deformable body
4750
identified by the given `id`.
4851
The reference positions are represented as a VectorX with 3N values where N
4952
is the number of vertices. The x-, y-, and z-positions (measured and
5053
expressed in the world frame) of the j-th vertex are 3j, 3j + 1, and 3j + 2
5154
in the VectorX. */
52-
const VectorX<T>& reference_positions() const { return reference_positions_; }
55+
const VectorX<double>& reference_positions() const {
56+
return reference_positions_;
57+
}
5358

5459
/** Returns the FemModel for this deformable body. */
5560
const fem::FemModel<T>& fem_model() const { return *fem_model_; }
@@ -195,12 +200,17 @@ class DeformableBody {
195200
void Enable(systems::Context<T>* context) const;
196201

197202
private:
203+
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(DeformableBody)
204+
198205
template <typename U>
199206
friend class DeformableModel;
207+
template <typename U>
208+
friend class DeformableBody;
200209

201210
/* Private constructor exposed only to DeformableModel.
202211
@param index Unique DeformableBodyIndex
203212
@param id Unique DeformableBodyId
213+
@param name Name of the body
204214
@param geometry_id GeometryId of the simulated geometry.
205215
@param model_instance ModelInstanceIndex for this body.
206216
@param mesh_G The simulated volume mesh in the geometry's frame.
@@ -211,13 +221,26 @@ class DeformableBody {
211221
@pre `plant` is not nullptr.
212222
@pre `plant` is not finalized. */
213223
DeformableBody(DeformableBodyIndex index, DeformableBodyId id,
214-
geometry::GeometryId geometry_id,
224+
std::string name, geometry::GeometryId geometry_id,
215225
ModelInstanceIndex model_instance,
216226
const geometry::VolumeMesh<double>& mesh_G,
217227
const math::RigidTransform<double>& X_WG,
218228
const fem::DeformableBodyConfig<T>& config,
219229
const MultibodyPlant<T>* plant);
220230

231+
std::unique_ptr<DeformableBody<double>> CloneToDouble(
232+
const MultibodyPlant<double>* plant) const {
233+
if constexpr (!std::is_same_v<T, double>) {
234+
/* A none double body shouldn't exist in the first place. */
235+
DRAKE_UNREACHABLE();
236+
} else {
237+
auto clone = std::unique_ptr<DeformableBody<double>>(
238+
new DeformableBody<double>(*this));
239+
clone->plant_ = plant;
240+
return clone;
241+
}
242+
}
243+
221244
/* Private setter accessible to DeformableModel. */
222245
void set_discrete_state_index(systems::DiscreteStateIndex index) {
223246
discrete_state_index_ = index;
@@ -240,33 +263,39 @@ class DeformableBody {
240263
single quadrature point. The reference positions as well as the connectivity
241264
of the elements are given by `mesh`, and physical properties of the body are
242265
given by `config`. */
243-
void BuildLinearVolumetricModel(const geometry::VolumeMesh<double>& mesh,
244-
const fem::DeformableBodyConfig<T>& config);
266+
template <typename T1 = T>
267+
typename std::enable_if_t<std::is_same_v<T1, double>, void>
268+
BuildLinearVolumetricModel(const geometry::VolumeMesh<double>& mesh,
269+
const fem::DeformableBodyConfig<T>& config);
245270

246271
/* Helper for BuildLinearVolumetricModel templated on constitutive model. */
247-
template <template <class> class Model>
248-
void BuildLinearVolumetricModelHelper(
249-
const geometry::VolumeMesh<double>& mesh,
250-
const fem::DeformableBodyConfig<T>& config);
272+
template <template <class> class Model, typename T1 = T>
273+
typename std::enable_if_t<std::is_same_v<T1, double>, void>
274+
BuildLinearVolumetricModelHelper(const geometry::VolumeMesh<double>& mesh,
275+
const fem::DeformableBodyConfig<T>& config);
251276

252277
DeformableBodyIndex index_{};
253278
DeformableBodyId id_{};
279+
std::string name_;
254280
geometry::GeometryId geometry_id_{};
255281
ModelInstanceIndex model_instance_{};
282+
/* The mesh of the deformable geometry (in its reference configuration) in its
283+
geometry frame. */
284+
geometry::VolumeMesh<double> mesh_G_;
256285
/* The pose of the deformable geometry (in its reference configuration) in the
257286
world frame. */
258287
math::RigidTransform<double> X_WG_;
259288
fem::DeformableBodyConfig<T> config_;
260289
const MultibodyPlant<T>* plant_{};
261-
VectorX<T> reference_positions_;
262-
std::unique_ptr<fem::FemModel<T>> fem_model_;
290+
VectorX<double> reference_positions_;
291+
copyable_unique_ptr<fem::FemModel<T>> fem_model_;
263292
systems::DiscreteStateIndex discrete_state_index_{};
264293
systems::AbstractParameterIndex is_enabled_parameter_index_{};
265294
std::vector<internal::DeformableRigidFixedConstraintSpec>
266295
fixed_constraint_specs_;
267296
/* External forces and constraints. */
268297
/* Owned gravity force. */
269-
std::unique_ptr<ForceDensityField<T>> gravity_force_;
298+
copyable_unique_ptr<ForceDensityField<T>> gravity_force_;
270299
/* All external forces affecting this body (including the owned gravity). */
271300
std::vector<const ForceDensityField<T>*> external_forces_;
272301
};

0 commit comments

Comments
 (0)