-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
manipulation_station.h
554 lines (495 loc) · 25.1 KB
/
manipulation_station.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
#pragma once
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "drake/common/eigen_types.h"
#include "drake/geometry/render/render_engine.h"
#include "drake/geometry/scene_graph.h"
#include "drake/math/rigid_transform.h"
#include "drake/multibody/plant/multibody_plant.h"
#include "drake/systems/framework/diagram.h"
namespace drake {
namespace examples {
namespace manipulation_station {
/// Determines which sdf is loaded for the IIWA in the ManipulationStation.
enum class IiwaCollisionModel { kNoCollision, kBoxCollision };
/// Determines which schunk model is used for the ManipulationStation.
/// - kBox loads a model with a box collision geometry. This model is for those
/// who want simplified collision behavior.
/// - kBoxPlusFingertipSpheres loads a Schunk model with collision
/// spheres that models the indentations at tip of the fingers, in addition
/// to the box collision geometry on the fingers.
enum class SchunkCollisionModel { kBox, kBoxPlusFingertipSpheres };
/// Determines which manipulation station is simulated.
enum class Setup { kNone, kManipulationClass, kClutterClearing, kPlanarIiwa };
/// @defgroup manipulation_station_systems Manipulation Station
/// @{
/// @brief Systems related to the "manipulation station" used in the <a
/// href="https://manipulation.csail.mit.edu">MIT Intelligent Robot
/// Manipulation</a> class.
/// @ingroup example_systems
/// @}
/// A system that represents the complete manipulation station, including
/// exactly one robotic arm (a Kuka IIWA LWR), one gripper (a Schunk WSG 50),
/// and anything a user might want to load into the model.
/// SetupDefaultStation() provides the setup that is used in the MIT
/// Intelligent Robot Manipulation class, which includes the supporting
/// structure for IIWA and several RGBD cameras. Alternative Setup___()
/// methods are provided, as well.
///
/// @system
/// name: ManipulationStation
/// input_ports:
/// - iiwa_position
/// - iiwa_feedforward_torque (optional)
/// - wsg_position
/// - wsg_force_limit (optional)
/// - <b style="color:orange">applied_spatial_force (optional)</b>
/// output_ports:
/// - iiwa_position_commanded
/// - iiwa_position_measured
/// - iiwa_velocity_estimated
/// - iiwa_state_estimated
/// - iiwa_torque_commanded
/// - iiwa_torque_measured
/// - iiwa_torque_external
/// - wsg_state_measured
/// - wsg_force_measured
/// - camera_[NAME]_rgb_image
/// - camera_[NAME]_depth_image
/// - <b style="color:orange">camera_[NAME]_label_image</b>
/// - <b style="color:orange">camera_[NAME]_point_cloud</b>
/// - ...
/// - camera_[NAME]_rgb_image
/// - camera_[NAME]_depth_image
/// - <b style="color:orange">camera_[NAME]_label_image</b>
/// - <b style="color:orange">camera_[NAME]_point_cloud</b>
/// - <b style="color:orange">query_object</b>
/// - <b style="color:orange">contact_results</b>
/// - <b style="color:orange">plant_continuous_state</b>
/// - <b style="color:orange">geometry_poses</b>
/// @endsystem
///
/// Each pixel in the output image from `depth_image` is a 16bit unsigned
/// short in millimeters.
///
/// Note that outputs in <b style="color:orange">orange</b> are
/// available in the simulation, but not on the real robot. The distinction
/// between q_measured and v_estimated is because the Kuka FRI reports
/// positions directly, but we have estimated v in our code that wraps the
/// FRI.
///
/// @warning The "camera_[NAME]_point_cloud" data currently has registration
/// errors per issue https://github.com/RobotLocomotion/drake/issues/12125.
///
/// Consider the robot dynamics
/// M(q)vdot + C(q,v)v = τ_g(q) + τ_commanded + τ_joint_friction + τ_external,
/// where q == position, v == velocity, and τ == torque.
///
/// This model of the IIWA internal controller in the FRI software's
/// `JointImpedanceControlMode` is:
/// <pre>
/// τ_commanded = Mₑ(qₑ)vdot_desired + Cₑ(qₑ, vₑ)vₑ - τₑ_g(q) -
/// τₑ_joint_friction + τ_feedforward
/// vdot_desired = PID(q_commanded, qₑ, v_commanded, vₑ)
/// </pre>
/// where Mₑ, Cₑ, τₑ_g, and τₑ_friction terms are now (Kuka's) estimates of the
/// true model, qₑ and vₑ are measured/estimation, and v_commanded
/// must be obtained from an online (causal) derivative of q_commanded. The
/// result is
/// <pre>
/// M(q)vdot ≈ Mₑ(q)vdot_desired + τ_feedforward + τ_external,
/// </pre>
/// where the "approximately equal" comes from the differences due to the
/// estimated model/state.
///
/// The model implemented in this System assumes that M, C, and τ_friction
/// terms are perfect (except that they contain only a lumped mass
/// approximation of the gripper), and that the measured signals are
/// noise/bias free (e.g. q_measured = q, v_estimated = v, τ_measured =
/// τ_commanded). What remains for τ_external is the generalized forces due
/// to contact (note that they could also include the missing contributions
/// from the gripper fingers, which the controller assumes are welded).
/// @see lcmt_iiwa_status.lcm for additional details/documentation.
///
///
/// To add objects into the environment for the robot to manipulate, use,
/// e.g.:
/// @code
/// ManipulationStation<double> station;
/// Parser parser(&station.get_mutable_multibody_plant(),
/// &station.get_mutable_scene_graph());
/// parser.AddModels("my.sdf");
/// ...
/// // coming soon -- sugar API for adding additional objects.
/// station.Finalize()
/// @endcode
/// Note that you *must* call Finalize() before you can use this class as a
/// System.
///
/// @tparam_double_only
/// @ingroup manipulation_station_systems
template <typename T>
class ManipulationStation : public systems::Diagram<T> {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(ManipulationStation)
/// Construct the EMPTY station model.
///
/// @param time_step The time step used by MultibodyPlant<T>, and by the
/// discrete derivative used to approximate velocity from the position
/// command inputs.
explicit ManipulationStation(double time_step = 0.002);
/// Adds a default iiwa, wsg, two bins, and a camera, then calls
/// RegisterIiwaControllerModel() and RegisterWsgControllerModel() with
/// the appropriate arguments.
/// @note Must be called before Finalize().
/// @note Only one of the `Setup___()` methods should be called.
/// @param X_WCameraBody Transformation between the world and the camera body.
/// @param collision_model Determines which sdf is loaded for the IIWA.
/// @param schunk_model Determines which sdf is loaded for the Schunk.
void SetupClutterClearingStation(
const std::optional<const math::RigidTransformd>& X_WCameraBody = {},
IiwaCollisionModel collision_model = IiwaCollisionModel::kNoCollision,
SchunkCollisionModel schunk_model = SchunkCollisionModel::kBox);
/// Adds a default iiwa, wsg, cupboard, and 80/20 frame for the MIT
/// Intelligent Robot Manipulation class, then calls
/// RegisterIiwaControllerModel() and RegisterWsgControllerModel() with
/// the appropriate arguments.
/// @note Must be called before Finalize().
/// @note Only one of the `Setup___()` methods should be called.
/// @param collision_model Determines which sdf is loaded for the IIWA.
/// @param schunk_model Determines which sdf is loaded for the Schunk.
void SetupManipulationClassStation(
IiwaCollisionModel collision_model = IiwaCollisionModel::kNoCollision,
SchunkCollisionModel schunk_model = SchunkCollisionModel::kBox);
/// Adds a version of the iiwa with joints that would result in
/// out-of-plane rotations welded in a fixed orientation, reducing the
/// total degrees of freedom of the arm to 3. This arm lives in the X-Z
/// plane. Also adds the WSG planar gripper and two tables to form the
/// workspace. Note that additional floating base objects (aka
/// manipulands) will still potentially move in 3D.
/// @note Must be called before Finalize().
/// @note Only one of the `Setup___()` methods should be called.
/// @param schunk_model Determines which sdf is loaded for the Schunk.
void SetupPlanarIiwaStation(
SchunkCollisionModel schunk_model = SchunkCollisionModel::kBox);
/// Sets the default State for the chosen setup.
/// @param context A const reference to the ManipulationStation context.
/// @param state A pointer to the State of the ManipulationStation system.
/// @pre `state` must be the systems::State<T> object contained in
/// `station_context`.
void SetDefaultState(const systems::Context<T>& station_context,
systems::State<T>* state) const override;
/// Sets a random State for the chosen setup.
/// @param context A const reference to the ManipulationStation context.
/// @param state A pointer to the State of the ManipulationStation system.
/// @param generator is the random number generator.
/// @pre `state` must be the systems::State<T> object contained in
/// `station_context`.
void SetRandomState(const systems::Context<T>& station_context,
systems::State<T>* state,
RandomGenerator* generator) const override;
/// Notifies the ManipulationStation that the IIWA robot model instance can
/// be identified by @p iiwa_instance as well as necessary information to
/// reload model for the internal controller's use. Assumes @p iiwa_instance
/// has already been added to the MultibodyPlant.
/// Note, the current implementation only allows @p parent_frame to be the
/// world frame. The IIWA frame needs to directly contain @p child_frame.
/// Only call this with custom IIWA models (i.e. not calling
/// SetupDefaultStation()). Must be called before Finalize().
/// @param model_path Full path to the model file.
/// @param iiwa_instance Identifies the IIWA model.
/// @param parent_frame Identifies frame P (the parent frame) in the
/// MultibodyPlant that the IIWA model has been attached to.
/// @param child_frame_name Identifies frame C (the child frame) in the IIWA
/// model that is welded to frame P.
/// @param X_PC Transformation between frame P and C.
/// @throws If @p parent_frame is not the world frame.
// TODO(siyuan.feng@tri.global): throws meaningful errors earlier here,
// rather than in Finalize() if the arguments are inconsistent with the plant.
// TODO(siyuan.feng@tri.global): remove the assumption that parent frame has
// to be world.
// TODO(siyuan.feng@tri.global): Some of these information should be
// retrievable from the MultibodyPlant directly or MultibodyPlant should
// provide partial tree cloning.
// TODO(jwnimmer-tri) The model_path should be a package URL, not a filename.
void RegisterIiwaControllerModel(
const std::string& model_path,
const multibody::ModelInstanceIndex iiwa_instance,
const multibody::Frame<T>& parent_frame,
const multibody::Frame<T>& child_frame,
const math::RigidTransform<double>& X_PC);
/// Notifies the ManipulationStation that the WSG gripper model instance can
/// be identified by @p wsg_instance, as well as necessary information to
/// reload model for the internal controller's use. Assumes @p wsg_instance
/// has already been added to the MultibodyPlant. The IIWA model needs to
/// directly contain @p parent_frame, and the WSG model needs to directly
/// contain @p child_frame.
/// Only call this with custom WSG models (i.e. not calling
/// SetupDefaultStation()). Must be called before Finalize().
/// @param model_path Full path to the model file.
/// @param wsg_instance Identifies the WSG model.
/// @param parent_frame Identifies frame P (the parent frame) in the
/// MultibodyPlant that the WSG model has been attached to. Has to be part
/// of the IIWA model.
/// @param child_frame Identifies frame C (the child frame) in the WSG
/// model that is used welded to frame P.
/// @param X_PC Transformation between frame P and C.
// TODO(siyuan.feng@tri.global): Some of these information should be
// retrievable from the MultibodyPlant directly or MultibodyPlant should
// provide partial tree cloning.
// TODO(siyuan.feng@tri.global): throws meaningful errors earlier here,
// rather than in Finalize() if the arguments are inconsistent with the plant.
void RegisterWsgControllerModel(
const std::string& model_path,
const multibody::ModelInstanceIndex wsg_instance,
const multibody::Frame<T>& parent_frame,
const multibody::Frame<T>& child_frame,
const math::RigidTransform<double>& X_PC);
/// Registers an RGBD sensor. Must be called before Finalize().
/// @param name Name for the camera.
/// @param parent_frame The parent frame (frame P). The body that
/// @p parent_frame is attached to must have a corresponding
/// geometry::FrameId. Otherwise, an exception will be thrown in Finalize().
/// @param X_PCameraBody Transformation between frame P and the camera body.
/// see systems::sensors:::RgbdSensor for descriptions about how the
/// camera body, RGB, and depth image frames are related.
/// @param depth_camera Specification for the RGBD camera. The color render
/// camera is inferred from the depth_camera. The color camera will share the
/// RenderCameraCore and be configured to *not* show its window.
/// @pydrake_mkdoc_identifier{single_camera}
void RegisterRgbdSensor(
const std::string& name, const multibody::Frame<T>& parent_frame,
const math::RigidTransform<double>& X_PCameraBody,
const geometry::render::DepthRenderCamera& depth_camera);
/// Registers an RGBD sensor with uniquely characterized color/label and
/// depth cameras.
/// @pydrake_mkdoc_identifier{dual_camera}
void RegisterRgbdSensor(
const std::string& name, const multibody::Frame<T>& parent_frame,
const math::RigidTransform<double>& X_PCameraBody,
const geometry::render::ColorRenderCamera& color_camera,
const geometry::render::DepthRenderCamera& depth_camera);
/// Adds a single object for the robot to manipulate
/// @note Must be called before Finalize().
/// @param model_file The path to the .sdf model file of the object.
/// @param X_WObject The pose of the object in world frame.
void AddManipulandFromFile(const std::string& model_file,
const math::RigidTransform<double>& X_WObject);
// TODO(russt): Add scalar copy constructor etc once we support more
// scalar types than T=double. See #9573.
/// Users *must* call Finalize() after making any additions to the
/// multibody plant and before using this class in the Systems framework.
/// This should be called exactly once.
/// This assumes an IIWA and WSG have been added to the MultibodyPlant, and
/// RegisterIiwaControllerModel() and RegisterWsgControllerModel() have been
/// called.
///
/// @see multibody::MultibodyPlant<T>::Finalize()
void Finalize();
/// Finalizes the station with the option of specifying the renderers the
/// manipulation station uses. Calling this method with an empty map is
/// equivalent to calling Finalize(). See Finalize() for more details.
void Finalize(std::map<std::string,
std::unique_ptr<geometry::render::RenderEngine>>
render_engines);
/// Returns a reference to the main plant responsible for the dynamics of
/// the robot and the environment. This can be used to, e.g., add
/// additional elements into the world before calling Finalize().
const multibody::MultibodyPlant<T>& get_multibody_plant() const {
return *plant_;
}
/// Returns a mutable reference to the main plant responsible for the
/// dynamics of the robot and the environment. This can be used to, e.g.,
/// add additional elements into the world before calling Finalize().
multibody::MultibodyPlant<T>& get_mutable_multibody_plant() {
return *plant_;
}
/// Returns a reference to the SceneGraph responsible for all of the geometry
/// for the robot and the environment. This can be used to, e.g., add
/// additional elements into the world before calling Finalize().
const geometry::SceneGraph<T>& get_scene_graph() const {
return *scene_graph_;
}
/// Returns a mutable reference to the SceneGraph responsible for all of the
/// geometry for the robot and the environment. This can be used to, e.g.,
/// add additional elements into the world before calling Finalize().
geometry::SceneGraph<T>& get_mutable_scene_graph() { return *scene_graph_; }
/// Returns the name of the station's default renderer.
static std::string default_renderer_name() { return default_renderer_name_; }
/// Return a reference to the plant used by the inverse dynamics controller
/// (which contains only a model of the iiwa + equivalent mass of the
/// gripper).
const multibody::MultibodyPlant<T>& get_controller_plant() const {
return *owned_controller_plant_;
}
/// Gets the number of joints in the IIWA (only -- does not include the
/// gripper).
/// @pre must call one of the "setup" methods first to register an IIWA
/// model.
int num_iiwa_joints() const;
/// Convenience method for getting all of the joint angles of the Kuka IIWA.
/// This does not include the gripper.
VectorX<T> GetIiwaPosition(const systems::Context<T>& station_context) const;
/// Convenience method for setting all of the joint angles of the Kuka IIWA.
/// Also sets the position history in the velocity command generator.
/// @p q must have size num_iiwa_joints().
/// @pre `state` must be the systems::State<T> object contained in
/// `station_context`.
void SetIiwaPosition(const systems::Context<T>& station_context,
systems::State<T>* state,
const Eigen::Ref<const VectorX<T>>& q) const;
/// Convenience method for setting all of the joint angles of the Kuka IIWA.
/// Also sets the position history in the velocity command generator.
/// @p q must have size num_iiwa_joints().
void SetIiwaPosition(systems::Context<T>* station_context,
const Eigen::Ref<const VectorX<T>>& q) const {
SetIiwaPosition(*station_context, &station_context->get_mutable_state(), q);
}
/// Convenience method for getting all of the joint velocities of the Kuka
// IIWA. This does not include the gripper.
VectorX<T> GetIiwaVelocity(const systems::Context<T>& station_context) const;
/// Convenience method for setting all of the joint velocities of the Kuka
/// IIWA. @v must have size num_iiwa_joints().
/// @pre `state` must be the systems::State<T> object contained in
/// `station_context`.
void SetIiwaVelocity(const systems::Context<T>& station_context,
systems::State<T>* state,
const Eigen::Ref<const VectorX<T>>& v) const;
/// Convenience method for setting all of the joint velocities of the Kuka
/// IIWA. @v must have size num_iiwa_joints().
void SetIiwaVelocity(systems::Context<T>* station_context,
const Eigen::Ref<const VectorX<T>>& v) const {
SetIiwaVelocity(*station_context, &station_context->get_mutable_state(), v);
}
/// Convenience method for getting the position of the Schunk WSG. Note
/// that the WSG position is the signed distance between the two fingers
/// (not the state of the fingers individually).
T GetWsgPosition(const systems::Context<T>& station_context) const;
/// Convenience method for getting the velocity of the Schunk WSG.
T GetWsgVelocity(const systems::Context<T>& station_context) const;
/// Convenience method for setting the position of the Schunk WSG. Also
/// sets the position history in the velocity interpolator. Note that the
/// WSG position is the signed distance between the two fingers (not the
/// state of the fingers individually).
/// @pre `state` must be the systems::State<T> object contained in
/// `station_context`.
void SetWsgPosition(const systems::Context<T>& station_context,
systems::State<T>* state, const T& q) const;
/// Convenience method for setting the position of the Schunk WSG. Also
/// sets the position history in the velocity interpolator. Note that the
/// WSG position is the signed distance between the two fingers (not the
/// state of the fingers individually).
void SetWsgPosition(systems::Context<T>* station_context, const T& q) const {
SetWsgPosition(*station_context, &station_context->get_mutable_state(), q);
}
/// Convenience method for setting the velocity of the Schunk WSG.
/// @pre `state` must be the systems::State<T> object contained in
/// `station_context`.
void SetWsgVelocity(const systems::Context<T>& station_context,
systems::State<T>* state, const T& v) const;
/// Convenience method for setting the velocity of the Schunk WSG.
void SetWsgVelocity(systems::Context<T>* station_context, const T& v) const {
SetWsgVelocity(*station_context, &station_context->get_mutable_state(), v);
}
/// Returns a map from camera name to X_WCameraBody for all the static
/// (rigidly attached to the world body) cameras that have been registered.
///
/// <!-- TODO(EricCousineau-TRI) To simplify (and possibly modularize) this
/// class, frame kinematics should be handled by MbP frames, since that's
/// where they have the most relevance. Change in workflow would be:
/// - Add camera frame first to the tree;
/// - Add camera directly to frame (perhaps without offset, per #10247);
/// - Change this function to return frames, so that we aren't restricted to
/// fixed-scene cameras.
/// -->
std::map<std::string, math::RigidTransform<double>>
GetStaticCameraPosesInWorld() const;
/// Get the camera names / unique ids.
std::vector<std::string> get_camera_names() const;
/// Set the gains for the WSG controller.
/// @throws std::exception if Finalize() has been called.
void SetWsgGains(double kp, double kd);
/// Set the position gains for the IIWA controller.
/// @throws std::exception if Finalize() has been called.
void SetIiwaPositionGains(const VectorX<double>& kp) {
DRAKE_THROW_UNLESS(!plant_->is_finalized());
iiwa_kp_ = kp;
}
/// Set the velocity gains for the IIWA controller.
/// @throws std::exception if Finalize() has been called.
void SetIiwaVelocityGains(const VectorX<double>& kd) {
DRAKE_THROW_UNLESS(!plant_->is_finalized());
iiwa_kd_ = kd;
}
/// Set the integral gains for the IIWA controller.
/// @throws std::exception if Finalize() has been called.
void SetIiwaIntegralGains(const VectorX<double>& ki) {
DRAKE_THROW_UNLESS(!plant_->is_finalized());
iiwa_ki_ = ki;
}
private:
// Struct defined to store information about the how to parse and add a model.
struct ModelInformation {
/// This needs to have the full path. i.e. drake::FindResourceOrThrow(...)
std::string model_path;
multibody::ModelInstanceIndex model_instance;
const multibody::Frame<T>* parent_frame{};
const multibody::Frame<T>* child_frame{};
math::RigidTransform<double> X_PC{math::RigidTransform<double>::Identity()};
};
struct CameraInformation {
const multibody::Frame<T>* parent_frame{};
math::RigidTransform<double> X_PC{math::RigidTransform<double>::Identity()};
geometry::render::ColorRenderCamera color_camera{
{"", {2, 2, M_PI}, {0.1, 10}, {}}, // RenderCameraCore
false, // show_window
};
geometry::render::DepthRenderCamera depth_camera{
{"", {2, 2, M_PI}, {0.1, 10}, {}}, // RenderCameraCore
{0.1, 0.2}, // DepthRange
};
};
// Assumes iiwa_model_info_ and wsg_model_info_ have already being populated.
// Should only be called from Finalize().
void MakeIiwaControllerModel();
void AddDefaultIiwa(const IiwaCollisionModel collision_model);
void AddDefaultWsg(const SchunkCollisionModel schunk_model);
// These are only valid until Finalize() is called.
std::unique_ptr<multibody::MultibodyPlant<T>> owned_plant_;
std::unique_ptr<geometry::SceneGraph<T>> owned_scene_graph_;
// These are valid for the lifetime of this system.
std::unique_ptr<multibody::MultibodyPlant<T>> owned_controller_plant_;
multibody::MultibodyPlant<T>* plant_;
geometry::SceneGraph<T>* scene_graph_;
static constexpr const char* default_renderer_name_ =
"manip_station_renderer";
// Populated by RegisterIiwaControllerModel() and
// RegisterWsgControllerModel().
ModelInformation iiwa_model_;
ModelInformation wsg_model_;
// Store references to objects as *body* indices instead of model indices,
// because this is needed for MultibodyPlant::SetFreeBodyPose(), etc.
std::vector<multibody::BodyIndex> object_ids_;
std::vector<math::RigidTransform<T>> object_poses_;
// Registered camera related information.
std::map<std::string, CameraInformation> camera_information_;
// These are kp and kd gains for iiwa and wsg controllers.
VectorX<double> iiwa_kp_;
VectorX<double> iiwa_kd_;
VectorX<double> iiwa_ki_;
// TODO(siyuan.feng@tri.global): Need to tunes these better.
double wsg_kp_{200};
double wsg_kd_{5};
// Represents the manipulation station to simulate. This gets set in the
// corresponding station setup function (e.g.,
// SetupManipulationClassStation()), and informs how SetDefaultState()
// initializes the sim.
Setup setup_{Setup::kNone};
};
} // namespace manipulation_station
} // namespace examples
} // namespace drake