wlsonar 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
wlsonar-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.3
2
+ Name: wlsonar
3
+ Version: 0.1.0
4
+ Summary: Python client and Range Image Protocol utilities for Water Linked Sonar 3D-15.
5
+ Author: Water Linked
6
+ Requires-Dist: protobuf>=5.29.5
7
+ Requires-Dist: python-snappy>=0.7.3
8
+ Requires-Dist: requests>=2.32.4
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+
12
+ # wlsonar
13
+
14
+ Package wlsonar is a python client library for the Water Linked [Sonar 3D-15](https://www.waterlinked.com/shop/wl-21045-2-sonar-3d-15-689).
15
+
16
+ The key features of this package are:
17
+
18
+ - `wlsonar.Sonar3D` for configuration and inspection of system state.
19
+ - `wlsonar.range_image_protocol` for [Range Image Protocol](https://docs.waterlinked.com/sonar-3d/sonar-3d-15-api/#range-image-protocol-rip2) packets.
20
+
21
+ ## Installation
22
+
23
+ The wlsonar package is hosted on pypi and can be installed with pip:
24
+
25
+ ```bash
26
+ pip install wlsonar
27
+ ```
28
+
29
+ ## Quickstart
30
+
31
+ Following is a snippet showing how to connect to the sonar and receive images.
32
+
33
+ ```python
34
+ import wlsonar
35
+ import wlsonar.range_image_protocol as rip
36
+
37
+ # (set to your sonar's IP address
38
+ ip = "10.1.2.24"
39
+
40
+ # connect, enable acoustics, configure to send images over UDP multicast
41
+ sonar = wlsonar.Sonar3D(ip)
42
+ sonar.set_acoustics_enabled(True)
43
+ sonar.set_udp_multicast()
44
+
45
+ print("Sonar configured, listening for UDP packets...")
46
+
47
+ # receive UDP packets, parse them into protobuf, and extract voxels
48
+ sock = wlsonar.open_sonar_udp_socket()
49
+ try:
50
+ while True:
51
+ packet, _ = sock.recvfrom(wlsonar.UDP_MAX_DATAGRAM_SIZE)
52
+ try:
53
+ msg = rip.unpackb(packet)
54
+ except rip.UnknownProtobufTypeError:
55
+ continue
56
+ if isinstance(msg, rip.RangeImage):
57
+ xyz = wlsonar.range_image_to_xyz(msg)
58
+ id = msg.header.sequence_id
59
+ print(f"Got range image {id} with {len(xyz)} voxels")
60
+ finally:
61
+ sock.close()
62
+ ```
63
+
64
+ More elaborate examples can be found in [the examples folder](./examples/).
65
+
66
+ ## Documentation and resources
67
+
68
+ Documentation for this package is provided in the form of:
69
+
70
+ - Elaborate examples in [the examples folder](./examples/).
71
+ - Tests in [the tests folder](./tests).
72
+ - Docstrings in code.
73
+
74
+ For general documentation about the Sonar 3D-15 see: https://docs.waterlinked.com/sonar-3d/sonar-3d-15/. The integration API that this package interfaces with is documented here: https://docs.waterlinked.com/sonar-3d/sonar-3d-15-api/. See also the replayer: https://sonar.replay.waterlinked.com/.
75
+
76
+ ## Development and testing
77
+
78
+ `uv` is required for development of the package. Run the following to set up the project:
79
+
80
+ ```bash
81
+ uv sync
82
+ ```
83
+
84
+ ### Linting
85
+
86
+ The package is linted with `ruff` and `mypy`:
87
+
88
+ ```bash
89
+ uv run ruff check
90
+ uv run ruff format --diff
91
+ uv run mypy .
92
+ ```
93
+
94
+ ### Testing
95
+
96
+ The package is tested with pytest:
97
+
98
+ ```bash
99
+ uv run pytest
100
+ ```
101
+
102
+ There are also end-to-end (e2e) tests to verify the package against a real Sonar 3D-15. Make sure to read the documentation of [tests/test_e2e_real_sonar.py](tests/test_e2e_real_sonar.py), then run the e2e test with:
103
+
104
+ ```bash
105
+ uv run pytest -m e2e -s --sonar-ip <sonar ip>
106
+ ```
107
+
108
+ ### Versioning
109
+
110
+ Versioning is handled with `uv`. Setting a new version with `uv version <new version>` and merging to master will build a new version on pypi. We follow semantic versioning.
111
+
112
+ ### Protobuf
113
+
114
+ The Sonar 3D-15 uses a .proto file to define message formats. This package includes generated Python for these messages. When changing the .proto file, run the following to generate new Python code:
115
+
116
+ ```bash
117
+ uv run protoc \
118
+ --proto_path=src/wlsonar/range_image_protocol/_proto/ \
119
+ --python_out=src/wlsonar/range_image_protocol/_proto/ \
120
+ --mypy_out=src/wlsonar/range_image_protocol/_proto/ \
121
+ src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol.proto
122
+ ```
@@ -0,0 +1,111 @@
1
+ # wlsonar
2
+
3
+ Package wlsonar is a python client library for the Water Linked [Sonar 3D-15](https://www.waterlinked.com/shop/wl-21045-2-sonar-3d-15-689).
4
+
5
+ The key features of this package are:
6
+
7
+ - `wlsonar.Sonar3D` for configuration and inspection of system state.
8
+ - `wlsonar.range_image_protocol` for [Range Image Protocol](https://docs.waterlinked.com/sonar-3d/sonar-3d-15-api/#range-image-protocol-rip2) packets.
9
+
10
+ ## Installation
11
+
12
+ The wlsonar package is hosted on pypi and can be installed with pip:
13
+
14
+ ```bash
15
+ pip install wlsonar
16
+ ```
17
+
18
+ ## Quickstart
19
+
20
+ Following is a snippet showing how to connect to the sonar and receive images.
21
+
22
+ ```python
23
+ import wlsonar
24
+ import wlsonar.range_image_protocol as rip
25
+
26
+ # (set to your sonar's IP address
27
+ ip = "10.1.2.24"
28
+
29
+ # connect, enable acoustics, configure to send images over UDP multicast
30
+ sonar = wlsonar.Sonar3D(ip)
31
+ sonar.set_acoustics_enabled(True)
32
+ sonar.set_udp_multicast()
33
+
34
+ print("Sonar configured, listening for UDP packets...")
35
+
36
+ # receive UDP packets, parse them into protobuf, and extract voxels
37
+ sock = wlsonar.open_sonar_udp_socket()
38
+ try:
39
+ while True:
40
+ packet, _ = sock.recvfrom(wlsonar.UDP_MAX_DATAGRAM_SIZE)
41
+ try:
42
+ msg = rip.unpackb(packet)
43
+ except rip.UnknownProtobufTypeError:
44
+ continue
45
+ if isinstance(msg, rip.RangeImage):
46
+ xyz = wlsonar.range_image_to_xyz(msg)
47
+ id = msg.header.sequence_id
48
+ print(f"Got range image {id} with {len(xyz)} voxels")
49
+ finally:
50
+ sock.close()
51
+ ```
52
+
53
+ More elaborate examples can be found in [the examples folder](./examples/).
54
+
55
+ ## Documentation and resources
56
+
57
+ Documentation for this package is provided in the form of:
58
+
59
+ - Elaborate examples in [the examples folder](./examples/).
60
+ - Tests in [the tests folder](./tests).
61
+ - Docstrings in code.
62
+
63
+ For general documentation about the Sonar 3D-15 see: https://docs.waterlinked.com/sonar-3d/sonar-3d-15/. The integration API that this package interfaces with is documented here: https://docs.waterlinked.com/sonar-3d/sonar-3d-15-api/. See also the replayer: https://sonar.replay.waterlinked.com/.
64
+
65
+ ## Development and testing
66
+
67
+ `uv` is required for development of the package. Run the following to set up the project:
68
+
69
+ ```bash
70
+ uv sync
71
+ ```
72
+
73
+ ### Linting
74
+
75
+ The package is linted with `ruff` and `mypy`:
76
+
77
+ ```bash
78
+ uv run ruff check
79
+ uv run ruff format --diff
80
+ uv run mypy .
81
+ ```
82
+
83
+ ### Testing
84
+
85
+ The package is tested with pytest:
86
+
87
+ ```bash
88
+ uv run pytest
89
+ ```
90
+
91
+ There are also end-to-end (e2e) tests to verify the package against a real Sonar 3D-15. Make sure to read the documentation of [tests/test_e2e_real_sonar.py](tests/test_e2e_real_sonar.py), then run the e2e test with:
92
+
93
+ ```bash
94
+ uv run pytest -m e2e -s --sonar-ip <sonar ip>
95
+ ```
96
+
97
+ ### Versioning
98
+
99
+ Versioning is handled with `uv`. Setting a new version with `uv version <new version>` and merging to master will build a new version on pypi. We follow semantic versioning.
100
+
101
+ ### Protobuf
102
+
103
+ The Sonar 3D-15 uses a .proto file to define message formats. This package includes generated Python for these messages. When changing the .proto file, run the following to generate new Python code:
104
+
105
+ ```bash
106
+ uv run protoc \
107
+ --proto_path=src/wlsonar/range_image_protocol/_proto/ \
108
+ --python_out=src/wlsonar/range_image_protocol/_proto/ \
109
+ --mypy_out=src/wlsonar/range_image_protocol/_proto/ \
110
+ src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol.proto
111
+ ```
@@ -0,0 +1,77 @@
1
+ [project]
2
+ name = "wlsonar"
3
+ version = "0.1.0"
4
+ description = "Python client and Range Image Protocol utilities for Water Linked Sonar 3D-15."
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Water Linked" }
8
+ ]
9
+ requires-python = ">=3.8"
10
+ dependencies = [
11
+ "protobuf>=5.29.5",
12
+ "python-snappy>=0.7.3",
13
+ "requests>=2.32.4",
14
+ ]
15
+
16
+ [build-system]
17
+ requires = ["uv_build>=0.9.15,<0.10.0"]
18
+ build-backend = "uv_build"
19
+
20
+ [tool.mypy]
21
+ warn_return_any = true
22
+ disallow_untyped_defs = true
23
+
24
+ [dependency-groups]
25
+ dev = [
26
+ "mypy>=1.14.1",
27
+ "mypy-protobuf>=3.7.0",
28
+ "pdbpp>=0.11.7",
29
+ "pillow>=10.4.0",
30
+ "pytest>=8.3.5",
31
+ "ruff>=0.14.8",
32
+ ]
33
+
34
+ [[tool.mypy.overrides]]
35
+ module = ["requests.*", "snappy.*"]
36
+ follow_untyped_imports = true
37
+
38
+ [tool.ruff]
39
+ line-length = 100
40
+ exclude = [
41
+ "*_pb2.py",
42
+ "*_pb2.pyi",
43
+ ]
44
+
45
+
46
+ [tool.ruff.format]
47
+ quote-style = "double"
48
+ line-ending = "auto"
49
+
50
+
51
+ [tool.ruff.lint]
52
+ select = [
53
+ "D", # pydocstyle
54
+ "F", # pyflakes
55
+ "E", # pycodestyle
56
+ "I", # isort
57
+ "ANN", # flake8 type annotations
58
+ "RUF", # ruff-specific rules
59
+ ]
60
+ fixable = ["ALL"]
61
+ ignore = [
62
+ "D107", # undocumented-public-init
63
+ ]
64
+
65
+ [tool.ruff.lint.per-file-ignores]
66
+ "tests/*.py" = ["D"]
67
+ "test_*.py" = ["D"]
68
+
69
+
70
+ [tool.ruff.lint.pydocstyle]
71
+ convention = "google"
72
+
73
+ [tool.pytest.ini_options]
74
+ markers = [
75
+ "e2e: end-to-end tests that require real sonar hardware. Skipped by default.",
76
+ ]
77
+ addopts = "-m 'not e2e'"
@@ -0,0 +1,27 @@
1
+ """Package wlsonar.
2
+
3
+ Package wlsonar provides a python client and Range Image Protocol utilities for Water Linked
4
+ Sonar 3D-15.
5
+ """
6
+
7
+ from ._client import (
8
+ DEFAULT_MCAST_GRP,
9
+ DEFAULT_MCAST_PORT,
10
+ FALLBACK_IP,
11
+ UDP_MAX_DATAGRAM_SIZE,
12
+ Sonar3D,
13
+ UdpConfig,
14
+ )
15
+ from ._udp_helper import open_sonar_udp_socket
16
+ from ._xyz_helper import range_image_to_xyz
17
+
18
+ __all__ = [
19
+ "DEFAULT_MCAST_GRP",
20
+ "DEFAULT_MCAST_PORT",
21
+ "FALLBACK_IP",
22
+ "UDP_MAX_DATAGRAM_SIZE",
23
+ "Sonar3D",
24
+ "UdpConfig",
25
+ "open_sonar_udp_socket",
26
+ "range_image_to_xyz",
27
+ ]