|
| 1 | +"""Catch DVL configurations rejected by Gazebo before publication starts.""" |
| 2 | + |
| 3 | +from pathlib import Path |
| 4 | +import re |
| 5 | +import xml.etree.ElementTree as ET |
| 6 | + |
| 7 | +import pytest |
| 8 | + |
| 9 | +DESCRIPTION = Path(__file__).resolve().parents[1] / "description" |
| 10 | +DVL_MODELS = [p for p in sorted(DESCRIPTION.glob("*/model.sdf")) if "<gz:dvl>" in p.read_text()] |
| 11 | + |
| 12 | + |
| 13 | +def test_dvl_catalog_is_present(): |
| 14 | + assert DVL_MODELS, "No DVL descriptors found; check the test resource path" |
| 15 | + |
| 16 | + |
| 17 | +@pytest.mark.parametrize("path", DVL_MODELS, ids=lambda p: p.parent.name) |
| 18 | +def test_water_mass_layer_fits_sensor_range(path): |
| 19 | + # SDF accepts the gz extension without an XML namespace declaration. |
| 20 | + text = re.sub(r"<sdf\b", '<sdf xmlns:gz="urn:gz"', path.read_text(), count=1) |
| 21 | + root = ET.fromstring(text) |
| 22 | + for dvl in root.iter("{urn:gz}dvl"): |
| 23 | + minimum = float(dvl.findtext("minimum_range")) |
| 24 | + maximum = float(dvl.findtext("maximum_range")) |
| 25 | + assert 0 <= minimum < maximum |
| 26 | + mode = dvl.find("tracking/water_mass_mode") |
| 27 | + if mode is None or mode.findtext("when") == "never": |
| 28 | + continue |
| 29 | + near = float(mode.findtext("boundaries/near", str(0.2 * maximum))) |
| 30 | + far = float(mode.findtext("boundaries/far", str(0.8 * maximum))) |
| 31 | + assert minimum <= near < far <= maximum, ( |
| 32 | + f"{path.parent.name}: water-mass [{near}, {far}] exceeds " |
| 33 | + f"sensor range [{minimum}, {maximum}]" |
| 34 | + ) |
0 commit comments