-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
point_source_force_field.h
80 lines (66 loc) · 3.23 KB
/
point_source_force_field.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#pragma once
#include <memory>
#include "drake/multibody/plant/force_density_field.h"
#include "drake/multibody/plant/multibody_plant.h"
namespace drake {
namespace examples {
namespace deformable {
/* A custom external force density field that applies external force to
deformable bodies. The force density points towards a point C affixed to a
rigid body. The magnitude of the force density decays linearly with the
distance to the point C and floors at 0. The maximum force density is read from
a double-valued input port (see maximum_force_density_input_port()). If the
port is unconnected, it reads as zero. */
class PointSourceForceField final
: public multibody::ForceDensityField<double> {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(PointSourceForceField)
/* Constructs a new PointSourceForceField object
@param plant The MultibodyPlant that owns this force field.
@param body The body to which the source of the force field C is
affixed to.
@param p_BC The fixed offset from the body origin to the point
source of the force field.
@param falloff_distance The force density decays linearly.
`falloff_distance` in meters is the distance from
the point source beyond which the force density is
zero. Must be positive and finite. */
PointSourceForceField(const multibody::MultibodyPlant<double>& plant,
const multibody::RigidBody<double>& body,
const Vector3<double>& p_BC, double falloff_distance);
/* Input port for desired maximum force density with units of N/m³.
The port belongs to the MultibodyPlant that owns this density field. */
const systems::InputPort<double>& maximum_force_density_input_port() const {
return parent_system_or_throw().get_input_port(
maximum_force_density_port_index_);
}
private:
/* Computes the world frame position of the center of the point source force
field. */
Vector3<double> CalcPointSourceLocation(
const systems::Context<double>& context) const {
return plant_->EvalBodyPoseInWorld(context, plant_->get_body(body_)) *
p_BC_;
}
/* Eval version of `CalcPointSourceLocation()`. */
const Vector3<double>& EvalPointSourceLocation(
const systems::Context<double>& context) const {
return parent_system_or_throw()
.get_cache_entry(point_source_position_cache_index_)
.template Eval<Vector3<double>>(context);
}
Vector3<double> DoEvaluateAt(const systems::Context<double>& context,
const Vector3<double>& p_WQ) const final;
std::unique_ptr<ForceDensityField<double>> DoClone() const final;
void DoDeclareCacheEntries(multibody::MultibodyPlant<double>* plant) final;
void DoDeclareInputPorts(multibody::MultibodyPlant<double>* plant) final;
const multibody::MultibodyPlant<double>* plant_{};
const multibody::BodyIndex body_;
Vector3<double> p_BC_;
double falloff_distance_{};
systems::CacheIndex point_source_position_cache_index_;
systems::InputPortIndex maximum_force_density_port_index_;
};
} // namespace deformable
} // namespace examples
} // namespace drake