Skip to content
Snippets Groups Projects
Commit cf02c73b authored by Andi Gerken's avatar Andi Gerken
Browse files

Renamed entity_poses to poses and select_entity_poses() to select_poses()

parent d7e6d77e
No related branches found
No related tags found
No related merge requests found
Pipeline #35782 passed
%% Cell type:code id: tags:
``` python
#! /usr/bin/env python3
import robofish.io
import numpy as np
from pathlib import Path
import os
# Helper function to enable relative paths from this file
def full_path(path):
return (Path(os.path.abspath("__file__")).parent / path).resolve()
if __name__ == "__main__":
# Create a new io file object with a 100x100cm world
sf = robofish.io.File(world_size=[100, 100])
# create a simple obstacle, fixed in place, fixed outline
obstacle_pose = [[50, 50, 0, 0]]
obstacle_outline = [[[-10, -10], [-10, 0], [0, 0], [0, -10]]]
obstacle_name = sf.create_entity(
"obstacle", poses=obstacle_pose, outlines=obstacle_outline
)
# create a robofish with 100 timesteps and 40ms between the timesteps. If we would not give a name, the name would be generated to be robot_1.
robofish_timesteps = 4
robofish_poses = np.zeros((robofish_timesteps, 4))
sf.create_entity("robot", robofish_poses, name="robot", monotonic_step=40)
# create multiple fishes with timestamps. Since we don't specify names, but only the type "fish" the fishes will be named ["fish_1", "fish_2", "fish_3"]
agents = 3
timesteps = 5
timestamps = np.linspace(0, timesteps + 1, timesteps)
agent_poses = np.random.random((agents, timesteps, 4))
fish_names = sf.create_multiple_entities(
"fish", agent_poses, monotonic_points=timestamps
)
# This would throw an exception if the file was invalid
sf.validate()
# Save file validates aswell
example_file = full_path("example.hdf5")
sf.save(example_file)
# Closing and opening files (just for demonstration)
sf.close()
sf = robofish.io.File(path=example_file)
print("\nEntity Names")
print(sf.entity_names)
# Get an array with all poses. As the length of poses varies per agent, it
# is filled up with nans. The result is not interpolated and the time scales
# per agent are different. It is planned to create a warning in the case of
# different time scales and have another function, which generates an
# interpolated array.
print("\nAll poses")
print(sf.select_entity_poses())
print(sf.select_poses())
print("\nFish poses")
print(sf.select_entity_poses(lambda e: e.category == "fish"))
print(sf.select_poses(lambda e: e.category == "fish"))
print("\nFile structure")
print(sf)
```
%% Output
Entity Names
['fish_1', 'fish_2', 'fish_3', 'obstacle_1', 'robot']
All poses
[[[8.86584103e-01 2.35670820e-01 5.41754842e-01 4.49850202e-01]
[8.15511882e-01 4.78223324e-01 6.29803419e-01 1.12592392e-01]
[1.53732300e-01 7.24954247e-01 9.38574493e-01 4.65665817e-01]
[9.10354614e-01 4.47880208e-01 3.81429136e-01 9.67544317e-01]
[6.07822955e-01 5.20158827e-01 8.17965686e-01 8.42760384e-01]]
[[2.29353935e-01 8.80753636e-01 7.94585168e-01 2.22074524e-01]
[6.13970399e-01 1.33511815e-02 2.89155185e-01 2.65219092e-01]
[6.62197351e-01 6.47982001e-01 9.46004018e-02 6.59599364e-01]
[4.86104101e-01 4.23153102e-01 1.39821902e-01 3.11809748e-01]
[8.03322852e-01 9.52799857e-01 3.89638603e-01 6.43237352e-01]]
[[9.70978260e-01 6.75936878e-01 6.23196602e-01 8.42264950e-01]
[4.07079160e-01 8.46290290e-01 5.64092159e-01 3.56871307e-01]
[4.84096229e-01 8.60232174e-01 1.39015794e-01 7.82253265e-01]
[1.24170482e-01 2.21511930e-01 8.88282284e-02 4.53450561e-01]
[1.28404438e-01 2.87771430e-02 4.57022637e-01 9.80571806e-01]]
[[5.00000000e+01 5.00000000e+01 0.00000000e+00 0.00000000e+00]
[ nan nan nan nan]
[ nan nan nan nan]
[ nan nan nan nan]
[ nan nan nan nan]]
[[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ nan nan nan nan]]]
Fish poses
[[[0.8865841 0.23567082 0.54175484 0.4498502 ]
[0.81551188 0.47822332 0.62980342 0.11259239]
[0.1537323 0.72495425 0.93857449 0.46566582]
[0.91035461 0.44788021 0.38142914 0.96754432]
[0.60782295 0.52015883 0.81796569 0.84276038]]
[[0.22935393 0.88075364 0.79458517 0.22207452]
[0.6139704 0.01335118 0.28915519 0.26521909]
[0.66219735 0.647982 0.0946004 0.65959936]
[0.4861041 0.4231531 0.1398219 0.31180975]
[0.80332285 0.95279986 0.3896386 0.64323735]]
[[0.97097826 0.67593688 0.6231966 0.84226495]
[0.40707916 0.84629029 0.56409216 0.35687131]
[0.48409623 0.86023217 0.13901579 0.78225327]
[0.12417048 0.22151193 0.08882823 0.45345056]
[0.12840444 0.02877714 0.45702264 0.98057181]]]
File structure
version: [1 0]
world size: [100. 100.]
| entities
|---| fish_1
|---|--- type: fish
|---|--- poses: Shape (5, 4)
|---|---| time
|---|---|--- monotonic points: Shape (5,)
|---| fish_2
|---|--- type: fish
|---|--- poses: Shape (5, 4)
|---|---| time
|---|---|--- monotonic points: Shape (5,)
|---| fish_3
|---|--- type: fish
|---|--- poses: Shape (5, 4)
|---|---| time
|---|---|--- monotonic points: Shape (5,)
|---| obstacle_1
|---|--- type: obstacle
|---|--- outlines: Shape (1, 4, 2)
|---|--- poses: Shape (1, 4)
|---|---| time
|---| robot
|---|--- type: robot
|---|--- poses: Shape (4, 4)
|---|---| time
|---|---|--- monotonic step: 40
......
......@@ -43,10 +43,10 @@ print(sf.entity_names)
# Get an array with all poses. As the length of poses varies per agent, it is filled up with nans.
print("\nAll poses")
print(sf.entity_poses)
print(sf.poses)
print("\nFish poses")
print(sf.select_entity_poses(lambda e: e.category == "fish"))
print(sf.select_poses(lambda e: e.category == "fish"))
print("\nFile structure")
print(sf)
......@@ -32,4 +32,4 @@ with robofish.io.File(path, "w", world_size_cm=[100, 100], frequency_hz=25.0) as
# Show and save the file
print(f)
print("Poses Shape: ", f.entity_poses.shape)
print("Poses Shape: ", f.poses.shape)
......@@ -322,10 +322,10 @@ class File(h5py.File):
]
@property
def entity_poses(self):
return self.select_entity_poses(None)
def poses(self):
return self.select_poses(None)
def select_entity_poses(self, predicate=None) -> Iterable:
def select_poses(self, predicate=None) -> Iterable:
""" Select an array of the poses of entities
If no name or category is specified, all entities will be selected.
......@@ -379,7 +379,7 @@ class File(h5py.File):
predicate = lambda e: e.name in names
else:
predicate = None
return self.select_entity_poses(predicate)
return self.select_poses(predicate)
def validate(self, strict_validate: bool = True) -> (bool, str):
"""Validate the file to the specification.
......
......@@ -80,16 +80,16 @@ def test_multiple_entities():
sf.validate()
# The returned poses should be equal to the inserted poses
returned_poses = sf.entity_poses
returned_poses = sf.poses
print(returned_poses)
assert (returned_poses == poses).all()
# Just get the array for some names
returned_poses = sf.select_entity_poses(lambda e: e.name in ["fish_1", "fish_2"])
returned_poses = sf.select_poses(lambda e: e.name in ["fish_1", "fish_2"])
assert (returned_poses == poses[:2]).all()
# Filter on both category and name
returned_poses = sf.select_entity_poses(
returned_poses = sf.select_poses(
lambda e: e.category == "fish" and e.name == "fish_1"
)
assert (returned_poses == poses[:1]).all()
......@@ -99,7 +99,7 @@ def test_multiple_entities():
"obstacle", poses=np.random.random((agents, timesteps, 4))
)
# Obstacles should not be returned when only fish are selected
returned_poses = sf.select_entity_poses(lambda e: e.category == "fish")
returned_poses = sf.select_poses(lambda e: e.category == "fish")
assert (returned_poses == poses).all()
# for each of the entities
......@@ -138,6 +138,14 @@ def test_multiple_entities():
return sf
def test_deprecated_get_poses():
f = test_multiple_entities()
with pytest.warns(DeprecationWarning):
assert f.get_poses().shape[0] == 10
assert f.get_poses(category="fish").shape[0] == 7
assert f.get_poses(names="fish_1").shape[0] == 1
def test_load_validate():
sf = robofish.io.File(path=valid_file_path)
sf.validate()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment