@@ -29,3 +29,235 @@ class Element(metaclass=abc.ABCMeta):
29
29
tree, all references held automatically become invalid.
30
30
"""
31
31
__slots__ = []
32
+
33
+ @abc .abstractmethod
34
+ def get_init_stack (self ):
35
+ """Gets the stack trace where this element was first initialized."""
36
+
37
+ @abc .abstractmethod
38
+ def get_last_modified_stacks_for_all_attributes (self ):
39
+ """Gets a dict of stack traces where each attribute was last modified."""
40
+
41
+ @abc .abstractmethod
42
+ def is_same_as (self , other ):
43
+ """Checks whether another element is semantically equivalent to this one.
44
+
45
+ Two elements are considered equivalent if they have the same
46
+ specification (i.e. same tag appearing in the same context), the same
47
+ attribute values, and all of their children are equivalent. The ordering
48
+ of non-repeated children is not important for this comparison, while
49
+ the ordering of repeated children are important only amongst the same
50
+ type* of children. In other words, for two bodies to be considered
51
+ equivalent, their child sites must appear in the same order, and their
52
+ child geoms must appear in the same order, but permutations between sites
53
+ and geoms are disregarded. (The only exception is in tendon definition,
54
+ where strict ordering of all children is necessary for equivalence.)
55
+
56
+ *Note that the notion of "same type" in this function is very loose:
57
+ for example different actuator element subtypes are treated as separate
58
+ types when children ordering is considered. Therefore, two <actuator>
59
+ elements might be considered equivalent even though they result in different
60
+ orderings of `mjData.ctrl` when compiled. As it stands, this function
61
+ is designed primarily as a testing aid and should not be used to guarantee
62
+ that models are actually identical.
63
+
64
+ Args:
65
+ other: An `mjcf.Element`
66
+
67
+ Returns:
68
+ `True` if `other` element is semantically equivalent to this one.
69
+ """
70
+
71
+ @property
72
+ @abc .abstractmethod
73
+ def tag (self ):
74
+ pass
75
+
76
+ @property
77
+ @abc .abstractmethod
78
+ def spec (self ):
79
+ pass
80
+
81
+ @property
82
+ @abc .abstractmethod
83
+ def parent (self ):
84
+ pass
85
+
86
+ @property
87
+ @abc .abstractmethod
88
+ def namescope (self ):
89
+ pass
90
+
91
+ @property
92
+ @abc .abstractmethod
93
+ def root (self ):
94
+ pass
95
+
96
+ @abc .abstractmethod
97
+ def prefixed_identifier (self , prefix_root ):
98
+ pass
99
+
100
+ @property
101
+ @abc .abstractmethod
102
+ def full_identifier (self ):
103
+ """Fully-qualified identifier used for this element in the generated XML."""
104
+
105
+ @abc .abstractmethod
106
+ def find (self , namespace , identifier ):
107
+ """Finds an element with a particular identifier.
108
+
109
+ This function allows the direct access to an arbitrarily deeply nested
110
+ child element by name, without the need to manually traverse through the
111
+ object tree. The `namespace` argument specifies the kind of element to
112
+ find. In most cases, this corresponds to the element's XML tag name.
113
+ However, if an element has multiple specialized tags, then the namespace
114
+ corresponds to the tag name of the most general element of that kind.
115
+ For example, `namespace='joint'` would search for `<joint>` and
116
+ `<freejoint>`, while `namespace='actuator'` would search for `<general>`,
117
+ `<motor>`, `<position>`, `<velocity>`, and `<cylinder>`.
118
+
119
+ Args:
120
+ namespace: A string specifying the namespace being searched. See the
121
+ docstring above for explanation.
122
+ identifier: The identifier string of the desired element.
123
+
124
+ Returns:
125
+ An `mjcf.Element` object, or `None` if an element with the specified
126
+ identifier is not found.
127
+
128
+ Raises:
129
+ ValueError: if either `namespace` or `identifier` is not a string, or if
130
+ `namespace` is not a valid namespace.
131
+ """
132
+
133
+ @abc .abstractmethod
134
+ def find_all (self , namespace ,
135
+ immediate_children_only = False , exclude_attachments = False ):
136
+ """Finds all elements of a particular kind.
137
+
138
+ The `namespace` argument specifies the kind of element to
139
+ find. In most cases, this corresponds to the element's XML tag name.
140
+ However, if an element has multiple specialized tags, then the namespace
141
+ corresponds to the tag name of the most general element of that kind.
142
+ For example, `namespace='joint'` would search for `<joint>` and
143
+ `<freejoint>`, while `namespace='actuator'` would search for `<general>`,
144
+ `<motor>`, `<position>`, `<velocity>`, and `<cylinder>`.
145
+
146
+ Args:
147
+ namespace: A string specifying the namespace being searched. See the
148
+ docstring above for explanation.
149
+ immediate_children_only: (optional) A boolean, if `True` then only
150
+ the immediate children of this element are returned.
151
+ exclude_attachments: (optional) A boolean, if `True` then elements
152
+ belonging to attached models are excluded.
153
+
154
+ Returns:
155
+ A list of `mjcf.Element`.
156
+
157
+ Raises:
158
+ ValueError: if `namespace` is not a valid namespace.
159
+ """
160
+
161
+ @abc .abstractmethod
162
+ def enter_scope (self , scope_identifier ):
163
+ """Finds the root element of the given scope and returns it.
164
+
165
+ This function allows the access to a nested scope that is a child of this
166
+ element. The `scope_identifier` argument specifies the path to the child
167
+ scope element.
168
+
169
+ Args:
170
+ scope_identifier: The path of the desired scope element.
171
+
172
+ Returns:
173
+ An `mjcf.Element` object, or `None` if a scope element with the
174
+ specified path is not found.
175
+ """
176
+
177
+ @abc .abstractmethod
178
+ def get_attribute_xml_string (self , attribute_name , prefix_root = None ):
179
+ pass
180
+
181
+ @abc .abstractmethod
182
+ def get_attributes (self ):
183
+ pass
184
+
185
+ @abc .abstractmethod
186
+ def set_attributes (self , ** kwargs ):
187
+ pass
188
+
189
+ @abc .abstractmethod
190
+ def get_children (self , element_name ):
191
+ pass
192
+
193
+ @abc .abstractmethod
194
+ def add (self , element_name , ** kwargs ):
195
+ """Add a new child element to this element.
196
+
197
+ Args:
198
+ element_name: The tag of the element to add.
199
+ **kwargs: Attributes of the new element being created.
200
+
201
+ Raises:
202
+ ValueError: If the 'element_name' is not a valid child, or if an invalid
203
+ attribute is specified in `kwargs`.
204
+
205
+ Returns:
206
+ An `mjcf.Element` corresponding to the newly created child element.
207
+ """
208
+
209
+ @abc .abstractmethod
210
+ def remove (self , affect_attachments = False ):
211
+ """Removes this element from the model."""
212
+
213
+ @property
214
+ @abc .abstractmethod
215
+ def is_removed (self ):
216
+ pass
217
+
218
+ @abc .abstractmethod
219
+ def all_children (self ):
220
+ pass
221
+
222
+ @abc .abstractmethod
223
+ def to_xml (self , prefix_root = None , debug_context = None ):
224
+ """Generates an etree._Element corresponding to this MJCF element.
225
+
226
+ Args:
227
+ prefix_root: (optional) A `NameScope` object to be treated as root
228
+ for the purpose of calculating the prefix.
229
+ If `None` then no prefix is included.
230
+ debug_context: (optional) A `debugging.DebugContext` object to which
231
+ the debugging information associated with the generated XML is written.
232
+ This is intended for internal use within PyMJCF; users should never need
233
+ manually pass this argument.
234
+
235
+ Returns:
236
+ An etree._Element object.
237
+ """
238
+
239
+ @abc .abstractmethod
240
+ def to_xml_string (self , prefix_root = None ,
241
+ self_only = False , pretty_print = True , debug_context = None ):
242
+ """Generates an XML string corresponding to this MJCF element.
243
+
244
+ Args:
245
+ prefix_root: (optional) A `NameScope` object to be treated as root
246
+ for the purpose of calculating the prefix.
247
+ If `None` then no prefix is included.
248
+ self_only: (optional) A boolean, whether to generate an XML corresponding
249
+ only to this element without any children.
250
+ pretty_print: (optional) A boolean, whether to the XML string should be
251
+ properly indented.
252
+ debug_context: (optional) A `debugging.DebugContext` object to which
253
+ the debugging information associated with the generated XML is written.
254
+ This is intended for internal use within PyMJCF; users should never need
255
+ manually pass this argument.
256
+
257
+ Returns:
258
+ A string.
259
+ """
260
+
261
+ @abc .abstractmethod
262
+ def resolve_references (self ):
263
+ pass
0 commit comments