From 58ef97591e0ce89ab49e905ad564c875063e9843 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Tue, 12 Sep 2023 16:52:37 +0100 Subject: [PATCH 01/11] Add verbose option, False as default --- setup.py | 2 +- src/zeroros/publisher.py | 4 +++- src/zeroros/subscriber.py | 8 ++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 7c0b4eb..ce5188b 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name="zeroros", - version="1.0.2", + version="1.0.4", description="ZeroROS middleware", long_description=long_description, long_description_content_type="text/markdown", diff --git a/src/zeroros/publisher.py b/src/zeroros/publisher.py index 4665aa3..81b3577 100644 --- a/src/zeroros/publisher.py +++ b/src/zeroros/publisher.py @@ -14,8 +14,10 @@ def __init__( message_class: type[Message], ip: str = "127.0.0.1", port: int = 5555, + verbose: bool = False, ): - print("Creating publisher for topic: ", topic) + if verbose: + print("Creating publisher for topic: ", topic) self.topic = validate_topic(topic) self.message_class = message_class self.ip = ip diff --git a/src/zeroros/subscriber.py b/src/zeroros/subscriber.py index 272cff6..8f78f85 100644 --- a/src/zeroros/subscriber.py +++ b/src/zeroros/subscriber.py @@ -18,10 +18,13 @@ def __init__( callback_handle: callable, ip: str = "127.0.0.1", port: int = 5556, + verbose: bool = False, ): self.ip = ip self.port = port - print("Subscribing to topic: ", topic) + self.verbose = verbose + if self.verbose: + print("Subscribing to topic: ", topic) self.topic = validate_topic(topic) self.message_class = message_class self.url = "tcp://" + str(self.ip) + ":" + str(self.port) @@ -47,7 +50,8 @@ def listen(self, callback_handle: callable): except Exception as e: print(f"Error for topic {self.topic} on {self.ip}:{self.port}: {e}") time.sleep(0.05) - print("Stopping subscriber") + if self.verbose: + print("Stopping subscriber") # Check if the socket is still open if self.sock.closed is False: self.sock.close() From 98485abfd7c9acdf7b5f80c8582e97df989c0963 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Thu, 12 Oct 2023 09:49:12 +0100 Subject: [PATCH 02/11] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e4a452d..81f2078 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,9 @@ for communication between processes. It is not intended to be a replacement for

