|
4 | 4 | import unittest |
5 | 5 | import uuid |
6 | 6 | from typing import Optional |
| 7 | +from uuid import UUID, uuid4 |
7 | 8 |
|
8 | 9 | import numpy as np |
9 | 10 | import sqlalchemy |
@@ -51,17 +52,37 @@ def deterministic_uuid(seed: str) -> uuid.UUID: |
51 | 52 | w.add_degree_of_freedom(y_dof) |
52 | 53 | z_dof = DegreeOfFreedom(name=PrefixedName("z"), id=deterministic_uuid("z_dof")) |
53 | 54 | w.add_degree_of_freedom(z_dof) |
54 | | - qx_dof = DegreeOfFreedom(name=PrefixedName("qx"), id=deterministic_uuid("qx_dof")) |
| 55 | + qx_dof = DegreeOfFreedom( |
| 56 | + name=PrefixedName("qx"), id=deterministic_uuid("qx_dof") |
| 57 | + ) |
55 | 58 | w.add_degree_of_freedom(qx_dof) |
56 | | - qy_dof = DegreeOfFreedom(name=PrefixedName("qy"), id=deterministic_uuid("qy_dof")) |
| 59 | + qy_dof = DegreeOfFreedom( |
| 60 | + name=PrefixedName("qy"), id=deterministic_uuid("qy_dof") |
| 61 | + ) |
57 | 62 | w.add_degree_of_freedom(qy_dof) |
58 | | - qz_dof = DegreeOfFreedom(name=PrefixedName("qz"), id=deterministic_uuid("qz_dof")) |
| 63 | + qz_dof = DegreeOfFreedom( |
| 64 | + name=PrefixedName("qz"), id=deterministic_uuid("qz_dof") |
| 65 | + ) |
59 | 66 | w.add_degree_of_freedom(qz_dof) |
60 | | - qw_dof = DegreeOfFreedom(name=PrefixedName("qw"), id=deterministic_uuid("qw_dof")) |
| 67 | + qw_dof = DegreeOfFreedom( |
| 68 | + name=PrefixedName("qw"), id=deterministic_uuid("qw_dof") |
| 69 | + ) |
61 | 70 | w.add_degree_of_freedom(qw_dof) |
62 | 71 | w.state[qw_dof.id].position = 1.0 |
63 | 72 |
|
64 | | - w.add_connection(Connection6DoF(parent=b1, child=b2, x_id=x_dof.id, y_id=y_dof.id, z_id=z_dof.id, qx_id=qx_dof.id, qy_id=qy_dof.id, qz_id=qz_dof.id, qw_id=qw_dof.id)) |
| 73 | + w.add_connection( |
| 74 | + Connection6DoF( |
| 75 | + parent=b1, |
| 76 | + child=b2, |
| 77 | + x_id=x_dof.id, |
| 78 | + y_id=y_dof.id, |
| 79 | + z_id=z_dof.id, |
| 80 | + qx_id=qx_dof.id, |
| 81 | + qy_id=qy_dof.id, |
| 82 | + qz_id=qz_dof.id, |
| 83 | + qw_id=qw_dof.id, |
| 84 | + ) |
| 85 | + ) |
65 | 86 | return w |
66 | 87 |
|
67 | 88 |
|
@@ -428,5 +449,49 @@ def test_synchronize_6dof(rclpy_node): |
428 | 449 | np.testing.assert_array_almost_equal(w1.state.data, w2.state.data) |
429 | 450 |
|
430 | 451 |
|
| 452 | +def test_compute_state_changes_no_changes(rclpy_node): |
| 453 | + w = create_dummy_world() |
| 454 | + s = StateSynchronizer(node=rclpy_node, world=w) |
| 455 | + # Immediately compare without changing state |
| 456 | + changes = s.compute_state_changes() |
| 457 | + assert changes == {} |
| 458 | + s.close() |
| 459 | + |
| 460 | + |
| 461 | +def test_compute_state_changes_single_change(rclpy_node): |
| 462 | + w = create_dummy_world() |
| 463 | + s = StateSynchronizer(node=rclpy_node, world=w) |
| 464 | + # change first position |
| 465 | + w.state.data[0, 0] += 1e-3 |
| 466 | + changes = s.compute_state_changes() |
| 467 | + names = w.state.keys() |
| 468 | + assert list(changes.keys()) == [names[0]] |
| 469 | + assert np.isclose(changes[names[0]], w.state.positions[0]) |
| 470 | + s.close() |
| 471 | + |
| 472 | + |
| 473 | +def test_compute_state_changes_shape_change_full_snapshot(rclpy_node): |
| 474 | + w = create_dummy_world() |
| 475 | + s = StateSynchronizer(node=rclpy_node, world=w) |
| 476 | + # append a new DOF by writing a new name into state |
| 477 | + new_uuid = uuid4() |
| 478 | + w.state._add_dof(new_uuid) |
| 479 | + w.state[new_uuid] = np.zeros(4) |
| 480 | + changes = s.compute_state_changes() |
| 481 | + # full snapshot expected |
| 482 | + assert len(changes) == len(w.state) |
| 483 | + s.close() |
| 484 | + |
| 485 | + |
| 486 | +def test_compute_state_changes_nan_handling(rclpy_node): |
| 487 | + w = create_dummy_world() |
| 488 | + s = StateSynchronizer(node=rclpy_node, world=w) |
| 489 | + # set both previous and current to NaN for entry 0 |
| 490 | + w.state.data[0, 0] = np.nan |
| 491 | + s.previous_world_state_data[0] = np.nan |
| 492 | + assert s.compute_state_changes() == {} |
| 493 | + s.close() |
| 494 | + |
| 495 | + |
431 | 496 | if __name__ == "__main__": |
432 | 497 | unittest.main() |
0 commit comments