Source code for blueprints.placeholder

"""
Placeholders can be attached to a :class:`blueprints.body.Body` to mark prominent locations. They do not appear 
in the resulting xml model and cannot be reconstructed from xml. Is is used to mimic a node in the kinematic 
tree that can be used to specify default attachment locations. If a Thing is attached to a Placeholder it is 
instead attached to the Placeholders parent in a position and orienation as if it would have been attached to 
the Placeholder directly. This can either be used for conveniance if many Things are attached to the same spot 
on the parent Body or in constructing a template with predefined spots for attachment. The following example 
shows how to build the template of a table.

.. code-block::
	:caption: Example table construction

	>>> top = blue.geoms.Box(name='top', x_length=2, y_length=1, z_length=0.002)
	>>> leg = blue.geoms.Box.from_points([0, 0, 0], [0, 0, 1], radius=0.03, name='leg')
	>>> table = blue.Body(name='table', pos=[0, 0, 1], geoms=top)
	>>> table.attach(blue.Placeholder(pos=[ 0.9, 0.4, 0], alpha=PI), 
	>>>              blue.Placeholder(pos=[ 0.9,-0.4, 0], alpha=PI), 
	>>>              blue.Placeholder(pos=[-0.9, 0.4, 0], alpha=PI), 
	>>>              blue.Placeholder(pos=[-0.9,-0.4, 0], alpha=PI))
	>>> table.placeholders.attach(leg)
	>>> table.geoms
	View[5|table.geoms]
	>>> table.attach(blue.Placeholder(name='plate', pos=[-0.7, 0, 0]), 
	>>>              blue.Placeholder(name='plate', pos=[ 0.7, 0, 0]))
	>>> table.placeholders
	['leg_(0)', 'leg_(1)', 'leg_(2)', 'leg_(3)', 'plate_(0)', 'plate_(1)']

.. code-block:: mxml
	:caption: XML structure

	<body pos="0.0 0.0 1.0" name="table">
		<geom size="1.0 0.5 0.001" type="box" name="top" />
		<geom size="0.015 0.015 0.5" type="box" euler="3.1415927 0.0 0.0" pos=" 0.9  0.4 -0.5" name="leg_(0)" />
		<geom size="0.015 0.015 0.5" type="box" euler="3.1415927 0.0 0.0" pos=" 0.9 -0.4 -0.5" name="leg_(1)" />
		<geom size="0.015 0.015 0.5" type="box" euler="3.1415927 0.0 0.0" pos="-0.9  0.4 -0.5" name="leg_(2)" />
		<geom size="0.015 0.015 0.5" type="box" euler="3.1415927 0.0 0.0" pos="-0.9 -0.4 -0.5" name="leg_(3)" />
	</body>
"""
import numpy as np
import blueprints as blue



[docs] class Placeholder(blue.PlaceholderType, blue.MoveableThing): """ This class is available through the shortcut :class:`blueprints.Placeholder <Placeholder>`. Placeholders can be attached to a :class:`blueprints.body.Body` to mark special places and orientations for attachment. It will not be included into the xml. Parameters ---------- pos : list[int | float] | np.ndarray, optional Represents the position of the object. Changing this attribute also changes the properties :attr:`x`, :attr:`y` and :attr:`z`. alpha : int | float | None, optional (Improper) euler angle of rotation around the x-axis in radian. Changing this value also changes the :attr:`euler` property. beta : int | float | None, optional (Improper) euler angle of rotation around the y-axis in radian. Changing this value also changes the :attr:`euler` property. gamma : int | float | None, optional (Improper) euler angle of rotation around the z-axis in radian. Changing this value also changes the :attr:`euler` property. name : str | None, optional The user specified name of the Body. In the case of a naming conflict the name is appended by an enumeration scheme. **kwargs Keyword arguments are passed to ``super().__init__``. Attributes ---------- parent : blue.NodeThingType | None When a Thing is attached to the Placeholder, it instead gets attached to the parent and its position and orientation will be adjusted such that it is positioned and oriented as if it were attached of the Placeholder. """
[docs] def attach(self, *args): """ Things that are attached to a Placeholder are instead attached to the Placeholders parent Body in a position and orientation as if they were attached to the Placeholder directly. Parameters ---------- *args the Things that sould be attached to the Placeholders :attr:`parent` Raises ------ Expection If the Placeholder is not attached to a parent an error is raised. """ if self.parent is None: raise Expection('Placeholders must be attached to a body before a Thing can be attached to them!') else: args = [arg.rotate(self.alpha, self.beta, self.gamma, center=np.zeros(3), globally=False).shift(self.pos) for arg in args] self.parent.attach(*args)
[docs] def detach(self, *args): """ This method redirects to the Placeholders parent. This means, that Things that have not been attached to the parent directly (not via the Placeholder) can also be detached with this method. Parameters ---------- *args the Things that sould be detached from the Placeholders :attr:`parent` """ if self.parent is None: raise Expection('Placeholders must be attached to a body before a Thing can be detached from them!') self.parent.detach(*args)
@blue.restrict def _build(self, parent, world, indicies, **kwargs): """ Placeholders are not part of mujoco xml. Parameters ---------- parent : xml.etree.ElementTree.Element The parent of the Thing world : blue.WorldType The World from which the initial _meth:`blueprints.world.World.build` method was called. """ pass