+## Why ZeroROS? +See these discussions in [ROS Discourse](https://discourse.ros.org/t/teaching-with-ros-or-zeroros-at-university/32124) and this one in [reddit/ROS](https://www.reddit.com/r/ROS/comments/14kh7pt/teaching_ros_zeroros_at_university_students/). + ## Installation Use pip to install the library: From ba7380282d7296e8fca0985d3048c1a086c031a7 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Sun, 12 Nov 2023 20:38:23 +0000 Subject: [PATCH 03/11] Add Windows Event loop policy --- src/zeroros/publisher.py | 6 ++++++ src/zeroros/subscriber.py | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/zeroros/publisher.py b/src/zeroros/publisher.py index 81b3577..3bb198c 100644 --- a/src/zeroros/publisher.py +++ b/src/zeroros/publisher.py @@ -1,5 +1,7 @@ +import asyncio import json import time +import sys import zmq @@ -7,6 +9,10 @@ from zeroros.topic import validate_topic +if sys.platform == 'win32': + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + + class Publisher: def __init__( self, diff --git a/src/zeroros/subscriber.py b/src/zeroros/subscriber.py index 8f78f85..0c3a8f7 100644 --- a/src/zeroros/subscriber.py +++ b/src/zeroros/subscriber.py @@ -2,6 +2,7 @@ import json import threading import time +import sys import zmq import zmq.asyncio @@ -10,6 +11,10 @@ from zeroros.topic import validate_topic +if sys.platform == 'win32': + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + + class Subscriber: def __init__( self, From 4d9f75863e390ce1bd829e185b934db65a57cbf9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 05:07:33 +0000 Subject: [PATCH 04/11] Bump pypa/gh-action-pypi-publish from 1.8.10 to 1.8.11 Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.10 to 1.8.11. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.10...v1.8.11) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/python-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index cefbdb2..1dd283e 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -27,7 +27,7 @@ jobs: with: name: artifact path: dist - - uses: pypa/gh-action-pypi-publish@v1.8.10 + - uses: pypa/gh-action-pypi-publish@v1.8.11 with: skip_existing: true user: __token__ From cbf5b765bce56a700c78b47cb4849a7491e8186a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 05:42:06 +0000 Subject: [PATCH 05/11] Bump actions/upload-artifact from 3 to 4 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/python-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index cefbdb2..72da20d 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -15,7 +15,7 @@ jobs: submodules: recursive - name: Build SDist run: pipx run build --sdist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: dist/*.tar.gz From 7a617d7f0082b8c045673dc7afb72f82059ac94b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 05:42:08 +0000 Subject: [PATCH 06/11] Bump actions/download-artifact from 3 to 4 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/python-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index cefbdb2..4aa166b 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -23,7 +23,7 @@ jobs: needs: make_sdist runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: artifact path: dist From b56d8278f4716aa9d78fcaaba98bc6efb0324303 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Mon, 22 Jan 2024 10:37:33 +0000 Subject: [PATCH 07/11] Add timestamp to datalogger --- src/zeroros/datalogger.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/zeroros/datalogger.py b/src/zeroros/datalogger.py index ffff342..28717d6 100644 --- a/src/zeroros/datalogger.py +++ b/src/zeroros/datalogger.py @@ -20,6 +20,8 @@ def log(self, msg: type[Message]): self.file.write( '{"class": "' + str(type(msg).__name__) + + '", "timestamp": "' + + str(datetime.datetime.now().timestamp()) + '", "message": ' + json.dumps(msg.to_json()) + "}\n" From 26ffabe13389cc0de01be68714cfe366f36af109 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Mon, 22 Jan 2024 10:46:18 +0000 Subject: [PATCH 08/11] Add array messages --- src/zeroros/messages/std_msgs.py | 102 +++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/zeroros/messages/std_msgs.py b/src/zeroros/messages/std_msgs.py index 665450d..32d171a 100644 --- a/src/zeroros/messages/std_msgs.py +++ b/src/zeroros/messages/std_msgs.py @@ -1,4 +1,6 @@ import time +import numpy as np +import numpy.typing as npt from . import Message @@ -96,3 +98,103 @@ def __init__(self, data: bool = False): def __str__(self): return "Bool:\n - data={}\n".format(self.data) + + +class MultiArrayDimension: + def __init__(self, label: str = "", size: int = 0, stride: int = 0): + self.label = label + self.size = size + self.stride = stride + + def __str__(self): + return ( + "MultiArrayDimension:\n - label={}\n - size={}\n - stride={}\n".format( + self.data["label"], self.data["size"], self.data["stride"] + ) + ) + + +class MultiArrayLayout: + def __init__(self, dim: MultiArrayDimension = None, data_offset: int = 0): + self.dim = dim + self.data_offset = data_offset + + +class Float32MultiArray: + def __init__( + self, layout: MultiArrayLayout = None, data: npt.NDArray[np.float32] = None + ): + self.layout = layout + self.data = data + + # Check if the layout matches the data + if layout is not None and data is not None: + if layout.dim.size != len(data): + raise ValueError( + "The size of the layout does not match the size of the data." + ) + + def __str__(self): + return "Float32MultiArray:\n - layout={}\n - data={}\n".format( + self.layout, self.data + ) + + +class Float64MultiArray: + def __init__( + self, layout: MultiArrayLayout = None, data: npt.NDArray[np.float64] = None + ): + self.layout = layout + self.data = data + + # Check if the layout matches the data + if layout is not None and data is not None: + if layout.dim.size != len(data): + raise ValueError( + "The size of the layout does not match the size of the data." + ) + + def __str__(self): + return "Float64MultiArray:\n - layout={}\n - data={}\n".format( + self.layout, self.data + ) + + +class Int32MultiArray: + def __init__( + self, layout: MultiArrayLayout = None, data: npt.NDArray[np.int32] = None + ): + self.layout = layout + self.data = data + + # Check if the layout matches the data + if layout is not None and data is not None: + if layout.dim.size != len(data): + raise ValueError( + "The size of the layout does not match the size of the data." + ) + + def __str__(self): + return "Int32MultiArray:\n - layout={}\n - data={}\n".format( + self.layout, self.data + ) + + +class Int64MultiArray: + def __init__( + self, layout: MultiArrayLayout = None, data: npt.NDArray[np.int64] = None + ): + self.layout = layout + self.data = data + + # Check if the layout matches the data + if layout is not None and data is not None: + if layout.dim.size != len(data): + raise ValueError( + "The size of the layout does not match the size of the data." + ) + + def __str__(self): + return "Int64MultiArray:\n - layout={}\n - data={}\n".format( + self.layout, self.data + ) From 5fc22f33f4b1aa196682577921602e51ab68d154 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Mon, 22 Jan 2024 15:38:51 +0000 Subject: [PATCH 09/11] Fix UTC timestamps --- src/zeroros/datalogger.py | 2 +- src/zeroros/messages/std_msgs.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zeroros/datalogger.py b/src/zeroros/datalogger.py index 28717d6..b7a4a1d 100644 --- a/src/zeroros/datalogger.py +++ b/src/zeroros/datalogger.py @@ -21,7 +21,7 @@ def log(self, msg: type[Message]): '{"class": "' + str(type(msg).__name__) + '", "timestamp": "' - + str(datetime.datetime.now().timestamp()) + + str(datetime.datetime.utcnow().timestamp()) + '", "message": ' + json.dumps(msg.to_json()) + "}\n" diff --git a/src/zeroros/messages/std_msgs.py b/src/zeroros/messages/std_msgs.py index 32d171a..eaa944d 100644 --- a/src/zeroros/messages/std_msgs.py +++ b/src/zeroros/messages/std_msgs.py @@ -1,4 +1,4 @@ -import time +import datetime import numpy as np import numpy.typing as npt @@ -11,7 +11,7 @@ def __init__(self, seq: int = 0, stamp: float = None, frame_id: str = ""): self.frame_id = frame_id self.stamp = stamp if stamp is None: - self.stamp = time.time() + self.stamp = datetime.datetime.utcnow().timestamp() def __str__(self): return "Header:\n - seq={}\n - stamp={}\n - frame_id={})\n".format( From d840525e5478b5a4d48ae0446238c74f9074ddb0 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Mon, 22 Jan 2024 15:39:03 +0000 Subject: [PATCH 10/11] Add angle list to LaserScan message --- src/zeroros/messages/sensor_msgs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/zeroros/messages/sensor_msgs.py b/src/zeroros/messages/sensor_msgs.py index 3c05e0c..d3ec87c 100644 --- a/src/zeroros/messages/sensor_msgs.py +++ b/src/zeroros/messages/sensor_msgs.py @@ -5,7 +5,7 @@ class LaserScan(Message): - def __init__(self, ranges=[], intensitites=[]): + def __init__(self, ranges=[], intensitites=[], angles=[]): self.header = Header() self.angle_min = None self.angle_max = None @@ -15,6 +15,7 @@ def __init__(self, ranges=[], intensitites=[]): self.range_min = None self.range_max = None self.ranges = np.array(ranges) + self.angles = np.array(angles) # Change NaNs to range_max if np.isnan(self.ranges).any(): self.ranges[np.isnan(self.ranges)] = self.range_max @@ -32,6 +33,7 @@ def __str__(self): msg += "Range Max: " + str(self.range_max) + "\n" msg += "Ranges: " + str(self.ranges) + "\n" msg += "Intensities: " + str(self.intensities) + "\n" + msg += "Angles: " + str(self.angles) + "\n" return msg def to_json(self): @@ -46,6 +48,7 @@ def to_json(self): "range_max": self.range_max, "ranges": self.ranges.tolist(), "intensities": self.intensities.tolist(), + "angles": self.angles.tolist(), } def from_json(self, msg): @@ -59,3 +62,4 @@ def from_json(self, msg): self.range_max = msg["range_max"] self.ranges = np.array(msg["ranges"]) self.intensities = np.array(msg["intensities"]) + self.angles = np.array(msg["angles"]) From 3af56d75980d8497aa503c741759fbac16d74084 Mon Sep 17 00:00:00 2001 From: Miquel Massot Date: Mon, 22 Jan 2024 15:39:27 +0000 Subject: [PATCH 11/11] Bump version to 1.0.5 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ce5188b..842f1cc 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name="zeroros", - version="1.0.4", + version="1.0.5", description="ZeroROS middleware", long_description=long_description, long_description_content_type="text/markdown",