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}
+
+
+