forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
internal_frame.h
192 lines (152 loc) · 7.04 KB
/
internal_frame.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
#pragma once
#include <string>
#include <unordered_set>
#include "drake/common/drake_copyable.h"
#include "drake/geometry/geometry_ids.h"
namespace drake {
namespace geometry {
namespace internal {
/* This is the internal representation of a GeometryFrame. It includes the
user-specified data (name and frame group), excludes the pose data, and then
includes topology data.
It is not intended to be used outside of the geometry library. To instantiate
frames in SceneGraph, use the drake::geometry::GeometryFrame class in
conjunction with the SceneGraph::RegisterFrame() methods.
This class works with InternalGeometry. The relationships between frames and
geometries are *stored* in these classes but these classes have no logic to
enforce a coherent picture. For example, an InternalFrame F can claim to have
another frame G as its child, such that G's frame id appears F's list of child
frame ids. However, this class does not guarantee that the instance of
%InternalFrame for G correctly reports F's id as its parent frame. It relies
on GeometryState to enforce those invariants. The same can be said of child
InternalGeometry instances. */
class InternalFrame {
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(InternalFrame)
/* Default constructor. The parent identifier and pose index will be
invalid. */
InternalFrame();
/* Full constructor.
@param source_id The identifier of the source this belongs to.
@param frame_id The identifier of _this_ frame.
@param name The name of the frame.
@param frame_group The frame's frame group membership.
@param index The index of this frame in the SceneGraph.
@param parent_id The id of the parent frame. */
InternalFrame(SourceId source_id, FrameId frame_id, const std::string& name,
int frame_group, int index, FrameId parent_id);
/* Compares two %InternalFrame instances for "equality". Two internal frames
are considered equal if they have the same frame identifier. */
bool operator==(const InternalFrame &other) const;
/* Compares two %InternalFrame instances for inequality. See operator==()
for the definition of equality. */
bool operator!=(const InternalFrame &other) const;
/* @name Frame properties */
//@{
/* Returns the source id that registered the frame. */
SourceId source_id() const { return source_id_; }
/* Returns the globally unique identifier for this frame. */
FrameId id() const { return id_; }
/* Returns the name of this frame. */
const std::string& name() const { return name_; }
/* Returns the frame group of this frame. It is an externally defined integer
value that can be used to create relationships between frames; it has no
internal significance or dependencies. */
int frame_group() const { return frame_group_; }
/* Returns the index of this frame in the full scene graph. */
int index() const { return index_; }
//@}
/* @name Scene Graph topology */
//@{
/* Returns true if this frame has the given id as its parent. */
bool has_parent(FrameId parent) const { return parent_id_ == parent; }
/* Returns true if this frame is the one and only world frame. */
bool is_world() const { return id_ == world_frame_id(); }
/* Returns the id of this frame's parent frame. If this is the world frame,
it returns its own id (as there is no usable "undefined" identifier value).
*/
FrameId parent_frame_id() const { return parent_id_; }
/* Returns a list of ids of the frames that have *this* frame as a parent
frame. */
const std::unordered_set<FrameId>& child_frames() const {
return child_frames_;
}
/* Returns a list of ids of the geometries that are *directly* attached to
this frame. It does *not* include geometries that are attached to child
frames of this frame. */
const std::unordered_set<GeometryId>& child_geometries() const {
return child_geometries_;
}
/* The number of total geometries attached to this frame. It should be true
that `this->num_child_geometries() == this->child_geometries().size()`.
To determine the number of geometries attached to this frame *by geometry
role*, use the GeometryState::GetNumFrameGeometriesByRole() method. */
int num_child_geometries() const {
return static_cast<int>(child_geometries_.size());
}
/* Returns true if this frame considers the given `frame_id` to be a child.
*/
bool has_child(FrameId frame_id) const {
return child_frames_.count(frame_id) > 0;
}
/* Adds the given `frame_id` to the set of frames that this frame considers
to be children. */
void add_child(FrameId frame_id) {
child_frames_.insert(frame_id);
}
/* Returns true if this frame considers the given `geometry_id` to be rigidly
affixed to it. */
bool has_child(GeometryId geometry_id) const {
return child_geometries_.count(geometry_id) > 0;
}
/* Adds the given `geometry_id` to the set of geometries that this frame
considers to be children. */
void add_child(GeometryId geometry_id) {
child_geometries_.insert(geometry_id);
}
/* Removes the given `geometry_id` from the set of geometries that this frame
considers to be children.
@pre the id _is_ a valid child of this frame. */
void remove_child(GeometryId geometry_id) {
DRAKE_ASSERT(child_geometries_.count(geometry_id) > 0);
child_geometries_.erase(geometry_id);
}
/* The identifier used for identifying the single world frame in all
instances of SceneGraph. The world frame will eventually have an arbitrary
number of child frames and geometries; but there will always only be one
world frame. */
static FrameId world_frame_id();
/* Reports the reserved frame group for the world frame. */
static int world_frame_group() {
// Pick a sentinel value that can't be mistaken for initialization noise.
// Users cannot declare geometry frames with negative frame groups
// so, using this value won't collide with any valid user-specified value.
return -1234567;
}
private:
// The identifier of the source, to which this frame belongs.
SourceId source_id_;
// The identifier of this frame.
FrameId id_;
// The name of the frame. Must be unique across frames from the same
// geometry source.
std::string name_;
// TODO(SeanCurtis-TRI): Consider whether this should be an Identifier or
// TypeSafeIndex type.
// The frame group to which this frame belongs.
int frame_group_{0};
// The index of this frame in the full SceneGraph.
int index_{};
// The identifier of this frame's parent frame.
FrameId parent_id_;
// The identifiers of the frames, who have this frame as parent.
std::unordered_set<FrameId> child_frames_;
// The identifiers for the geometries that are rigidly affixed to this frame.
// This includes geometries that were hung directly on the frame and those
// that were hung on geometries that were already rigidly affixed.
// It does *not* include geometries hung on child frames.
std::unordered_set<GeometryId> child_geometries_;
};
} // namespace internal
} // namespace geometry
} // namespace drake