From e7e86685c67c0eadd3487ab2fc84eac9d642ba37 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Mon, 18 Dec 2023 15:07:35 -0500 Subject: [PATCH 01/37] Initial Ridgeback --- clearpath_config/common/types/platform.py | 2 ++ clearpath_config/platform/attachments/mux.py | 2 ++ clearpath_config/platform/attachments/r100.py | 34 +++++++++++++++++++ clearpath_config/platform/battery.py | 5 +++ clearpath_config/platform/extras.py | 17 ++++++++++ 5 files changed, 60 insertions(+) create mode 100644 clearpath_config/platform/attachments/r100.py diff --git a/clearpath_config/common/types/platform.py b/clearpath_config/common/types/platform.py index 259a30c..c3fd68f 100644 --- a/clearpath_config/common/types/platform.py +++ b/clearpath_config/common/types/platform.py @@ -90,6 +90,7 @@ class Platform: A200: PACSProfile(rows=8, columns=7), J100: PACSProfile(rows=4, columns=2), W200: PACSProfile(rows=100, columns=100), + R100: PACSProfile(rows=100, columns=100), } INDEX = { @@ -100,5 +101,6 @@ class Platform: DD150: IndexingProfile(imu=1), DO150: IndexingProfile(imu=1), J100: IndexingProfile(gps=1, imu=1), + R100: IndexingProfile(imu=1), W200: IndexingProfile(imu=1), } diff --git a/clearpath_config/platform/attachments/mux.py b/clearpath_config/platform/attachments/mux.py index be5b22e..7812072 100644 --- a/clearpath_config/platform/attachments/mux.py +++ b/clearpath_config/platform/attachments/mux.py @@ -34,6 +34,7 @@ from clearpath_config.platform.attachments.do150 import DO150Attachment from clearpath_config.platform.attachments.generic import GENERICAttachment from clearpath_config.platform.attachments.j100 import J100Attachment +from clearpath_config.platform.attachments.r100 import R100Attachment from clearpath_config.platform.attachments.w200 import W200Attachment from clearpath_config.platform.types.attachment import BaseAttachment @@ -48,6 +49,7 @@ class AttachmentsConfigMux: Platform.GENERIC: AttachmentsConfig(GENERICAttachment), Platform.J100: AttachmentsConfig(J100Attachment), Platform.W200: AttachmentsConfig(W200Attachment), + Platform.R100: AttachmentsConfig(R100Attachment), } def __new__(cls, platform: str, attachments: dict = None) -> AttachmentsConfig: diff --git a/clearpath_config/platform/attachments/r100.py b/clearpath_config/platform/attachments/r100.py new file mode 100644 index 0000000..0007fc3 --- /dev/null +++ b/clearpath_config/platform/attachments/r100.py @@ -0,0 +1,34 @@ +# Software License Agreement (BSD) +# +# @author Luis Camero +# @copyright (c) 2023, Clearpath Robotics, Inc., All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Clearpath Robotics nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +from clearpath_config.common.types.platform import Platform +from clearpath_config.platform.types.attachment import PlatformAttachment + + +# R100 Attachments +class R100Attachment(PlatformAttachment): + PLATFORM = Platform.R100 diff --git a/clearpath_config/platform/battery.py b/clearpath_config/platform/battery.py index 7f3bf51..5fe74d4 100644 --- a/clearpath_config/platform/battery.py +++ b/clearpath_config/platform/battery.py @@ -46,6 +46,8 @@ class BatteryConfig(BaseConfig): ES20_12C = "ES20_12C" # A200/J100 LiION HE2613 = "HE2613" + # R100 Lead Acid + DTM8A31 = "8A31DTM" # W200 Lead Acid U1_35 = "U1_35" # W200 LiFEPO4 @@ -90,6 +92,9 @@ class BatteryConfig(BaseConfig): Platform.J100: { HE2613: [S1P1], }, + Platform.R100: { + DTM8A31: [S2P1], + }, Platform.W200: { U1_35: [S4P3], NEC_ALM12V35: [S4P3], diff --git a/clearpath_config/platform/extras.py b/clearpath_config/platform/extras.py index 7062cde..df4fff4 100644 --- a/clearpath_config/platform/extras.py +++ b/clearpath_config/platform/extras.py @@ -104,6 +104,22 @@ class ROSParameterDefaults: "platform_velocity_controller.angular.z.min_acceleration": -25.0, } + R100 = { + "platform_velocity_controller.wheel_radius": 0.05, + "platform_velocity_controller.linear.x.max_velocity": 1.3, + "platform_velocity_controller.linear.x.min_velocity": -1.3, + "platform_velocity_controller.linear.x.max_acceleration": 1.0, + "platform_velocity_controller.linear.x.min_acceleration": -1.0, + "platform_velocity_controller.linear.y.max_velocity": 1.3, + "platform_velocity_controller.linear.y.min_velocity": -1.3, + "platform_velocity_controller.linear.y.max_acceleration": 1.0, + "platform_velocity_controller.linear.y.min_acceleration": -1.0, + "platform_velocity_controller.angular.z.max_velocity": 4.0, + "platform_velocity_controller.angular.z.min_velocity": -4.0, + "platform_velocity_controller.angular.z.max_acceleration": 2.0, + "platform_velocity_controller.angular.z.min_acceleration": -2.0, + } + W200 = { "platform_velocity_controller.wheel_radius": 0.3, "platform_velocity_controller.linear.x.max_velocity": 5.0, @@ -124,6 +140,7 @@ class ROSParameterDefaults: Platform.DO150: DO150, Platform.J100: J100, Platform.GENERIC: GENERIC, + Platform.R100: R100, Platform.W200: W200, } From 32a5dd463398a123ff1182bbbaadfc746359fb47 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Thu, 11 Jan 2024 11:14:15 -0500 Subject: [PATCH 02/37] Added Ridgeback attachments --- clearpath_config/common/types/platform.py | 2 +- clearpath_config/platform/attachments/r100.py | 32 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/clearpath_config/common/types/platform.py b/clearpath_config/common/types/platform.py index c3fd68f..cce5f24 100644 --- a/clearpath_config/common/types/platform.py +++ b/clearpath_config/common/types/platform.py @@ -61,7 +61,7 @@ class Platform: # Dingo D V1.5 DD150 = "dd150" # Dingo D V1.5 - DO150 = "d0150" + DO150 = "do150" # Jackal V1 J100 = "j100" # Husky V2 diff --git a/clearpath_config/platform/attachments/r100.py b/clearpath_config/platform/attachments/r100.py index 0007fc3..c9f4aa5 100644 --- a/clearpath_config/platform/attachments/r100.py +++ b/clearpath_config/platform/attachments/r100.py @@ -25,10 +25,40 @@ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +from typing import List +from clearpath_config.common.types.accessory import Accessory from clearpath_config.common.types.platform import Platform -from clearpath_config.platform.types.attachment import PlatformAttachment +from clearpath_config.platform.types.attachment import BaseAttachment, PlatformAttachment + + +class R100ArmMount(BaseAttachment): + PLATFORM = Platform.R100 + ATTACHMENT_MODEL = "%s.arm_mount" % PLATFORM + FAMS = "fams" + HAMS = "hams" + TOWER = "tower" + MODELS = [FAMS, HAMS, TOWER] + DEFAULT = TOWER + PARENT = "default_mount" + + def __init__( + self, + name: str = ATTACHMENT_MODEL, + model: str = DEFAULT, + enabled: bool = BaseAttachment.ENABLED, + parent: str = PARENT, + xyz: List[float] = Accessory.XYZ, + rpy: List[float] = Accessory.RPY + ) -> None: + super().__init__(name, model, enabled, parent, xyz, rpy) # R100 Attachments class R100Attachment(PlatformAttachment): PLATFORM = Platform.R100 + # Arm Mount + ARM_MOUNT = R100ArmMount.ATTACHMENT_MODEL + + TYPES = { + ARM_MOUNT: R100ArmMount + } From c8da2980126ca737fc9c9c018249b2eeca2c067e Mon Sep 17 00:00:00 2001 From: Hilary Luo <103377417+hilary-luo@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:23:59 -0500 Subject: [PATCH 03/37] Find packages for meshes / extras urdf (#45) * Allow meshes visual and extras urdf to be linked using find package functionality --- clearpath_config/common/types/file.py | 17 ++--- clearpath_config/common/types/package_path.py | 70 +++++++++++++++++++ clearpath_config/links/links.py | 2 +- clearpath_config/links/types/mesh.py | 18 ++--- clearpath_config/platform/extras.py | 16 +++-- clearpath_config/platform/platform.py | 42 +---------- 6 files changed, 100 insertions(+), 65 deletions(-) create mode 100644 clearpath_config/common/types/package_path.py diff --git a/clearpath_config/common/types/file.py b/clearpath_config/common/types/file.py index e54e110..42e4e1d 100644 --- a/clearpath_config/common/types/file.py +++ b/clearpath_config/common/types/file.py @@ -31,12 +31,12 @@ # File # - file class class File: - def __init__(self, path: str, creatable=False, exists=False) -> None: + def __init__(self, path: str, creatable=False, exists=False, make_abs=True) -> None: if creatable: assert File.is_creatable(path) if exists: assert File.is_exists(path) - self.path = File.clean(path) + self.path = File.clean(path, make_abs) def __str__(self) -> str: return self.path @@ -50,23 +50,24 @@ def __eq__(self, other: object) -> bool: return False @staticmethod - def clean(path: str) -> str: + def clean(path: str, make_abs=True) -> str: if not path: return "" path = os.path.expanduser(path) path = os.path.normpath(path) - path = os.path.abspath(path) + if make_abs: + path = os.path.abspath(path) return path @staticmethod - def is_creatable(path: str) -> bool: - path = File.clean(path) + def is_creatable(path: str, make_abs=True) -> bool: + path = File.clean(path, make_abs) dirname = os.path.dirname(path) or os.getcwd() return os.access(dirname, os.W_OK) @staticmethod - def is_exists(path: str) -> bool: - path = File.clean(path) + def is_exists(path: str, make_abs=True) -> bool: + path = File.clean(path, make_abs) return os.path.exists(path) def get_path(self) -> str: diff --git a/clearpath_config/common/types/package_path.py b/clearpath_config/common/types/package_path.py new file mode 100644 index 0000000..628f0b3 --- /dev/null +++ b/clearpath_config/common/types/package_path.py @@ -0,0 +1,70 @@ +# Software License Agreement (BSD) +# +# @author Luis Camero +# @copyright (c) 2023, Clearpath Robotics, Inc., All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Clearpath Robotics nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from clearpath_config.common.types.file import File + + +class PackagePath: + PACKAGE = "package" + PATH = "path" + + def __init__( + self, + package: str = None, + path: str = None, + ) -> None: + self.package = package + self.path = File.clean(path, make_abs=False) + + def from_dict(self, config: dict) -> None: + if self.PACKAGE in config: + self.package = config[self.PACKAGE] + if self.PATH in config: + self.path = config[self.PATH] + + def to_dict(self) -> dict: + return { + self.PACKAGE: self.package, + self.PATH: self.path, + } + + @property + def package(self) -> str: + return self._package + + @package.setter + def package(self, value: str) -> None: + self._package = value + + @property + def path(self) -> str: + return self._path + + @path.setter + def path(self, value: str) -> None: + self._path = value diff --git a/clearpath_config/links/links.py b/clearpath_config/links/links.py index 4923e5b..6b71a53 100644 --- a/clearpath_config/links/links.py +++ b/clearpath_config/links/links.py @@ -497,7 +497,7 @@ def add_mesh( mesh: Mesh = None, # By Parameters name: str = None, - visual: float = Mesh.VISUAL, + visual: dict = Mesh.VISUAL, parent: str = Accessory.PARENT, xyz: List[float] = Accessory.XYZ, rpy: List[float] = Accessory.RPY, diff --git a/clearpath_config/links/types/mesh.py b/clearpath_config/links/types/mesh.py index 6707be1..4bf6f9b 100644 --- a/clearpath_config/links/types/mesh.py +++ b/clearpath_config/links/types/mesh.py @@ -26,21 +26,21 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from clearpath_config.common.types.accessory import Accessory -from clearpath_config.common.types.file import File from clearpath_config.links.types.link import BaseLink +from clearpath_config.common.types.package_path import PackagePath from typing import List class Mesh(BaseLink): LINK_TYPE = "mesh" - VISUAL = "empty.stl" + VISUAL = "" # COLLISION = "empty.stl" def __init__( self, name: str, parent: str = Accessory.PARENT, - visual: float = VISUAL, + visual: dict = VISUAL, # collision: float = COLLISION, xyz: List[float] = Accessory.XYZ, rpy: List[float] = Accessory.RPY, @@ -55,7 +55,8 @@ def __init__( offset_xyz, offset_rpy ) - self.visual: File = File(Mesh.VISUAL) + + self.visual: PackagePath = PackagePath(Mesh.VISUAL) self.set_visual(visual) def to_dict(self) -> dict: @@ -68,8 +69,9 @@ def from_dict(self, d: dict) -> None: if 'visual' in d: self.set_visual(d['visual']) - def set_visual(self, visual: str) -> None: - self.visual = File(visual) + def set_visual(self, visual: dict) -> None: + if visual: + self.visual.from_dict(visual) - def get_visual(self) -> str: - return self.visual.get_path() + def get_visual(self) -> dict: + return self.visual.to_dict() diff --git a/clearpath_config/platform/extras.py b/clearpath_config/platform/extras.py index df4fff4..5f23a24 100644 --- a/clearpath_config/platform/extras.py +++ b/clearpath_config/platform/extras.py @@ -27,6 +27,7 @@ # POSSIBILITY OF SUCH DAMAGE. from clearpath_config.common.types.config import BaseConfig from clearpath_config.common.types.file import File +from clearpath_config.common.types.package_path import PackagePath from clearpath_config.common.types.platform import Platform from clearpath_config.common.utils.dictionary import ( flatten_dict, @@ -191,14 +192,14 @@ class ExtrasConfig(BaseConfig): KEYS[ROS_PARAMETERS] = ".".join([EXTRAS, ROS_PARAMETERS]) DEFAULTS = { - URDF: "empty.urdf.xacro", + URDF: "", ROS_PARAMETERS: ROSParameterDefaults(BaseConfig.get_platform_model()), } def __init__( self, config: dict = {}, - urdf: str = DEFAULTS[URDF], + urdf: dict = DEFAULTS[URDF], ros_parameters: dict = {}, ) -> None: # ROS Parameter Setter Template @@ -231,19 +232,20 @@ def update(self, serial_number: bool = False) -> None: self._update_ros_parameter() @property - def urdf(self) -> str: - urdf = None if self._is_default(self._urdf, self.URDF) else str(self._urdf) + def urdf(self) -> dict: + urdf = None if self._is_default(self._urdf, self.URDF) else dict(self._urdf.to_dict()) self.set_config_param( key=self.KEYS[self.URDF], - value=urdf + value=urdf, ) return urdf @urdf.setter - def urdf(self, value: str) -> None: + def urdf(self, value: dict) -> None: if value is None or value == "None": return - self._urdf = File(path=str(value)) + self._urdf = PackagePath() + self._urdf.from_dict(value) def _is_default(self, curr: str, key: str) -> bool: return curr == str(File(self.DEFAULTS[key])) diff --git a/clearpath_config/platform/platform.py b/clearpath_config/platform/platform.py index be7e0cb..625452e 100644 --- a/clearpath_config/platform/platform.py +++ b/clearpath_config/platform/platform.py @@ -27,6 +27,7 @@ # POSSIBILITY OF SUCH DAMAGE. from clearpath_config.common.types.platform import Platform from clearpath_config.common.types.config import BaseConfig +from clearpath_config.common.types.package_path import PackagePath from clearpath_config.common.utils.dictionary import flip_dict from clearpath_config.platform.battery import BatteryConfig from clearpath_config.platform.extras import ExtrasConfig @@ -34,47 +35,6 @@ from clearpath_config.platform.attachments.mux import AttachmentsConfigMux -class PackagePath: - PACKAGE = "package" - PATH = "path" - - def __init__( - self, - package: str = None, - path: str = None, - ) -> None: - self.package = package - self.path = path - - def from_dict(self, config: dict) -> None: - if self.PACKAGE in config: - self.package = config[self.PACKAGE] - if self.PATH in config: - self.path = config[self.PATH] - - def to_dict(self) -> dict: - return { - self.PACKAGE: self.package, - self.PATH: self.path, - } - - @property - def package(self) -> str: - return self._package - - @package.setter - def package(self, value: str) -> None: - self._package = value - - @property - def path(self) -> str: - return self._path - - @path.setter - def path(self, value: str) -> None: - self._path = value - - class DescriptionPackagePath(PackagePath): MACRO = "macro" PARAMETERS = "parameters" From c062c80ae41c7ac06951299caa2a54239c002837 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Thu, 4 Jan 2024 15:16:29 -0500 Subject: [PATCH 04/37] Changes. --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8897f6e..3ee1922 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Find packages for meshes / extras urdf (`#45 `_) + * Allow meshes visual and extras urdf to be linked using find package functionality +* Contributors: Hilary Luo + 0.2.0 (2023-12-07) ------------------ * Added wheel parameter to platform From a63ae57ada5a97538f1c37605559ec6871a8085f Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Thu, 4 Jan 2024 15:16:40 -0500 Subject: [PATCH 05/37] 0.2.1 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3ee1922..189d599 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.1 (2024-01-04) +------------------ * Find packages for meshes / extras urdf (`#45 `_) * Allow meshes visual and extras urdf to be linked using find package functionality * Contributors: Hilary Luo diff --git a/package.xml b/package.xml index 9d43242..ed7de33 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.0 + 0.2.1 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index 0d8244a..f6e5a0f 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.0", + version="0.2.1", packages=[ package_name, package_name + ".common", From 04b3df16ad2ea018a3bb57d3425718e46a5d0230 Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Fri, 5 Jan 2024 16:26:18 -0500 Subject: [PATCH 06/37] Fix how blank urdf extras is handled --- clearpath_config/platform/extras.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/clearpath_config/platform/extras.py b/clearpath_config/platform/extras.py index 5f23a24..2aee61a 100644 --- a/clearpath_config/platform/extras.py +++ b/clearpath_config/platform/extras.py @@ -26,7 +26,6 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from clearpath_config.common.types.config import BaseConfig -from clearpath_config.common.types.file import File from clearpath_config.common.types.package_path import PackagePath from clearpath_config.common.types.platform import Platform from clearpath_config.common.utils.dictionary import ( @@ -192,7 +191,7 @@ class ExtrasConfig(BaseConfig): KEYS[ROS_PARAMETERS] = ".".join([EXTRAS, ROS_PARAMETERS]) DEFAULTS = { - URDF: "", + URDF: None, ROS_PARAMETERS: ROSParameterDefaults(BaseConfig.get_platform_model()), } @@ -233,7 +232,7 @@ def update(self, serial_number: bool = False) -> None: @property def urdf(self) -> dict: - urdf = None if self._is_default(self._urdf, self.URDF) else dict(self._urdf.to_dict()) + urdf = None if (self._urdf == self.DEFAULTS[self.URDF]) else dict(self._urdf.to_dict()) self.set_config_param( key=self.KEYS[self.URDF], value=urdf, @@ -241,14 +240,17 @@ def urdf(self) -> dict: return urdf @urdf.setter - def urdf(self, value: dict) -> None: - if value is None or value == "None": - return - self._urdf = PackagePath() - self._urdf.from_dict(value) - - def _is_default(self, curr: str, key: str) -> bool: - return curr == str(File(self.DEFAULTS[key])) + def urdf(self, value: dict | PackagePath) -> None: + if isinstance(value, dict) and PackagePath.PATH in value and value[PackagePath.PATH]: + self._urdf = PackagePath() + self._urdf.from_dict(value) + elif isinstance(value, PackagePath) and value.path: + self._urdf = value + else: + self._urdf = self.DEFAULTS[self.URDF] + assert not value or isinstance(value, dict) or (isinstance(value, PackagePath)), ( + "Extras URDF must be null or of type `dict` or `PackagePath`" + ) def _is_ros_parameter(self, key) -> bool: return any([key in i for i in self._ros_parameters_setters]) From 926e94cfcaf700c01c354dbcb423e1d9cf4a2616 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 8 Jan 2024 11:52:22 -0500 Subject: [PATCH 07/37] Changes. --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 189d599..faf5ff9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix how blank urdf extras is handled +* Contributors: Hilary Luo + 0.2.1 (2024-01-04) ------------------ * Find packages for meshes / extras urdf (`#45 `_) From 482fc9b1a77ad23131a4ed0a0409d1c0ca0ce99f Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 8 Jan 2024 11:52:32 -0500 Subject: [PATCH 08/37] 0.2.2 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index faf5ff9..e0d1ee2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.2 (2024-01-08) +------------------ * Fix how blank urdf extras is handled * Contributors: Hilary Luo diff --git a/package.xml b/package.xml index ed7de33..6b5b6fc 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.1 + 0.2.2 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index f6e5a0f..5b4f2ad 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.1", + version="0.2.2", packages=[ package_name, package_name + ".common", From 5a7406537e513578eee55d543270a7b5fa505136 Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Fri, 5 Jan 2024 14:25:57 -0500 Subject: [PATCH 09/37] Give option to get topic without namespace --- clearpath_config/sensors/types/sensor.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/clearpath_config/sensors/types/sensor.py b/clearpath_config/sensors/types/sensor.py index 3d6f271..ab8ab0e 100644 --- a/clearpath_config/sensors/types/sensor.py +++ b/clearpath_config/sensors/types/sensor.py @@ -143,12 +143,15 @@ def set_idx(self, idx: int) -> None: super().set_idx(idx) self.topic = self.get_topic_from_idx(idx) - def get_topic(self, topic: str) -> str: + def get_topic(self, topic: str, local=False) -> str: assert topic in self.TOPICS.NAME, ( "Topic must be one of %s" % [i for i in self.TOPICS.NAME] ) - ns = BaseConfig.get_namespace() - return os.path.join(ns, "sensors", self.name, self.TOPICS.NAME[topic]) + if local: + return os.path.join("sensors", self.name, self.TOPICS.NAME[topic]) + else: + ns = BaseConfig.get_namespace() + return os.path.join(ns, "sensors", self.name, self.TOPICS.NAME[topic]) def get_topic_rate(self, topic: str) -> float: assert topic in self.TOPICS.RATE, ( From aac48fa28a22f924383f817fa67b4ca43f03fecb Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Wed, 10 Jan 2024 11:28:23 -0500 Subject: [PATCH 10/37] Changes. --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e0d1ee2..f6acb97 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Give option to get topic without namespace +* Contributors: Hilary Luo + 0.2.2 (2024-01-08) ------------------ * Fix how blank urdf extras is handled From 743559361be2b33911ec4d46bb3b964a28ec9f3a Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Wed, 10 Jan 2024 11:28:30 -0500 Subject: [PATCH 11/37] 0.2.3 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f6acb97..fc595d2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.3 (2024-01-10) +------------------ * Give option to get topic without namespace * Contributors: Hilary Luo diff --git a/package.xml b/package.xml index 6b5b6fc..5f73ca0 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.2 + 0.2.3 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index 5b4f2ad..57607df 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.2", + version="0.2.3", packages=[ package_name, package_name + ".common", From cdfb73e91c9c6e32fa448becda35c6c9951289d3 Mon Sep 17 00:00:00 2001 From: Roni Kreinin Date: Thu, 18 Jan 2024 17:33:15 -0500 Subject: [PATCH 12/37] Fixed j100 and w200 laser sample --- clearpath_config/sample/j100/j100_dual_laser.yaml | 4 ++-- clearpath_config/sample/w200/w200_dual_laser.yaml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clearpath_config/sample/j100/j100_dual_laser.yaml b/clearpath_config/sample/j100/j100_dual_laser.yaml index 9e8814b..8b35b64 100644 --- a/clearpath_config/sample/j100/j100_dual_laser.yaml +++ b/clearpath_config/sample/j100/j100_dual_laser.yaml @@ -55,7 +55,7 @@ sensors: - model: hokuyo_ust urdf_enabled: true launch_enabled: true - parent: front_mount + parent: front_0_mount xyz: [0.0, 0.0, 0.0] rpy: [0.0, 0.0, 0.0] ros_parameters: @@ -68,7 +68,7 @@ sensors: - model: hokuyo_ust urdf_enabled: true launch_enabled: true - parent: rear_mount + parent: rear_0_mount xyz: [0.0, 0.0, 0.0] rpy: [0.0, 0.0, 3.1415] ros_parameters: diff --git a/clearpath_config/sample/w200/w200_dual_laser.yaml b/clearpath_config/sample/w200/w200_dual_laser.yaml index beb4010..1151c34 100644 --- a/clearpath_config/sample/w200/w200_dual_laser.yaml +++ b/clearpath_config/sample/w200/w200_dual_laser.yaml @@ -67,8 +67,8 @@ sensors: laser_frame_id: lidar2d_0_laser ip_address: 192.168.131.20 ip_port: 10940 - angle_min: -3.141592653589793 - angle_max: 3.141592653589793 + angle_min: -1.5707 + angle_max: 1.5707 - model: hokuyo_ust urdf_enabled: true launch_enabled: true @@ -80,6 +80,6 @@ sensors: laser_frame_id: lidar2d_1_laser ip_address: 192.168.131.21 ip_port: 10940 - angle_min: -3.141592653589793 - angle_max: 3.141592653589793 + angle_min: -1.5707 + angle_max: 1.5707 lidar3d: [] From 51734350f1619b6d437a5763c0f3703e97a884da Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Sat, 20 Jan 2024 10:32:49 -0500 Subject: [PATCH 13/37] Install the W200 samples. --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index 57607df..9fab6dd 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,9 @@ package_name + "/sample/j100/j100_dual_laser.yaml", package_name + "/sample/j100/j100_sample.yaml", package_name + "/sample/j100/j100_velodyne.yaml", + package_name + "/sample/w200/w200_default.yaml", + package_name + "/sample/w200/w200_dual_laser.yaml", + package_name + "/sample/w200/w200_velodyne.yaml", ]), ], install_requires=[ From 15624987e6fe04c0553716c59f85514c95cd4e03 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 22 Jan 2024 10:04:45 -0500 Subject: [PATCH 14/37] Changes. --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fc595d2..954d427 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Install the W200 samples. +* Fixed j100 and w200 laser sample +* Contributors: Roni Kreinin, Tony Baltovski + 0.2.3 (2024-01-10) ------------------ * Give option to get topic without namespace From 41cf6077611420f24e4dc446a11536302a8833bb Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 22 Jan 2024 10:05:12 -0500 Subject: [PATCH 15/37] 0.2.4 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 954d427..92e477d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.4 (2024-01-22) +------------------ * Install the W200 samples. * Fixed j100 and w200 laser sample * Contributors: Roni Kreinin, Tony Baltovski diff --git a/package.xml b/package.xml index 5f73ca0..42830cc 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.3 + 0.2.4 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index 9fab6dd..f298590 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.3", + version="0.2.4", packages=[ package_name, package_name + ".common", From e1b323895bdcc3e9ec4fd340f9fc5dc791333818 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Mon, 22 Jan 2024 10:02:36 -0500 Subject: [PATCH 16/37] Fix ros_parameters --- clearpath_config/sample/j100/j100_default.yaml | 17 +++++++++-------- .../sample/j100/j100_dual_laser.yaml | 17 +++++++++-------- clearpath_config/sample/j100/j100_sample.yaml | 17 +++++++++-------- .../sample/j100/j100_velodyne.yaml | 17 +++++++++-------- clearpath_config/sample/w200/w200_default.yaml | 18 +++++++++--------- .../sample/w200/w200_dual_laser.yaml | 18 +++++++++--------- .../sample/w200/w200_velodyne.yaml | 18 +++++++++--------- 7 files changed, 63 insertions(+), 59 deletions(-) diff --git a/clearpath_config/sample/j100/j100_default.yaml b/clearpath_config/sample/j100/j100_default.yaml index 293f21f..3802cb9 100644 --- a/clearpath_config/sample/j100/j100_default.yaml +++ b/clearpath_config/sample/j100/j100_default.yaml @@ -27,14 +27,15 @@ platform: extras: urdf: null ros_parameters: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 + platform_velocity_controller: + linear.x.max_velocity": 2.0 + linear.x.min_velocity": -2.0 + linear.x.max_acceleration": 20.0 + linear.x.min_acceleration": -20.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 25.0 + angular.z.min_acceleration": -25.0 links: box: [] cylinder: [] diff --git a/clearpath_config/sample/j100/j100_dual_laser.yaml b/clearpath_config/sample/j100/j100_dual_laser.yaml index 8b35b64..9c33f31 100644 --- a/clearpath_config/sample/j100/j100_dual_laser.yaml +++ b/clearpath_config/sample/j100/j100_dual_laser.yaml @@ -27,14 +27,15 @@ platform: extras: urdf: null ros_parameters: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 + platform_velocity_controller: + linear.x.max_velocity": 2.0 + linear.x.min_velocity": -2.0 + linear.x.max_acceleration": 20.0 + linear.x.min_acceleration": -20.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 25.0 + angular.z.min_acceleration": -25.0 links: box: [] cylinder: [] diff --git a/clearpath_config/sample/j100/j100_sample.yaml b/clearpath_config/sample/j100/j100_sample.yaml index 39284f1..5694efe 100644 --- a/clearpath_config/sample/j100/j100_sample.yaml +++ b/clearpath_config/sample/j100/j100_sample.yaml @@ -27,14 +27,15 @@ platform: extras: urdf: null ros_parameters: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 + platform_velocity_controller: + linear.x.max_velocity": 2.0 + linear.x.min_velocity": -2.0 + linear.x.max_acceleration": 20.0 + linear.x.min_acceleration": -20.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 25.0 + angular.z.min_acceleration": -25.0 links: box: [] cylinder: diff --git a/clearpath_config/sample/j100/j100_velodyne.yaml b/clearpath_config/sample/j100/j100_velodyne.yaml index b9be2cf..3d5a8d1 100644 --- a/clearpath_config/sample/j100/j100_velodyne.yaml +++ b/clearpath_config/sample/j100/j100_velodyne.yaml @@ -27,14 +27,15 @@ platform: extras: urdf: null ros_parameters: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 + platform_velocity_controller: + linear.x.max_velocity": 2.0 + linear.x.min_velocity": -2.0 + linear.x.max_acceleration": 20.0 + linear.x.min_acceleration": -20.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 25.0 + angular.z.min_acceleration": -25.0 links: box: [] cylinder: [] diff --git a/clearpath_config/sample/w200/w200_default.yaml b/clearpath_config/sample/w200/w200_default.yaml index ad1a705..cf93ec7 100644 --- a/clearpath_config/sample/w200/w200_default.yaml +++ b/clearpath_config/sample/w200/w200_default.yaml @@ -18,15 +18,15 @@ platform: extras: urdf: null ros_parameters: - ros_parameters: - linear.x.max_velocity": 5.0 - linear.x.min_velocity": -5.0 - linear.x.max_acceleration": 50.0 - linear.x.min_acceleration": -50.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 40.0 - angular.z.min_acceleration": -40.0 + platform_velocity_controller: + linear.x.max_velocity": 5.0 + linear.x.min_velocity": -5.0 + linear.x.max_acceleration": 50.0 + linear.x.min_acceleration": -50.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 40.0 + angular.z.min_acceleration": -40.0 links: box: [] cylinder: [] diff --git a/clearpath_config/sample/w200/w200_dual_laser.yaml b/clearpath_config/sample/w200/w200_dual_laser.yaml index 1151c34..4336cd7 100644 --- a/clearpath_config/sample/w200/w200_dual_laser.yaml +++ b/clearpath_config/sample/w200/w200_dual_laser.yaml @@ -18,15 +18,15 @@ platform: extras: urdf: null ros_parameters: - ros_parameters: - linear.x.max_velocity": 5.0 - linear.x.min_velocity": -5.0 - linear.x.max_acceleration": 50.0 - linear.x.min_acceleration": -50.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 40.0 - angular.z.min_acceleration": -40.0 + platform_velocity_controller: + linear.x.max_velocity": 5.0 + linear.x.min_velocity": -5.0 + linear.x.max_acceleration": 50.0 + linear.x.min_acceleration": -50.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 40.0 + angular.z.min_acceleration": -40.0 links: box: [] cylinder: [] diff --git a/clearpath_config/sample/w200/w200_velodyne.yaml b/clearpath_config/sample/w200/w200_velodyne.yaml index 8bf3ebf..eed3722 100644 --- a/clearpath_config/sample/w200/w200_velodyne.yaml +++ b/clearpath_config/sample/w200/w200_velodyne.yaml @@ -18,15 +18,15 @@ platform: extras: urdf: null ros_parameters: - ros_parameters: - linear.x.max_velocity": 5.0 - linear.x.min_velocity": -5.0 - linear.x.max_acceleration": 50.0 - linear.x.min_acceleration": -50.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 40.0 - angular.z.min_acceleration": -40.0 + platform_velocity_controller: + linear.x.max_velocity": 5.0 + linear.x.min_velocity": -5.0 + linear.x.max_acceleration": 50.0 + linear.x.min_acceleration": -50.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 40.0 + angular.z.min_acceleration": -40.0 links: box: - name: structure From a624e0f7aecb9958478314e6d2bf93b981e6e653 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Thu, 1 Feb 2024 15:21:02 -0500 Subject: [PATCH 17/37] Add republishers to camera --- clearpath_config/sensors/types/cameras.py | 97 +++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/clearpath_config/sensors/types/cameras.py b/clearpath_config/sensors/types/cameras.py index 10c4151..a6285d5 100644 --- a/clearpath_config/sensors/types/cameras.py +++ b/clearpath_config/sensors/types/cameras.py @@ -31,6 +31,80 @@ from typing import List +class Republisher(): + TYPE = "type" + + class Base(): + INPUT = "input" + OUTPUT = "output" + INPUT_DEFAULT = "in" + OUTPUT_DEFAULT = "out" + + def __init__(self, config: dict) -> None: + + self.from_dict(config) + + def from_dict(self, config: dict) -> None: + self.input = config.get(self.INPUT, self.INPUT_DEFAULT) + self.output = config.get(self.OUTPUT, self.OUTPUT_DEFAULT) + + def to_dict(self) -> dict: + return { + self.INPUT: self.input, + self.OUTPUT: self.output + } + + @property + def input(self) -> str: + return self._input + + @input.setter + def input(self, value: str) -> None: + self._input = value + + @property + def output(self) -> str: + return self._output + + @output.setter + def output(self, value: str) -> None: + self._output = value + + class Compress(Base): + TYPE = "compress" + INPUT_DEFAULT = "color" + OUTPUT_DEFAULT = "compressed" + + class Rectify(Base): + TYPE = "rectify" + INPUT_DEFAULT = "color" + OUTPUT_DEFAULT = "rectified" + + class Resize(Base): + TYPE = "resize" + INPUT_DEFAULT = "color" + OUTPUT_DEFAULT = "resize" + + class Theora(Base): + TYPE = "theora" + INPUT_DEFAULT = "color" + OUTPUT_DEFAULT = "theora" + + TYPES = { + Compress.TYPE: Compress, + Rectify.TYPE: Rectify, + Resize.TYPE: Resize, + Theora.TYPE: Theora + } + + def __new__(self, config: dict) -> None: + assert self.TYPE in config, ( + "Republisher must have '%s' specified." % self.TYPE) + assert config[self.TYPE] in self.TYPES, ( + "Republisher '%s' must be one of: '%s'." % (self.TYPE, [i for i in self.TYPES])) + return self.TYPES[config[self.TYPE]](config) + + class BaseCamera(BaseSensor): SENSOR_TYPE = "camera" SENSOR_MODEL = "base" @@ -138,6 +212,29 @@ def get_serial(self) -> str: def set_serial(self, serial: str) -> None: self.serial = serial + @property + def republishers(self) -> list: + return [republisher.to_dict() for republisher in self._republishers] + + @republishers.setter + def republishers(self, republishers: list) -> None: + assert isinstance(republishers, list), ( + "Camera republishers must be a list of dictionaries") + assert all([isinstance(i, dict) for i in republishers]), ( + "Camera republishers must be a list of dictionaries") + self._republishers = [] + for republisher in republishers: + self._republishers.append(Republisher(republisher)) + + def to_dict(self) -> dict: + config = super().to_dict() + config['republishers'] = self.republishers + return config + + def from_dict(self, d: dict) -> None: + super().from_dict(d) + self.republishers = d.get('republishers', []) + class IntelRealsense(BaseCamera): SENSOR_MODEL = "intel_realsense" From 0929c0b5f9215ac00cd9b280c7b9ddd6ae41ac22 Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Thu, 18 Jan 2024 23:56:50 -0500 Subject: [PATCH 18/37] Added battery launch arguments to support launching the valence bms node --- clearpath_config/platform/battery.py | 30 ++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/clearpath_config/platform/battery.py b/clearpath_config/platform/battery.py index 5fe74d4..5b53704 100644 --- a/clearpath_config/platform/battery.py +++ b/clearpath_config/platform/battery.py @@ -57,6 +57,7 @@ class BatteryConfig(BaseConfig): # Configurations CONFIGURATION = "configuration" + LAUNCH_ARGS = 'launch_args' S1P1 = "S1P1" S1P2 = "S1P2" S1P3 = "S1P3" @@ -106,7 +107,8 @@ class BatteryConfig(BaseConfig): TEMPLATE = { BATTERY: { MODEL: MODEL, - CONFIGURATION: CONFIGURATION + CONFIGURATION: CONFIGURATION, + LAUNCH_ARGS: LAUNCH_ARGS } } @@ -114,7 +116,8 @@ class BatteryConfig(BaseConfig): DEFAULTS = { MODEL: UNKNOWN, - CONFIGURATION: UNKNOWN + CONFIGURATION: UNKNOWN, + LAUNCH_ARGS: {} } def __init__( @@ -122,6 +125,7 @@ def __init__( config: dict = {}, model: str = DEFAULTS[MODEL], configuration: str = DEFAULTS[CONFIGURATION], + launch_args: dict = DEFAULTS[LAUNCH_ARGS] ) -> None: # Initialization self._config = {} @@ -135,10 +139,16 @@ def __init__( self.configuration = self.DEFAULTS[self.CONFIGURATION] else: self.configuration = configuration + if launch_args == self.DEFAULTS[self.LAUNCH_ARGS] or not launch_args: + self.launch_args = self.DEFAULTS[self.LAUNCH_ARGS] + else: + self.launch_args = launch_args + # Setter Template setters = { self.KEYS[self.MODEL]: BatteryConfig.model, self.KEYS[self.CONFIGURATION]: BatteryConfig.configuration, + self.KEYS[self.LAUNCH_ARGS]: BatteryConfig.launch_args, } super().__init__(setters, config, self.BATTERY) @@ -202,3 +212,19 @@ def configuration(self, value: str) -> None: platform, self.model, list(self.VALID[platform][self.model])) )) self._configuration = value + + @property + def launch_args(self) -> dict: + self.set_config_param( + key=self.KEYS[self.LAUNCH_ARGS], + value=self._launch_args + ) + return self._launch_args + + @launch_args.setter + def launch_args(self, value: dict) -> None: + assert isinstance(value, dict), (( + "Battery Launch args %s are invalid. " % value + + "They must be in the format of a dictionary." + )) + self._launch_args = value From f7b8c0fe780704a0fe0f098bc6ca6de20d2a4bd9 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Wed, 6 Mar 2024 10:29:36 -0500 Subject: [PATCH 19/37] Changes. --- CHANGELOG.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 92e477d..f82fa32 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add republishers to camera +* Added battery launch arguments to support launching the valence bms node +* Fix ros_parameters +* Contributors: Hilary Luo, Luis Camero + 0.2.4 (2024-01-22) ------------------ * Install the W200 samples. From 8b07980eee30933915be3d05517efa6211504eda Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Wed, 6 Mar 2024 10:29:44 -0500 Subject: [PATCH 20/37] 0.2.5 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f82fa32..7b4f70c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.5 (2024-03-06) +------------------ * Add republishers to camera * Added battery launch arguments to support launching the valence bms node * Fix ros_parameters diff --git a/package.xml b/package.xml index 42830cc..88eba47 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.4 + 0.2.5 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index f298590..89199b0 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.4", + version="0.2.5", packages=[ package_name, package_name + ".common", From 106a138881f3a960db9af4c3d35c7fcd878e9887 Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Fri, 23 Feb 2024 23:02:20 -0500 Subject: [PATCH 21/37] Reformat hosts section to single list of all computers --- clearpath_config/common/types/host.py | 68 -------- clearpath_config/system/hosts.py | 234 +++++++------------------- clearpath_config/system/system.py | 24 +-- 3 files changed, 77 insertions(+), 249 deletions(-) delete mode 100644 clearpath_config/common/types/host.py diff --git a/clearpath_config/common/types/host.py b/clearpath_config/common/types/host.py deleted file mode 100644 index 30c01d9..0000000 --- a/clearpath_config/common/types/host.py +++ /dev/null @@ -1,68 +0,0 @@ -# Software License Agreement (BSD) -# -# @author Luis Camero -# @copyright (c) 2023, Clearpath Robotics, Inc., All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Clearpath Robotics nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -from clearpath_config.common.types.hostname import Hostname -from clearpath_config.common.types.ip import IP - - -# Host -# - hostname and config pair -class Host: - def __init__( - self, - hostname: str = "hostname", - ip: str = "0.0.0.0" - ) -> None: - self.hostname = Hostname() - self.ip = IP() - self.set_hostname(hostname) - self.set_ip(ip) - - def __eq__(self, other) -> bool: - return self.hostname == other.hostname and self.ip == other.ip - - def __str__(self) -> str: - return "{ hostname: %s, ip: %s }" % (str(self.hostname), str(self.ip)) - - def to_dict(self) -> dict: - return {str(self.hostname): str(self.ip)} - - # Hostname: - # - the hostname of this host - def get_hostname(self) -> str: - return str(self.hostname) - - def set_hostname(self, hostname: str) -> None: - self.hostname = Hostname(hostname) - - # IP - # - the ip of this host - def get_ip(self) -> str: - return str(self.ip) - - def set_ip(self, ip: str) -> None: - self.ip = IP(ip) diff --git a/clearpath_config/system/hosts.py b/clearpath_config/system/hosts.py index 701bf7e..5a8578d 100644 --- a/clearpath_config/system/hosts.py +++ b/clearpath_config/system/hosts.py @@ -26,82 +26,48 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from clearpath_config.common.types.config import BaseConfig -from clearpath_config.common.types.host import Host from clearpath_config.common.types.hostname import Hostname +from clearpath_config.common.types.ip import IP from clearpath_config.common.types.list import ListConfig from clearpath_config.common.utils.dictionary import flip_dict from typing import List -# HostListConfig -# - list of hosts -class HostListConfig(ListConfig[Host, str]): - def __init__(self) -> None: - super().__init__( - uid=lambda obj: obj.get_hostname(), - obj_type=Host, - uid_type=str - ) - - def to_dict(self) -> dict: - hostdict = {} - for host in self.get_all(): - hostdict[host.get_hostname()] = host.get_ip() - return hostdict - - -# HostsConfig -# - these are the hosts that are involved in this system -class HostsConfig(BaseConfig): +# HostConfig +# - this is the format for which each host involved in the system will be described +class HostConfig(BaseConfig): - HOSTS = "hosts" - SELF = "self" - PLATFORM = "platform" - ONBOARD = "onboard" - REMOTE = "remote" + HOSTNAME = "host" + IP_ADDRESS = "ip" TEMPLATE = { - HOSTS: { - SELF: SELF, - PLATFORM: PLATFORM, - ONBOARD: ONBOARD, - REMOTE: REMOTE, - } + HOSTNAME: HOSTNAME, + IP_ADDRESS: IP_ADDRESS } KEYS = flip_dict(TEMPLATE) DEFAULTS = { - SELF: BaseConfig.get_serial_number(), - PLATFORM: { - BaseConfig.get_serial_number(): "192.168.131.1" - }, - ONBOARD: {}, - REMOTE: {} + HOSTNAME: BaseConfig.get_serial_number(), + IP_ADDRESS: "192.168.131.1", } def __init__( self, config: dict = {}, - selfhost: str | Hostname = DEFAULTS[SELF], - platform: dict | Host = DEFAULTS[PLATFORM], - onboard: dict | List[Host] = DEFAULTS[ONBOARD], - remote: dict | List[Host] = DEFAULTS[REMOTE], + hostname: str | Hostname = DEFAULTS[HOSTNAME], + ip_address: str | IP = DEFAULTS[IP_ADDRESS], ) -> None: # Initialization - self.self = selfhost - self.platform = platform - self.onboard = onboard - self.remote = remote + self.hostname = hostname + self.ip_address = ip_address # Setter Template setters = { - self.KEYS[self.SELF]: HostsConfig.self, - self.KEYS[self.PLATFORM]: HostsConfig.platform, - self.KEYS[self.ONBOARD]: HostsConfig.onboard, - self.KEYS[self.REMOTE]: HostsConfig.remote + self.KEYS[self.HOSTNAME]: HostConfig.hostname, + self.KEYS[self.IP_ADDRESS]: HostConfig.ip_address, } # Set from Config - super().__init__(setters, config, self.HOSTS) + super().__init__(setters, config, None) def update(self, serial_number=False) -> None: if serial_number: @@ -115,140 +81,70 @@ def update(self, serial_number=False) -> None: self.DEFAULTS[self.SELF] = sn self.DEFAULTS[self.PLATFORM] = {sn: "192.168.131.1"} - # Self: - # - the hostname of the computer running this config + def __eq__(self, other) -> bool: + return self.hostname == other.hostname and self.ip_address == other.ip + + def __str__(self) -> str: + return "{ hostname: %s, ip: %s }" % (str(self.hostname), str(self.ip_address)) + + def to_dict(self) -> dict: + return {str(self.hostname): str(self.ip_address)} + + # Hostname: + # - the hostname of the computer @property - def self(self) -> str: + def hostname(self) -> str: self.set_config_param( - key=self.KEYS[self.SELF], - value=str(self._self) + key=self.KEYS[self.HOSTNAME], + value=str(self._hostname) ) - return str(self._self) + return str(self._hostname) - @self.setter - def self(self, value: str | Hostname) -> None: + @hostname.setter + def hostname(self, value: str | Hostname) -> None: if isinstance(value, str): - self._self = Hostname(value) + self._hostname = Hostname(value) elif isinstance(value, Hostname): - self._self = value + self._hostname = value else: assert isinstance(value, str) or isinstance(value, Hostname), ( - "Self must be of type 'str' or 'Hostname'" + f"Hostname of {value} is invalid, must be of type 'str' or 'Hostname'" ) - # Platform: - # - the main computer for this system (i.e. the robot's computer) + # IP Address: + # - the IP address at which the computer can be accessed @property - def platform(self) -> Host: + def ip_address(self) -> IP: self.set_config_param( - key=self.KEYS[self.PLATFORM], - value=self._platform.to_dict() + key=self.KEYS[self.IP_ADDRESS], + value=self._ip ) - return self._platform - - @platform.setter - def platform(self, value: dict | Host) -> None: - if isinstance(value, dict): - entry = [{'hostname': k, 'ip': v} for k, v in value.items()] - assert len(entry) == 1, ( - "Platform must only be one hostname, ip pair" - ) - self._platform = Host( - hostname=entry[0]['hostname'], - ip=entry[0]['ip']) - elif isinstance(value, Host): - self._platform = value - else: - assert isinstance(value, dict) or isinstance(value, Host), ( - "Platform must be of type 'dict' or 'Host'" - ) - - @property - def platform_ip(self) -> str: - return self._platform.get_ip() - - @platform_ip.setter - def platform_ip(self, value: str): - self._platform.set_ip(value) - self.config[self.KEYS[self.PLATFORM]] = self.platform + return self._ip - @property - def platform_hostname(self) -> str: - return self._platform.get_hostname() - - @platform_hostname.setter - def platform_hostname(self, value: str) -> None: - self._platform.set_hostname(value) - - # Onboard: - # - these are additional on-board computer - @property - def onboard(self) -> HostListConfig: - self.set_config_param( - key=self.KEYS[self.ONBOARD], - value=self._onboard.to_dict() - ) - return self._onboard - - @onboard.setter - def onboard(self, value: dict | List[Host] | HostListConfig) -> None: - if isinstance(value, dict): - onboard = HostListConfig() - onboard.set_all([Host(k, v) for k, v in value.items()]) - self._onboard = onboard - elif isinstance(value, list): - assert all([isinstance(i, Host) for i in value]), ( - "Onboard hosts passed as list must be of type 'List[Host]'" - ) - onboard = HostListConfig() - onboard.set_all(value) - self._onboard = value - - elif isinstance(value, HostListConfig): - self._onboard = value + @ip_address.setter + def ip_address(self, value: str | IP) -> None: + if isinstance(value, str): + self._ip = IP(value) + elif isinstance(value, IP): + self._ip = value else: - assert (( - isinstance(value, dict)) or ( - isinstance(value, list)) or ( - isinstance(value, HostListConfig))), ( - "Onboard hosts must be of type '%s', '%s' or '%s'" % ( - dict.__name__, list.__name__, HostListConfig.__name__ - ) + assert isinstance(value, dict) or isinstance(value, IP), ( + f"IP address of {value} is invalid, must be of type 'str' or 'IP'" ) - # Remote: - # - these are remote machines which need to interact with the system - # - ex. laptops or other robots - @property - def remote(self) -> HostListConfig: - self.set_config_param( - key=self.KEYS[self.REMOTE], - value=self._remote.to_dict() + +# HostListConfig +# - list of hosts that are involved with the system +class HostListConfig(ListConfig[HostConfig, str]): + def __init__(self) -> None: + super().__init__( + uid=lambda obj: obj.get_hostname(), + obj_type=HostConfig, + uid_type=str ) - return self._remote - - @remote.setter - def remote(self, value: dict | List[Host] | HostListConfig) -> None: - if isinstance(value, dict): - remote = HostListConfig() - remote.set_all([Host(k, v) for k, v in value.items()]) - self._remote = remote - elif isinstance(value, list): - assert all([isinstance(i, Host) for i in value]), ( - "Remote hosts passed as list must be of type 'List[Host]'" - ) - remote = HostListConfig() - remote.set_all(value) - self._remote = value - elif isinstance(value, HostListConfig): - self._remote = value - else: - assert (( - isinstance(value, dict)) or ( - isinstance(value, list)) or ( - isinstance(value, HostListConfig))), ( - "Remote hosts must be of type '%s', '%s' or '%s'" % ( - dict.__name__, list.__name__, HostListConfig.__name__ - ) - ) + def to_dict(self) -> List[dict]: + hosts = [] + for host in self.get_all(): + hosts.append(host.config) + return hosts \ No newline at end of file diff --git a/clearpath_config/system/system.py b/clearpath_config/system/system.py index efffece..649577f 100644 --- a/clearpath_config/system/system.py +++ b/clearpath_config/system/system.py @@ -25,19 +25,19 @@ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +from typing import List from clearpath_config.common.types.config import BaseConfig from clearpath_config.common.types.domain_id import DomainID from clearpath_config.common.types.namespace import Namespace from clearpath_config.common.types.username import Username -from clearpath_config.common.types.rmw_implementation import RMWImplementation from clearpath_config.common.utils.dictionary import flip_dict -from clearpath_config.system.hosts import HostsConfig +from clearpath_config.system.hosts import HostConfig, HostListConfig class SystemConfig(BaseConfig): SYSTEM = "system" - HOSTS = HostsConfig.HOSTS + HOSTS = "hosts" SELF = "self" ROS2 = "ros2" USERNAME = "username" @@ -63,8 +63,8 @@ class SystemConfig(BaseConfig): KEYS = flip_dict(TEMPLATE) DEFAULTS = { - # HOSTS: platform hostname (serial number) at 192.168.131.1 - HOSTS: HostsConfig.DEFAULTS, + # HOSTS: hostnames and IP's for all computers involved with the system + HOSTS: HostConfig.DEFAULTS, # USERNAME: administrator USERNAME: "administrator", # NAMESPACE: serial number @@ -80,7 +80,7 @@ class SystemConfig(BaseConfig): def __init__( self, config: dict = {}, - hosts: dict = DEFAULTS[HOSTS], + hosts: List[dict] | HostListConfig = DEFAULTS[HOSTS], username: str = DEFAULTS[USERNAME], namespace: str = DEFAULTS[NAMESPACE], domain_id: int = DEFAULTS[DOMAIN_ID], @@ -118,7 +118,7 @@ def update(self, serial_number=False) -> None: self.DEFAULTS[self.NAMESPACE] = namespace @property - def hosts(self) -> HostsConfig: + def hosts(self) -> HostConfig: self.set_config_param( key=self.KEYS[self.HOSTS], value=self._hosts.config[self.HOSTS] @@ -126,14 +126,14 @@ def hosts(self) -> HostsConfig: return self._hosts @hosts.setter - def hosts(self, value: dict | HostsConfig) -> None: + def hosts(self, value: List[dict] | HostListConfig) -> None: if isinstance(value, dict): - self._hosts = HostsConfig(config=value) - elif isinstance(value, HostsConfig): + self._hosts = HostConfig(config=value) + elif isinstance(value, HostConfig): self._hosts = value else: - assert isinstance(value, dict) or isinstance(value, HostsConfig), ( - "Hosts must be of type 'dict' or 'HostsConfig'" + assert isinstance(value, dict) or isinstance(value, HostConfig), ( + f"Hosts value of {value} is invalid, it must be of type 'dict' or 'HostListConfig'" ) @property From fb91125156a25f9288cf640889d4b09b90fe6d93 Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Mon, 26 Feb 2024 11:24:00 -0500 Subject: [PATCH 22/37] Add localhost field which is set automatically --- clearpath_config/system/system.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/clearpath_config/system/system.py b/clearpath_config/system/system.py index 649577f..5e0e847 100644 --- a/clearpath_config/system/system.py +++ b/clearpath_config/system/system.py @@ -25,7 +25,10 @@ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. + +import socket from typing import List + from clearpath_config.common.types.config import BaseConfig from clearpath_config.common.types.domain_id import DomainID from clearpath_config.common.types.namespace import Namespace @@ -38,6 +41,7 @@ class SystemConfig(BaseConfig): SYSTEM = "system" HOSTS = "hosts" + LOCALHOST = "localhost" SELF = "self" ROS2 = "ros2" USERNAME = "username" @@ -50,6 +54,7 @@ class SystemConfig(BaseConfig): SYSTEM: { SELF: SELF, HOSTS: HOSTS, + LOCALHOST: LOCALHOST, USERNAME: USERNAME, ROS2: { NAMESPACE: NAMESPACE, @@ -65,6 +70,8 @@ class SystemConfig(BaseConfig): DEFAULTS = { # HOSTS: hostnames and IP's for all computers involved with the system HOSTS: HostConfig.DEFAULTS, + # LOCALHOST: hostname for the specific devices - automatically determined + LOCALHOST: socket.gethostname(), # USERNAME: administrator USERNAME: "administrator", # NAMESPACE: serial number @@ -81,7 +88,7 @@ def __init__( self, config: dict = {}, hosts: List[dict] | HostListConfig = DEFAULTS[HOSTS], - username: str = DEFAULTS[USERNAME], + localhost: str | Hostname = DEFAULTS[LOCALHOST], namespace: str = DEFAULTS[NAMESPACE], domain_id: int = DEFAULTS[DOMAIN_ID], rmw_implementation: str = DEFAULTS[RMW], @@ -90,6 +97,7 @@ def __init__( # Initialization self._config = {} self.hosts = hosts + self.localhost = localhost self.username = username self.namespace = namespace self.domain_id = domain_id @@ -98,6 +106,7 @@ def __init__( # Setter Template setters = { self.KEYS[self.HOSTS]: SystemConfig.hosts, + self.KEYS[self.LOCALHOST]: SystemConfig.localhost, self.KEYS[self.USERNAME]: SystemConfig.username, self.KEYS[self.NAMESPACE]: SystemConfig.namespace, self.KEYS[self.DOMAIN_ID]: SystemConfig.domain_id, @@ -136,6 +145,24 @@ def hosts(self, value: List[dict] | HostListConfig) -> None: f"Hosts value of {value} is invalid, it must be of type 'dict' or 'HostListConfig'" ) + @property + def localhost(self) -> str: + self.set_config_param( + key=self.KEYS[self.LOCALHOST], + value=str(self._localhost) + ) + return str(self._localhost) + + @localhost.setter + def localhost(self, value: str | Hostname) -> None: + assert isinstance(value, str) or isinstance(value, Hostname), ( + f"Localhost of {value} is invalid, must be of type 'str' or 'Hostname'" + ) + if isinstance(value, str): + self._localhost = Hostname(value) + elif isinstance(value, Hostname): + self._localhost = value + @property def username(self) -> str: self.set_config_param( From fb9e5517929b58424dda0d795cb43ea438cb2f13 Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Sun, 3 Mar 2024 21:59:36 -0500 Subject: [PATCH 23/37] assertion error if the hostname is blank (otherwise causes an invalid index exception) --- clearpath_config/common/types/hostname.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clearpath_config/common/types/hostname.py b/clearpath_config/common/types/hostname.py index c2ffdda..8b72cfb 100644 --- a/clearpath_config/common/types/hostname.py +++ b/clearpath_config/common/types/hostname.py @@ -66,6 +66,10 @@ def assert_valid(hostname: str): assert isinstance(hostname, str), ( "Hostname '%s' must be of type 'str'" % hostname ) + # Min 1 ASCII Characters + assert len(hostname) > 0, ( + "Hostname '%s' is blank." % hostname + ) # Max 253 ASCII Characters assert len(hostname) < 254, ( "Hostname '%s' exceeds 253 ASCII character limit." % hostname From 288685d5af2329a31ba0bf3bd6e999b84214fdac Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Sun, 3 Mar 2024 22:00:12 -0500 Subject: [PATCH 24/37] Add discovery server support --- clearpath_config/common/types/config.py | 1 + clearpath_config/common/types/discovery.py | 66 ++++ clearpath_config/common/types/list.py | 1 + .../common/types/rmw_implementation.py | 10 +- .../sample/a200/a200_default.yaml | 10 +- .../sample/a200/a200_dual_laser.yaml | 10 +- clearpath_config/sample/a200/a200_sample.yaml | 10 +- .../sample/a200/a200_velodyne.yaml | 10 +- .../sample/dd100/dd100_default.yaml | 10 +- .../sample/dd100/dd100_dual_laser.yaml | 10 +- .../sample/dd100/dd100_velodyne.yaml | 10 +- .../sample/dd150/dd150_default.yaml | 10 +- .../sample/dd150/dd150_dual_laser.yaml | 10 +- .../sample/dd150/dd150_velodyne.yaml | 10 +- .../sample/j100/j100_default.yaml | 10 +- .../sample/j100/j100_dual_laser.yaml | 10 +- clearpath_config/sample/j100/j100_sample.yaml | 10 +- .../sample/j100/j100_velodyne.yaml | 10 +- .../sample/w200/w200_default.yaml | 10 +- .../sample/w200/w200_dual_laser.yaml | 10 +- .../sample/w200/w200_velodyne.yaml | 10 +- clearpath_config/system/hosts.py | 23 +- clearpath_config/system/middleware.py | 282 ++++++++++++++++++ clearpath_config/system/servers.py | 209 +++++++++++++ clearpath_config/system/system.py | 93 ++++-- 25 files changed, 700 insertions(+), 155 deletions(-) create mode 100644 clearpath_config/common/types/discovery.py create mode 100644 clearpath_config/system/middleware.py create mode 100644 clearpath_config/system/servers.py diff --git a/clearpath_config/common/types/config.py b/clearpath_config/common/types/config.py index 998db40..eee82e8 100644 --- a/clearpath_config/common/types/config.py +++ b/clearpath_config/common/types/config.py @@ -50,6 +50,7 @@ def __init__( parent_key: str = None, ) -> None: # Dictionaries are Stored Flat + self._config = {} self.template = template self._parent_key = parent_key if self._parent_key is not None and self._parent_key not in config: diff --git a/clearpath_config/common/types/discovery.py b/clearpath_config/common/types/discovery.py new file mode 100644 index 0000000..0a771a0 --- /dev/null +++ b/clearpath_config/common/types/discovery.py @@ -0,0 +1,66 @@ +# Software License Agreement (BSD) +# +# @author Hilary Luo +# @copyright (c) 2024, Clearpath Robotics, Inc., All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Clearpath Robotics nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +class Discovery: + SIMPLE = "simple" + SERVER = "server" + + # All supported discovery modes, currently only set up for FastDDS + ALL_SUPPORTED = [SIMPLE, SERVER] + + # The discovery mode that the system will default to + DEFAULT = SIMPLE + + def __init__( + self, + mode: str = DEFAULT + ) -> None: + self.assert_valid(mode) + self.mode = mode + + def __eq__(self, other: object) -> bool: + if isinstance(other, str): + return self.mode == other + elif isinstance(other, Discovery): + return self.mode == other.mode + else: + return False + + def __str__(self) -> str: + return self.mode + + @classmethod + def is_valid(cls, mode: str) -> bool: + return mode in cls.ALL_SUPPORTED + + @classmethod + def assert_valid(cls, mode: str) -> None: + assert cls.is_valid(mode), ("\n".join[ + f"Discovery mode '{mode}' not supported." + f"Discovery mode must be one of: '{cls.ALL_SUPPORTED}'" + ]) diff --git a/clearpath_config/common/types/list.py b/clearpath_config/common/types/list.py index 6b44a30..7a3d152 100644 --- a/clearpath_config/common/types/list.py +++ b/clearpath_config/common/types/list.py @@ -159,6 +159,7 @@ def set_all( except AssertionError: self.__list = tmp_list + # TODO: the below UID methods are not supported by most implementations of this class # Unique Identifier: Name @staticmethod def uid_name(T) -> str: diff --git a/clearpath_config/common/types/rmw_implementation.py b/clearpath_config/common/types/rmw_implementation.py index ef20d67..30ab813 100644 --- a/clearpath_config/common/types/rmw_implementation.py +++ b/clearpath_config/common/types/rmw_implementation.py @@ -32,11 +32,13 @@ class RMWImplementation: FAST_RTPS = "rmw_fastrtps_cpp" GURUM_DDS = "rmw_gurumdds_cpp" - MIDDLEWARE = [FAST_RTPS] + ALL_SUPPORTED = [FAST_RTPS] + + DEFAULT = FAST_RTPS def __init__( self, - rmw: str = FAST_RTPS + rmw: str = DEFAULT ) -> None: self.assert_valid(rmw) self.rmw = rmw @@ -54,11 +56,11 @@ def __str__(self) -> str: @classmethod def is_valid(cls, rmw: str) -> bool: - return rmw in cls.MIDDLEWARE + return rmw in cls.ALL_SUPPORTED @classmethod def assert_valid(cls, rmw: str) -> None: assert cls.is_valid(rmw), ("\n".join[ "RMW '%s' not supported." % rmw, - "RMW must be one of: '%s'" % cls.MIDDLEWARE + "RMW must be one of: '%s'" % cls.ALL_SUPPORTED ]) diff --git a/clearpath_config/sample/a200/a200_default.yaml b/clearpath_config/sample/a200/a200_default.yaml index 7bbc295..a01ea75 100644 --- a/clearpath_config/sample/a200/a200_default.yaml +++ b/clearpath_config/sample/a200/a200_default.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-a200-0000 - platform: - cpr-a200-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-a200-0000 + ip: 192.168.131.1 ros2: namespace: a200_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/a200/a200_dual_laser.yaml b/clearpath_config/sample/a200/a200_dual_laser.yaml index 96b47b6..8107d5c 100644 --- a/clearpath_config/sample/a200/a200_dual_laser.yaml +++ b/clearpath_config/sample/a200/a200_dual_laser.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-a200-0000 - platform: - cpr-a200-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-a200-0000 + ip: 192.168.131.1 ros2: namespace: a200_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/a200/a200_sample.yaml b/clearpath_config/sample/a200/a200_sample.yaml index 7aa4bb1..fa8affa 100644 --- a/clearpath_config/sample/a200/a200_sample.yaml +++ b/clearpath_config/sample/a200/a200_sample.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-a200-0000 - platform: - cpr-a200-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-a200-0000 + ip: 192.168.131.1 ros2: namespace: a200_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/a200/a200_velodyne.yaml b/clearpath_config/sample/a200/a200_velodyne.yaml index 49728f1..d3d8868 100644 --- a/clearpath_config/sample/a200/a200_velodyne.yaml +++ b/clearpath_config/sample/a200/a200_velodyne.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-a200-0000 - platform: - cpr-a200-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-a200-0000 + ip: 192.168.131.1 ros2: namespace: a200_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/dd100/dd100_default.yaml b/clearpath_config/sample/dd100/dd100_default.yaml index edae92d..c60f869 100644 --- a/clearpath_config/sample/dd100/dd100_default.yaml +++ b/clearpath_config/sample/dd100/dd100_default.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-dd100-0000 - platform: - cpr-dd100-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-dd100-0000 + ip: 192.168.131.1 ros2: namespace: dd100_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/dd100/dd100_dual_laser.yaml b/clearpath_config/sample/dd100/dd100_dual_laser.yaml index cdf151b..3f6ba62 100644 --- a/clearpath_config/sample/dd100/dd100_dual_laser.yaml +++ b/clearpath_config/sample/dd100/dd100_dual_laser.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-dd100-0000 - platform: - cpr-dd100-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-dd100-0000 + ip: 192.168.131.1 ros2: namespace: dd100_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/dd100/dd100_velodyne.yaml b/clearpath_config/sample/dd100/dd100_velodyne.yaml index 4efd738..e2b98b5 100644 --- a/clearpath_config/sample/dd100/dd100_velodyne.yaml +++ b/clearpath_config/sample/dd100/dd100_velodyne.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-dd100-0000 - platform: - cpr-dd100-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-dd100-0000 + ip: 192.168.131.1 ros2: namespace: dd100_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/dd150/dd150_default.yaml b/clearpath_config/sample/dd150/dd150_default.yaml index 2473b8f..1598bac 100644 --- a/clearpath_config/sample/dd150/dd150_default.yaml +++ b/clearpath_config/sample/dd150/dd150_default.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-dd150-0000 - platform: - cpr-dd150-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-dd150-0000 + ip: 192.168.131.1 ros2: namespace: dd150_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/dd150/dd150_dual_laser.yaml b/clearpath_config/sample/dd150/dd150_dual_laser.yaml index 4fd1505..df65f21 100644 --- a/clearpath_config/sample/dd150/dd150_dual_laser.yaml +++ b/clearpath_config/sample/dd150/dd150_dual_laser.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-dd150-0000 - platform: - cpr-dd150-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-dd150-0000 + ip: 192.168.131.1 ros2: namespace: dd150_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/dd150/dd150_velodyne.yaml b/clearpath_config/sample/dd150/dd150_velodyne.yaml index 21d305e..b5714f7 100644 --- a/clearpath_config/sample/dd150/dd150_velodyne.yaml +++ b/clearpath_config/sample/dd150/dd150_velodyne.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-dd150-0000 - platform: - cpr-dd150-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-dd150-0000 + ip: 192.168.131.1 ros2: namespace: dd150_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/j100/j100_default.yaml b/clearpath_config/sample/j100/j100_default.yaml index 3802cb9..21f31de 100644 --- a/clearpath_config/sample/j100/j100_default.yaml +++ b/clearpath_config/sample/j100/j100_default.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-j100-0000 - platform: - cpr-j100-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-j100-0000 + ip: 192.168.131.1 ros2: namespace: j100_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/j100/j100_dual_laser.yaml b/clearpath_config/sample/j100/j100_dual_laser.yaml index 9c33f31..02e6083 100644 --- a/clearpath_config/sample/j100/j100_dual_laser.yaml +++ b/clearpath_config/sample/j100/j100_dual_laser.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-j100-0000 - platform: - cpr-j100-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-j100-0000 + ip: 192.168.131.1 ros2: namespace: j100_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/j100/j100_sample.yaml b/clearpath_config/sample/j100/j100_sample.yaml index 5694efe..880f8ac 100644 --- a/clearpath_config/sample/j100/j100_sample.yaml +++ b/clearpath_config/sample/j100/j100_sample.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-j100-0000 - platform: - cpr-j100-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-j100-0000 + ip: 192.168.131.1 ros2: namespace: j100_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/j100/j100_velodyne.yaml b/clearpath_config/sample/j100/j100_velodyne.yaml index 3d5a8d1..cc7f066 100644 --- a/clearpath_config/sample/j100/j100_velodyne.yaml +++ b/clearpath_config/sample/j100/j100_velodyne.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-j100-0000 - platform: - cpr-j100-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-j100-0000 + ip: 192.168.131.1 ros2: namespace: j100_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp workspaces: [] platform: controller: ps4 diff --git a/clearpath_config/sample/w200/w200_default.yaml b/clearpath_config/sample/w200/w200_default.yaml index cf93ec7..5658581 100644 --- a/clearpath_config/sample/w200/w200_default.yaml +++ b/clearpath_config/sample/w200/w200_default.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-w200-0000 - platform: - cpr-w200-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-w200-0000 + ip: 192.168.131.1 ros2: namespace: w200_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp platform: controller: ps4 attachments: [] diff --git a/clearpath_config/sample/w200/w200_dual_laser.yaml b/clearpath_config/sample/w200/w200_dual_laser.yaml index 4336cd7..f46963b 100644 --- a/clearpath_config/sample/w200/w200_dual_laser.yaml +++ b/clearpath_config/sample/w200/w200_dual_laser.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-w200-0000 - platform: - cpr-w200-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-w200-0000 + ip: 192.168.131.1 ros2: namespace: w200_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp platform: controller: ps4 attachments: [] diff --git a/clearpath_config/sample/w200/w200_velodyne.yaml b/clearpath_config/sample/w200/w200_velodyne.yaml index eed3722..5a88a07 100644 --- a/clearpath_config/sample/w200/w200_velodyne.yaml +++ b/clearpath_config/sample/w200/w200_velodyne.yaml @@ -3,15 +3,13 @@ version: 0 system: username: administrator hosts: - self: cpr-w200-0000 - platform: - cpr-w200-0000: 192.168.131.1 - onboard: {} - remote: {} + - hostname: cpr-w200-0000 + ip: 192.168.131.1 ros2: namespace: w200_0000 domain_id: 0 - rmw_implementation: rmw_fastrtps_cpp + middleware: + implementation: rmw_fastrtps_cpp platform: controller: ps4 attachments: [] diff --git a/clearpath_config/system/hosts.py b/clearpath_config/system/hosts.py index 5a8578d..3f737cc 100644 --- a/clearpath_config/system/hosts.py +++ b/clearpath_config/system/hosts.py @@ -37,7 +37,7 @@ # - this is the format for which each host involved in the system will be described class HostConfig(BaseConfig): - HOSTNAME = "host" + HOSTNAME = "hostname" IP_ADDRESS = "ip" TEMPLATE = { @@ -69,20 +69,8 @@ def __init__( # Set from Config super().__init__(setters, config, None) - def update(self, serial_number=False) -> None: - if serial_number: - sn = BaseConfig.get_serial_number() - # Update if still defaults - if self.self == self.DEFAULTS[self.SELF]: - self.self = sn - if self.platform.get_hostname() == sn: - self.platform.set_hostname(sn) - # Update Defaults - self.DEFAULTS[self.SELF] = sn - self.DEFAULTS[self.PLATFORM] = {sn: "192.168.131.1"} - def __eq__(self, other) -> bool: - return self.hostname == other.hostname and self.ip_address == other.ip + return self.hostname == other.hostname and self.ip_address == other.ip_address def __str__(self) -> str: return "{ hostname: %s, ip: %s }" % (str(self.hostname), str(self.ip_address)) @@ -136,9 +124,12 @@ def ip_address(self, value: str | IP) -> None: # HostListConfig # - list of hosts that are involved with the system class HostListConfig(ListConfig[HostConfig, str]): + + DEFAULTS = [HostConfig.DEFAULTS] + def __init__(self) -> None: super().__init__( - uid=lambda obj: obj.get_hostname(), + uid=lambda obj: obj.hostname, obj_type=HostConfig, uid_type=str ) @@ -147,4 +138,4 @@ def to_dict(self) -> List[dict]: hosts = [] for host in self.get_all(): hosts.append(host.config) - return hosts \ No newline at end of file + return hosts diff --git a/clearpath_config/system/middleware.py b/clearpath_config/system/middleware.py new file mode 100644 index 0000000..f2d39dd --- /dev/null +++ b/clearpath_config/system/middleware.py @@ -0,0 +1,282 @@ +# Software License Agreement (BSD) +# +# @author Hilary Luo +# @copyright (c) 2024, Clearpath Robotics, Inc., All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Clearpath Robotics nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import os +from typing import List + +from clearpath_config.common.types.config import BaseConfig +from clearpath_config.common.types.discovery import Discovery +from clearpath_config.common.types.hostname import Hostname +from clearpath_config.common.types.rmw_implementation import RMWImplementation +from clearpath_config.common.utils.dictionary import flip_dict +from clearpath_config.system.hosts import HostListConfig +from clearpath_config.system.servers import ServerListConfig, ServerConfig + + +class MiddlewareConfig(BaseConfig): + MIDDLEWARE = "middleware" + RMW = "implementation" + DISCOVERY = "discovery" + PROFILE = "profile" + OVERRIDE_SERVER_ID = "override_server_id" + SERVERS = "servers" + + TEMPLATE = { + MIDDLEWARE: { + RMW: RMW, + DISCOVERY: DISCOVERY, + PROFILE: PROFILE, + OVERRIDE_SERVER_ID: OVERRIDE_SERVER_ID, + SERVERS: SERVERS, + } + } + + KEYS = flip_dict(TEMPLATE) + + DEFAULTS = { + RMW: RMWImplementation.DEFAULT, + DISCOVERY: Discovery.DEFAULT, + PROFILE: "", + OVERRIDE_SERVER_ID: False, + SERVERS: [], + } + + def __init__( + self, + config: dict = {}, + rmw_implementation: str | RMWImplementation = DEFAULTS[RMW], + discovery: str | Discovery = DEFAULTS[DISCOVERY], + profile: str = DEFAULTS[PROFILE], + override_server_id: bool = DEFAULTS[OVERRIDE_SERVER_ID], + servers: List[dict] | ServerListConfig = DEFAULTS[SERVERS], + hosts: HostListConfig = None, + localhost: Hostname = None + ) -> None: + # Initialization + self._config = {} + self.hosts = hosts + self.localhost = localhost + self.rmw_implementation = rmw_implementation + self.discovery = discovery + self.profile = profile + self.override_server_id = override_server_id + if servers: + self.servers = servers + elif hosts: + self.servers = hosts.to_dict() + setters = { + self.KEYS[self.RMW]: MiddlewareConfig.rmw_implementation, + self.KEYS[self.DISCOVERY]: MiddlewareConfig.discovery, + self.KEYS[self.PROFILE]: MiddlewareConfig.profile, + self.KEYS[self.OVERRIDE_SERVER_ID]: MiddlewareConfig.override_server_id, + self.KEYS[self.SERVERS]: MiddlewareConfig.servers, + } + super().__init__(setters, config, self.MIDDLEWARE) + + @property + def rmw_implementation(self) -> str: + self.set_config_param( + key=self.KEYS[self.RMW], + value=str(self._rmw_implementation) + ) + return str(self._rmw_implementation) + + @rmw_implementation.setter + def rmw_implementation(self, value: str | RMWImplementation) -> None: + if isinstance(value, str): + self._rmw_implementation = RMWImplementation(value) + elif isinstance(value, RMWImplementation): + self._rmw_implementation = value + else: + assert (isinstance(value, str)) or (isinstance(value, RMWImplementation)), ( + f"RMW value of {value} is invalid, must be of type 'str' or 'RMWImplementation'" + ) + + @property + def discovery(self) -> Discovery: + self.set_config_param( + key=self.KEYS[self.DISCOVERY], + value=str(self._discovery) + ) + return str(self._discovery) + + @discovery.setter + def discovery(self, value: str | Discovery) -> None: + if isinstance(value, str): + self._discovery = Discovery(value) + elif isinstance(value, Discovery): + self._discovery = value + else: + assert ( + isinstance(value, str)) or (isinstance(value, Discovery)), ( + f"Discovery mode value of {value} is invalid." + f"Discovery mode must be of type 'str' or 'RMWImplementation'" + ) + self._discovery = value + + @property + def profile(self) -> str: + self.set_config_param( + key=self.KEYS[self.PROFILE], + value=self._profile + ) + return self._profile + + @profile.setter + def profile(self, value: str) -> None: + # Check Type + assert isinstance(value, str), ( + f"Middleware profile {value} is invalid, must be a string" + ) + # Valid file + if value != self.DEFAULTS[self.PROFILE]: + assert os.path.exists(value), ( + f"Middleware profile path {value} does not exist" + ) + self._profile = value + return + + @property + def override_server_id(self) -> bool: + self.set_config_param( + key=self.KEYS[self.OVERRIDE_SERVER_ID], + value=self._override_server_id + ) + return self._override_server_id + + @override_server_id.setter + def override_server_id(self, value: bool) -> None: + assert isinstance(value, bool), ( + f"Override server_id value of {value} is invalid, must be a boolean") + self._override_server_id = value + + @property + def servers(self) -> List[dict]: + if self._servers: + self.set_config_param( + key=self.KEYS[self.SERVERS], + value=self._servers.to_dict() + ) + return self._servers + + @servers.setter + def servers(self, value: List[dict] | ServerListConfig) -> None: + # Generate a list of ServerConfig Objects based on how the input was provided + server_list = [] + if isinstance(value, list): + assert all([isinstance(i, dict) for i in value]), ( + f"Server {value} is invalid, must be list of " + + "type 'dict' or of type 'ServerListConfig'" + ) + # If the servers were not explicitly listed, assume every device in the hosts list + # should have its own discovery server running + if (not value) and (self.discovery == Discovery.SERVER): + value = [] + [value.append({ServerConfig.HOSTNAME: h.hostname}) for h in self.hosts.get_all()] + + for d in value: + assert isinstance(d, dict), ( + f"Server value of {d} is invalid, it must be of type 'dict'" + ) + server_list.append(ServerConfig(config=d)) + else: + assert isinstance(value, ServerListConfig), ( + f"Servers {value} is invalid, must be list of " + + "type 'dict' or of type 'ServerListConfig'" + ) + server_list = value.get_all() + + # set IP addresses based on the host names provided + for server in server_list: + # if a host name was provided, use the look up to determine the ip address + if server.hostname: + assert any(server.hostname == s.hostname for s in self.hosts.get_all()), ( + f"Provided hostname: {server.hostname} is not listed in the hosts list" + ) + match = next((s for s in self.hosts.get_all() if s.hostname == server.hostname)) + server.ip_address = match.ip_address + else: + assert server.ip_address, ( + f"Server {server} is listed without a host name or IP address." + ) + + for server in server_list: + # Ensure no duplicate server host/ip + port + count = sum(((s.ip_address == server.ip_address) and (s.port == server.port)) + for s in server_list) + assert count == 1, ( + f"Discovery server {server} conflicts with another discovery server. " + + "Each combination of host/ip and port number must be unique." + ) + + # sort the servers by host/ip address and then port + # required for consistent server id numbering + server_list.sort(key=lambda s: (str.lower(s.hostname), s.ip_address, s.port)) + + if not self.override_server_id: + # assign server id numbering - this numbering must be consistent across all devices + for i, server in enumerate(server_list): + server.server_id = i + else: + # Only for edge cases where server id is needed to be manually specified in the config + # Ensure no duplicate server server_id + # (unspecified ones will default and show up as duplicates) + for server in server_list: + count = sum(s.server_id == server.server_id for s in server_list) + assert count == 1, ( + f"Server {server} does not have a unique server id. While " + + "override_server_id is true, each server must have a unique id specified." + ) + + servers = ServerListConfig() + servers.set_all(server_list) + self._servers = servers + + def get_servers_string(self) -> str: + server_list = self.servers.get_all() + + servers_str = '' + i = 0 + for s in server_list: + if not s.enabled: + continue + while i < s.server_id: + servers_str += ';' + i += 1 + servers_str += f'{s.ip_address}:{s.port};' + i += 1 + + return servers_str + + def get_local_server(self) -> ServerConfig: + # check for the localhost in the server list + server_list = self.servers.get_all() + local_server = next((s for s in server_list if (s.hostname == self.localhost and + s.enabled)), None) + # returns None if the localhost is not listed in the server list + return local_server diff --git a/clearpath_config/system/servers.py b/clearpath_config/system/servers.py new file mode 100644 index 0000000..71b4deb --- /dev/null +++ b/clearpath_config/system/servers.py @@ -0,0 +1,209 @@ +# Software License Agreement (BSD) +# +# @author Hilary Luo +# @copyright (c) 2024, Clearpath Robotics, Inc., All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Clearpath Robotics nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from typing import List + +from clearpath_config.common.types.config import BaseConfig +from clearpath_config.common.types.hostname import Hostname +from clearpath_config.common.types.ip import IP +from clearpath_config.common.types.port import Port +from clearpath_config.common.types.list import ListConfig +from clearpath_config.common.utils.dictionary import flip_dict + + +class ServerConfig(BaseConfig): + HOSTNAME = "hostname" + IP_ADDRESS = "ip" + PORT = "port" + SERVER_ID = "server_id" + ENABLED = "enabled" + + TEMPLATE = { + HOSTNAME: HOSTNAME, + IP_ADDRESS: IP_ADDRESS, + PORT: PORT, + SERVER_ID: SERVER_ID, + ENABLED: ENABLED + } + + KEYS = flip_dict(TEMPLATE) + + DEFAULTS = { + HOSTNAME: '', + IP_ADDRESS: '', + PORT: 11811, + SERVER_ID: 0, + ENABLED: True + } + + def __init__( + self, + config: dict = {}, + hostname: str | Hostname = DEFAULTS[HOSTNAME], + ip_address: str | IP = DEFAULTS[IP_ADDRESS], + port: int | Port = DEFAULTS[PORT], + server_id: int = DEFAULTS[SERVER_ID], + enabled: bool = DEFAULTS[ENABLED] + ) -> None: + self.hostname = hostname + self.ip_address = ip_address + self.port = port + self.server_id = server_id + self.enabled = enabled + # Setter Template + setters = { + self.KEYS[self.HOSTNAME]: ServerConfig.hostname, + self.KEYS[self.IP_ADDRESS]: ServerConfig.ip_address, + self.KEYS[self.PORT]: ServerConfig.port, + self.KEYS[self.SERVER_ID]: ServerConfig.server_id, + self.KEYS[self.ENABLED]: ServerConfig.enabled, + } + super().__init__(setters, config, None) + + def __str__(self) -> str: + return "{ hostname: %s, ip: %s, port: %s, server_id: %s, enabled: %s}" % ( + str(self.hostname), str(self.ip_address), str(self.port), + str(self.server_id), str(self.enabled)) + + @property + def server_id(self) -> int: + self.set_config_param( + key=self.KEYS[self.SERVER_ID], + value=int(self._server_id) + ) + return int(self._server_id) + + @server_id.setter + def server_id(self, value: int) -> None: + # Check Type + assert isinstance(value, int), ( + f"Remote Server ID {value} is invalid, must be an integer" + ) + # [0-255] Range + assert 0 <= value < 255, ( + f"Discovery Server ID {value} is invalid, must be in range 0 - 254" + ) + self._server_id = value + return + + @property + def hostname(self) -> str: + self.set_config_param( + key=self.KEYS[self.HOSTNAME], + value=str(self._hostname) + ) + return str(self._hostname) + + @hostname.setter + def hostname(self, value: str | Hostname) -> None: + if not value: + self._hostname = '' + elif isinstance(value, str): + self._hostname = Hostname(value) + elif isinstance(value, Hostname): + self._hostname = value + else: + assert isinstance(value, str) or isinstance(value, Hostname), ( + f"Hostname of {value} is invalid, must be of type 'str' or 'Hostname'" + ) + return + + @property + def ip_address(self) -> str: + self.set_config_param( + key=self.KEYS[self.IP_ADDRESS], + value=str(self._ip_address) + ) + return str(self._ip_address) + + @ip_address.setter + def ip_address(self, value: str | IP) -> None: + if not value: + self._ip_address = '' + elif isinstance(value, str): + self._ip_address = IP(value) + elif isinstance(value, IP): + self._ip_address = value + else: + assert isinstance(value, dict) or isinstance(value, IP), ( + f"IP address of {value} is invalid, must be of type 'str' or 'IP'" + ) + return + + @property + def port(self) -> int: + self.set_config_param( + key=self.KEYS[self.PORT], + value=int(self._port) + ) + return int(self._port) + + @port.setter + def port(self, value: int | Port) -> None: + if isinstance(value, int): + self._port = Port(value) + elif isinstance(value, Port): + self._port = value + else: + assert isinstance(value, dict) or isinstance(value, Port), ( + f"Port of {value} is invalid, must be of type 'str' or 'Port'" + ) + return + + @property + def enabled(self) -> bool: + self.set_config_param( + key=self.KEYS[self.ENABLED], + value=self._enabled + ) + return self._enabled + + @enabled.setter + def enabled(self, value: bool) -> None: + # Check Type + assert (isinstance(value, bool)), ( + f"Enabled {value} is invalid, must be a boolean" + ) + self._enabled = value + return + + +# LinkListConfig +class ServerListConfig(ListConfig[ServerConfig, int]): + def __init__(self) -> None: + super().__init__( + uid=lambda obj: obj.server_id, + obj_type=ServerConfig, + uid_type=int + ) + + def to_dict(self) -> List[dict]: + d = [] + for server in self.get_all(): + d.append(server.config) + return d diff --git a/clearpath_config/system/system.py b/clearpath_config/system/system.py index 5e0e847..6a11090 100644 --- a/clearpath_config/system/system.py +++ b/clearpath_config/system/system.py @@ -31,10 +31,12 @@ from clearpath_config.common.types.config import BaseConfig from clearpath_config.common.types.domain_id import DomainID +from clearpath_config.common.types.hostname import Hostname from clearpath_config.common.types.namespace import Namespace from clearpath_config.common.types.username import Username from clearpath_config.common.utils.dictionary import flip_dict from clearpath_config.system.hosts import HostConfig, HostListConfig +from clearpath_config.system.middleware import MiddlewareConfig class SystemConfig(BaseConfig): @@ -47,7 +49,7 @@ class SystemConfig(BaseConfig): USERNAME = "username" NAMESPACE = "namespace" DOMAIN_ID = "domain_id" - RMW = "rmw_implementation" + MIDDLEWARE = MiddlewareConfig.MIDDLEWARE WORKSPACES = "workspaces" TEMPLATE = { @@ -59,7 +61,7 @@ class SystemConfig(BaseConfig): ROS2: { NAMESPACE: NAMESPACE, DOMAIN_ID: DOMAIN_ID, - RMW: RMW, + MIDDLEWARE: MIDDLEWARE, WORKSPACES: WORKSPACES } } @@ -69,7 +71,7 @@ class SystemConfig(BaseConfig): DEFAULTS = { # HOSTS: hostnames and IP's for all computers involved with the system - HOSTS: HostConfig.DEFAULTS, + HOSTS: HostListConfig.DEFAULTS, # LOCALHOST: hostname for the specific devices - automatically determined LOCALHOST: socket.gethostname(), # USERNAME: administrator @@ -78,8 +80,8 @@ class SystemConfig(BaseConfig): NAMESPACE: Namespace.clean(BaseConfig.get_serial_number(prefix=True)), # DOMAIN_ID: 0 DOMAIN_ID: 0, - # RMW: "rmw_fastrtps_cpp" - RMW: "rmw_fastrtps_cpp", + # Discovery Server Disabled + MIDDLEWARE: MiddlewareConfig.DEFAULTS, # Workpaces: empty list WORKSPACES: [] } @@ -89,9 +91,10 @@ def __init__( config: dict = {}, hosts: List[dict] | HostListConfig = DEFAULTS[HOSTS], localhost: str | Hostname = DEFAULTS[LOCALHOST], - namespace: str = DEFAULTS[NAMESPACE], - domain_id: int = DEFAULTS[DOMAIN_ID], - rmw_implementation: str = DEFAULTS[RMW], + username: str | Username = DEFAULTS[USERNAME], + namespace: str | Namespace = DEFAULTS[NAMESPACE], + domain_id: int | DomainID = DEFAULTS[DOMAIN_ID], + middleware: dict | MiddlewareConfig = DEFAULTS[MIDDLEWARE], workspaces: list = DEFAULTS[WORKSPACES] ) -> None: # Initialization @@ -101,7 +104,7 @@ def __init__( self.username = username self.namespace = namespace self.domain_id = domain_id - self.rmw_implementation = rmw_implementation + self.middleware = middleware self.workspaces = workspaces # Setter Template setters = { @@ -110,7 +113,7 @@ def __init__( self.KEYS[self.USERNAME]: SystemConfig.username, self.KEYS[self.NAMESPACE]: SystemConfig.namespace, self.KEYS[self.DOMAIN_ID]: SystemConfig.domain_id, - self.KEYS[self.RMW]: SystemConfig.rmw_implementation, + self.KEYS[self.MIDDLEWARE]: SystemConfig.middleware, self.KEYS[self.WORKSPACES]: SystemConfig.workspaces, } # Set from Config @@ -118,31 +121,54 @@ def __init__( def update(self, serial_number=False) -> None: if serial_number: - self.hosts.update(serial_number=serial_number) + # check if hosts list is set to default, if so update it + hosts = self.DEFAULTS[self.HOSTS] + hosts[0][HostConfig.HOSTNAME] = BaseConfig.get_serial_number() + if self.hosts.to_dict() == self.DEFAULTS[self.HOSTS]: + self.hosts = hosts # Update if still defaults - namespace = Namespace.clean(self.get_serial_number(prefix=True)) + namespace = Namespace.clean(BaseConfig.get_serial_number(prefix=True)) if self.namespace == self.DEFAULTS[self.NAMESPACE]: self.namespace = namespace # Update defaults + self.DEFAULTS[self.HOSTS] = hosts self.DEFAULTS[self.NAMESPACE] = namespace @property - def hosts(self) -> HostConfig: + def hosts(self) -> HostListConfig: self.set_config_param( key=self.KEYS[self.HOSTS], - value=self._hosts.config[self.HOSTS] + value=self._hosts.to_dict() ) return self._hosts @hosts.setter def hosts(self, value: List[dict] | HostListConfig) -> None: - if isinstance(value, dict): - self._hosts = HostConfig(config=value) - elif isinstance(value, HostConfig): + host_list = [] + if isinstance(value, list): + for d in value: + assert isinstance(d, dict), ( + f"Host value of {d} is invalid, it must be of type 'dict'" + ) + host_list.append(HostConfig(config=d)) + + for host in host_list: + # Ensure no duplicate hostname or IP + count = sum(((host.ip_address == h.ip_address) or (host.hostname == h.hostname)) + for h in host_list) + assert count == 1, ( + f"Host {host} conflicts with another host. " + + "Each hostname and ip must be unique." + ) + + self._hosts = HostListConfig() + self._hosts.set_all(host_list) + elif isinstance(value, HostListConfig): self._hosts = value else: - assert isinstance(value, dict) or isinstance(value, HostConfig), ( - f"Hosts value of {value} is invalid, it must be of type 'dict' or 'HostListConfig'" + assert isinstance(value, list) or isinstance(value, HostConfig), ( + f"Hosts value of {value} is invalid, " + + "it must be of type 'List[dict]' or 'HostListConfig'" ) @property @@ -214,24 +240,25 @@ def domain_id(self, value: int | DomainID) -> None: ) @property - def rmw_implementation(self) -> str: + def middleware(self) -> MiddlewareConfig: self.set_config_param( - key=self.KEYS[self.RMW], - value=str(self._rmw_implementation) + key=self.KEYS[self.MIDDLEWARE], + value=self._middleware.config[self.MIDDLEWARE] ) - return str(self._rmw_implementation) + return self._middleware - @rmw_implementation.setter - def rmw_implementation(self, value: str | RMWImplementation) -> None: - if isinstance(value, str): - self._rmw_implementation = RMWImplementation(value) - elif isinstance(value, RMWImplementation): - self._rmw_implementation = value + @middleware.setter + def middleware(self, value: dict | MiddlewareConfig) -> None: + if isinstance(value, dict): + self._middleware = MiddlewareConfig(config=value, + hosts=self.hosts, + localhost=self.localhost) + elif isinstance(value, MiddlewareConfig): + self._middleware = value else: - assert ( - isinstance(value, str)) or ( - isinstance(value, RMWImplementation)), ( - "RMW must be of type 'str' or 'RMWImplementation'" + assert isinstance(value, dict) or ( + isinstance(value, MiddlewareConfig)), ( + "Middleware configuration must be of type 'dict' or 'MiddlewareConfig'" ) @property From da71cb016783b42724482906e33aa839df7d326c Mon Sep 17 00:00:00 2001 From: Hilary Luo Date: Thu, 7 Mar 2024 10:10:54 -0500 Subject: [PATCH 25/37] Switched local server to be referenced as loopback in the ROS_DISCOVERY_SERVER envar --- clearpath_config/system/middleware.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clearpath_config/system/middleware.py b/clearpath_config/system/middleware.py index f2d39dd..37c3d7b 100644 --- a/clearpath_config/system/middleware.py +++ b/clearpath_config/system/middleware.py @@ -268,7 +268,10 @@ def get_servers_string(self) -> str: while i < s.server_id: servers_str += ';' i += 1 - servers_str += f'{s.ip_address}:{s.port};' + if s.hostname == self.localhost: + servers_str += f'127.0.0.1:{s.port};' + else: + servers_str += f'{s.ip_address}:{s.port};' i += 1 return servers_str From d86eef76bf88748f74bd95e62798dd28ed135fdd Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 18 Mar 2024 10:07:29 -0400 Subject: [PATCH 26/37] Changes. --- CHANGELOG.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7b4f70c..1fd1ff0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,15 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Switched local server to be referenced as loopback in the ROS_DISCOVERY_SERVER envar +* Add discovery server support +* assertion error if the hostname is blank (otherwise causes an invalid index exception) +* Add localhost field which is set automatically +* Reformat hosts section to single list of all computers +* Contributors: Hilary Luo + 0.2.5 (2024-03-06) ------------------ * Add republishers to camera From 9b517d8c2cb08daed8b7de0a996c044da3f7a6d3 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 18 Mar 2024 10:07:44 -0400 Subject: [PATCH 27/37] 0.2.6 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1fd1ff0..a1c8e59 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.6 (2024-03-18) +------------------ * Switched local server to be referenced as loopback in the ROS_DISCOVERY_SERVER envar * Add discovery server support * assertion error if the hostname is blank (otherwise causes an invalid index exception) diff --git a/package.xml b/package.xml index 88eba47..3cc6673 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.5 + 0.2.6 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index 89199b0..7b82d88 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.5", + version="0.2.6", packages=[ package_name, package_name + ".common", From 466c10f4990d2ceecb785877a0e2d974b9033e82 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Wed, 13 Mar 2024 11:32:18 -0400 Subject: [PATCH 28/37] Added launch to extras --- clearpath_config/platform/extras.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/clearpath_config/platform/extras.py b/clearpath_config/platform/extras.py index 2aee61a..e8696a8 100644 --- a/clearpath_config/platform/extras.py +++ b/clearpath_config/platform/extras.py @@ -155,6 +155,7 @@ class ExtrasConfig(BaseConfig): EXTRAS = "extras" URDF = "urdf" + LAUNCH = "launch" ROS_PARAMETERS = "ros_parameters" PLATFORM_VELOCITY_CONTROLLER = "platform_velocity_controller" @@ -171,6 +172,7 @@ class ExtrasConfig(BaseConfig): TEMPLATE = { EXTRAS: { URDF: URDF, + LAUNCH: LAUNCH, ROS_PARAMETERS: { PLATFORM_VELOCITY_CONTROLLER: { WHEEL_RADIUS: WHEEL_RADIUS, @@ -192,6 +194,7 @@ class ExtrasConfig(BaseConfig): DEFAULTS = { URDF: None, + LAUNCH: None, ROS_PARAMETERS: ROSParameterDefaults(BaseConfig.get_platform_model()), } @@ -199,6 +202,7 @@ def __init__( self, config: dict = {}, urdf: dict = DEFAULTS[URDF], + launch: dict = DEFAULTS[LAUNCH], ros_parameters: dict = {}, ) -> None: # ROS Parameter Setter Template @@ -216,12 +220,14 @@ def __init__( # Setter Template self.setters = { self.KEYS[self.URDF]: ExtrasConfig.urdf, + self.KEYS[self.LAUNCH]: ExtrasConfig.launch, self.KEYS[self.ROS_PARAMETERS]: ExtrasConfig.ros_parameters, } # Initialization self._init_ros_parameter() self._config = {} self.urdf = urdf + self.launch = launch self.ros_parameters = ros_parameters # Set from Config super().__init__(self.setters, config, self.EXTRAS) @@ -252,6 +258,28 @@ def urdf(self, value: dict | PackagePath) -> None: "Extras URDF must be null or of type `dict` or `PackagePath`" ) + @property + def launch(self) -> dict: + launch = None if (self._launch == self.DEFAULTS[self.LAUNCH]) else dict(self._launch.to_dict()) + self.set_config_param( + key=self.KEYS[self.LAUNCH], + value=launch, + ) + return launch + + @launch.setter + def launch(self, value: dict | PackagePath) -> None: + if isinstance(value, dict) and PackagePath.PATH in value and value[PackagePath.PATH]: + self._launch = PackagePath() + self._launch.from_dict(value) + elif isinstance(value, PackagePath) and value.path: + self._launch = value + else: + self._launch = self.DEFAULTS[self.LAUNCH] + assert not value or isinstance(value, dict) or (isinstance(value, PackagePath)), ( + "Extras LAUNCH must be null or of type `dict` or `PackagePath`" + ) + def _is_ros_parameter(self, key) -> bool: return any([key in i for i in self._ros_parameters_setters]) From b82236480438b328fd940673ad95aa18027402cb Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Fri, 15 Mar 2024 09:45:09 -0400 Subject: [PATCH 29/37] Removed long line --- clearpath_config/platform/extras.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clearpath_config/platform/extras.py b/clearpath_config/platform/extras.py index e8696a8..f736d65 100644 --- a/clearpath_config/platform/extras.py +++ b/clearpath_config/platform/extras.py @@ -260,7 +260,10 @@ def urdf(self, value: dict | PackagePath) -> None: @property def launch(self) -> dict: - launch = None if (self._launch == self.DEFAULTS[self.LAUNCH]) else dict(self._launch.to_dict()) + if (self._launch == self.DEFAULTS[self.LAUNCH]): + launch = None + else: + launch = dict(self._launch.to_dict()) self.set_config_param( key=self.KEYS[self.LAUNCH], value=launch, From eefab8de50317f6e4949492b4204cfad6ee0a3c7 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Mon, 18 Mar 2024 13:41:10 -0400 Subject: [PATCH 30/37] Minimal samples. --- .../sample/a200/a200_default.yaml | 55 +----------------- .../sample/a200/a200_dual_laser.yaml | 53 +---------------- .../sample/a200/a200_outline.yaml | 58 +++++++++++++++++++ clearpath_config/sample/a200/a200_sample.yaml | 44 ++------------ .../sample/a200/a200_velodyne.yaml | 50 ++-------------- .../sample/dd100/dd100_default.yaml | 38 ------------ .../sample/dd100/dd100_dual_laser.yaml | 34 ----------- .../sample/dd100/dd100_outline.yaml | 40 +++++++++++++ .../sample/dd100/dd100_velodyne.yaml | 32 ---------- .../sample/dd150/dd150_default.yaml | 38 ------------ .../sample/dd150/dd150_dual_laser.yaml | 34 ----------- .../sample/dd150/dd150_outline.yaml | 40 +++++++++++++ .../sample/dd150/dd150_velodyne.yaml | 32 ---------- .../sample/j100/j100_default.yaml | 49 +--------------- .../sample/j100/j100_dual_laser.yaml | 47 +-------------- .../sample/j100/j100_outline.yaml | 54 +++++++++++++++++ clearpath_config/sample/j100/j100_sample.yaml | 42 +------------- .../sample/j100/j100_velodyne.yaml | 47 +-------------- .../sample/w200/w200_default.yaml | 43 -------------- .../sample/w200/w200_dual_laser.yaml | 39 +------------ .../sample/w200/w200_outline.yaml | 45 ++++++++++++++ .../sample/w200/w200_velodyne.yaml | 35 ----------- 22 files changed, 260 insertions(+), 689 deletions(-) create mode 100644 clearpath_config/sample/a200/a200_outline.yaml create mode 100644 clearpath_config/sample/dd100/dd100_outline.yaml create mode 100644 clearpath_config/sample/dd150/dd150_outline.yaml create mode 100644 clearpath_config/sample/j100/j100_outline.yaml create mode 100644 clearpath_config/sample/w200/w200_outline.yaml diff --git a/clearpath_config/sample/a200/a200_default.yaml b/clearpath_config/sample/a200/a200_default.yaml index a01ea75..e11921a 100644 --- a/clearpath_config/sample/a200/a200_default.yaml +++ b/clearpath_config/sample/a200/a200_default.yaml @@ -1,61 +1,12 @@ serial_number: a200-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-a200-0000 - ip: 192.168.131.1 - ros2: - namespace: a200_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: ES20_12C - configuration: S2P1 attachments: - name: front_bumper - type: bumper + type: a200.bumper parent: front_bumper_mount - name: rear_bumper - type: bumper + type: a200.bumper parent: rear_bumper_mount - name: top_plate - type: top_plate - - name: sensor_arch - type: sensor_arch - parent: default_mount - enabled: False - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 1.0 - linear.x.min_velocity": -1.0 - linear.x.max_acceleration": 3.0 - linear.x.min_acceleration": -3.0 - angular.z.max_velocity": 2.0 - angular.z.min_velocity": -2.0 - angular.z.max_acceleration": 6.0 - angular.z.min_acceleration": -6.0 -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] -sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] - lidar3d: [] + type: a200.top_plate diff --git a/clearpath_config/sample/a200/a200_dual_laser.yaml b/clearpath_config/sample/a200/a200_dual_laser.yaml index 8107d5c..58265c8 100644 --- a/clearpath_config/sample/a200/a200_dual_laser.yaml +++ b/clearpath_config/sample/a200/a200_dual_laser.yaml @@ -1,62 +1,16 @@ serial_number: a200-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-a200-0000 - ip: 192.168.131.1 - ros2: - namespace: a200_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: ES20_12C - configuration: S2P1 attachments: - name: front_bumper - type: bumper + type: a200.bumper parent: front_bumper_mount - name: rear_bumper - type: bumper + type: a200.bumper parent: rear_bumper_mount - name: top_plate - type: top_plate - model: pacs - - name: sensor_arch - type: sensor_arch - parent: default_mount - enabled: False - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 1.0 - linear.x.min_velocity": -1.0 - linear.x.max_acceleration": 3.0 - linear.x.min_acceleration": -3.0 - angular.z.max_velocity": 2.0 - angular.z.min_velocity": -2.0 - angular.z.max_acceleration": 6.0 - angular.z.min_acceleration": -6.0 -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] + type: a200.top_plate sensors: - camera: [] - gps: [] imu: - model: microstrain_imu urdf_enabled: true @@ -96,4 +50,3 @@ sensors: ip_port: 10940 angle_min: -3.141592653589793 angle_max: 3.141592653589793 - lidar3d: [] diff --git a/clearpath_config/sample/a200/a200_outline.yaml b/clearpath_config/sample/a200/a200_outline.yaml new file mode 100644 index 0000000..19ecf49 --- /dev/null +++ b/clearpath_config/sample/a200/a200_outline.yaml @@ -0,0 +1,58 @@ +serial_number: a200-0000 +version: 0 +system: + username: administrator + hosts: + - hostname: cpr-a200-0000 + ip: 192.168.131.1 + ros2: + namespace: a200_0000 + domain_id: 0 + middleware: + implementation: rmw_fastrtps_cpp + workspaces: [] +platform: + controller: ps4 + battery: + model: ES20_12C + configuration: S2P1 + attachments: + - name: front_bumper + type: a200.bumper + parent: front_bumper_mount + - name: rear_bumper + type: a200.bumper + parent: rear_bumper_mount + - name: top_plate + type: a200.top_plate + extras: + urdf: null + launch: null + ros_parameters: + platform_velocity_controller: + linear.x.max_velocity": 1.0 + linear.x.min_velocity": -1.0 + linear.x.max_acceleration": 3.0 + linear.x.min_acceleration": -3.0 + angular.z.max_velocity": 2.0 + angular.z.min_velocity": -2.0 + angular.z.max_acceleration": 6.0 + angular.z.min_acceleration": -6.0 +links: + box: [] + cylinder: [] + frame: [] + mesh: [] + sphere: [] +mounts: + bracket: [] + fath_pivot: [] + riser: [] + disk: [] + post: [] +sensors: + camera: [] + gps: [] + imu: [] + lidar2d: [] + lidar3d: [] diff --git a/clearpath_config/sample/a200/a200_sample.yaml b/clearpath_config/sample/a200/a200_sample.yaml index fa8affa..8a48f6f 100644 --- a/clearpath_config/sample/a200/a200_sample.yaml +++ b/clearpath_config/sample/a200/a200_sample.yaml @@ -1,48 +1,21 @@ serial_number: a200-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-a200-0000 - ip: 192.168.131.1 - ros2: - namespace: a200_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: ES20_12C - configuration: S2P1 attachments: - name: front_bumper - type: bumper + type: a200.bumper parent: front_bumper_mount - name: rear_bumper - type: bumper + type: a200.bumper parent: rear_bumper_mount - name: top_plate - type: top_plate + type: a200.top_plate model: pacs - name: sensor_arch - type: sensor_arch + type: a200.sensor_arch parent: default_mount model: sensor_arch_300 enabled: true - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 1.0 - linear.x.min_velocity": -1.0 - linear.x.max_acceleration": 3.0 - linear.x.min_acceleration": -3.0 - angular.z.max_velocity": 2.0 - angular.z.min_velocity": -2.0 - angular.z.max_acceleration": 6.0 - angular.z.min_acceleration": -6.0 links: box: - name: user_bay_cover @@ -50,10 +23,6 @@ links: xyz: [0.0, 0.0, 0.0075] rpy: [0.0, 0.0, 0.0] size: [0.4, 0.4, 0.002] - cylinder: [] - frame: [] - mesh: [] - sphere: [] mounts: bracket: - parent: top_plate_mount_d1 @@ -65,9 +34,6 @@ mounts: xyz: [0.0, 0.0, -0.021] rpy: [3.1415, 0.0, 0.0] angle: 0.0 - riser: [] - disk: [] - post: [] sensors: camera: - model: intel_realsense @@ -86,8 +52,6 @@ sensors: enable_depth: true depth_module.profile: 640,480,30 pointcloud.enable: true - gps: [] - imu: [] lidar2d: - model: hokuyo_ust urdf_enabled: true diff --git a/clearpath_config/sample/a200/a200_velodyne.yaml b/clearpath_config/sample/a200/a200_velodyne.yaml index d3d8868..37aa8ff 100644 --- a/clearpath_config/sample/a200/a200_velodyne.yaml +++ b/clearpath_config/sample/a200/a200_velodyne.yaml @@ -1,63 +1,22 @@ serial_number: a200-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-a200-0000 - ip: 192.168.131.1 - ros2: - namespace: a200_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: ES20_12C - configuration: S2P1 attachments: - name: front_bumper - type: bumper + type: a200.bumper parent: front_bumper_mount - name: rear_bumper - type: bumper + type: a200.bumper parent: rear_bumper_mount - name: top_plate - type: top_plate + type: a200.top_plate model: pacs - name: sensor_arch - type: sensor_arch + type: a200.sensor_arch parent: default_mount model: sensor_arch_300 enabled: true - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 1.0 - linear.x.min_velocity": -1.0 - linear.x.max_acceleration": 3.0 - linear.x.min_acceleration": -3.0 - angular.z.max_velocity": 2.0 - angular.z.min_velocity": -2.0 - angular.z.max_acceleration": 6.0 - angular.z.min_acceleration": -6.0 -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] imu: - model: microstrain_imu urdf_enabled: true @@ -70,7 +29,6 @@ sensors: imu_frame_id: imu_0_link port: /dev/microstrain_main use_enu_frame: true - lidar2d: [] lidar3d: - model: velodyne_lidar urdf_enabled: true diff --git a/clearpath_config/sample/dd100/dd100_default.yaml b/clearpath_config/sample/dd100/dd100_default.yaml index c60f869..bbd4a35 100644 --- a/clearpath_config/sample/dd100/dd100_default.yaml +++ b/clearpath_config/sample/dd100/dd100_default.yaml @@ -1,40 +1,2 @@ serial_number: dd100-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-dd100-0000 - ip: 192.168.131.1 - ros2: - namespace: dd100_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] -platform: - controller: ps4 - battery: - model: TLV1222 - configuration: S1P1 - attachments: [] - extras: - urdf: null - ros_parameters: {} -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] -sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] - lidar3d: [] diff --git a/clearpath_config/sample/dd100/dd100_dual_laser.yaml b/clearpath_config/sample/dd100/dd100_dual_laser.yaml index 3f6ba62..7d42732 100644 --- a/clearpath_config/sample/dd100/dd100_dual_laser.yaml +++ b/clearpath_config/sample/dd100/dd100_dual_laser.yaml @@ -1,47 +1,13 @@ serial_number: dd100-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-dd100-0000 - ip: 192.168.131.1 - ros2: - namespace: dd100_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] -platform: - controller: ps4 - battery: - model: TLV1222 - configuration: S1P1 - attachments: [] - extras: - urdf: null - ros_parameters: {} -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] mounts: bracket: - parent: front_2_mount - parent: rear_2_mount rpy: [0.0, 0.0, 3.1415] - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] lidar2d: - model: hokuyo_ust parent: bracket_0_mount - model: hokuyo_ust parent: bracket_1_mount - lidar3d: [] diff --git a/clearpath_config/sample/dd100/dd100_outline.yaml b/clearpath_config/sample/dd100/dd100_outline.yaml new file mode 100644 index 0000000..c60f869 --- /dev/null +++ b/clearpath_config/sample/dd100/dd100_outline.yaml @@ -0,0 +1,40 @@ +serial_number: dd100-0000 +version: 0 +system: + username: administrator + hosts: + - hostname: cpr-dd100-0000 + ip: 192.168.131.1 + ros2: + namespace: dd100_0000 + domain_id: 0 + middleware: + implementation: rmw_fastrtps_cpp + workspaces: [] +platform: + controller: ps4 + battery: + model: TLV1222 + configuration: S1P1 + attachments: [] + extras: + urdf: null + ros_parameters: {} +links: + box: [] + cylinder: [] + frame: [] + mesh: [] + sphere: [] +mounts: + bracket: [] + fath_pivot: [] + riser: [] + disk: [] + post: [] +sensors: + camera: [] + gps: [] + imu: [] + lidar2d: [] + lidar3d: [] diff --git a/clearpath_config/sample/dd100/dd100_velodyne.yaml b/clearpath_config/sample/dd100/dd100_velodyne.yaml index e2b98b5..92a5c7c 100644 --- a/clearpath_config/sample/dd100/dd100_velodyne.yaml +++ b/clearpath_config/sample/dd100/dd100_velodyne.yaml @@ -1,27 +1,6 @@ serial_number: dd100-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-dd100-0000 - ip: 192.168.131.1 - ros2: - namespace: dd100_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] -platform: - controller: ps4 - battery: - model: TLV1222 - configuration: S1P1 - attachments: [] - extras: - urdf: null - ros_parameters: {} links: - box: [] cylinder: - name: leg_0 radius: 0.004 @@ -43,21 +22,10 @@ links: length: 0.1 parent: default_mount xyz: [-0.04, -0.04, 0.05] - frame: [] - mesh: [] - sphere: [] mounts: bracket: - xyz: [0.0, 0.0, 0.1] - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] lidar3d: - model: velodyne_lidar parent: bracket_0_mount diff --git a/clearpath_config/sample/dd150/dd150_default.yaml b/clearpath_config/sample/dd150/dd150_default.yaml index 1598bac..168d967 100644 --- a/clearpath_config/sample/dd150/dd150_default.yaml +++ b/clearpath_config/sample/dd150/dd150_default.yaml @@ -1,40 +1,2 @@ serial_number: dd150-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-dd150-0000 - ip: 192.168.131.1 - ros2: - namespace: dd150_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] -platform: - controller: ps4 - battery: - model: TLV1222 - configuration: S1P1 - attachments: [] - extras: - urdf: null - ros_parameters: {} -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] -sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] - lidar3d: [] diff --git a/clearpath_config/sample/dd150/dd150_dual_laser.yaml b/clearpath_config/sample/dd150/dd150_dual_laser.yaml index df65f21..46c4257 100644 --- a/clearpath_config/sample/dd150/dd150_dual_laser.yaml +++ b/clearpath_config/sample/dd150/dd150_dual_laser.yaml @@ -1,47 +1,13 @@ serial_number: dd150-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-dd150-0000 - ip: 192.168.131.1 - ros2: - namespace: dd150_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] -platform: - controller: ps4 - battery: - model: TLV1222 - configuration: S1P1 - attachments: [] - extras: - urdf: null - ros_parameters: {} -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] mounts: bracket: - parent: front_1_mount - parent: rear_1_mount rpy: [0.0, 0.0, 3.1415] - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] lidar2d: - model: hokuyo_ust parent: bracket_0_mount - model: hokuyo_ust parent: bracket_1_mount - lidar3d: [] diff --git a/clearpath_config/sample/dd150/dd150_outline.yaml b/clearpath_config/sample/dd150/dd150_outline.yaml new file mode 100644 index 0000000..1598bac --- /dev/null +++ b/clearpath_config/sample/dd150/dd150_outline.yaml @@ -0,0 +1,40 @@ +serial_number: dd150-0000 +version: 0 +system: + username: administrator + hosts: + - hostname: cpr-dd150-0000 + ip: 192.168.131.1 + ros2: + namespace: dd150_0000 + domain_id: 0 + middleware: + implementation: rmw_fastrtps_cpp + workspaces: [] +platform: + controller: ps4 + battery: + model: TLV1222 + configuration: S1P1 + attachments: [] + extras: + urdf: null + ros_parameters: {} +links: + box: [] + cylinder: [] + frame: [] + mesh: [] + sphere: [] +mounts: + bracket: [] + fath_pivot: [] + riser: [] + disk: [] + post: [] +sensors: + camera: [] + gps: [] + imu: [] + lidar2d: [] + lidar3d: [] diff --git a/clearpath_config/sample/dd150/dd150_velodyne.yaml b/clearpath_config/sample/dd150/dd150_velodyne.yaml index b5714f7..e0273a9 100644 --- a/clearpath_config/sample/dd150/dd150_velodyne.yaml +++ b/clearpath_config/sample/dd150/dd150_velodyne.yaml @@ -1,27 +1,6 @@ serial_number: dd150-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-dd150-0000 - ip: 192.168.131.1 - ros2: - namespace: dd150_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] -platform: - controller: ps4 - battery: - model: TLV1222 - configuration: S1P1 - attachments: [] - extras: - urdf: null - ros_parameters: {} links: - box: [] cylinder: - name: leg_0 radius: 0.004 @@ -43,21 +22,10 @@ links: length: 0.1 parent: default_mount xyz: [-0.04, -0.04, 0.05] - frame: [] - mesh: [] - sphere: [] mounts: bracket: - xyz: [0.0, 0.0, 0.1] - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] lidar3d: - model: velodyne_lidar parent: bracket_0_mount diff --git a/clearpath_config/sample/j100/j100_default.yaml b/clearpath_config/sample/j100/j100_default.yaml index 21f31de..2187197 100644 --- a/clearpath_config/sample/j100/j100_default.yaml +++ b/clearpath_config/sample/j100/j100_default.yaml @@ -1,54 +1,9 @@ serial_number: j100-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-j100-0000 - ip: 192.168.131.1 - ros2: - namespace: j100_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: HE2613 - configuration: S1P1 attachments: - name: front_fender - type: fender + type: j100.fender - name: rear_fender - type: fender + type: j100.fender rpy: [0.0, 0.0, 3.1415] - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] -sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] - lidar3d: [] diff --git a/clearpath_config/sample/j100/j100_dual_laser.yaml b/clearpath_config/sample/j100/j100_dual_laser.yaml index 02e6083..0a4df05 100644 --- a/clearpath_config/sample/j100/j100_dual_laser.yaml +++ b/clearpath_config/sample/j100/j100_dual_laser.yaml @@ -1,55 +1,13 @@ serial_number: j100-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-j100-0000 - ip: 192.168.131.1 - ros2: - namespace: j100_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: HE2613 - configuration: S1P1 attachments: - name: front_fender - type: fender + type: j100.fender - name: rear_fender - type: fender + type: j100.fender rpy: [0.0, 0.0, 3.1415] - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] lidar2d: - model: hokuyo_ust urdf_enabled: true @@ -77,4 +35,3 @@ sensors: ip_port: 10940 angle_min: -3.141592653589793 angle_max: 3.141592653589793 - lidar3d: [] diff --git a/clearpath_config/sample/j100/j100_outline.yaml b/clearpath_config/sample/j100/j100_outline.yaml new file mode 100644 index 0000000..cc47e9d --- /dev/null +++ b/clearpath_config/sample/j100/j100_outline.yaml @@ -0,0 +1,54 @@ +serial_number: j100-0000 +version: 0 +system: + username: administrator + hosts: + - hostname: cpr-j100-0000 + ip: 192.168.131.1 + ros2: + namespace: j100_0000 + domain_id: 0 + middleware: + implementation: rmw_fastrtps_cpp + workspaces: [] +platform: + controller: ps4 + battery: + model: HE2613 + configuration: S1P1 + attachments: + - name: front_fender + type: j100.fender + - name: rear_fender + type: j100.fender + rpy: [0.0, 0.0, 3.1415] + extras: + urdf: null + ros_parameters: + platform_velocity_controller: + linear.x.max_velocity": 2.0 + linear.x.min_velocity": -2.0 + linear.x.max_acceleration": 20.0 + linear.x.min_acceleration": -20.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 25.0 + angular.z.min_acceleration": -25.0 +links: + box: [] + cylinder: [] + frame: [] + mesh: [] + sphere: [] +mounts: + bracket: [] + fath_pivot: [] + riser: [] + disk: [] + post: [] +sensors: + camera: [] + gps: [] + imu: [] + lidar2d: [] + lidar3d: [] diff --git a/clearpath_config/sample/j100/j100_sample.yaml b/clearpath_config/sample/j100/j100_sample.yaml index 880f8ac..4d68e3c 100644 --- a/clearpath_config/sample/j100/j100_sample.yaml +++ b/clearpath_config/sample/j100/j100_sample.yaml @@ -1,41 +1,13 @@ serial_number: j100-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-j100-0000 - ip: 192.168.131.1 - ros2: - namespace: j100_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: HE2613 - configuration: S1P1 attachments: - name: front_fender - type: fender + type: j100.fender - name: rear_fender - type: fender + type: j100.fender rpy: [0.0, 0.0, 3.1415] - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 links: - box: [] cylinder: - name: cylinder parent: default_mount @@ -43,9 +15,6 @@ links: rpy: [0.0, 0.0, 0.0] radius: 0.05 length: 0.1 - frame: [] - mesh: [] - sphere: [] mounts: bracket: - parent: front_0_mount @@ -56,14 +25,7 @@ mounts: xyz: [0.0, 0.0, 0.0] rpy: [0.0, 0.0, 0.0] model: horizontal - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] lidar2d: - model: hokuyo_ust urdf_enabled: true diff --git a/clearpath_config/sample/j100/j100_velodyne.yaml b/clearpath_config/sample/j100/j100_velodyne.yaml index cc7f066..65a2f7d 100644 --- a/clearpath_config/sample/j100/j100_velodyne.yaml +++ b/clearpath_config/sample/j100/j100_velodyne.yaml @@ -1,56 +1,13 @@ serial_number: j100-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-j100-0000 - ip: 192.168.131.1 - ros2: - namespace: j100_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp - workspaces: [] platform: - controller: ps4 - battery: - model: HE2613 - configuration: S1P1 attachments: - name: front_fender - type: fender + type: j100.fender - name: rear_fender - type: fender + type: j100.fender rpy: [0.0, 0.0, 3.1415] - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 2.0 - linear.x.min_velocity": -2.0 - linear.x.max_acceleration": 20.0 - linear.x.min_acceleration": -20.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 25.0 - angular.z.min_acceleration": -25.0 -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] lidar3d: - model: velodyne_lidar urdf_enabled: true diff --git a/clearpath_config/sample/w200/w200_default.yaml b/clearpath_config/sample/w200/w200_default.yaml index 5658581..b90a20f 100644 --- a/clearpath_config/sample/w200/w200_default.yaml +++ b/clearpath_config/sample/w200/w200_default.yaml @@ -1,45 +1,2 @@ serial_number: w200-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-w200-0000 - ip: 192.168.131.1 - ros2: - namespace: w200_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp -platform: - controller: ps4 - attachments: [] - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 5.0 - linear.x.min_velocity": -5.0 - linear.x.max_acceleration": 50.0 - linear.x.min_acceleration": -50.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 40.0 - angular.z.min_acceleration": -40.0 -links: - box: [] - cylinder: [] - frame: [] - mesh: [] - sphere: [] -mounts: - bracket: [] - fath_pivot: [] - riser: [] - disk: [] - post: [] -sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] - lidar3d: [] diff --git a/clearpath_config/sample/w200/w200_dual_laser.yaml b/clearpath_config/sample/w200/w200_dual_laser.yaml index f46963b..122723d 100644 --- a/clearpath_config/sample/w200/w200_dual_laser.yaml +++ b/clearpath_config/sample/w200/w200_dual_laser.yaml @@ -1,33 +1,6 @@ serial_number: w200-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-w200-0000 - ip: 192.168.131.1 - ros2: - namespace: w200_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp -platform: - controller: ps4 - attachments: [] - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 5.0 - linear.x.min_velocity": -5.0 - linear.x.max_acceleration": 50.0 - linear.x.min_acceleration": -50.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 40.0 - angular.z.min_acceleration": -40.0 links: - box: [] - cylinder: [] frame: - name: front_left parent: left_diff_unit_link @@ -37,22 +10,13 @@ links: parent: right_diff_unit_link xyz: [-0.68, 0.03, 0.35] rpy: [3.1415, 1.5707, 0.0] - mesh: [] - sphere: [] mounts: bracket: - model: vertical parent: front_left_link - model: vertical parent: rear_right_link - fath_pivot: [] - riser: [] - disk: [] - post: [] sensors: - camera: [] - gps: [] - imu: [] lidar2d: - model: hokuyo_ust urdf_enabled: true @@ -72,7 +36,7 @@ sensors: launch_enabled: true parent: bracket_1_vertical_mount xyz: [0.0, 0.0, 0.0] - rpy: [0.0, 0.0, 3.1415] + rpy: [0.0, 0.0, 0.0] ros_parameters: urg_node: laser_frame_id: lidar2d_1_laser @@ -80,4 +44,3 @@ sensors: ip_port: 10940 angle_min: -1.5707 angle_max: 1.5707 - lidar3d: [] diff --git a/clearpath_config/sample/w200/w200_outline.yaml b/clearpath_config/sample/w200/w200_outline.yaml new file mode 100644 index 0000000..5658581 --- /dev/null +++ b/clearpath_config/sample/w200/w200_outline.yaml @@ -0,0 +1,45 @@ +serial_number: w200-0000 +version: 0 +system: + username: administrator + hosts: + - hostname: cpr-w200-0000 + ip: 192.168.131.1 + ros2: + namespace: w200_0000 + domain_id: 0 + middleware: + implementation: rmw_fastrtps_cpp +platform: + controller: ps4 + attachments: [] + extras: + urdf: null + ros_parameters: + platform_velocity_controller: + linear.x.max_velocity": 5.0 + linear.x.min_velocity": -5.0 + linear.x.max_acceleration": 50.0 + linear.x.min_acceleration": -50.0 + angular.z.max_velocity": 4.0 + angular.z.min_velocity": -4.0 + angular.z.max_acceleration": 40.0 + angular.z.min_acceleration": -40.0 +links: + box: [] + cylinder: [] + frame: [] + mesh: [] + sphere: [] +mounts: + bracket: [] + fath_pivot: [] + riser: [] + disk: [] + post: [] +sensors: + camera: [] + gps: [] + imu: [] + lidar2d: [] + lidar3d: [] diff --git a/clearpath_config/sample/w200/w200_velodyne.yaml b/clearpath_config/sample/w200/w200_velodyne.yaml index 5a88a07..b5408d0 100644 --- a/clearpath_config/sample/w200/w200_velodyne.yaml +++ b/clearpath_config/sample/w200/w200_velodyne.yaml @@ -1,30 +1,5 @@ serial_number: w200-0000 version: 0 -system: - username: administrator - hosts: - - hostname: cpr-w200-0000 - ip: 192.168.131.1 - ros2: - namespace: w200_0000 - domain_id: 0 - middleware: - implementation: rmw_fastrtps_cpp -platform: - controller: ps4 - attachments: [] - extras: - urdf: null - ros_parameters: - platform_velocity_controller: - linear.x.max_velocity": 5.0 - linear.x.min_velocity": -5.0 - linear.x.max_acceleration": 50.0 - linear.x.min_acceleration": -50.0 - angular.z.max_velocity": 4.0 - angular.z.min_velocity": -4.0 - angular.z.max_acceleration": 40.0 - angular.z.min_acceleration": -40.0 links: box: - name: structure @@ -33,17 +8,11 @@ links: size: [0.15, 0.15, 0.5] parent: structure_link xyz: [0.0, 0.0, 0.5] - cylinder: [] frame: - name: top_tower parent: tower_link xyz: [0.0, 0.0, 0.25] - mesh: [] - sphere: [] mounts: - bracket: [] - fath_pivot: [] - riser: [] disk: - parent: post_0_mount post: @@ -52,10 +21,6 @@ mounts: xyz: [0.0, 0.0, 0.5] spacing: 0.12 sensors: - camera: [] - gps: [] - imu: [] - lidar2d: [] lidar3d: - model: velodyne_lidar urdf_enabled: true From d08dd0d37c2d10ab06588e61d8ea1e0ca2a91a67 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Fri, 22 Mar 2024 12:07:06 -0400 Subject: [PATCH 31/37] Re-added host and namespace --- clearpath_config/sample/a200/a200_default.yaml | 6 ++++++ clearpath_config/sample/a200/a200_dual_laser.yaml | 6 ++++++ clearpath_config/sample/a200/a200_sample.yaml | 6 ++++++ clearpath_config/sample/a200/a200_velodyne.yaml | 6 ++++++ clearpath_config/sample/dd100/dd100_default.yaml | 6 ++++++ clearpath_config/sample/dd100/dd100_dual_laser.yaml | 6 ++++++ clearpath_config/sample/dd100/dd100_velodyne.yaml | 6 ++++++ clearpath_config/sample/dd150/dd150_default.yaml | 6 ++++++ clearpath_config/sample/dd150/dd150_dual_laser.yaml | 6 ++++++ clearpath_config/sample/dd150/dd150_velodyne.yaml | 6 ++++++ clearpath_config/sample/j100/j100_default.yaml | 6 ++++++ clearpath_config/sample/j100/j100_dual_laser.yaml | 6 ++++++ clearpath_config/sample/j100/j100_sample.yaml | 6 ++++++ clearpath_config/sample/j100/j100_velodyne.yaml | 6 ++++++ clearpath_config/sample/w200/w200_default.yaml | 6 ++++++ clearpath_config/sample/w200/w200_dual_laser.yaml | 6 ++++++ clearpath_config/sample/w200/w200_velodyne.yaml | 6 ++++++ 17 files changed, 102 insertions(+) diff --git a/clearpath_config/sample/a200/a200_default.yaml b/clearpath_config/sample/a200/a200_default.yaml index e11921a..fd811a1 100644 --- a/clearpath_config/sample/a200/a200_default.yaml +++ b/clearpath_config/sample/a200/a200_default.yaml @@ -1,5 +1,11 @@ serial_number: a200-0000 version: 0 +system: + hosts: + - hostname: cpr-a200-0000 + ip: 192.168.131.1 + ros2: + namespace: a200_0000 platform: attachments: - name: front_bumper diff --git a/clearpath_config/sample/a200/a200_dual_laser.yaml b/clearpath_config/sample/a200/a200_dual_laser.yaml index 58265c8..f3bc9cd 100644 --- a/clearpath_config/sample/a200/a200_dual_laser.yaml +++ b/clearpath_config/sample/a200/a200_dual_laser.yaml @@ -1,5 +1,11 @@ serial_number: a200-0000 version: 0 +system: + hosts: + - hostname: cpr-a200-0000 + ip: 192.168.131.1 + ros2: + namespace: a200_0000 platform: attachments: - name: front_bumper diff --git a/clearpath_config/sample/a200/a200_sample.yaml b/clearpath_config/sample/a200/a200_sample.yaml index 8a48f6f..7843318 100644 --- a/clearpath_config/sample/a200/a200_sample.yaml +++ b/clearpath_config/sample/a200/a200_sample.yaml @@ -1,5 +1,11 @@ serial_number: a200-0000 version: 0 +system: + hosts: + - hostname: cpr-a200-0000 + ip: 192.168.131.1 + ros2: + namespace: a200_0000 platform: attachments: - name: front_bumper diff --git a/clearpath_config/sample/a200/a200_velodyne.yaml b/clearpath_config/sample/a200/a200_velodyne.yaml index 37aa8ff..8d7a5fc 100644 --- a/clearpath_config/sample/a200/a200_velodyne.yaml +++ b/clearpath_config/sample/a200/a200_velodyne.yaml @@ -1,5 +1,11 @@ serial_number: a200-0000 version: 0 +system: + hosts: + - hostname: cpr-a200-0000 + ip: 192.168.131.1 + ros2: + namespace: a200_0000 platform: attachments: - name: front_bumper diff --git a/clearpath_config/sample/dd100/dd100_default.yaml b/clearpath_config/sample/dd100/dd100_default.yaml index bbd4a35..f5d5b34 100644 --- a/clearpath_config/sample/dd100/dd100_default.yaml +++ b/clearpath_config/sample/dd100/dd100_default.yaml @@ -1,2 +1,8 @@ serial_number: dd100-0000 version: 0 +system: + hosts: + - hostname: cpr-dd100-0000 + ip: 192.168.131.1 + ros2: + namespace: dd100_0000 diff --git a/clearpath_config/sample/dd100/dd100_dual_laser.yaml b/clearpath_config/sample/dd100/dd100_dual_laser.yaml index 7d42732..61ba56d 100644 --- a/clearpath_config/sample/dd100/dd100_dual_laser.yaml +++ b/clearpath_config/sample/dd100/dd100_dual_laser.yaml @@ -1,5 +1,11 @@ serial_number: dd100-0000 version: 0 +system: + hosts: + - hostname: cpr-dd100-0000 + ip: 192.168.131.1 + ros2: + namespace: dd100_0000 mounts: bracket: - parent: front_2_mount diff --git a/clearpath_config/sample/dd100/dd100_velodyne.yaml b/clearpath_config/sample/dd100/dd100_velodyne.yaml index 92a5c7c..2f61d34 100644 --- a/clearpath_config/sample/dd100/dd100_velodyne.yaml +++ b/clearpath_config/sample/dd100/dd100_velodyne.yaml @@ -1,5 +1,11 @@ serial_number: dd100-0000 version: 0 +system: + hosts: + - hostname: cpr-dd100-0000 + ip: 192.168.131.1 + ros2: + namespace: dd100_0000 links: cylinder: - name: leg_0 diff --git a/clearpath_config/sample/dd150/dd150_default.yaml b/clearpath_config/sample/dd150/dd150_default.yaml index 168d967..f1f1a07 100644 --- a/clearpath_config/sample/dd150/dd150_default.yaml +++ b/clearpath_config/sample/dd150/dd150_default.yaml @@ -1,2 +1,8 @@ serial_number: dd150-0000 version: 0 +system: + hosts: + - hostname: cpr-dd150-0000 + ip: 192.168.131.1 + ros2: + namespace: dd150_0000 diff --git a/clearpath_config/sample/dd150/dd150_dual_laser.yaml b/clearpath_config/sample/dd150/dd150_dual_laser.yaml index 46c4257..abec00d 100644 --- a/clearpath_config/sample/dd150/dd150_dual_laser.yaml +++ b/clearpath_config/sample/dd150/dd150_dual_laser.yaml @@ -1,5 +1,11 @@ serial_number: dd150-0000 version: 0 +system: + hosts: + - hostname: cpr-dd150-0000 + ip: 192.168.131.1 + ros2: + namespace: dd150_0000 mounts: bracket: - parent: front_1_mount diff --git a/clearpath_config/sample/dd150/dd150_velodyne.yaml b/clearpath_config/sample/dd150/dd150_velodyne.yaml index e0273a9..92a4849 100644 --- a/clearpath_config/sample/dd150/dd150_velodyne.yaml +++ b/clearpath_config/sample/dd150/dd150_velodyne.yaml @@ -1,5 +1,11 @@ serial_number: dd150-0000 version: 0 +system: + hosts: + - hostname: cpr-dd150-0000 + ip: 192.168.131.1 + ros2: + namespace: dd150_0000 links: cylinder: - name: leg_0 diff --git a/clearpath_config/sample/j100/j100_default.yaml b/clearpath_config/sample/j100/j100_default.yaml index 2187197..fa1a350 100644 --- a/clearpath_config/sample/j100/j100_default.yaml +++ b/clearpath_config/sample/j100/j100_default.yaml @@ -1,5 +1,11 @@ serial_number: j100-0000 version: 0 +system: + hosts: + - hostname: cpr-j100-0000 + ip: 192.168.131.1 + ros2: + namespace: j100_0000 platform: attachments: - name: front_fender diff --git a/clearpath_config/sample/j100/j100_dual_laser.yaml b/clearpath_config/sample/j100/j100_dual_laser.yaml index 0a4df05..b9157f0 100644 --- a/clearpath_config/sample/j100/j100_dual_laser.yaml +++ b/clearpath_config/sample/j100/j100_dual_laser.yaml @@ -1,5 +1,11 @@ serial_number: j100-0000 version: 0 +system: + hosts: + - hostname: cpr-j100-0000 + ip: 192.168.131.1 + ros2: + namespace: j100_0000 platform: attachments: - name: front_fender diff --git a/clearpath_config/sample/j100/j100_sample.yaml b/clearpath_config/sample/j100/j100_sample.yaml index 4d68e3c..0c0421b 100644 --- a/clearpath_config/sample/j100/j100_sample.yaml +++ b/clearpath_config/sample/j100/j100_sample.yaml @@ -1,5 +1,11 @@ serial_number: j100-0000 version: 0 +system: + hosts: + - hostname: cpr-j100-0000 + ip: 192.168.131.1 + ros2: + namespace: j100_0000 platform: attachments: - name: front_fender diff --git a/clearpath_config/sample/j100/j100_velodyne.yaml b/clearpath_config/sample/j100/j100_velodyne.yaml index 65a2f7d..c88413c 100644 --- a/clearpath_config/sample/j100/j100_velodyne.yaml +++ b/clearpath_config/sample/j100/j100_velodyne.yaml @@ -1,5 +1,11 @@ serial_number: j100-0000 version: 0 +system: + hosts: + - hostname: cpr-j100-0000 + ip: 192.168.131.1 + ros2: + namespace: j100_0000 platform: attachments: - name: front_fender diff --git a/clearpath_config/sample/w200/w200_default.yaml b/clearpath_config/sample/w200/w200_default.yaml index b90a20f..277f8a9 100644 --- a/clearpath_config/sample/w200/w200_default.yaml +++ b/clearpath_config/sample/w200/w200_default.yaml @@ -1,2 +1,8 @@ serial_number: w200-0000 version: 0 +system: + hosts: + - hostname: cpr-w200-0000 + ip: 192.168.131.1 + ros2: + namespace: w200_0000 diff --git a/clearpath_config/sample/w200/w200_dual_laser.yaml b/clearpath_config/sample/w200/w200_dual_laser.yaml index 122723d..9a1a2b3 100644 --- a/clearpath_config/sample/w200/w200_dual_laser.yaml +++ b/clearpath_config/sample/w200/w200_dual_laser.yaml @@ -1,5 +1,11 @@ serial_number: w200-0000 version: 0 +system: + hosts: + - hostname: cpr-w200-0000 + ip: 192.168.131.1 + ros2: + namespace: w200_0000 links: frame: - name: front_left diff --git a/clearpath_config/sample/w200/w200_velodyne.yaml b/clearpath_config/sample/w200/w200_velodyne.yaml index b5408d0..5635562 100644 --- a/clearpath_config/sample/w200/w200_velodyne.yaml +++ b/clearpath_config/sample/w200/w200_velodyne.yaml @@ -1,5 +1,11 @@ serial_number: w200-0000 version: 0 +system: + hosts: + - hostname: cpr-w200-0000 + ip: 192.168.131.1 + ros2: + namespace: w200_0000 links: box: - name: structure From 9ba3704eeb0c0baeccad823a34aedaa1fc9ee988 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Fri, 22 Mar 2024 11:46:19 -0400 Subject: [PATCH 32/37] W200 attachments default to 0 --- clearpath_config/platform/attachments/w200.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/clearpath_config/platform/attachments/w200.py b/clearpath_config/platform/attachments/w200.py index 70e5ed3..e091e42 100644 --- a/clearpath_config/platform/attachments/w200.py +++ b/clearpath_config/platform/attachments/w200.py @@ -36,7 +36,7 @@ class W200Generator(BaseAttachment): DEFAULT = "default" MODELS = [DEFAULT] PARENT = "default_mount" - XYZ = [-0.42506, 0.0, 0.0017] + XYZ = [0.0, 0.0, 0.0] RPY = [0.0, 0.0, 0.0] def __init__( @@ -55,10 +55,10 @@ class W200Bulkhead(BaseAttachment): PLATFORM = Platform.W200 ATTACHMENT_MODEL = "%s.bulkhead" % PLATFORM DEFAULT = "default" - ARM_MOUNT = "arm_mount" - MODELS = [DEFAULT, ARM_MOUNT] + ARM_PLATE = "arm_plate" + MODELS = [DEFAULT, ARM_PLATE] PARENT = "default_mount" - XYZ = [0.00705, 0.0, 0.24184] + XYZ = [0.0, 0.0, 0.0] RPY = [0.0, 0.0, 0.0] def __init__( @@ -73,9 +73,9 @@ def __init__( super().__init__(name, model, enabled, parent, xyz, rpy) -class W200ArmMount(BaseAttachment): +class W200ArmPlate(BaseAttachment): PLATFORM = Platform.W200 - ATTACHMENT_MODEL = "%s.arm_mount" % PLATFORM + ATTACHMENT_MODEL = "%s.arm_plate" % PLATFORM DEFAULT = "default" MODELS = [DEFAULT] PARENT = "default_mount" @@ -101,11 +101,11 @@ class W200Attachment(PlatformAttachment): GENERATOR = W200Generator.ATTACHMENT_MODEL # Bulkhead BULKHEAD = W200Bulkhead.ATTACHMENT_MODEL - # ArmMount - ARM_MOUNT = W200ArmMount.ATTACHMENT_MODEL + # ArmPlate + ARM_PLATE = W200ArmPlate.ATTACHMENT_MODEL TYPES = { GENERATOR: W200Generator, BULKHEAD: W200Bulkhead, - ARM_MOUNT: W200ArmMount + ARM_PLATE: W200ArmPlate } From d38b2a95c35ebdfad4de0bd0faf1d3ed1eceda10 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 8 Apr 2024 12:07:50 -0400 Subject: [PATCH 33/37] Changes. --- CHANGELOG.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a1c8e59..d01cf2f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,15 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Re-added host and namespace +* W200 attachments default to 0 +* Minimal samples. +* Removed long line +* Added launch to extras +* Contributors: Luis Camero + 0.2.6 (2024-03-18) ------------------ * Switched local server to be referenced as loopback in the ROS_DISCOVERY_SERVER envar From fb877cedc0e5a0eb0b0e787ffa6680d688637e64 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Mon, 8 Apr 2024 12:08:06 -0400 Subject: [PATCH 34/37] 0.2.7 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d01cf2f..9effe0e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.7 (2024-04-08) +------------------ * Re-added host and namespace * W200 attachments default to 0 * Minimal samples. diff --git a/package.xml b/package.xml index 3cc6673..807958b 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.6 + 0.2.7 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index 7b82d88..2e7ec14 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.6", + version="0.2.7", packages=[ package_name, package_name + ".common", From 42ee4ee1a913a45e9a5febca42df004b7eaf9434 Mon Sep 17 00:00:00 2001 From: Luis Camero Date: Mon, 13 May 2024 16:50:50 -0400 Subject: [PATCH 35/37] Renamed node to intel_realsense in config --- clearpath_config/sensors/types/cameras.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clearpath_config/sensors/types/cameras.py b/clearpath_config/sensors/types/cameras.py index a6285d5..32c586f 100644 --- a/clearpath_config/sensors/types/cameras.py +++ b/clearpath_config/sensors/types/cameras.py @@ -258,14 +258,14 @@ class IntelRealsense(BaseCamera): POINTCLOUD_ENABLED = True class ROS_PARAMETER_KEYS: - FPS = "camera.rgb_camera.profile" - SERIAL = "camera.serial_no" - CAMERA_NAME = "camera.camera_name" - DEVICE_TYPE = "camera.device_type" - DEPTH_PROFILE = "camera.depth_module.profile" - DEPTH_ENABLE = "camera.enable_depth" - COLOR_ENABLE = "camera.enable_color" - POINTCLOUD_ENABLE = "camera.pointcloud.enable" + FPS = "intel_realsense.rgb_camera.profile" + SERIAL = "intel_realsense.serial_no" + CAMERA_NAME = "intel_realsense.camera_name" + DEVICE_TYPE = "intel_realsense.device_type" + DEPTH_PROFILE = "intel_realsense.depth_module.profile" + DEPTH_ENABLE = "intel_realsense.enable_depth" + COLOR_ENABLE = "intel_realsense.enable_color" + POINTCLOUD_ENABLE = "intel_realsense.pointcloud.enable" class TOPICS: COLOR_IMAGE = "color_image" From 091e5a215345fad8d1068ae73397696b83ebe989 Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Tue, 14 May 2024 09:06:38 -0400 Subject: [PATCH 36/37] Changes. --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9effe0e..4773269 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Renamed node to intel_realsense in config +* Contributors: Luis Camero + 0.2.7 (2024-04-08) ------------------ * Re-added host and namespace From 2404ebc2728468604fb71ccef8f971094cbacc1b Mon Sep 17 00:00:00 2001 From: Tony Baltovski Date: Tue, 14 May 2024 09:06:49 -0400 Subject: [PATCH 37/37] 0.2.8 --- CHANGELOG.rst | 4 ++-- package.xml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4773269..ba467f0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package clearpath_config ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +0.2.8 (2024-05-14) +------------------ * Renamed node to intel_realsense in config * Contributors: Luis Camero diff --git a/package.xml b/package.xml index 807958b..11c3b4b 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ clearpath_config - 0.2.7 + 0.2.8 Clearpath Configuration YAML Parser and Writer Luis Camero BSD-3 diff --git a/setup.py b/setup.py index 2e7ec14..af3925a 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name=package_name, - version="0.2.7", + version="0.2.8", packages=[ package_name, package_name + ".common",