Regions

Regions#

Regions are entities in the world similar to bodies; they live in the same kinematic tree but represent semantic areas rather than physical geometry. For example, a region can represent the surface of a table that you can place objects on, or the opening of a container you can insert items into.

This tutorial explores a region describing the supporting surface of a table-top.

Used Concepts:

First, let’s create a simple table with one leg.

from semantic_world.datastructures.prefixed_name import PrefixedName
from semantic_world.spatial_types import TransformationMatrix
from semantic_world.world import World
from semantic_world.world_description.connections import FixedConnection, Connection6DoF
from semantic_world.world_description.geometry import Box, Scale
from semantic_world.world_description.world_entity import Body, Region
from semantic_world.spatial_computations.raytracer import RayTracer

world = World()

root = Body(name=PrefixedName("root"))

table_leg = Body(name=PrefixedName("leg"))
leg_shapes = [
    Box(
        origin=TransformationMatrix(reference_frame=table_leg),
        scale=Scale(0.1, 0.1, 0.6),
    )
]
table_leg.collision = leg_shapes
table_leg.visual = leg_shapes

table_top = Body(name=PrefixedName("top"))
table_top_shapes = [
    Box(
        origin=TransformationMatrix(reference_frame=table_top),
        scale=Scale(1, 1, 0.05),
    )
]
table_top.collision = table_top_shapes
table_top.visual = table_top_shapes

with world.modify_world():
    root_to_leg = Connection6DoF(parent=root, child=table_leg, _world=world)
    world.add_connection(root_to_leg)

    leg_to_top = FixedConnection(
        parent=table_leg,
        child=table_top,
        origin_expression=TransformationMatrix.from_xyz_rpy(
            z=0.3, reference_frame=table_leg
        ),
        _world=world,
    )
    world.add_connection(leg_to_top)

Next, we create a region describing the top of the table. We declare that the region is a very thin box that sits on top of the table-top.

table_surface = Region(
    name=PrefixedName("supporting surface of table"),
)

surface = Box(
    origin=TransformationMatrix.from_xyz_rpy(z=0.05 / 2, reference_frame=table_surface),
    scale=Scale(1, 1, 0.001),
)
table_surface.area = [surface]

Regions are connected the same way bodies are connected. Hence, you can specify how the regions move w. r. t. to a body or even another region. We will now say the the region moves exactly as the table top moves.

with world.modify_world():
    world.add_kinematic_structure_entity(table_surface)
    connection = FixedConnection(table_top, table_surface, _world=world)
    world.add_connection(connection)
print(world.regions)
[Region(name=PrefixedName(name='supporting surface of table', prefix=None), index=3, area=[Box(origin=TransformationMatrix(reference_frame=..., casadi_sx=SX(@1=1, @2=0, 
[[@1, @2, @2, @2], 
 [@2, @1, @2, @2], 
 [@2, @2, @1, 0.025], 
 [00, 00, 00, @1]]), child_frame=None), color=Color(R=1.0, G=1.0, B=1.0, A=1.0), scale=Scale(x=1.0, y=1.0, z=0.001))])]

We can now see that if we move the table, we also move the region.

print(table_surface.global_pose.to_position().to_np()[:3])

with world.modify_world():
    root_to_leg.origin = TransformationMatrix.from_xyz_rpy(
        x=1.0, y=2.0, reference_frame=table_leg
    )

print(table_surface.global_pose.to_position().to_np()[:3])
[0.  0.  0.3]
[1.  2.  0.3]

Note that Regions are a relatively new concept that may change in the future.