|
| 1 | +# SPDX-FileCopyrightText: (C) 2026 Intel Corporation |
| 2 | +# SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +import pytest |
| 5 | + |
| 6 | +from scene_common.geometry import getTripwireEvents, Tripwire, Point |
| 7 | + |
| 8 | +UUID = "39bd9698-8603-43fb-9cb9-06d9a14e6a24" |
| 9 | + |
| 10 | +# --- Positive tests: crossing in both directions for four orientations --- |
| 11 | + |
| 12 | +@pytest.mark.parametrize( |
| 13 | + "tripwire_pts, current, previous, expected_dir", |
| 14 | + [ |
| 15 | + # Horizontal tripwire [(0,0) -> (10,0)] |
| 16 | + ([[0, 0], [10, 0]], Point(5, 1), Point(5, -1), -1), |
| 17 | + ([[0, 0], [10, 0]], Point(5, -1), Point(5, 1), 1), |
| 18 | + # Vertical tripwire [(5,0) -> (5,10)] |
| 19 | + ([[5, 0], [5, 10]], Point(6, 5), Point(4, 5), 1), |
| 20 | + ([[5, 0], [5, 10]], Point(4, 5), Point(6, 5), -1), |
| 21 | + # Acute angle (~45 deg) tripwire [(0,0) -> (10,10)] |
| 22 | + ([[0, 0], [10, 10]], Point(10, 0), Point(0, 10), 1), |
| 23 | + ([[0, 0], [10, 10]], Point(0, 10), Point(10, 0), -1), |
| 24 | + # Obtuse angle (~135 deg) tripwire [(10,0) -> (0,10)] |
| 25 | + ([[10, 0], [0, 10]], Point(0, 0), Point(10, 10), -1), |
| 26 | + ([[10, 0], [0, 10]], Point(10, 10), Point(0, 0), 1), |
| 27 | + ], |
| 28 | + ids=[ |
| 29 | + "horizontal-south-to-north", |
| 30 | + "horizontal-north-to-south", |
| 31 | + "vertical-left-to-right", |
| 32 | + "vertical-right-to-left", |
| 33 | + "acute-cross-a", |
| 34 | + "acute-cross-b", |
| 35 | + "obtuse-cross-a", |
| 36 | + "obtuse-cross-b", |
| 37 | + ]) |
| 38 | +def test_tripwire_crossing(tripwire_pts, current, previous, expected_dir): |
| 39 | + """! Verify tripwire crossing detection for various orientations and directions. """ |
| 40 | + tripwire = Tripwire(UUID, "tw", {"points": tripwire_pts}) |
| 41 | + result = getTripwireEvents({"tw": tripwire}, [(current, previous)]) |
| 42 | + assert len(result["tw"]) == 1 |
| 43 | + assert result["tw"][0] == (0, expected_dir) |
| 44 | + |
| 45 | +# --- No-match tests --- |
| 46 | + |
| 47 | +def test_no_crossing_parallel_offset(): |
| 48 | + """! Verify no crossing when movement is parallel to tripwire but offset. """ |
| 49 | + tripwire = Tripwire(UUID, "tw", {"points": [[0, 0], [10, 0]]}) |
| 50 | + result = getTripwireEvents({"tw": tripwire}, [(Point(15, 2), Point(5, 2))]) |
| 51 | + assert result["tw"] == [] |
| 52 | + |
| 53 | +def test_no_crossing_collinear(): |
| 54 | + """! Verify no crossing when movement is along the tripwire (collinear). """ |
| 55 | + tripwire = Tripwire(UUID, "tw", {"points": [[0, 0], [10, 0]]}) |
| 56 | + result = getTripwireEvents({"tw": tripwire}, [(Point(8, 0), Point(2, 0))]) |
| 57 | + assert result["tw"] == [] |
| 58 | + |
| 59 | +# --- Positive tests: endpoint on tripwire --- |
| 60 | + |
| 61 | +def test_crossing_when_endpoint_on_tripwire(): |
| 62 | + """! Verify that endpoint landing exactly on the tripwire counts as a crossing. """ |
| 63 | + tripwire = Tripwire(UUID, "tw", {"points": [[0, 0], [10, 0]]}) |
| 64 | + result = getTripwireEvents({"tw": tripwire}, [(Point(5, 0), Point(5, -5))]) |
| 65 | + assert len(result["tw"]) == 1 |
| 66 | + assert result["tw"][0][0] == 0 |
| 67 | + |
| 68 | +# --- Length variations --- |
| 69 | + |
| 70 | +def test_single_tripwire_single_object(): |
| 71 | + """! Verify single tripwire with one crossing object. """ |
| 72 | + tripwire = Tripwire(UUID, "tw", {"points": [[0, 0], [10, 0]]}) |
| 73 | + result = getTripwireEvents({"tw": tripwire}, [(Point(5, 1), Point(5, -1))]) |
| 74 | + assert len(result["tw"]) == 1 |
| 75 | + assert result["tw"][0][0] == 0 |
| 76 | + |
| 77 | +def test_multiple_tripwires_multiple_objects(): |
| 78 | + """! Verify detection with multiple tripwires and objects, one crossing both. """ |
| 79 | + tw_h = Tripwire(UUID, "h", {"points": [[0, 0], [10, 0]]}) |
| 80 | + tw_v = Tripwire(UUID, "v", {"points": [[5, -5], [5, 5]]}) |
| 81 | + tripwires = {"h": tw_h, "v": tw_v} |
| 82 | + objects = [ |
| 83 | + (Point(6, 1), Point(4, -1)), # crosses both |
| 84 | + (Point(1, 5), Point(1, 4)), # crosses neither |
| 85 | + ] |
| 86 | + result = getTripwireEvents(tripwires, objects) |
| 87 | + assert len(result["h"]) == 1 |
| 88 | + assert result["h"][0][0] == 0 |
| 89 | + assert len(result["v"]) == 1 |
| 90 | + assert result["v"][0][0] == 0 |
| 91 | + |
| 92 | +# --- Empty inputs --- |
| 93 | + |
| 94 | +def test_empty_object_list(): |
| 95 | + """! Verify tripwires with no objects returns empty lists per key. """ |
| 96 | + tripwire = Tripwire(UUID, "tw", {"points": [[0, 0], [10, 0]]}) |
| 97 | + result = getTripwireEvents({"tw": tripwire}, []) |
| 98 | + assert result["tw"] == [] |
| 99 | + |
| 100 | +def test_empty_tripwire_dict(): |
| 101 | + """! Verify empty tripwire dict returns empty result. """ |
| 102 | + result = getTripwireEvents({}, [(Point(5, 1), Point(5, -1))]) |
| 103 | + assert result == {} |
0 commit comments