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 +122 -0
- wlsonar-0.1.0/README.md +111 -0
- wlsonar-0.1.0/pyproject.toml +77 -0
- wlsonar-0.1.0/src/wlsonar/__init__.py +27 -0
- wlsonar-0.1.0/src/wlsonar/_client.py +385 -0
- wlsonar-0.1.0/src/wlsonar/_semver.py +12 -0
- wlsonar-0.1.0/src/wlsonar/_udp_helper.py +37 -0
- wlsonar-0.1.0/src/wlsonar/_xyz_helper.py +43 -0
- wlsonar-0.1.0/src/wlsonar/py.typed +0 -0
- wlsonar-0.1.0/src/wlsonar/range_image_protocol/__init__.py +39 -0
- wlsonar-0.1.0/src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol.proto +69 -0
- wlsonar-0.1.0/src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol_pb2.py +35 -0
- wlsonar-0.1.0/src/wlsonar/range_image_protocol/_proto/WaterLinkedSonarIntegrationProtocol_pb2.pyi +214 -0
- wlsonar-0.1.0/src/wlsonar/range_image_protocol/_protocol.py +320 -0
- wlsonar-0.1.0/src/wlsonar/range_image_protocol/py.typed +0 -0
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
|
+
```
|
wlsonar-0.1.0/README.md
ADDED
|
@@ -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
|
+
]
|