diff --git a/.github/workflows/colcon_test_build.yaml b/.github/workflows/colcon_test_build.yaml index e335369..59035f6 100644 --- a/.github/workflows/colcon_test_build.yaml +++ b/.github/workflows/colcon_test_build.yaml @@ -7,13 +7,10 @@ jobs: colcon-test-build-ubuntu-22-04: strategy: matrix: - build-type: [ignition-gazebo, gazebo-classic] ros-distro: [humble] - env: - GAZEBO_VERSION: ${{ matrix.build-type }} runs-on: ubuntu-22.04 - name: ${{ matrix.ros-distro }} + name: Build ${{ matrix.ros-distro }} steps: - uses: ros-tooling/setup-ros@v0.7 with: diff --git a/CMakeLists.txt b/CMakeLists.txt index 36a8d13..c07fe79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,12 +10,12 @@ install( if(BUILD_TESTING) find_package(ament_cmake_pytest REQUIRED) - set(_pytest_tests - test/test_components_yaml_parse.py + set(pytest_tests + test/test_components_xacro.py ) - foreach(_test_path ${_pytest_tests}) - get_filename_component(_test_name ${_test_path} NAME_WE) - ament_add_pytest_test(${_test_name} ${_test_path} + foreach(test_path ${pytest_tests}) + get_filename_component(test_name ${test_path} NAME_WE) + ament_add_pytest_test(${test_name} ${test_path} APPEND_ENV PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR} TIMEOUT 60 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} diff --git a/README.md b/README.md index 54538a9..de8404d 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,6 @@ git clone https://github.com/husarion/ros_components_description.git src/ros_com # in case the package will be used within simulation export HUSARION_ROS_BUILD_TYPE=simulation -# to specify which simulation engine will be used -# for gazebo classic -export SIMULATION_ENGINE=gazebo-classic -# for ignition gazebo -export SIMULATION_ENGINE=ignition-gazebo - rosdep update --rosdistro $ROS_DISTRO rosdep install -i --from-path src --rosdistro $ROS_DISTRO -y colcon build @@ -36,9 +30,7 @@ To include the sensor, use the following code: + rpy="0.0 0.0 0.0" /> ``` A list of parameters can be found here: @@ -46,12 +38,9 @@ A list of parameters can be found here: - `parent_link` [*string*, default: **None**] parent link to which sensor should be attached. - `xyz` [*float list*, default: **None**] 3 float values defining translation between base of a sensor and parent link. Values in **m**. - `rpy` [*float list*, default: **None**] 3 float values define rotation between parent link and base of a sensor. Values in **rad**. -- `tf_prefix` [*string*, optional] tf prefix applied before all links created by sensor. If defined, applies `_`. If not defined, leaves `` intact. Applies also to `frame_id` parameter. -- `topic` [*string*, default: **same as manufacturer's default**] name of topic at which simulated sensor will publish data. -- `frame_id` [*string*, default: **same as manufacturer's default**] name of final tf to which sensor will be attached. Should match one from message published by sensor. -- `use_gpu` [*bool*, default: **false**] enable GPU acceleration for sensor. Available only if sensor can be accelerated. -- `simulation_engine` [*string*, default: **gazebo-classic**] selected for which simulation engine plugins should be loaded. Currently the only supported: - - **gazebo-classic** used to select [Gazebo Classic](https://classic.gazebosim.org/). - - **ignition-gazebo** used to select [Ignition Gazebo](https://gazebosim.org/home). +- `namespace` [*string*, default: **None**] global namespace common to the entire robot. +- `device_namespace` [*string*, default: **None**] local namespace allowing to distinguish two identical devices from each other. + +- `model` [*string*, default: **None**] model argument that appears when you want to load the appropriate model from a given manufacturer. Some sensors can define their specific parameters. Refer to their definition for more info. diff --git a/package.xml b/package.xml index 18c8671..8eb911b 100644 --- a/package.xml +++ b/package.xml @@ -24,29 +24,10 @@ kortex_description robotiq_description - - gazebo_plugins - - - - ros_gz_sim - - - - ros_gz_bridge - - - - launch - - - - nav2_common - - - - robotiq_controllers - + ros_gz_sim + ros_gz_bridge + launch + nav2_common ament_index_python ament_python_pytest diff --git a/test/component.urdf.xacro b/test/component.urdf.xacro index 42d211c..abcd233 100644 --- a/test/component.urdf.xacro +++ b/test/component.urdf.xacro @@ -10,8 +10,6 @@ diff --git a/test/test_components_xacro.py b/test/test_components_xacro.py new file mode 100644 index 0000000..7b0f066 --- /dev/null +++ b/test/test_components_xacro.py @@ -0,0 +1,137 @@ +# Copyright 2024 Husarion sp. z o.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import xml.dom +import xml.dom.minidom +import os +import xacro +import xml +import yaml +from ament_index_python.packages import get_package_share_directory + +ros_components_description = get_package_share_directory("ros_components_description") +xacro_path = os.path.join(ros_components_description, "test/component.urdf.xacro") + +# Type: [model_link, sensor_link, sensor_name] +components_types_with_names = { + "LDR01": ["slamtec_rplidar_s1", "laser", "slamtec_rplidar_s1_sensor"], + "LDR06": ["slamtec_rplidar_s3", "laser", "slamtec_rplidar_s3_sensor"], + "LDR13": ["ouster_os1_32", "os_lidar", "ouster_os1_32_sensor"], + "LDR20": ["velodyne_puck", "velodyne", "velodyne_puck_sensor"], + "CAM01": ["orbbec_astra", "link", "orbbec_astra_color"], +} + + +class ComponentsYamlParseUtils: + __test__ = False + + def __init__(self, components_config_path: str) -> None: + self.components_config_path = components_config_path + self._urdf = xml.dom.minidom.Document() + + def save_yaml(self, node: yaml.Node) -> None: + with open(self.components_config_path, mode="w", encoding="utf-8") as file: + yaml.dump(node, file, default_flow_style=False) + + def create_component( + self, + type: str, + device_namespace: str, + parent_link="cover_link", + xyz="0.0 0.0 0.0", + rpy="0.0 0.0 0.0", + ) -> dict: + return { + "type": type, + "parent_link": parent_link, + "xyz": xyz, + "rpy": rpy, + "device_namespace": device_namespace, + } + + def does_urdf_parse(self) -> bool: + try: + self._urdf = xacro.process_file( + xacro_path, mappings={"components_config_path": self.components_config_path} + ) + except xacro.XacroException as e: + return False + return True + + def does_link_exist(self, doc: xml.dom.minidom.Document, link_name: str) -> bool: + links = doc.getElementsByTagName('link') + for link in links: + if link.getAttribute('name') == link_name: + return True + return False + + def does_sensor_name_exist( + self, doc: xml.dom.minidom.Document, link_name: str, sensor_name: str + ) -> bool: + gazebos_tags = doc.getElementsByTagName('gazebo') + for tag in gazebos_tags: + if tag.getAttribute('reference') == link_name: + sensors = doc.getElementsByTagName('sensor') + for sensor in sensors: + if sensor.getAttribute('name') == sensor_name: + return True + + return False + + def test_component(self, component: dict, expected_result: list, components_config_path: str): + names = components_types_with_names[component["type"]] + component_name = names[0] + sensor_reference = names[1] + sensor_name = names[2] + + device_namespace = component["device_namespace"] + link_name = device_namespace + "_" + component_name + "_link" + sensor_name = device_namespace + "_" + sensor_name + sensor_link_name = device_namespace + "_" + sensor_reference + + if self.does_urdf_parse() != expected_result[0]: + assert ( + False + ), f"Expected prase result {expected_result[0]} with file {components_config_path} and component {component_name}." + + if self.does_link_exist(self._urdf, link_name) != expected_result[1]: + assert ( + False + ), f"Link name: {link_name}. Expected result {expected_result[1]} with file {components_config_path} and component {component_name}." + + if ( + self.does_sensor_name_exist(self._urdf, sensor_link_name, sensor_name) + != expected_result[2] + ): + assert ( + False + ), f"Sensor name: {sensor_name}, sensor link name: {sensor_link_name}. Expected result {expected_result[2]} with file {components_config_path} and component {component_name}." + + +def test_all_good_single_components(tmpdir_factory): + for type_name, value in components_types_with_names.items(): + name = value[0] + dir = tmpdir_factory.mktemp(name) + components_config_path = dir.join(name + "_test_components.yaml") + + utils = ComponentsYamlParseUtils(str(components_config_path)) + components = { + "components": [utils.create_component(type_name, name)], + } + + utils.save_yaml(components) + + for component in components["components"]: + utils.test_component(component, [True, True, True], str(components_config_path)) diff --git a/test/test_components_yaml_parse.py b/test/test_components_yaml_parse.py deleted file mode 100644 index ac11d1b..0000000 --- a/test/test_components_yaml_parse.py +++ /dev/null @@ -1,347 +0,0 @@ -# Copyright 2024 Husarion sp. z o.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -import xml.dom -import xml.dom.minidom -import os -import xacro -import xml -import yaml -from ament_index_python.packages import get_package_share_directory - -ros_components_description = get_package_share_directory("ros_components_description") -xacro_path = os.path.join(ros_components_description, "test/component.urdf.xacro") - - -class ComponentsYamlParseUtils: - __test__ = False - - def __init__(self, components_config_path: str) -> None: - self.components_config_path = components_config_path - - def save_yaml(self, node: yaml.Node) -> None: - with open(self.components_config_path, mode="w", encoding="utf-8") as file: - yaml.dump(node, file, default_flow_style=False) - - def create_component( - self, - type: str, - tf_prefix: str, - namespace: str, - name="None", - parent_link="cover_link", - xyz="0.0 0.0 0.0", - rpy="0.0 0.0 0.0", - ) -> dict: - return { - "type": type, - "parent_link": parent_link, - "xyz": xyz, - "rpy": rpy, - "tf_prefix": tf_prefix, - "namespace": namespace, - "name": name, - } - - def try_to_parse_wrong_and_test(self, log: str) -> None: - try: - xacro.process_file( - xacro_path, mappings={"components_config_path": self.components_config_path} - ) - assert False, log - except xacro.XacroException as e: - f"{log} Error:\n{e}" - assert True - - def try_to_parse_well_and_test(self, log: str) -> xml.dom.minidom.Document: - doc = xml.dom.minidom.Document() - try: - doc = xacro.process_file( - xacro_path, mappings={"components_config_path": self.components_config_path} - ) - assert True - except xacro.XacroException as e: - assert False, f"{log}\nError:\n{e}" - - return doc - - def look_for_link_well_and_test( - self, doc: xml.dom.minidom.Document, link_name: str, log: str - ) -> None: - links = doc.getElementsByTagName('link') - for link in links: - if link.getAttribute('name') == link_name: - assert True - return - assert False, f"{log}" - - def look_for_link_wrong_and_test( - self, doc: xml.dom.minidom.Document, link_name: str, log: str - ) -> None: - links = doc.getElementsByTagName('link') - for link in links: - if link.getAttribute('name') == link_name: - assert False, f"{log}" - assert True - - def look_for_sensor_name_well( - self, doc: xml.dom.minidom.Document, link_name: str, sensor_name: str, log: str - ) -> None: - gazebos_tags = doc.getElementsByTagName('gazebo') - for tag in gazebos_tags: - if tag.getAttribute('reference') == link_name: - sensors = doc.getElementsByTagName('sensor') - for sensor in sensors: - if sensor.getAttribute('name') == sensor_name: - assert True - return - - assert False, f"{log}" - - def test_lidar(self, doc: xml.dom.minidom.Document, tf_prefix: str, namespace: str) -> None: - link_name = "laser" - if tf_prefix != "None": - link_name = tf_prefix + "_" + link_name - - sensor_name = "rplidar_s1_sensor" - if tf_prefix != "None": - sensor_name = tf_prefix + "_" + sensor_name - if namespace != "None": - sensor_name = namespace + "/" + sensor_name - - self.look_for_link_well_and_test(doc, link_name, f"Could not find link: {link_name}") - self.look_for_sensor_name_well( - doc, - link_name, - sensor_name, - f"Could not find sensor: {sensor_name}, referencing to link: {link_name} with config {self.components_config_path}", - ) - - def test_camera( - self, doc: xml.dom.minidom.Document, tf_prefix: str, namespace: str, name: str - ) -> None: - link_name = name + "_orbbec_astra_link" - if tf_prefix != "None": - link_name = tf_prefix + "_" + link_name - - sensor_name = name + "_orbbec_astra_color" - if tf_prefix != "None": - sensor_name = tf_prefix + "_" + sensor_name - if namespace != "None": - sensor_name = namespace + "/" + sensor_name - - self.look_for_link_well_and_test( - doc, - link_name, - f"Could not find link: {link_name} with config {self.components_config_path}", - ) - - self.look_for_sensor_name_well( - doc, - link_name, - sensor_name, - f"Could not find sensor: {sensor_name}, referencing to link: {link_name} with config {self.components_config_path}", - ) - - -def test_wrong_config(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join("test_wrong_config.yaml") - - node = yaml.safe_load("a: 5") - utils = ComponentsYamlParseUtils(components_config_path) - - utils.save_yaml(node) - utils.try_to_parse_wrong_and_test(f"Xacro should not parse well for this yaml file: {node}") - - -def test_good_lidars_with_tf_prefix_and_namespace(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join("test_good_lidars_with_tf_prefix_and_namespace.yaml") - - tf_prefixes = ["main_lidar", "additional_lidar"] - namespaces = ["/main_lidar", "/additional_lidar"] - - utils = ComponentsYamlParseUtils(str(components_config_path)) - - node = { - "components": [], - } - for i in range(len(tf_prefixes)): - node["components"].append(utils.create_component("LDR01", tf_prefixes[i], namespaces[i])) - - utils.save_yaml(node) - - doc = utils.try_to_parse_well_and_test( - f"Could not parse without namespace:\n\t{node}\nIn file {components_config_path} with config {components_config_path}" - ) - - for i in range(len(tf_prefixes)): - utils.test_lidar(doc, tf_prefixes[i], namespaces[i]) - - -def test_good_cameras_with_tf_prefix_and_namespace(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join("test_good_cameras_with_tf_prefix_and_namespace.yaml") - - tf_prefixes = ["main", "additional"] - namespaces = ["/main", "/additional"] - names = ["camera", "camera"] - - utils = ComponentsYamlParseUtils(str(components_config_path)) - - node = { - "components": [], - } - for i in range(len(tf_prefixes)): - node["components"].append( - utils.create_component( - "CAM01", - tf_prefixes[i], - namespaces[i], - names[i], - ) - ) - - utils.save_yaml(node) - - doc = utils.try_to_parse_well_and_test( - f"Could not parse without namespace:\n\t{node}\nIn file {components_config_path}" - ) - - for i in range(len(tf_prefixes)): - utils.test_camera(doc, tf_prefixes[i], namespaces[i], names[i]) - - -def test_good_cameras_and_lidars_without_namespace_and_tf_prefix(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join( - "test_good_cameras_and_lidars_without_namespace_and_tf_prefix.yaml" - ) - - utils = ComponentsYamlParseUtils(str(components_config_path)) - - names = ["camera_front", "camera_back"] - node = { - "components": [], - } - for i in range(len(names)): - node["components"].append(utils.create_component("CAM01", "None", "None", names[i])) - - node["components"].append(utils.create_component("LDR01", "None", "None")) - - utils.save_yaml(node) - - doc = utils.try_to_parse_well_and_test( - f"Could not parse without namespace:\n\t{node}\nIn file {components_config_path}" - ) - - for i in range(len(names)): - utils.test_camera(doc, "None", "None", names[i]) - - utils.test_lidar(doc, "None", "None") - - -def test_good_cameras_and_lidars_without_tf_prefix(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join("test_good_cameras_and_lidars_without_tf_prefix.yaml") - - utils = ComponentsYamlParseUtils(str(components_config_path)) - - names = ["camera_front", "camera_back"] - node = { - "components": [], - } - namespaces = ["/front", "/left"] - lidar_namespace = "/main_lidar" - - for i in range(len(names)): - node["components"].append(utils.create_component("CAM01", "None", namespaces[i], names[i])) - - node["components"].append(utils.create_component("LDR01", "None", lidar_namespace)) - - utils.save_yaml(node) - - doc = utils.try_to_parse_well_and_test( - f"Could not parse without namespace:\n\t{node}\nIn file {components_config_path}" - ) - - for i in range(len(names)): - utils.test_camera(doc, "None", namespaces[i], names[i]) - - utils.test_lidar(doc, "None", lidar_namespace) - - -def test_good_cameras_and_lidars_without_namespace(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join("test_good_cameras_and_lidars_without_namespace.yaml") - - utils = ComponentsYamlParseUtils(str(components_config_path)) - - names = ["camera_front", "camera_back"] - node = { - "components": [], - } - tf_prefixes = ["front", "left"] - lidar_tf_prefix = "main_lidar" - - for i in range(len(names)): - node["components"].append( - utils.create_component( - "CAM01", - tf_prefixes[i], - "None", - names[i], - ) - ) - - node["components"].append(utils.create_component("LDR01", lidar_tf_prefix, "None")) - - utils.save_yaml(node) - - doc = utils.try_to_parse_well_and_test( - f"Could not parse without namespace:\n\t{node}\nIn file {components_config_path}" - ) - - for i in range(len(names)): - utils.test_camera(doc, tf_prefixes[i], "None", names[i]) - - utils.test_lidar(doc, lidar_tf_prefix, "None") - - -def test_good_without_any_component(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join("test_wrong_unfilled_params.yaml") - - utils = ComponentsYamlParseUtils(str(components_config_path)) - node = { - "components": [], - } - - utils.save_yaml(node) - utils.try_to_parse_well_and_test( - f"This configuration should be parsed :\n\t{node}\nIn file {components_config_path}" - ) - -def test_wrong_empty_file(tmpdir_factory): - dir = tmpdir_factory.mktemp("panther_bringup_test") - components_config_path = dir.join("test_wrong_unfilled_params.yaml") - - utils = ComponentsYamlParseUtils(str(components_config_path)) - open(components_config_path, mode="w") - - utils.try_to_parse_wrong_and_test( - f"This configuration should not be parsed.\nIn file {components_config_path}" - ) diff --git a/urdf/components.urdf.xacro b/urdf/components.urdf.xacro index b63d44c..54ffdf7 100644 --- a/urdf/components.urdf.xacro +++ b/urdf/components.urdf.xacro @@ -28,7 +28,6 @@ - diff --git a/urdf/intel_realsense_d435.urdf.xacro b/urdf/intel_realsense_d435.urdf.xacro index 743fe5a..93b4d74 100644 --- a/urdf/intel_realsense_d435.urdf.xacro +++ b/urdf/intel_realsense_d435.urdf.xacro @@ -20,12 +20,9 @@ + device_namespace:=camera"> @@ -34,13 +31,6 @@ - - - - - - - @@ -70,22 +60,22 @@ - + - + - + - + - - + + - + @@ -112,132 +102,130 @@ published. e.g. running the device in simulation --> - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + - - - - - - true - 30.0 - - ${ns}${topic}/color/image_raw - false - - ${prefix}${name}_color_optical_frame - ${69.0/180.0*pi} + + + + + true + 30.0 + + ${ns}${device_namespace}/color/image_raw + false + + ${device_namespace}_color_optical_frame + ${69.0/180.0*pi} + + 1280 + 720 + R8G8B8 + + + 0.02 + 300.0 + + + ${ns}${device_namespace} + + + + + true + 30.0 + + ${ns}${device_namespace}/depth/image_rect_raw + false + + ${device_namespace}_depth_optical_frame + + ${87.0/180.0*pi} 1280 720 - R8G8B8 + R_FLOAT32 - 0.02 - 300.0 + 0.28 + 8.0 - - ${ns} - - - - - true - 30.0 - - ${ns}${topic}/depth/image_rect_raw - false - - ${prefix}${name}_depth_optical_frame - - ${87.0/180.0*pi} - - 1280 - 720 - R_FLOAT32 - - - 0.28 - 8.0 - - - gaussian - 0.0 - 0.005 - - - - ${ns} - - - - + + gaussian + 0.0 + 0.005 + + + + ${ns}${device_namespace} + + + diff --git a/urdf/orbbec_astra.urdf.xacro b/urdf/orbbec_astra.urdf.xacro index 605a7c4..c273fa9 100644 --- a/urdf/orbbec_astra.urdf.xacro +++ b/urdf/orbbec_astra.urdf.xacro @@ -2,8 +2,8 @@ + namespace:=None + device_namespace:=camera"> @@ -91,7 +91,7 @@ - + true @@ -143,7 +143,7 @@ - ${ns} + ${ns}${device_namespace} diff --git a/urdf/ouster_os1_32.urdf.xacro b/urdf/ouster_os1_32.urdf.xacro index 45056ce..ac11d7d 100644 --- a/urdf/ouster_os1_32.urdf.xacro +++ b/urdf/ouster_os1_32.urdf.xacro @@ -104,6 +104,10 @@ ${ns}${prefix}os_lidar true + + ${ns}${device_ns} + + diff --git a/urdf/slamtec_rplidar_a2.urdf.xacro b/urdf/slamtec_rplidar_a2.urdf.xacro index df286d0..c99f7c0 100644 --- a/urdf/slamtec_rplidar_a2.urdf.xacro +++ b/urdf/slamtec_rplidar_a2.urdf.xacro @@ -94,7 +94,7 @@ - + ${ns}${device_ns}scan ${ns}${prefix}laser diff --git a/urdf/slamtec_rplidar_a3.urdf.xacro b/urdf/slamtec_rplidar_a3.urdf.xacro index 9371050..223f8e9 100644 --- a/urdf/slamtec_rplidar_a3.urdf.xacro +++ b/urdf/slamtec_rplidar_a3.urdf.xacro @@ -69,7 +69,7 @@ - + ${ns}${device_ns}scan ${ns}${prefix}laser diff --git a/urdf/slamtec_rplidar_s1.urdf.xacro b/urdf/slamtec_rplidar_s1.urdf.xacro index ae53dd1..baf3820 100644 --- a/urdf/slamtec_rplidar_s1.urdf.xacro +++ b/urdf/slamtec_rplidar_s1.urdf.xacro @@ -76,10 +76,10 @@ - + ${ns}${device_ns}scan - {ns}${prefix}laser + ${ns}${prefix}laser ${ns}${prefix}laser 10.0 diff --git a/urdf/slamtec_rplidar_s2.urdf.xacro b/urdf/slamtec_rplidar_s2.urdf.xacro index 53a19c5..b739e75 100644 --- a/urdf/slamtec_rplidar_s2.urdf.xacro +++ b/urdf/slamtec_rplidar_s2.urdf.xacro @@ -68,9 +68,9 @@ - + - ${ns}${device_ns}${topic} + ${ns}${device_ns}scan ${ns}${prefix}laser ${ns}${prefix}laser diff --git a/urdf/slamtec_rplidar_s3.urdf.xacro b/urdf/slamtec_rplidar_s3.urdf.xacro index 629e506..0c13a43 100644 --- a/urdf/slamtec_rplidar_s3.urdf.xacro +++ b/urdf/slamtec_rplidar_s3.urdf.xacro @@ -68,7 +68,7 @@ - + ${ns}${device_ns}scan ${ns}${prefix}laser diff --git a/urdf/stereolabs_zed.urdf.xacro b/urdf/stereolabs_zed.urdf.xacro index 7958b36..7168733 100644 --- a/urdf/stereolabs_zed.urdf.xacro +++ b/urdf/stereolabs_zed.urdf.xacro @@ -23,8 +23,7 @@ params="parent_link xyz rpy model:=zed namespace:=None - device_namespace:=None - "> + device_namespace:=zed"> @@ -33,13 +32,6 @@ - - - - - - - @@ -90,15 +82,15 @@ - - + + - + - + @@ -114,135 +106,133 @@ - - - + + + - - - - + + + + - - - - + + + + - - + + - - + + - - - - + + + + - - + + - - + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - true - 30.0 - - ${ns}${prefix}camera/zed_node/rgb/image_rect_color - false - - ${prefix}camera_center_optical_frame - - ${110.0/180.0*pi} - - 1920 - 1080 - R8G8B8 - - - 0.02 - 300.0 - - - - ${ns} - - - - - true - 30.0 - - ${ns}${prefix}camera/zed_node/depth - false - - ${prefix}camera_center_optical_frame - - ${110.0/180.0*pi} - - 1920 - 1080 - R_FLOAT32 - - - 0.3 - 20.0 - - - 0.0 - 0.03 - - - - ${ns} - - - - + + + + true + 30.0 + + ${ns}${device_namespace}/zed_node/rgb/image_rect_color + false + + ${device_namespace}_center_optical_frame + + ${110.0/180.0*pi} + + 1920 + 1080 + R8G8B8 + + + 0.02 + 300.0 + + + + ${ns} + + + + + true + 30.0 + + ${ns}${device_namespace}/zed_node/depth + false + + ${device_namespace}_center_optical_frame + + ${110.0/180.0*pi} + + 1920 + 1080 + R_FLOAT32 + + + 0.3 + 20.0 + + + 0.0 + 0.03 + + + + ${ns}${device_namespace} + + +