From 78ab38628d023142332c4c862e1a023eb68123c4 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Fri, 13 Dec 2024 18:09:28 -0300 Subject: [PATCH 01/21] Working on a republisher node test using a rosbag to harcode data on humble, inspired by noetic-test-sample_data --- .../fake_sensor_sample_rep_20241213162920.py | 0 .../fake_sensor_sample_rep_20241213162928.py | 24 ++ .../fake_sensor_sample_rep_20241213163048.py | 50 +++ .../fake_sensor_sample_rep_20241213163652.py | 50 +++ .../fake_sensor_sample_rep_20241213163836.py | 50 +++ .../republisher_20241213161527.py | 303 +++++++++++++ .../republisher_20241213164444.py | 50 +++ .../republisher_20241213164541.py | 303 +++++++++++++ .../republisher_20241213164629.py | 303 +++++++++++++ .../sample_data.launch_20241213172505.xml | 8 + .../sample_data.launch_20241213174002.xml | 8 + .../sample_data.launch_20241213174830.xml | 8 + .../sample_data.launch_20241213174900.xml | 8 + .../sample_data.launch_20241213175417.xml | 9 + .../sample_data.launch_20241213175425.xml | 9 + .../setup_20241213161527.py | 30 ++ .../setup_20241213172142.py | 30 ++ .../setup_20241213172214.py | 30 ++ .../test/README_20241213162953.md | 0 .../test/README_20241213163651.md | 10 + .../test/README_20241213175317.md | 17 + .../test/README_20241213175932.md | 22 + .../test/README_20241213180602.md | 26 ++ .../test/README_20241213180720.md | 27 ++ .../sample_data/config_20241213162657.yaml | 0 .../sample_data/config_20241213165503.yaml | 23 + .../sample_data.launch_20241213174001.xml | 8 + .../sample_data.launch_20241213174614.xml | 8 + .../sample_data_launch_20241213162714.xml | 0 .../sample_data_launch_20241213162848.xml | 6 + .../sample_data_launch_20241213165700.xml | 6 + .../sample_data_launch_20241213165739.xml | 6 + .../sample_data_launch_20241213172506.xml | 8 + .../launch/sample_data.launch.xml | 9 + inorbit_republisher/test/README.md | 27 ++ .../test/sample_data/build/.built_by | 1 + .../test/sample_data/build/COLCON_IGNORE | 0 .../test/sample_data/config.yaml | 23 + .../sample_data/hardcodedRosbag/metadata.yaml | 32 ++ .../rosbag2_2024_12_13-19_33_34_0.db3 | Bin 0 -> 24576 bytes .../install/.colcon_install_layout | 1 + .../test/sample_data/install/COLCON_IGNORE | 0 .../install/_local_setup_util_ps1.py | 407 ++++++++++++++++++ .../install/_local_setup_util_sh.py | 407 ++++++++++++++++++ .../test/sample_data/install/local_setup.bash | 121 ++++++ .../test/sample_data/install/local_setup.ps1 | 55 +++ .../test/sample_data/install/local_setup.sh | 137 ++++++ .../test/sample_data/install/local_setup.zsh | 134 ++++++ .../test/sample_data/install/setup.bash | 37 ++ .../test/sample_data/install/setup.ps1 | 31 ++ .../test/sample_data/install/setup.sh | 53 +++ .../test/sample_data/install/setup.zsh | 37 ++ .../test/sample_data/log/COLCON_IGNORE | 0 .../log/build_2024-12-13_20-02-50/events.log | 2 + .../build_2024-12-13_20-02-50/logger_all.log | 77 ++++ .../log/build_2024-12-13_20-49-52/events.log | 2 + .../build_2024-12-13_20-49-52/logger_all.log | 76 ++++ .../test/sample_data/log/latest | 1 + .../test/sample_data/log/latest_build | 1 + 59 files changed, 3111 insertions(+) create mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162920.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py create mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml create mode 100644 .history/inorbit_republisher/setup_20241213161527.py create mode 100644 .history/inorbit_republisher/setup_20241213172142.py create mode 100644 .history/inorbit_republisher/setup_20241213172214.py create mode 100644 .history/inorbit_republisher/test/README_20241213162953.md create mode 100644 .history/inorbit_republisher/test/README_20241213163651.md create mode 100644 .history/inorbit_republisher/test/README_20241213175317.md create mode 100644 .history/inorbit_republisher/test/README_20241213175932.md create mode 100644 .history/inorbit_republisher/test/README_20241213180602.md create mode 100644 .history/inorbit_republisher/test/README_20241213180720.md create mode 100644 .history/inorbit_republisher/test/sample_data/config_20241213162657.yaml create mode 100644 .history/inorbit_republisher/test/sample_data/config_20241213165503.yaml create mode 100644 .history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml create mode 100644 .history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml create mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162714.xml create mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml create mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml create mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml create mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml create mode 100644 inorbit_republisher/launch/sample_data.launch.xml create mode 100644 inorbit_republisher/test/README.md create mode 100644 inorbit_republisher/test/sample_data/build/.built_by create mode 100644 inorbit_republisher/test/sample_data/build/COLCON_IGNORE create mode 100644 inorbit_republisher/test/sample_data/config.yaml create mode 100644 inorbit_republisher/test/sample_data/hardcodedRosbag/metadata.yaml create mode 100644 inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 create mode 100644 inorbit_republisher/test/sample_data/install/.colcon_install_layout create mode 100644 inorbit_republisher/test/sample_data/install/COLCON_IGNORE create mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py create mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.bash create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.ps1 create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.sh create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.zsh create mode 100644 inorbit_republisher/test/sample_data/install/setup.bash create mode 100644 inorbit_republisher/test/sample_data/install/setup.ps1 create mode 100644 inorbit_republisher/test/sample_data/install/setup.sh create mode 100644 inorbit_republisher/test/sample_data/install/setup.zsh create mode 100644 inorbit_republisher/test/sample_data/log/COLCON_IGNORE create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log create mode 120000 inorbit_republisher/test/sample_data/log/latest create mode 120000 inorbit_republisher/test/sample_data/log/latest_build diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162920.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162920.py new file mode 100644 index 0000000..e69de29 diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py new file mode 100644 index 0000000..6c6bcc9 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py @@ -0,0 +1,24 @@ +import launch +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, LogInfo, Node +from launch.substitutions import LaunchConfiguration, PathJoinSubstitution + +def generate_launch_description(): + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher.py', # Cambia 'republisher' por 'republisher.py' si es un script Python + name='inorbit_republisher', + parameters=[{'config': PathJoinSubstitution([LaunchConfiguration('config_dir'), 'config.yaml'])}], + ), + + # Nodo rosbag + Node( + package='rosbag2', + executable='play', + name='player', + output='screen', + arguments=['-l', PathJoinSubstitution([LaunchConfiguration('config_dir'), 'fake_sensors_sample.bag'])], + ), + ]) diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py new file mode 100644 index 0000000..7fe77d3 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py @@ -0,0 +1,50 @@ +import rclpy +from rclpy.node import Node +from sensor_msgs.msg import MagneticField, Temperature +from std_msgs.msg import String +import random +import time + +class FakeSensorPublisher(Node): + def __init__(self): + super().__init__('fake_sensor_publisher') + + # Publicadores de los sensores + self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) + self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) + + # Timer para publicar los mensajes cada 1 segundo + self.timer = self.create_timer(1.0, self.publish_fake_data) + + def publish_fake_data(self): + # Publicar datos simulados para el campo magnético + magnetic_field_msg = MagneticField() + magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) + self.magnetic_field_publisher.publish(magnetic_field_msg) + self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " + f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") + + # Publicar datos simulados para la temperatura + temperature_msg = Temperature() + temperature_msg.temperature = random.uniform(20.0, 30.0) + self.temperature_publisher.publish(temperature_msg) + self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") + + +def main(args=None): + rclpy.init(args=args) + node = FakeSensorPublisher() + + try: + rclpy.spin(node) + except KeyboardInterrupt: + pass + + # Destruir el nodo después de detener el spin + node.destroy_node() + rclpy.shutdown() + +if __name__ == '__main__': + main() diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py new file mode 100644 index 0000000..7fe77d3 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py @@ -0,0 +1,50 @@ +import rclpy +from rclpy.node import Node +from sensor_msgs.msg import MagneticField, Temperature +from std_msgs.msg import String +import random +import time + +class FakeSensorPublisher(Node): + def __init__(self): + super().__init__('fake_sensor_publisher') + + # Publicadores de los sensores + self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) + self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) + + # Timer para publicar los mensajes cada 1 segundo + self.timer = self.create_timer(1.0, self.publish_fake_data) + + def publish_fake_data(self): + # Publicar datos simulados para el campo magnético + magnetic_field_msg = MagneticField() + magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) + self.magnetic_field_publisher.publish(magnetic_field_msg) + self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " + f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") + + # Publicar datos simulados para la temperatura + temperature_msg = Temperature() + temperature_msg.temperature = random.uniform(20.0, 30.0) + self.temperature_publisher.publish(temperature_msg) + self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") + + +def main(args=None): + rclpy.init(args=args) + node = FakeSensorPublisher() + + try: + rclpy.spin(node) + except KeyboardInterrupt: + pass + + # Destruir el nodo después de detener el spin + node.destroy_node() + rclpy.shutdown() + +if __name__ == '__main__': + main() diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py new file mode 100644 index 0000000..7fe77d3 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py @@ -0,0 +1,50 @@ +import rclpy +from rclpy.node import Node +from sensor_msgs.msg import MagneticField, Temperature +from std_msgs.msg import String +import random +import time + +class FakeSensorPublisher(Node): + def __init__(self): + super().__init__('fake_sensor_publisher') + + # Publicadores de los sensores + self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) + self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) + + # Timer para publicar los mensajes cada 1 segundo + self.timer = self.create_timer(1.0, self.publish_fake_data) + + def publish_fake_data(self): + # Publicar datos simulados para el campo magnético + magnetic_field_msg = MagneticField() + magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) + self.magnetic_field_publisher.publish(magnetic_field_msg) + self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " + f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") + + # Publicar datos simulados para la temperatura + temperature_msg = Temperature() + temperature_msg.temperature = random.uniform(20.0, 30.0) + self.temperature_publisher.publish(temperature_msg) + self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") + + +def main(args=None): + rclpy.init(args=args) + node = FakeSensorPublisher() + + try: + rclpy.spin(node) + except KeyboardInterrupt: + pass + + # Destruir el nodo después de detener el spin + node.destroy_node() + rclpy.shutdown() + +if __name__ == '__main__': + main() diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py new file mode 100644 index 0000000..d81aa30 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python + +# Copyright 2021 InOrbit, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# ROS to InOrbit republisher node sample +# +# It uses a YAML-based configuration to map between arbitrary +# ROS topics into InOrbit key/value custom data topics. + +import json +import rclpy +from rosidl_runtime_py.utilities import get_message +import yaml +import os +from rosidl_runtime_py.convert import message_to_ordereddict +from std_msgs.msg import String +from builtin_interfaces.msg import Time +from operator import attrgetter + +# Types of mappings allowed +MAPPING_TYPE_SINGLE_FIELD = "single_field" +MAPPING_TYPE_ARRAY_OF_FIELDS = "array_of_fields" +MAPPING_TYPE_JSON_OF_FIELDS = "json_of_fields" +MAPPING_TYPE_SERIALIZE = "serialize" + +# Supported static publisher value sources +STATIC_VALUE_FROM_PACKAGE_VERSION = "package_version" +STATIC_VALUE_FROM_ENVIRONMENT_VAR = "environment_variable" + +""" +Custom JSON encoder to deal with types found on ROS 2 messages that are not +serializable to string by default. +For now this includes: + - bytes objects to decoded String objects +""" +class ROS2JSONEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, bytes): + return obj.decode() + return json.JSONEncoder.default(self, obj) + +""" +Main node entry point. + +Currently a simple function that does everything. +We can later turn it into a class and divide in proper methods +as complexity increases. +""" +def main(args = None): + # Start the ROS node + rclpy.init(args=args) + node = rclpy.create_node('inorbit_republisher') + # Declares the "config" parameter, it contains the path of the config file + node.declare_parameter('config') + # Read republisher configuration from the 'config_file' or 'config' parameter + # TODO(adamantivm) Error handling and schema checking + if node.has_parameter('config'): + config_file = node.get_parameter( + 'config').get_parameter_value().string_value + node.get_logger().info("Using config from config file: {}".format(config_file)) + config_yaml = open(config_file, "r") + config = yaml.safe_load(config_yaml) + + # Go through republisher configurations + # For each of them: create a publisher if necessary - only one per InOrbit + # custom data field - and a matching subscriber to receive and republish + # the desired fields. + + # Dictionary of publisher instances by topic name + pubs = {} + + # Dictionary of subscriber instances by topic name + subs = {} + + # TODO(adamantivm) Port ability to publish package versions from ROS 1 Noetic to ROS 2 Foxy + # # In case we want to query ROS package options + # rospack = rospkg.RosPack() + + # Set-up ROS topic republishers + republishers = config.get('republishers', ()) + for repub in republishers: + + # Load subscriber message type + msg_class = get_message(repub['msg_type']) + if msg_class is None: + node.get_logger().warning('Failed to load msg class for {}'.format(repub['msg_type'])) + continue + + # Create publisher for each new seen outgoing topic + for mapping in repub['mappings']: + out_topic = mapping['out']['topic'] + if not out_topic in pubs: + # NOTE(adamantivm) Using QOS = 10 to match InOrbit Custom Data topic spec + pubs[out_topic] = node.create_publisher(String, out_topic, 10) + # 'field' mapping is not defined when serializing messages + if 'field' in mapping: + mapping['attrgetter'] = attrgetter(mapping['field']) + + # Prepare callback to relay messages through InOrbit custom data + def callback(msg, repub=repub): + + for mapping in repub['mappings']: + key = mapping['out']['key'] + val = None + mapping_type = mapping.get('mapping_type', MAPPING_TYPE_SINGLE_FIELD) + topic = mapping['out']['topic'] + + if mapping_type == MAPPING_TYPE_SINGLE_FIELD: + # TODO(adamantivm) Exception handling + field = extract_value(msg, attrgetter(mapping['field'])) + val = process_single_field(field, mapping) + # Time values can't be cleanly serialized into JSON. convert them to milliseconds + if isinstance(val, Time): + val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 + + elif mapping_type == MAPPING_TYPE_ARRAY_OF_FIELDS: + field = extract_value(msg, attrgetter(mapping['field'])) + val = process_array(field, mapping) + + elif mapping_type == MAPPING_TYPE_JSON_OF_FIELDS: + try: + val = extract_values_as_dict(msg, mapping, node) + # extract_values_as_dict has the ability to filter messages and + # returns None when an element doesn't pass the filter + if val: + val = json.dumps(val, cls=ROS2JSONEncoder) + except TypeError as e: + node.get_logger().warning(f"Failed to serialize message: {e}") + elif mapping_type == MAPPING_TYPE_SERIALIZE: + try: + val = serialize(msg, mapping) + if val: + val = json.dumps(val, cls=ROS2JSONEncoder) + except TypeError as e: + node.get_logger().warning(f"Failed to serialize message: {e}") + + if val is not None: + pubs[topic].publish(String(data=f"{key}={val}")) + + in_topic = repub['topic'] + # Reads QoS from the topic settings + in_qos = getattr(repub, 'qos', 10) + + # subscribe + subs[in_topic] = node.create_subscription(msg_class, in_topic, callback, in_qos) + + # Set-up static publishers + static_publishers = config.get('static_publishers', ()) + for static_pub_config in static_publishers: + key = static_pub_config['out']['key'] + topic = static_pub_config['out']['topic'] + + # If a literal value is provided, it takes highest precendence + val = static_pub_config.get('value') + + # Otherwise, fetch the value from the specified source + if val is None: + value_from = static_pub_config.get('value_from') + if STATIC_VALUE_FROM_ENVIRONMENT_VAR in value_from: + var_name = value_from[STATIC_VALUE_FROM_ENVIRONMENT_VAR] + val = os.environ.get(var_name) + # TODO(adamantivm) Implement publishing of package version for ROS 2 + # elif STATIC_VALUE_FROM_PACKAGE_VERSION in value_from: + # pkg_name = value_from[STATIC_VALUE_FROM_PACKAGE_VERSION] + # # TODO(adamantivm) Exception handling + # pkg_manifest = rospack.get_manifest(pkg_name) + # val = pkg_manifest.version + + # If there is a value to publish, publish it using once per subscriber + # TODO(adamantivm) Make these values latched + if val is not None: + pub = node.create_publisher(String, topic, 10) + pub.publish(String(data=f"{key}={val}")) + + node.get_logger().info("Republisher started") + rclpy.spin(node) + node.get_logger().info("Republisher shutting down") + + node.destroy_node() + rclpy.shutdown() + node.get_logger().info("Shutdown complete") + +""" +Extracts a value from the given message using the provided getter function +""" +def extract_value(msg, getter_fn): + # TODO(adamantivm) Graceful handling of missing values to extract + # TODO(adamantivm) Allow serialization of complex values + val = getter_fn(msg) + return val + + +""" +Extracts several values from a given nested msg field and returns a dictionary of + elements +""" +# TODO(elvioaruta): after refactoring and using Node as classes +# remove the node from this function and figure out a better way +# to log warnings inside +def extract_values_as_dict(msg, mapping, node): + values = {} + base_getter_fn = attrgetter(mapping['field']) + base_value = base_getter_fn(msg) + fields = mapping.get('mapping_options', {}).get('fields') + for field in fields: + getter_fn = attrgetter(field) + try: + val = getter_fn(base_value) + # Time values aren't cleanly serialized into JSON. + # Convert them to milliseconds + if isinstance(val, Time): + val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 + # TODO(diegobatt): Make it possible to use a different key than the field + values[field] = val + except AttributeError as e: + node.get_logger().warning(f"Couldn\'t get attribute {field}: {e}") + filter_fn = mapping.get('mapping_options', {}).get('filter') + return values if not filter_fn or eval(filter_fn)(values) else None + +""" +Processes a scalar value before publishing according to mapping options + - If a 'filter' function is provided, it returns the value only if the + result of passing the field value through the filter function is True, + otherwise it returns None +""" +def process_single_field(field_value, mapping): + filter_fn = mapping.get('mapping_options', {}).get('filter') + return field_value if not filter_fn or eval(filter_fn)(field_value) else None + +""" +Processes a given array field from the ROS message and: + - Filters it using the 'filter' function (if provided) + - For each element, it gets the set of keys defined by array_fields + - Returns a key/value with the value being a json string containing + the resulting array of objects. + +Note that the array fields to retrieve should have a String value in order to +serialize them properly. +""" +def process_array(field, mapping): + # Output array of objects + values = { + 'data': [] + } + + filter_fn = mapping.get('mapping_options', {}).get('filter') + if filter_fn: + # Apply the filter function if any + filtered_array = list(filter(eval(filter_fn), field)) + else: + filtered_array = field + + # Get only the array_fields specified. If none was specified, return the whole array + # TODO(FlorGrosso): check that the array fields are Strings and discard those which + # are not. + if 'fields' in mapping.get('mapping_options', {}): + fields = mapping['mapping_options']['fields'] + values['data'] = [{f: extract_value(elem, attrgetter(f)) for f in fields} for elem in filtered_array] + else: + values['data'] = filtered_array + return json.dumps(values, cls=ROS2JSONEncoder) + +""" +Transforms the ROS message to json and: + - Filters out fields on the top level of the json only. +""" +def serialize(msg, mapping): + # TODO: design filtering support and implement it. It should be possible + # to leverage jq to do so. However, this would require adding a new rosdep + # rule for `pyjq`: https://pypi.org/project/pyjq/. + # filter = mapping.get('mapping_options', {}).get('filter') + + # Get fields configuration + fields = mapping.get('mapping_options', {}).get('fields') + # Transform ROS message to dict + msg_dict = message_to_ordereddict(msg) + + # Shrink output by keeping only selected fields or keys + if fields: + msg_dict = { k: v for k, v in msg_dict.items() if k in fields} + + return msg_dict + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py new file mode 100644 index 0000000..7fe77d3 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py @@ -0,0 +1,50 @@ +import rclpy +from rclpy.node import Node +from sensor_msgs.msg import MagneticField, Temperature +from std_msgs.msg import String +import random +import time + +class FakeSensorPublisher(Node): + def __init__(self): + super().__init__('fake_sensor_publisher') + + # Publicadores de los sensores + self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) + self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) + + # Timer para publicar los mensajes cada 1 segundo + self.timer = self.create_timer(1.0, self.publish_fake_data) + + def publish_fake_data(self): + # Publicar datos simulados para el campo magnético + magnetic_field_msg = MagneticField() + magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) + magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) + self.magnetic_field_publisher.publish(magnetic_field_msg) + self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " + f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") + + # Publicar datos simulados para la temperatura + temperature_msg = Temperature() + temperature_msg.temperature = random.uniform(20.0, 30.0) + self.temperature_publisher.publish(temperature_msg) + self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") + + +def main(args=None): + rclpy.init(args=args) + node = FakeSensorPublisher() + + try: + rclpy.spin(node) + except KeyboardInterrupt: + pass + + # Destruir el nodo después de detener el spin + node.destroy_node() + rclpy.shutdown() + +if __name__ == '__main__': + main() diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py new file mode 100644 index 0000000..d81aa30 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python + +# Copyright 2021 InOrbit, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# ROS to InOrbit republisher node sample +# +# It uses a YAML-based configuration to map between arbitrary +# ROS topics into InOrbit key/value custom data topics. + +import json +import rclpy +from rosidl_runtime_py.utilities import get_message +import yaml +import os +from rosidl_runtime_py.convert import message_to_ordereddict +from std_msgs.msg import String +from builtin_interfaces.msg import Time +from operator import attrgetter + +# Types of mappings allowed +MAPPING_TYPE_SINGLE_FIELD = "single_field" +MAPPING_TYPE_ARRAY_OF_FIELDS = "array_of_fields" +MAPPING_TYPE_JSON_OF_FIELDS = "json_of_fields" +MAPPING_TYPE_SERIALIZE = "serialize" + +# Supported static publisher value sources +STATIC_VALUE_FROM_PACKAGE_VERSION = "package_version" +STATIC_VALUE_FROM_ENVIRONMENT_VAR = "environment_variable" + +""" +Custom JSON encoder to deal with types found on ROS 2 messages that are not +serializable to string by default. +For now this includes: + - bytes objects to decoded String objects +""" +class ROS2JSONEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, bytes): + return obj.decode() + return json.JSONEncoder.default(self, obj) + +""" +Main node entry point. + +Currently a simple function that does everything. +We can later turn it into a class and divide in proper methods +as complexity increases. +""" +def main(args = None): + # Start the ROS node + rclpy.init(args=args) + node = rclpy.create_node('inorbit_republisher') + # Declares the "config" parameter, it contains the path of the config file + node.declare_parameter('config') + # Read republisher configuration from the 'config_file' or 'config' parameter + # TODO(adamantivm) Error handling and schema checking + if node.has_parameter('config'): + config_file = node.get_parameter( + 'config').get_parameter_value().string_value + node.get_logger().info("Using config from config file: {}".format(config_file)) + config_yaml = open(config_file, "r") + config = yaml.safe_load(config_yaml) + + # Go through republisher configurations + # For each of them: create a publisher if necessary - only one per InOrbit + # custom data field - and a matching subscriber to receive and republish + # the desired fields. + + # Dictionary of publisher instances by topic name + pubs = {} + + # Dictionary of subscriber instances by topic name + subs = {} + + # TODO(adamantivm) Port ability to publish package versions from ROS 1 Noetic to ROS 2 Foxy + # # In case we want to query ROS package options + # rospack = rospkg.RosPack() + + # Set-up ROS topic republishers + republishers = config.get('republishers', ()) + for repub in republishers: + + # Load subscriber message type + msg_class = get_message(repub['msg_type']) + if msg_class is None: + node.get_logger().warning('Failed to load msg class for {}'.format(repub['msg_type'])) + continue + + # Create publisher for each new seen outgoing topic + for mapping in repub['mappings']: + out_topic = mapping['out']['topic'] + if not out_topic in pubs: + # NOTE(adamantivm) Using QOS = 10 to match InOrbit Custom Data topic spec + pubs[out_topic] = node.create_publisher(String, out_topic, 10) + # 'field' mapping is not defined when serializing messages + if 'field' in mapping: + mapping['attrgetter'] = attrgetter(mapping['field']) + + # Prepare callback to relay messages through InOrbit custom data + def callback(msg, repub=repub): + + for mapping in repub['mappings']: + key = mapping['out']['key'] + val = None + mapping_type = mapping.get('mapping_type', MAPPING_TYPE_SINGLE_FIELD) + topic = mapping['out']['topic'] + + if mapping_type == MAPPING_TYPE_SINGLE_FIELD: + # TODO(adamantivm) Exception handling + field = extract_value(msg, attrgetter(mapping['field'])) + val = process_single_field(field, mapping) + # Time values can't be cleanly serialized into JSON. convert them to milliseconds + if isinstance(val, Time): + val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 + + elif mapping_type == MAPPING_TYPE_ARRAY_OF_FIELDS: + field = extract_value(msg, attrgetter(mapping['field'])) + val = process_array(field, mapping) + + elif mapping_type == MAPPING_TYPE_JSON_OF_FIELDS: + try: + val = extract_values_as_dict(msg, mapping, node) + # extract_values_as_dict has the ability to filter messages and + # returns None when an element doesn't pass the filter + if val: + val = json.dumps(val, cls=ROS2JSONEncoder) + except TypeError as e: + node.get_logger().warning(f"Failed to serialize message: {e}") + elif mapping_type == MAPPING_TYPE_SERIALIZE: + try: + val = serialize(msg, mapping) + if val: + val = json.dumps(val, cls=ROS2JSONEncoder) + except TypeError as e: + node.get_logger().warning(f"Failed to serialize message: {e}") + + if val is not None: + pubs[topic].publish(String(data=f"{key}={val}")) + + in_topic = repub['topic'] + # Reads QoS from the topic settings + in_qos = getattr(repub, 'qos', 10) + + # subscribe + subs[in_topic] = node.create_subscription(msg_class, in_topic, callback, in_qos) + + # Set-up static publishers + static_publishers = config.get('static_publishers', ()) + for static_pub_config in static_publishers: + key = static_pub_config['out']['key'] + topic = static_pub_config['out']['topic'] + + # If a literal value is provided, it takes highest precendence + val = static_pub_config.get('value') + + # Otherwise, fetch the value from the specified source + if val is None: + value_from = static_pub_config.get('value_from') + if STATIC_VALUE_FROM_ENVIRONMENT_VAR in value_from: + var_name = value_from[STATIC_VALUE_FROM_ENVIRONMENT_VAR] + val = os.environ.get(var_name) + # TODO(adamantivm) Implement publishing of package version for ROS 2 + # elif STATIC_VALUE_FROM_PACKAGE_VERSION in value_from: + # pkg_name = value_from[STATIC_VALUE_FROM_PACKAGE_VERSION] + # # TODO(adamantivm) Exception handling + # pkg_manifest = rospack.get_manifest(pkg_name) + # val = pkg_manifest.version + + # If there is a value to publish, publish it using once per subscriber + # TODO(adamantivm) Make these values latched + if val is not None: + pub = node.create_publisher(String, topic, 10) + pub.publish(String(data=f"{key}={val}")) + + node.get_logger().info("Republisher started") + rclpy.spin(node) + node.get_logger().info("Republisher shutting down") + + node.destroy_node() + rclpy.shutdown() + node.get_logger().info("Shutdown complete") + +""" +Extracts a value from the given message using the provided getter function +""" +def extract_value(msg, getter_fn): + # TODO(adamantivm) Graceful handling of missing values to extract + # TODO(adamantivm) Allow serialization of complex values + val = getter_fn(msg) + return val + + +""" +Extracts several values from a given nested msg field and returns a dictionary of + elements +""" +# TODO(elvioaruta): after refactoring and using Node as classes +# remove the node from this function and figure out a better way +# to log warnings inside +def extract_values_as_dict(msg, mapping, node): + values = {} + base_getter_fn = attrgetter(mapping['field']) + base_value = base_getter_fn(msg) + fields = mapping.get('mapping_options', {}).get('fields') + for field in fields: + getter_fn = attrgetter(field) + try: + val = getter_fn(base_value) + # Time values aren't cleanly serialized into JSON. + # Convert them to milliseconds + if isinstance(val, Time): + val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 + # TODO(diegobatt): Make it possible to use a different key than the field + values[field] = val + except AttributeError as e: + node.get_logger().warning(f"Couldn\'t get attribute {field}: {e}") + filter_fn = mapping.get('mapping_options', {}).get('filter') + return values if not filter_fn or eval(filter_fn)(values) else None + +""" +Processes a scalar value before publishing according to mapping options + - If a 'filter' function is provided, it returns the value only if the + result of passing the field value through the filter function is True, + otherwise it returns None +""" +def process_single_field(field_value, mapping): + filter_fn = mapping.get('mapping_options', {}).get('filter') + return field_value if not filter_fn or eval(filter_fn)(field_value) else None + +""" +Processes a given array field from the ROS message and: + - Filters it using the 'filter' function (if provided) + - For each element, it gets the set of keys defined by array_fields + - Returns a key/value with the value being a json string containing + the resulting array of objects. + +Note that the array fields to retrieve should have a String value in order to +serialize them properly. +""" +def process_array(field, mapping): + # Output array of objects + values = { + 'data': [] + } + + filter_fn = mapping.get('mapping_options', {}).get('filter') + if filter_fn: + # Apply the filter function if any + filtered_array = list(filter(eval(filter_fn), field)) + else: + filtered_array = field + + # Get only the array_fields specified. If none was specified, return the whole array + # TODO(FlorGrosso): check that the array fields are Strings and discard those which + # are not. + if 'fields' in mapping.get('mapping_options', {}): + fields = mapping['mapping_options']['fields'] + values['data'] = [{f: extract_value(elem, attrgetter(f)) for f in fields} for elem in filtered_array] + else: + values['data'] = filtered_array + return json.dumps(values, cls=ROS2JSONEncoder) + +""" +Transforms the ROS message to json and: + - Filters out fields on the top level of the json only. +""" +def serialize(msg, mapping): + # TODO: design filtering support and implement it. It should be possible + # to leverage jq to do so. However, this would require adding a new rosdep + # rule for `pyjq`: https://pypi.org/project/pyjq/. + # filter = mapping.get('mapping_options', {}).get('filter') + + # Get fields configuration + fields = mapping.get('mapping_options', {}).get('fields') + # Transform ROS message to dict + msg_dict = message_to_ordereddict(msg) + + # Shrink output by keeping only selected fields or keys + if fields: + msg_dict = { k: v for k, v in msg_dict.items() if k in fields} + + return msg_dict + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py new file mode 100644 index 0000000..d81aa30 --- /dev/null +++ b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python + +# Copyright 2021 InOrbit, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# ROS to InOrbit republisher node sample +# +# It uses a YAML-based configuration to map between arbitrary +# ROS topics into InOrbit key/value custom data topics. + +import json +import rclpy +from rosidl_runtime_py.utilities import get_message +import yaml +import os +from rosidl_runtime_py.convert import message_to_ordereddict +from std_msgs.msg import String +from builtin_interfaces.msg import Time +from operator import attrgetter + +# Types of mappings allowed +MAPPING_TYPE_SINGLE_FIELD = "single_field" +MAPPING_TYPE_ARRAY_OF_FIELDS = "array_of_fields" +MAPPING_TYPE_JSON_OF_FIELDS = "json_of_fields" +MAPPING_TYPE_SERIALIZE = "serialize" + +# Supported static publisher value sources +STATIC_VALUE_FROM_PACKAGE_VERSION = "package_version" +STATIC_VALUE_FROM_ENVIRONMENT_VAR = "environment_variable" + +""" +Custom JSON encoder to deal with types found on ROS 2 messages that are not +serializable to string by default. +For now this includes: + - bytes objects to decoded String objects +""" +class ROS2JSONEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, bytes): + return obj.decode() + return json.JSONEncoder.default(self, obj) + +""" +Main node entry point. + +Currently a simple function that does everything. +We can later turn it into a class and divide in proper methods +as complexity increases. +""" +def main(args = None): + # Start the ROS node + rclpy.init(args=args) + node = rclpy.create_node('inorbit_republisher') + # Declares the "config" parameter, it contains the path of the config file + node.declare_parameter('config') + # Read republisher configuration from the 'config_file' or 'config' parameter + # TODO(adamantivm) Error handling and schema checking + if node.has_parameter('config'): + config_file = node.get_parameter( + 'config').get_parameter_value().string_value + node.get_logger().info("Using config from config file: {}".format(config_file)) + config_yaml = open(config_file, "r") + config = yaml.safe_load(config_yaml) + + # Go through republisher configurations + # For each of them: create a publisher if necessary - only one per InOrbit + # custom data field - and a matching subscriber to receive and republish + # the desired fields. + + # Dictionary of publisher instances by topic name + pubs = {} + + # Dictionary of subscriber instances by topic name + subs = {} + + # TODO(adamantivm) Port ability to publish package versions from ROS 1 Noetic to ROS 2 Foxy + # # In case we want to query ROS package options + # rospack = rospkg.RosPack() + + # Set-up ROS topic republishers + republishers = config.get('republishers', ()) + for repub in republishers: + + # Load subscriber message type + msg_class = get_message(repub['msg_type']) + if msg_class is None: + node.get_logger().warning('Failed to load msg class for {}'.format(repub['msg_type'])) + continue + + # Create publisher for each new seen outgoing topic + for mapping in repub['mappings']: + out_topic = mapping['out']['topic'] + if not out_topic in pubs: + # NOTE(adamantivm) Using QOS = 10 to match InOrbit Custom Data topic spec + pubs[out_topic] = node.create_publisher(String, out_topic, 10) + # 'field' mapping is not defined when serializing messages + if 'field' in mapping: + mapping['attrgetter'] = attrgetter(mapping['field']) + + # Prepare callback to relay messages through InOrbit custom data + def callback(msg, repub=repub): + + for mapping in repub['mappings']: + key = mapping['out']['key'] + val = None + mapping_type = mapping.get('mapping_type', MAPPING_TYPE_SINGLE_FIELD) + topic = mapping['out']['topic'] + + if mapping_type == MAPPING_TYPE_SINGLE_FIELD: + # TODO(adamantivm) Exception handling + field = extract_value(msg, attrgetter(mapping['field'])) + val = process_single_field(field, mapping) + # Time values can't be cleanly serialized into JSON. convert them to milliseconds + if isinstance(val, Time): + val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 + + elif mapping_type == MAPPING_TYPE_ARRAY_OF_FIELDS: + field = extract_value(msg, attrgetter(mapping['field'])) + val = process_array(field, mapping) + + elif mapping_type == MAPPING_TYPE_JSON_OF_FIELDS: + try: + val = extract_values_as_dict(msg, mapping, node) + # extract_values_as_dict has the ability to filter messages and + # returns None when an element doesn't pass the filter + if val: + val = json.dumps(val, cls=ROS2JSONEncoder) + except TypeError as e: + node.get_logger().warning(f"Failed to serialize message: {e}") + elif mapping_type == MAPPING_TYPE_SERIALIZE: + try: + val = serialize(msg, mapping) + if val: + val = json.dumps(val, cls=ROS2JSONEncoder) + except TypeError as e: + node.get_logger().warning(f"Failed to serialize message: {e}") + + if val is not None: + pubs[topic].publish(String(data=f"{key}={val}")) + + in_topic = repub['topic'] + # Reads QoS from the topic settings + in_qos = getattr(repub, 'qos', 10) + + # subscribe + subs[in_topic] = node.create_subscription(msg_class, in_topic, callback, in_qos) + + # Set-up static publishers + static_publishers = config.get('static_publishers', ()) + for static_pub_config in static_publishers: + key = static_pub_config['out']['key'] + topic = static_pub_config['out']['topic'] + + # If a literal value is provided, it takes highest precendence + val = static_pub_config.get('value') + + # Otherwise, fetch the value from the specified source + if val is None: + value_from = static_pub_config.get('value_from') + if STATIC_VALUE_FROM_ENVIRONMENT_VAR in value_from: + var_name = value_from[STATIC_VALUE_FROM_ENVIRONMENT_VAR] + val = os.environ.get(var_name) + # TODO(adamantivm) Implement publishing of package version for ROS 2 + # elif STATIC_VALUE_FROM_PACKAGE_VERSION in value_from: + # pkg_name = value_from[STATIC_VALUE_FROM_PACKAGE_VERSION] + # # TODO(adamantivm) Exception handling + # pkg_manifest = rospack.get_manifest(pkg_name) + # val = pkg_manifest.version + + # If there is a value to publish, publish it using once per subscriber + # TODO(adamantivm) Make these values latched + if val is not None: + pub = node.create_publisher(String, topic, 10) + pub.publish(String(data=f"{key}={val}")) + + node.get_logger().info("Republisher started") + rclpy.spin(node) + node.get_logger().info("Republisher shutting down") + + node.destroy_node() + rclpy.shutdown() + node.get_logger().info("Shutdown complete") + +""" +Extracts a value from the given message using the provided getter function +""" +def extract_value(msg, getter_fn): + # TODO(adamantivm) Graceful handling of missing values to extract + # TODO(adamantivm) Allow serialization of complex values + val = getter_fn(msg) + return val + + +""" +Extracts several values from a given nested msg field and returns a dictionary of + elements +""" +# TODO(elvioaruta): after refactoring and using Node as classes +# remove the node from this function and figure out a better way +# to log warnings inside +def extract_values_as_dict(msg, mapping, node): + values = {} + base_getter_fn = attrgetter(mapping['field']) + base_value = base_getter_fn(msg) + fields = mapping.get('mapping_options', {}).get('fields') + for field in fields: + getter_fn = attrgetter(field) + try: + val = getter_fn(base_value) + # Time values aren't cleanly serialized into JSON. + # Convert them to milliseconds + if isinstance(val, Time): + val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 + # TODO(diegobatt): Make it possible to use a different key than the field + values[field] = val + except AttributeError as e: + node.get_logger().warning(f"Couldn\'t get attribute {field}: {e}") + filter_fn = mapping.get('mapping_options', {}).get('filter') + return values if not filter_fn or eval(filter_fn)(values) else None + +""" +Processes a scalar value before publishing according to mapping options + - If a 'filter' function is provided, it returns the value only if the + result of passing the field value through the filter function is True, + otherwise it returns None +""" +def process_single_field(field_value, mapping): + filter_fn = mapping.get('mapping_options', {}).get('filter') + return field_value if not filter_fn or eval(filter_fn)(field_value) else None + +""" +Processes a given array field from the ROS message and: + - Filters it using the 'filter' function (if provided) + - For each element, it gets the set of keys defined by array_fields + - Returns a key/value with the value being a json string containing + the resulting array of objects. + +Note that the array fields to retrieve should have a String value in order to +serialize them properly. +""" +def process_array(field, mapping): + # Output array of objects + values = { + 'data': [] + } + + filter_fn = mapping.get('mapping_options', {}).get('filter') + if filter_fn: + # Apply the filter function if any + filtered_array = list(filter(eval(filter_fn), field)) + else: + filtered_array = field + + # Get only the array_fields specified. If none was specified, return the whole array + # TODO(FlorGrosso): check that the array fields are Strings and discard those which + # are not. + if 'fields' in mapping.get('mapping_options', {}): + fields = mapping['mapping_options']['fields'] + values['data'] = [{f: extract_value(elem, attrgetter(f)) for f in fields} for elem in filtered_array] + else: + values['data'] = filtered_array + return json.dumps(values, cls=ROS2JSONEncoder) + +""" +Transforms the ROS message to json and: + - Filters out fields on the top level of the json only. +""" +def serialize(msg, mapping): + # TODO: design filtering support and implement it. It should be possible + # to leverage jq to do so. However, this would require adding a new rosdep + # rule for `pyjq`: https://pypi.org/project/pyjq/. + # filter = mapping.get('mapping_options', {}).get('filter') + + # Get fields configuration + fields = mapping.get('mapping_options', {}).get('fields') + # Transform ROS message to dict + msg_dict = message_to_ordereddict(msg) + + # Shrink output by keeping only selected fields or keys + if fields: + msg_dict = { k: v for k, v in msg_dict.items() if k in fields} + + return msg_dict + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml new file mode 100644 index 0000000..e9ae845 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml new file mode 100644 index 0000000..e9ae845 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml new file mode 100644 index 0000000..e331473 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml new file mode 100644 index 0000000..e331473 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml new file mode 100644 index 0000000..1527175 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml new file mode 100644 index 0000000..1527175 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/setup_20241213161527.py b/.history/inorbit_republisher/setup_20241213161527.py new file mode 100644 index 0000000..5a4ee20 --- /dev/null +++ b/.history/inorbit_republisher/setup_20241213161527.py @@ -0,0 +1,30 @@ +from setuptools import setup +import os +from glob import glob + +package_name = 'inorbit_republisher' + +setup( + name=package_name, + version='0.4.1', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + (os.path.join('share', package_name), glob('launch/*')), + (os.path.join('share', package_name, 'config'), glob('config/*')) + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='InOrbit', + maintainer_email='support@inorbit.ai', + description='ROS2 to InOrbit topic republisher', + license='MIT', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'republisher = inorbit_republisher.republisher:main' + ], + }, +) diff --git a/.history/inorbit_republisher/setup_20241213172142.py b/.history/inorbit_republisher/setup_20241213172142.py new file mode 100644 index 0000000..5a4ee20 --- /dev/null +++ b/.history/inorbit_republisher/setup_20241213172142.py @@ -0,0 +1,30 @@ +from setuptools import setup +import os +from glob import glob + +package_name = 'inorbit_republisher' + +setup( + name=package_name, + version='0.4.1', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + (os.path.join('share', package_name), glob('launch/*')), + (os.path.join('share', package_name, 'config'), glob('config/*')) + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='InOrbit', + maintainer_email='support@inorbit.ai', + description='ROS2 to InOrbit topic republisher', + license='MIT', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'republisher = inorbit_republisher.republisher:main' + ], + }, +) diff --git a/.history/inorbit_republisher/setup_20241213172214.py b/.history/inorbit_republisher/setup_20241213172214.py new file mode 100644 index 0000000..5a4ee20 --- /dev/null +++ b/.history/inorbit_republisher/setup_20241213172214.py @@ -0,0 +1,30 @@ +from setuptools import setup +import os +from glob import glob + +package_name = 'inorbit_republisher' + +setup( + name=package_name, + version='0.4.1', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + (os.path.join('share', package_name), glob('launch/*')), + (os.path.join('share', package_name, 'config'), glob('config/*')) + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='InOrbit', + maintainer_email='support@inorbit.ai', + description='ROS2 to InOrbit topic republisher', + license='MIT', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'republisher = inorbit_republisher.republisher:main' + ], + }, +) diff --git a/.history/inorbit_republisher/test/README_20241213162953.md b/.history/inorbit_republisher/test/README_20241213162953.md new file mode 100644 index 0000000..e69de29 diff --git a/.history/inorbit_republisher/test/README_20241213163651.md b/.history/inorbit_republisher/test/README_20241213163651.md new file mode 100644 index 0000000..01379ea --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241213163651.md @@ -0,0 +1,10 @@ +1. generar nuestro propio rosbag, para eso: +ros2 bag record /my_magnetic_field /my_temperature +y en otro tab +corremos el archivo fake_sensor_sample_rep-pu + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + diff --git a/.history/inorbit_republisher/test/README_20241213175317.md b/.history/inorbit_republisher/test/README_20241213175317.md new file mode 100644 index 0000000..bbfca11 --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241213175317.md @@ -0,0 +1,17 @@ +1. generar nuestro propio rosbag, para eso: +ros2 bag record /my_magnetic_field /my_temperature +y en otro tab +corremos el archivo fake_sensor_sample_rep-pu + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + con ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recorde desde ros2_ws/src, lo movi a donde queria con mv "file" path +Corremos el package: + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: \ No newline at end of file diff --git a/.history/inorbit_republisher/test/README_20241213175932.md b/.history/inorbit_republisher/test/README_20241213175932.md new file mode 100644 index 0000000..9229e8f --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241213175932.md @@ -0,0 +1,22 @@ +1. generar nuestro propio rosbag, para eso: +ros2 bag record /my_magnetic_field /my_temperature +y en otro tab +corremos el archivo fake_sensor_sample_rep-pu + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + con ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recorde desde ros2_ws/src, lo movi a donde queria con mv "file" path +Corremos el package: + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + + 3.Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature diff --git a/.history/inorbit_republisher/test/README_20241213180602.md b/.history/inorbit_republisher/test/README_20241213180602.md new file mode 100644 index 0000000..6631616 --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241213180602.md @@ -0,0 +1,26 @@ +1. A. generar nuestro propio rosbag, para eso: + ros2 bag record /my_magnetic_field /my_temperature + B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + usando ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path +2. Corremos el package: + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + +3. Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature + +IRi del lunes: + Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: + ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" +Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo diff --git a/.history/inorbit_republisher/test/README_20241213180720.md b/.history/inorbit_republisher/test/README_20241213180720.md new file mode 100644 index 0000000..f4c50b0 --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241213180720.md @@ -0,0 +1,27 @@ +1. A. generar nuestro propio rosbag, para eso: + ros2 bag record /my_magnetic_field /my_temperature + B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + usando ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path +2. Corremos el package: + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + +3. Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature + +IRi del lunes: + Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: + ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" +Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo +Tengo que crear un docker en humble xq elimine el mio g \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/config_20241213162657.yaml b/.history/inorbit_republisher/test/sample_data/config_20241213162657.yaml new file mode 100644 index 0000000..e69de29 diff --git a/.history/inorbit_republisher/test/sample_data/config_20241213165503.yaml b/.history/inorbit_republisher/test/sample_data/config_20241213165503.yaml new file mode 100644 index 0000000..c7eccf9 --- /dev/null +++ b/.history/inorbit_republisher/test/sample_data/config_20241213165503.yaml @@ -0,0 +1,23 @@ +republishers: + - topic: "/my_magnetic_field" + msg_type: "sensor_msgs/MagneticField" + mappings: + - field: "magnetic_field.x" + out: + topic: "/inorbit/custom_data" + key: "my_magnetic_field_x" + - field: "magnetic_field.y" + out: + topic: "/inorbit/custom_data" + key: "my_magnetic_field_y" + - field: "magnetic_field.z" + out: + topic: "/inorbit/custom_data" + key: "my_magnetic_field_z" + - topic: "/my_temperature" + msg_type: "sensor_msgs/Temperature" + mappings: + - field: "temperature" + out: + topic: "/inorbit/custom_data" + key: "my_temperature" \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml b/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml new file mode 100644 index 0000000..e9ae845 --- /dev/null +++ b/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml b/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml new file mode 100644 index 0000000..e331473 --- /dev/null +++ b/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162714.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162714.xml new file mode 100644 index 0000000..e69de29 diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml new file mode 100644 index 0000000..62822e8 --- /dev/null +++ b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml new file mode 100644 index 0000000..31d7d22 --- /dev/null +++ b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml new file mode 100644 index 0000000..31d7d22 --- /dev/null +++ b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml new file mode 100644 index 0000000..e9ae845 --- /dev/null +++ b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/inorbit_republisher/launch/sample_data.launch.xml b/inorbit_republisher/launch/sample_data.launch.xml new file mode 100644 index 0000000..1527175 --- /dev/null +++ b/inorbit_republisher/launch/sample_data.launch.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md new file mode 100644 index 0000000..f4c50b0 --- /dev/null +++ b/inorbit_republisher/test/README.md @@ -0,0 +1,27 @@ +1. A. generar nuestro propio rosbag, para eso: + ros2 bag record /my_magnetic_field /my_temperature + B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + usando ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path +2. Corremos el package: + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + +3. Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature + +IRi del lunes: + Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: + ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" +Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo +Tengo que crear un docker en humble xq elimine el mio g \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/build/.built_by b/inorbit_republisher/test/sample_data/build/.built_by new file mode 100644 index 0000000..06e74ac --- /dev/null +++ b/inorbit_republisher/test/sample_data/build/.built_by @@ -0,0 +1 @@ +colcon diff --git a/inorbit_republisher/test/sample_data/build/COLCON_IGNORE b/inorbit_republisher/test/sample_data/build/COLCON_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/inorbit_republisher/test/sample_data/config.yaml b/inorbit_republisher/test/sample_data/config.yaml new file mode 100644 index 0000000..c7eccf9 --- /dev/null +++ b/inorbit_republisher/test/sample_data/config.yaml @@ -0,0 +1,23 @@ +republishers: + - topic: "/my_magnetic_field" + msg_type: "sensor_msgs/MagneticField" + mappings: + - field: "magnetic_field.x" + out: + topic: "/inorbit/custom_data" + key: "my_magnetic_field_x" + - field: "magnetic_field.y" + out: + topic: "/inorbit/custom_data" + key: "my_magnetic_field_y" + - field: "magnetic_field.z" + out: + topic: "/inorbit/custom_data" + key: "my_magnetic_field_z" + - topic: "/my_temperature" + msg_type: "sensor_msgs/Temperature" + mappings: + - field: "temperature" + out: + topic: "/inorbit/custom_data" + key: "my_temperature" \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/hardcodedRosbag/metadata.yaml b/inorbit_republisher/test/sample_data/hardcodedRosbag/metadata.yaml new file mode 100644 index 0000000..d4b7cc5 --- /dev/null +++ b/inorbit_republisher/test/sample_data/hardcodedRosbag/metadata.yaml @@ -0,0 +1,32 @@ +rosbag2_bagfile_information: + version: 5 + storage_identifier: sqlite3 + duration: + nanoseconds: 16005861016 + starting_time: + nanoseconds_since_epoch: 1734119100085674077 + message_count: 34 + topics_with_message_count: + - topic_metadata: + name: /my_temperature + type: sensor_msgs/msg/Temperature + serialization_format: cdr + offered_qos_profiles: "- history: 3\n depth: 0\n reliability: 1\n durability: 2\n deadline:\n sec: 9223372036\n nsec: 854775807\n lifespan:\n sec: 9223372036\n nsec: 854775807\n liveliness: 1\n liveliness_lease_duration:\n sec: 9223372036\n nsec: 854775807\n avoid_ros_namespace_conventions: false" + message_count: 17 + - topic_metadata: + name: /my_magnetic_field + type: sensor_msgs/msg/MagneticField + serialization_format: cdr + offered_qos_profiles: "- history: 3\n depth: 0\n reliability: 1\n durability: 2\n deadline:\n sec: 9223372036\n nsec: 854775807\n lifespan:\n sec: 9223372036\n nsec: 854775807\n liveliness: 1\n liveliness_lease_duration:\n sec: 9223372036\n nsec: 854775807\n avoid_ros_namespace_conventions: false" + message_count: 17 + compression_format: "" + compression_mode: "" + relative_file_paths: + - rosbag2_2024_12_13-19_33_34_0.db3 + files: + - path: rosbag2_2024_12_13-19_33_34_0.db3 + starting_time: + nanoseconds_since_epoch: 1734119100085674077 + duration: + nanoseconds: 16005861016 + message_count: 34 \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 b/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 new file mode 100644 index 0000000000000000000000000000000000000000..c4f6806609bbe1641df270d70c90b3de9961b0d1 GIT binary patch literal 24576 zcmeI4eNYtV9mn_HU*L9m5$+B+U0zJUgbIg-*WiI(7!VbYvuH-WtlS=Ky*F{CQ_V}yuqNu5X*FppHZ{?q)uCgX5=p9!jfs8sV0VwpIxUvz zAI`HQcl+IEf6w!|4~H}R+k@t%jTA%ToU`NRZ z@GOhjzuoREyBT7Qm*h|5pH<_tI%{eh?ZPDalpCz$wAa}kc$1@kQH^5-zRpaE#$ZZe=#C=hddhYz%hxa)s#(;sfo05kv%Km*VKGyn}i1JD3801ZF` z&;T@W7aQQN|K*0I2zmfKzzrIJ2A~0G02+V>paEzA8h{3%0chaAH?YYe*C6-JPu)^K z+t=-4NMDc)5llyjq)9&=2)TT88$BC5%yx=Ht?p1E-VQ#V9SC(-;3aw-cauS;y#g-+ zyCKp`5o;(f#elJ5Zmc6DWNY+X!tJH}WChsAahhzcz{{=Hl9EzuQON_*WB%yDvbl3g zOXrpqm4ahl%0tpY!aup1PJrSEzo{_B;idTO@{$Bix;QZI)Ay5^l;{jlZWs6QbnavR z0I8L9wFdm1q@SA!tmGlQG`Xoora_A9#-;j*Hb2RL-%;>Tq}Ltqb?2poI`(5YMSfIH1rlK`G~=67r6OEI*Wo_KEU&dL~Y zqX3?FrmK9VRMF6{B3EX5N9JiYhyR{&afXfgW%x= z>B1!OAd}73Bmq2khGl@IE-PoZ&C1n&=*BuX(n>eyQ}?NaOyr$GeoC-UBwD*EVNnKJm}Y+G0J<`*t( z*0XaCJ3Zfx=%>zjq6pspS8G6u;nt~b^gv1MTO~mRZ$H_0Nva6HSpL+~+A9M?+g9y% zxjvtFeD$uI7qX302d)>v3!fd#kYcbI&MzB07yJLXP6RKk+;@*uQEAJKL%&gHvr5yt zZN(ci*q7-l)h%82)PZXS@SM+6KJ!X3jQWO$6Yq;Pt`WdrHYV-cTRkNS%R%< zNp5lXb|Y)v&~#{D*$ft$qRpxn!H*C}e=Wsu*`m@ut$jd{6_%?+@FN;izf{rpkcIv} zr-k(@PcPHH?32OVO#TSw}!9Bf-6Mu^(!1YsiKD~uQmJM zGqcA@wz+3fmaTpJOJ$}!RCx9Ot9Ywi1YfYcKUIq1*t&A``Q+I5xJ(4E{{4%qq>2V! z3Cv;(a#%yb9^dfv>1;6lo#*Qw(@vRjJ$U6gXdQz61N#eh9y^V(*z4EF_6+$FK_fxBIi zB?NFAB9jl?{eTQ1fIh!@JVYDrCLw@Ex{(iDM?0MlT&FsX4_wQ5nh-!MIF%1vPd0@Q zT(32GJVcwGNkRb4OpFg)R}mEg=oT9Iz_slXg#g-d34GxCVtOHfewS`ML>o_9K5z{s n4IjA9j#>zyW252&*E&%O0klLEeBgQ$@&tui2fkT3T+iX(!}-HT literal 0 HcmV?d00001 diff --git a/inorbit_republisher/test/sample_data/install/.colcon_install_layout b/inorbit_republisher/test/sample_data/install/.colcon_install_layout new file mode 100644 index 0000000..3aad533 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/.colcon_install_layout @@ -0,0 +1 @@ +isolated diff --git a/inorbit_republisher/test/sample_data/install/COLCON_IGNORE b/inorbit_republisher/test/sample_data/install/COLCON_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py new file mode 100644 index 0000000..3c6d9e8 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py @@ -0,0 +1,407 @@ +# Copyright 2016-2019 Dirk Thomas +# Licensed under the Apache License, Version 2.0 + +import argparse +from collections import OrderedDict +import os +from pathlib import Path +import sys + + +FORMAT_STR_COMMENT_LINE = '# {comment}' +FORMAT_STR_SET_ENV_VAR = 'Set-Item -Path "Env:{name}" -Value "{value}"' +FORMAT_STR_USE_ENV_VAR = '$env:{name}' +FORMAT_STR_INVOKE_SCRIPT = '_colcon_prefix_powershell_source_script "{script_path}"' # noqa: E501 +FORMAT_STR_REMOVE_LEADING_SEPARATOR = '' # noqa: E501 +FORMAT_STR_REMOVE_TRAILING_SEPARATOR = '' # noqa: E501 + +DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' +DSV_TYPE_SET = 'set' +DSV_TYPE_SET_IF_UNSET = 'set-if-unset' +DSV_TYPE_SOURCE = 'source' + + +def main(argv=sys.argv[1:]): # noqa: D103 + parser = argparse.ArgumentParser( + description='Output shell commands for the packages in topological ' + 'order') + parser.add_argument( + 'primary_extension', + help='The file extension of the primary shell') + parser.add_argument( + 'additional_extension', nargs='?', + help='The additional file extension to be considered') + parser.add_argument( + '--merged-install', action='store_true', + help='All install prefixes are merged into a single location') + args = parser.parse_args(argv) + + packages = get_packages(Path(__file__).parent, args.merged_install) + + ordered_packages = order_packages(packages) + for pkg_name in ordered_packages: + if _include_comments(): + print( + FORMAT_STR_COMMENT_LINE.format_map( + {'comment': 'Package: ' + pkg_name})) + prefix = os.path.abspath(os.path.dirname(__file__)) + if not args.merged_install: + prefix = os.path.join(prefix, pkg_name) + for line in get_commands( + pkg_name, prefix, args.primary_extension, + args.additional_extension + ): + print(line) + + for line in _remove_ending_separators(): + print(line) + + +def get_packages(prefix_path, merged_install): + """ + Find packages based on colcon-specific files created during installation. + + :param Path prefix_path: The install prefix path of all packages + :param bool merged_install: The flag if the packages are all installed + directly in the prefix or if each package is installed in a subdirectory + named after the package + :returns: A mapping from the package name to the set of runtime + dependencies + :rtype: dict + """ + packages = {} + # since importing colcon_core isn't feasible here the following constant + # must match colcon_core.location.get_relative_package_index_path() + subdirectory = 'share/colcon-core/packages' + if merged_install: + # return if workspace is empty + if not (prefix_path / subdirectory).is_dir(): + return packages + # find all files in the subdirectory + for p in (prefix_path / subdirectory).iterdir(): + if not p.is_file(): + continue + if p.name.startswith('.'): + continue + add_package_runtime_dependencies(p, packages) + else: + # for each subdirectory look for the package specific file + for p in prefix_path.iterdir(): + if not p.is_dir(): + continue + if p.name.startswith('.'): + continue + p = p / subdirectory / p.name + if p.is_file(): + add_package_runtime_dependencies(p, packages) + + # remove unknown dependencies + pkg_names = set(packages.keys()) + for k in packages.keys(): + packages[k] = {d for d in packages[k] if d in pkg_names} + + return packages + + +def add_package_runtime_dependencies(path, packages): + """ + Check the path and if it exists extract the packages runtime dependencies. + + :param Path path: The resource file containing the runtime dependencies + :param dict packages: A mapping from package names to the sets of runtime + dependencies to add to + """ + content = path.read_text() + dependencies = set(content.split(os.pathsep) if content else []) + packages[path.name] = dependencies + + +def order_packages(packages): + """ + Order packages topologically. + + :param dict packages: A mapping from package name to the set of runtime + dependencies + :returns: The package names + :rtype: list + """ + # select packages with no dependencies in alphabetical order + to_be_ordered = list(packages.keys()) + ordered = [] + while to_be_ordered: + pkg_names_without_deps = [ + name for name in to_be_ordered if not packages[name]] + if not pkg_names_without_deps: + reduce_cycle_set(packages) + raise RuntimeError( + 'Circular dependency between: ' + ', '.join(sorted(packages))) + pkg_names_without_deps.sort() + pkg_name = pkg_names_without_deps[0] + to_be_ordered.remove(pkg_name) + ordered.append(pkg_name) + # remove item from dependency lists + for k in list(packages.keys()): + if pkg_name in packages[k]: + packages[k].remove(pkg_name) + return ordered + + +def reduce_cycle_set(packages): + """ + Reduce the set of packages to the ones part of the circular dependency. + + :param dict packages: A mapping from package name to the set of runtime + dependencies which is modified in place + """ + last_depended = None + while len(packages) > 0: + # get all remaining dependencies + depended = set() + for pkg_name, dependencies in packages.items(): + depended = depended.union(dependencies) + # remove all packages which are not dependent on + for name in list(packages.keys()): + if name not in depended: + del packages[name] + if last_depended: + # if remaining packages haven't changed return them + if last_depended == depended: + return packages.keys() + # otherwise reduce again + last_depended = depended + + +def _include_comments(): + # skipping comment lines when COLCON_TRACE is not set speeds up the + # processing especially on Windows + return bool(os.environ.get('COLCON_TRACE')) + + +def get_commands(pkg_name, prefix, primary_extension, additional_extension): + commands = [] + package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') + if os.path.exists(package_dsv_path): + commands += process_dsv_file( + package_dsv_path, prefix, primary_extension, additional_extension) + return commands + + +def process_dsv_file( + dsv_path, prefix, primary_extension=None, additional_extension=None +): + commands = [] + if _include_comments(): + commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) + with open(dsv_path, 'r') as h: + content = h.read() + lines = content.splitlines() + + basenames = OrderedDict() + for i, line in enumerate(lines): + # skip over empty or whitespace-only lines + if not line.strip(): + continue + # skip over comments + if line.startswith('#'): + continue + try: + type_, remainder = line.split(';', 1) + except ValueError: + raise RuntimeError( + "Line %d in '%s' doesn't contain a semicolon separating the " + 'type from the arguments' % (i + 1, dsv_path)) + if type_ != DSV_TYPE_SOURCE: + # handle non-source lines + try: + commands += handle_dsv_types_except_source( + type_, remainder, prefix) + except RuntimeError as e: + raise RuntimeError( + "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e + else: + # group remaining source lines by basename + path_without_ext, ext = os.path.splitext(remainder) + if path_without_ext not in basenames: + basenames[path_without_ext] = set() + assert ext.startswith('.') + ext = ext[1:] + if ext in (primary_extension, additional_extension): + basenames[path_without_ext].add(ext) + + # add the dsv extension to each basename if the file exists + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if os.path.exists(basename + '.dsv'): + extensions.add('dsv') + + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if 'dsv' in extensions: + # process dsv files recursively + commands += process_dsv_file( + basename + '.dsv', prefix, primary_extension=primary_extension, + additional_extension=additional_extension) + elif primary_extension in extensions and len(extensions) == 1: + # source primary-only files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + primary_extension})] + elif additional_extension in extensions: + # source non-primary files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + additional_extension})] + + return commands + + +def handle_dsv_types_except_source(type_, remainder, prefix): + commands = [] + if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): + try: + env_name, value = remainder.split(';', 1) + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the value') + try_prefixed_value = os.path.join(prefix, value) if value else prefix + if os.path.exists(try_prefixed_value): + value = try_prefixed_value + if type_ == DSV_TYPE_SET: + commands += _set(env_name, value) + elif type_ == DSV_TYPE_SET_IF_UNSET: + commands += _set_if_unset(env_name, value) + else: + assert False + elif type_ in ( + DSV_TYPE_APPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS + ): + try: + env_name_and_values = remainder.split(';') + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the values') + env_name = env_name_and_values[0] + values = env_name_and_values[1:] + for value in values: + if not value: + value = prefix + elif not os.path.isabs(value): + value = os.path.join(prefix, value) + if ( + type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and + not os.path.exists(value) + ): + comment = f'skip extending {env_name} with not existing ' \ + f'path: {value}' + if _include_comments(): + commands.append( + FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) + elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: + commands += _append_unique_value(env_name, value) + else: + commands += _prepend_unique_value(env_name, value) + else: + raise RuntimeError( + 'contains an unknown environment hook type: ' + type_) + return commands + + +env_state = {} + + +def _append_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # append even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional leading separator + extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': extend + value}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +def _prepend_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # prepend even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional trailing separator + extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value + extend}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +# generate commands for removing prepended underscores +def _remove_ending_separators(): + # do nothing if the shell extension does not implement the logic + if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: + return [] + + global env_state + commands = [] + for name in env_state: + # skip variables that already had values before this script started prepending + if name in os.environ: + continue + commands += [ + FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), + FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] + return commands + + +def _set(name, value): + global env_state + env_state[name] = value + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + return [line] + + +def _set_if_unset(name, value): + global env_state + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + if env_state.get(name, os.environ.get(name)): + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +if __name__ == '__main__': # pragma: no cover + try: + rc = main() + except RuntimeError as e: + print(str(e), file=sys.stderr) + rc = 1 + sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py new file mode 100644 index 0000000..f67eaa9 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py @@ -0,0 +1,407 @@ +# Copyright 2016-2019 Dirk Thomas +# Licensed under the Apache License, Version 2.0 + +import argparse +from collections import OrderedDict +import os +from pathlib import Path +import sys + + +FORMAT_STR_COMMENT_LINE = '# {comment}' +FORMAT_STR_SET_ENV_VAR = 'export {name}="{value}"' +FORMAT_STR_USE_ENV_VAR = '${name}' +FORMAT_STR_INVOKE_SCRIPT = 'COLCON_CURRENT_PREFIX="{prefix}" _colcon_prefix_sh_source_script "{script_path}"' # noqa: E501 +FORMAT_STR_REMOVE_LEADING_SEPARATOR = 'if [ "$(echo -n ${name} | head -c 1)" = ":" ]; then export {name}=${{{name}#?}} ; fi' # noqa: E501 +FORMAT_STR_REMOVE_TRAILING_SEPARATOR = 'if [ "$(echo -n ${name} | tail -c 1)" = ":" ]; then export {name}=${{{name}%?}} ; fi' # noqa: E501 + +DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' +DSV_TYPE_SET = 'set' +DSV_TYPE_SET_IF_UNSET = 'set-if-unset' +DSV_TYPE_SOURCE = 'source' + + +def main(argv=sys.argv[1:]): # noqa: D103 + parser = argparse.ArgumentParser( + description='Output shell commands for the packages in topological ' + 'order') + parser.add_argument( + 'primary_extension', + help='The file extension of the primary shell') + parser.add_argument( + 'additional_extension', nargs='?', + help='The additional file extension to be considered') + parser.add_argument( + '--merged-install', action='store_true', + help='All install prefixes are merged into a single location') + args = parser.parse_args(argv) + + packages = get_packages(Path(__file__).parent, args.merged_install) + + ordered_packages = order_packages(packages) + for pkg_name in ordered_packages: + if _include_comments(): + print( + FORMAT_STR_COMMENT_LINE.format_map( + {'comment': 'Package: ' + pkg_name})) + prefix = os.path.abspath(os.path.dirname(__file__)) + if not args.merged_install: + prefix = os.path.join(prefix, pkg_name) + for line in get_commands( + pkg_name, prefix, args.primary_extension, + args.additional_extension + ): + print(line) + + for line in _remove_ending_separators(): + print(line) + + +def get_packages(prefix_path, merged_install): + """ + Find packages based on colcon-specific files created during installation. + + :param Path prefix_path: The install prefix path of all packages + :param bool merged_install: The flag if the packages are all installed + directly in the prefix or if each package is installed in a subdirectory + named after the package + :returns: A mapping from the package name to the set of runtime + dependencies + :rtype: dict + """ + packages = {} + # since importing colcon_core isn't feasible here the following constant + # must match colcon_core.location.get_relative_package_index_path() + subdirectory = 'share/colcon-core/packages' + if merged_install: + # return if workspace is empty + if not (prefix_path / subdirectory).is_dir(): + return packages + # find all files in the subdirectory + for p in (prefix_path / subdirectory).iterdir(): + if not p.is_file(): + continue + if p.name.startswith('.'): + continue + add_package_runtime_dependencies(p, packages) + else: + # for each subdirectory look for the package specific file + for p in prefix_path.iterdir(): + if not p.is_dir(): + continue + if p.name.startswith('.'): + continue + p = p / subdirectory / p.name + if p.is_file(): + add_package_runtime_dependencies(p, packages) + + # remove unknown dependencies + pkg_names = set(packages.keys()) + for k in packages.keys(): + packages[k] = {d for d in packages[k] if d in pkg_names} + + return packages + + +def add_package_runtime_dependencies(path, packages): + """ + Check the path and if it exists extract the packages runtime dependencies. + + :param Path path: The resource file containing the runtime dependencies + :param dict packages: A mapping from package names to the sets of runtime + dependencies to add to + """ + content = path.read_text() + dependencies = set(content.split(os.pathsep) if content else []) + packages[path.name] = dependencies + + +def order_packages(packages): + """ + Order packages topologically. + + :param dict packages: A mapping from package name to the set of runtime + dependencies + :returns: The package names + :rtype: list + """ + # select packages with no dependencies in alphabetical order + to_be_ordered = list(packages.keys()) + ordered = [] + while to_be_ordered: + pkg_names_without_deps = [ + name for name in to_be_ordered if not packages[name]] + if not pkg_names_without_deps: + reduce_cycle_set(packages) + raise RuntimeError( + 'Circular dependency between: ' + ', '.join(sorted(packages))) + pkg_names_without_deps.sort() + pkg_name = pkg_names_without_deps[0] + to_be_ordered.remove(pkg_name) + ordered.append(pkg_name) + # remove item from dependency lists + for k in list(packages.keys()): + if pkg_name in packages[k]: + packages[k].remove(pkg_name) + return ordered + + +def reduce_cycle_set(packages): + """ + Reduce the set of packages to the ones part of the circular dependency. + + :param dict packages: A mapping from package name to the set of runtime + dependencies which is modified in place + """ + last_depended = None + while len(packages) > 0: + # get all remaining dependencies + depended = set() + for pkg_name, dependencies in packages.items(): + depended = depended.union(dependencies) + # remove all packages which are not dependent on + for name in list(packages.keys()): + if name not in depended: + del packages[name] + if last_depended: + # if remaining packages haven't changed return them + if last_depended == depended: + return packages.keys() + # otherwise reduce again + last_depended = depended + + +def _include_comments(): + # skipping comment lines when COLCON_TRACE is not set speeds up the + # processing especially on Windows + return bool(os.environ.get('COLCON_TRACE')) + + +def get_commands(pkg_name, prefix, primary_extension, additional_extension): + commands = [] + package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') + if os.path.exists(package_dsv_path): + commands += process_dsv_file( + package_dsv_path, prefix, primary_extension, additional_extension) + return commands + + +def process_dsv_file( + dsv_path, prefix, primary_extension=None, additional_extension=None +): + commands = [] + if _include_comments(): + commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) + with open(dsv_path, 'r') as h: + content = h.read() + lines = content.splitlines() + + basenames = OrderedDict() + for i, line in enumerate(lines): + # skip over empty or whitespace-only lines + if not line.strip(): + continue + # skip over comments + if line.startswith('#'): + continue + try: + type_, remainder = line.split(';', 1) + except ValueError: + raise RuntimeError( + "Line %d in '%s' doesn't contain a semicolon separating the " + 'type from the arguments' % (i + 1, dsv_path)) + if type_ != DSV_TYPE_SOURCE: + # handle non-source lines + try: + commands += handle_dsv_types_except_source( + type_, remainder, prefix) + except RuntimeError as e: + raise RuntimeError( + "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e + else: + # group remaining source lines by basename + path_without_ext, ext = os.path.splitext(remainder) + if path_without_ext not in basenames: + basenames[path_without_ext] = set() + assert ext.startswith('.') + ext = ext[1:] + if ext in (primary_extension, additional_extension): + basenames[path_without_ext].add(ext) + + # add the dsv extension to each basename if the file exists + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if os.path.exists(basename + '.dsv'): + extensions.add('dsv') + + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if 'dsv' in extensions: + # process dsv files recursively + commands += process_dsv_file( + basename + '.dsv', prefix, primary_extension=primary_extension, + additional_extension=additional_extension) + elif primary_extension in extensions and len(extensions) == 1: + # source primary-only files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + primary_extension})] + elif additional_extension in extensions: + # source non-primary files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + additional_extension})] + + return commands + + +def handle_dsv_types_except_source(type_, remainder, prefix): + commands = [] + if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): + try: + env_name, value = remainder.split(';', 1) + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the value') + try_prefixed_value = os.path.join(prefix, value) if value else prefix + if os.path.exists(try_prefixed_value): + value = try_prefixed_value + if type_ == DSV_TYPE_SET: + commands += _set(env_name, value) + elif type_ == DSV_TYPE_SET_IF_UNSET: + commands += _set_if_unset(env_name, value) + else: + assert False + elif type_ in ( + DSV_TYPE_APPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS + ): + try: + env_name_and_values = remainder.split(';') + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the values') + env_name = env_name_and_values[0] + values = env_name_and_values[1:] + for value in values: + if not value: + value = prefix + elif not os.path.isabs(value): + value = os.path.join(prefix, value) + if ( + type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and + not os.path.exists(value) + ): + comment = f'skip extending {env_name} with not existing ' \ + f'path: {value}' + if _include_comments(): + commands.append( + FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) + elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: + commands += _append_unique_value(env_name, value) + else: + commands += _prepend_unique_value(env_name, value) + else: + raise RuntimeError( + 'contains an unknown environment hook type: ' + type_) + return commands + + +env_state = {} + + +def _append_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # append even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional leading separator + extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': extend + value}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +def _prepend_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # prepend even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional trailing separator + extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value + extend}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +# generate commands for removing prepended underscores +def _remove_ending_separators(): + # do nothing if the shell extension does not implement the logic + if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: + return [] + + global env_state + commands = [] + for name in env_state: + # skip variables that already had values before this script started prepending + if name in os.environ: + continue + commands += [ + FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), + FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] + return commands + + +def _set(name, value): + global env_state + env_state[name] = value + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + return [line] + + +def _set_if_unset(name, value): + global env_state + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + if env_state.get(name, os.environ.get(name)): + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +if __name__ == '__main__': # pragma: no cover + try: + rc = main() + except RuntimeError as e: + print(str(e), file=sys.stderr) + rc = 1 + sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/local_setup.bash b/inorbit_republisher/test/sample_data/install/local_setup.bash new file mode 100644 index 0000000..03f0025 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.bash @@ -0,0 +1,121 @@ +# generated from colcon_bash/shell/template/prefix.bash.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# a bash script is able to determine its own path if necessary +if [ -z "$COLCON_CURRENT_PREFIX" ]; then + _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" +else + _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +fi + +# function to prepend a value to a variable +# which uses colons as separators +# duplicates as well as trailing separators are avoided +# first argument: the name of the result variable +# second argument: the value to be prepended +_colcon_prefix_bash_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + + # get values from variable + eval _values=\"\$$_listname\" + # backup the field separator + _colcon_prefix_bash_prepend_unique_value_IFS="$IFS" + IFS=":" + # start with the new value + _all_values="$_value" + _contained_value="" + # iterate over existing values in the variable + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + # ignore duplicates of _value + if [ "$_item" = "$_value" ]; then + _contained_value=1 + continue + fi + # keep non-duplicate values + _all_values="$_all_values:$_item" + done + unset _item + if [ -z "$_contained_value" ]; then + if [ -n "$COLCON_TRACE" ]; then + if [ "$_all_values" = "$_value" ]; then + echo "export $_listname=$_value" + else + echo "export $_listname=$_value:\$$_listname" + fi + fi + fi + unset _contained_value + # restore the field separator + IFS="$_colcon_prefix_bash_prepend_unique_value_IFS" + unset _colcon_prefix_bash_prepend_unique_value_IFS + # export the updated variable + eval export $_listname=\"$_all_values\" + unset _all_values + unset _values + + unset _value + unset _listname +} + +# add this prefix to the COLCON_PREFIX_PATH +_colcon_prefix_bash_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX" +unset _colcon_prefix_bash_prepend_unique_value + +# check environment variable for custom Python executable +if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then + if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then + echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" + return 1 + fi + _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" +else + # try the Python executable known at configure time + _colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if [ ! -f "$_colcon_python_executable" ]; then + if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then + echo "error: unable to find python3 executable" + return 1 + fi + _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` + fi +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# get all commands in topological order +_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh bash)" +unset _colcon_python_executable +if [ -n "$COLCON_TRACE" ]; then + echo "$(declare -f _colcon_prefix_sh_source_script)" + echo "# Execute generated script:" + echo "# <<<" + echo "${_colcon_ordered_commands}" + echo "# >>>" + echo "unset _colcon_prefix_sh_source_script" +fi +eval "${_colcon_ordered_commands}" +unset _colcon_ordered_commands + +unset _colcon_prefix_sh_source_script + +unset _colcon_prefix_bash_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.ps1 b/inorbit_republisher/test/sample_data/install/local_setup.ps1 new file mode 100644 index 0000000..6f68c8d --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.ps1 @@ -0,0 +1,55 @@ +# generated from colcon_powershell/shell/template/prefix.ps1.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# check environment variable for custom Python executable +if ($env:COLCON_PYTHON_EXECUTABLE) { + if (!(Test-Path "$env:COLCON_PYTHON_EXECUTABLE" -PathType Leaf)) { + echo "error: COLCON_PYTHON_EXECUTABLE '$env:COLCON_PYTHON_EXECUTABLE' doesn't exist" + exit 1 + } + $_colcon_python_executable="$env:COLCON_PYTHON_EXECUTABLE" +} else { + # use the Python executable known at configure time + $_colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if (!(Test-Path "$_colcon_python_executable" -PathType Leaf)) { + if (!(Get-Command "python3" -ErrorAction SilentlyContinue)) { + echo "error: unable to find python3 executable" + exit 1 + } + $_colcon_python_executable="python3" + } +} + +# function to source another script with conditional trace output +# first argument: the path of the script +function _colcon_prefix_powershell_source_script { + param ( + $_colcon_prefix_powershell_source_script_param + ) + # source script with conditional trace output + if (Test-Path $_colcon_prefix_powershell_source_script_param) { + if ($env:COLCON_TRACE) { + echo ". '$_colcon_prefix_powershell_source_script_param'" + } + . "$_colcon_prefix_powershell_source_script_param" + } else { + Write-Error "not found: '$_colcon_prefix_powershell_source_script_param'" + } +} + +# get all commands in topological order +$_colcon_ordered_commands = & "$_colcon_python_executable" "$(Split-Path $PSCommandPath -Parent)/_local_setup_util_ps1.py" ps1 + +# execute all commands in topological order +if ($env:COLCON_TRACE) { + echo "Execute generated script:" + echo "<<<" + $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Write-Output + echo ">>>" +} +if ($_colcon_ordered_commands) { + $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Invoke-Expression +} diff --git a/inorbit_republisher/test/sample_data/install/local_setup.sh b/inorbit_republisher/test/sample_data/install/local_setup.sh new file mode 100644 index 0000000..d40d34d --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.sh @@ -0,0 +1,137 @@ +# generated from colcon_core/shell/template/prefix.sh.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# since a plain shell script can't determine its own path when being sourced +# either use the provided COLCON_CURRENT_PREFIX +# or fall back to the build time prefix (if it exists) +_colcon_prefix_sh_COLCON_CURRENT_PREFIX="/root/ros2_ws/src/inorbit_republisher/test/sample_data/install" +if [ -z "$COLCON_CURRENT_PREFIX" ]; then + if [ ! -d "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" ]; then + echo "The build time path \"$_colcon_prefix_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 + unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX + return 1 + fi +else + _colcon_prefix_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +fi + +# function to prepend a value to a variable +# which uses colons as separators +# duplicates as well as trailing separators are avoided +# first argument: the name of the result variable +# second argument: the value to be prepended +_colcon_prefix_sh_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + + # get values from variable + eval _values=\"\$$_listname\" + # backup the field separator + _colcon_prefix_sh_prepend_unique_value_IFS="$IFS" + IFS=":" + # start with the new value + _all_values="$_value" + _contained_value="" + # iterate over existing values in the variable + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + # ignore duplicates of _value + if [ "$_item" = "$_value" ]; then + _contained_value=1 + continue + fi + # keep non-duplicate values + _all_values="$_all_values:$_item" + done + unset _item + if [ -z "$_contained_value" ]; then + if [ -n "$COLCON_TRACE" ]; then + if [ "$_all_values" = "$_value" ]; then + echo "export $_listname=$_value" + else + echo "export $_listname=$_value:\$$_listname" + fi + fi + fi + unset _contained_value + # restore the field separator + IFS="$_colcon_prefix_sh_prepend_unique_value_IFS" + unset _colcon_prefix_sh_prepend_unique_value_IFS + # export the updated variable + eval export $_listname=\"$_all_values\" + unset _all_values + unset _values + + unset _value + unset _listname +} + +# add this prefix to the COLCON_PREFIX_PATH +_colcon_prefix_sh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" +unset _colcon_prefix_sh_prepend_unique_value + +# check environment variable for custom Python executable +if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then + if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then + echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" + return 1 + fi + _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" +else + # try the Python executable known at configure time + _colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if [ ! -f "$_colcon_python_executable" ]; then + if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then + echo "error: unable to find python3 executable" + return 1 + fi + _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` + fi +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# get all commands in topological order +_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh)" +unset _colcon_python_executable +if [ -n "$COLCON_TRACE" ]; then + echo "_colcon_prefix_sh_source_script() { + if [ -f \"\$1\" ]; then + if [ -n \"\$COLCON_TRACE\" ]; then + echo \"# . \\\"\$1\\\"\" + fi + . \"\$1\" + else + echo \"not found: \\\"\$1\\\"\" 1>&2 + fi + }" + echo "# Execute generated script:" + echo "# <<<" + echo "${_colcon_ordered_commands}" + echo "# >>>" + echo "unset _colcon_prefix_sh_source_script" +fi +eval "${_colcon_ordered_commands}" +unset _colcon_ordered_commands + +unset _colcon_prefix_sh_source_script + +unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.zsh b/inorbit_republisher/test/sample_data/install/local_setup.zsh new file mode 100644 index 0000000..b648710 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.zsh @@ -0,0 +1,134 @@ +# generated from colcon_zsh/shell/template/prefix.zsh.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# a zsh script is able to determine its own path if necessary +if [ -z "$COLCON_CURRENT_PREFIX" ]; then + _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" +else + _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +fi + +# function to convert array-like strings into arrays +# to workaround SH_WORD_SPLIT not being set +_colcon_prefix_zsh_convert_to_array() { + local _listname=$1 + local _dollar="$" + local _split="{=" + local _to_array="(\"$_dollar$_split$_listname}\")" + eval $_listname=$_to_array +} + +# function to prepend a value to a variable +# which uses colons as separators +# duplicates as well as trailing separators are avoided +# first argument: the name of the result variable +# second argument: the value to be prepended +_colcon_prefix_zsh_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + + # get values from variable + eval _values=\"\$$_listname\" + # backup the field separator + _colcon_prefix_zsh_prepend_unique_value_IFS="$IFS" + IFS=":" + # start with the new value + _all_values="$_value" + _contained_value="" + # workaround SH_WORD_SPLIT not being set + _colcon_prefix_zsh_convert_to_array _values + # iterate over existing values in the variable + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + # ignore duplicates of _value + if [ "$_item" = "$_value" ]; then + _contained_value=1 + continue + fi + # keep non-duplicate values + _all_values="$_all_values:$_item" + done + unset _item + if [ -z "$_contained_value" ]; then + if [ -n "$COLCON_TRACE" ]; then + if [ "$_all_values" = "$_value" ]; then + echo "export $_listname=$_value" + else + echo "export $_listname=$_value:\$$_listname" + fi + fi + fi + unset _contained_value + # restore the field separator + IFS="$_colcon_prefix_zsh_prepend_unique_value_IFS" + unset _colcon_prefix_zsh_prepend_unique_value_IFS + # export the updated variable + eval export $_listname=\"$_all_values\" + unset _all_values + unset _values + + unset _value + unset _listname +} + +# add this prefix to the COLCON_PREFIX_PATH +_colcon_prefix_zsh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX" +unset _colcon_prefix_zsh_prepend_unique_value +unset _colcon_prefix_zsh_convert_to_array + +# check environment variable for custom Python executable +if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then + if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then + echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" + return 1 + fi + _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" +else + # try the Python executable known at configure time + _colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if [ ! -f "$_colcon_python_executable" ]; then + if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then + echo "error: unable to find python3 executable" + return 1 + fi + _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` + fi +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# get all commands in topological order +_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh zsh)" +unset _colcon_python_executable +if [ -n "$COLCON_TRACE" ]; then + echo "$(declare -f _colcon_prefix_sh_source_script)" + echo "# Execute generated script:" + echo "# <<<" + echo "${_colcon_ordered_commands}" + echo "# >>>" + echo "unset _colcon_prefix_sh_source_script" +fi +eval "${_colcon_ordered_commands}" +unset _colcon_ordered_commands + +unset _colcon_prefix_sh_source_script + +unset _colcon_prefix_zsh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.bash b/inorbit_republisher/test/sample_data/install/setup.bash new file mode 100644 index 0000000..a648296 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.bash @@ -0,0 +1,37 @@ +# generated from colcon_bash/shell/template/prefix_chain.bash.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_chain_bash_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# source chained prefixes +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/opt/ros/humble" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/install" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" + +# source this prefix +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" + +unset COLCON_CURRENT_PREFIX +unset _colcon_prefix_chain_bash_source_script diff --git a/inorbit_republisher/test/sample_data/install/setup.ps1 b/inorbit_republisher/test/sample_data/install/setup.ps1 new file mode 100644 index 0000000..8c90c86 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.ps1 @@ -0,0 +1,31 @@ +# generated from colcon_powershell/shell/template/prefix_chain.ps1.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# function to source another script with conditional trace output +# first argument: the path of the script +function _colcon_prefix_chain_powershell_source_script { + param ( + $_colcon_prefix_chain_powershell_source_script_param + ) + # source script with conditional trace output + if (Test-Path $_colcon_prefix_chain_powershell_source_script_param) { + if ($env:COLCON_TRACE) { + echo ". '$_colcon_prefix_chain_powershell_source_script_param'" + } + . "$_colcon_prefix_chain_powershell_source_script_param" + } else { + Write-Error "not found: '$_colcon_prefix_chain_powershell_source_script_param'" + } +} + +# source chained prefixes +_colcon_prefix_chain_powershell_source_script "/opt/ros/humble\local_setup.ps1" +_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/install\local_setup.ps1" +_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/src/install\local_setup.ps1" + +# source this prefix +$env:COLCON_CURRENT_PREFIX=(Split-Path $PSCommandPath -Parent) +_colcon_prefix_chain_powershell_source_script "$env:COLCON_CURRENT_PREFIX\local_setup.ps1" diff --git a/inorbit_republisher/test/sample_data/install/setup.sh b/inorbit_republisher/test/sample_data/install/setup.sh new file mode 100644 index 0000000..e4196d7 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.sh @@ -0,0 +1,53 @@ +# generated from colcon_core/shell/template/prefix_chain.sh.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# since a plain shell script can't determine its own path when being sourced +# either use the provided COLCON_CURRENT_PREFIX +# or fall back to the build time prefix (if it exists) +_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX=/root/ros2_ws/src/inorbit_republisher/test/sample_data/install +if [ ! -z "$COLCON_CURRENT_PREFIX" ]; then + _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +elif [ ! -d "$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" ]; then + echo "The build time path \"$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 + unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX + return 1 +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_chain_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# source chained prefixes +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="/opt/ros/humble" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/install" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + + +# source this prefix +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + +unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX +unset _colcon_prefix_chain_sh_source_script +unset COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.zsh b/inorbit_republisher/test/sample_data/install/setup.zsh new file mode 100644 index 0000000..c478d8a --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.zsh @@ -0,0 +1,37 @@ +# generated from colcon_zsh/shell/template/prefix_chain.zsh.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_chain_zsh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# source chained prefixes +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/opt/ros/humble" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/install" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" + +# source this prefix +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" + +unset COLCON_CURRENT_PREFIX +unset _colcon_prefix_chain_zsh_source_script diff --git a/inorbit_republisher/test/sample_data/log/COLCON_IGNORE b/inorbit_republisher/test/sample_data/log/COLCON_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log new file mode 100644 index 0000000..08ed030 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log @@ -0,0 +1,2 @@ +[0.000000] (-) TimerEvent: {} +[0.000379] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log new file mode 100644 index 0000000..fe428ee --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log @@ -0,0 +1,77 @@ +[0.165s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build', '--packages-select', 'inorbit_republisher', '--symlink-install'] +[0.165s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=True, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=['inorbit_republisher'], packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) +[0.361s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters +[0.362s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' +[0.363s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover +[0.363s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored +[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] +[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' +[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults +[0.380s] WARNING:colcon.colcon_core.package_selection:ignoring unknown package 'inorbit_republisher' in --packages-select +[0.410s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor +[0.411s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete +[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop +[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed +[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' +[0.412s] DEBUG:colcon.colcon_core.event_reactor:joining thread +[0.418s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' +[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems +[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems +[0.419s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' +[0.419s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 +[0.419s] DEBUG:colcon.colcon_core.event_reactor:joined thread +[0.422s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems +[0.422s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' +[0.423s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' +[0.425s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' +[0.428s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' +[0.428s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' +[0.429s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' +[0.430s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' +[0.431s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' +[0.432s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' +[0.433s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log new file mode 100644 index 0000000..ffcb674 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log @@ -0,0 +1,2 @@ +[0.000000] (-) TimerEvent: {} +[0.000588] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log new file mode 100644 index 0000000..dad4847 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log @@ -0,0 +1,76 @@ +[0.181s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build'] +[0.181s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=False, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=None, packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) +[0.389s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters +[0.390s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' +[0.391s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover +[0.392s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] +[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' +[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] +[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults +[0.438s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' +[0.441s] DEBUG:colcon.colcon_core.event_reactor:joining thread +[0.447s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' +[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems +[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems +[0.448s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' +[0.448s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 +[0.448s] DEBUG:colcon.colcon_core.event_reactor:joined thread +[0.451s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems +[0.451s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' +[0.453s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' +[0.455s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' +[0.457s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' +[0.458s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' +[0.458s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' +[0.460s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' +[0.460s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' +[0.462s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' +[0.462s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/latest b/inorbit_republisher/test/sample_data/log/latest new file mode 120000 index 0000000..b57d247 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/latest @@ -0,0 +1 @@ +latest_build \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/log/latest_build b/inorbit_republisher/test/sample_data/log/latest_build new file mode 120000 index 0000000..4ba36b2 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/latest_build @@ -0,0 +1 @@ +build_2024-12-13_20-49-52 \ No newline at end of file From 3eb6cec4ec43d9beca5ada19c86c89ad9dd49096 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Tue, 17 Dec 2024 12:37:31 -0300 Subject: [PATCH 02/21] publisher test works when running rosbag from cmd yet not from launch file --- .../sample_data.launch_20241217094439.xml | 19 ++++++++ .../sample_data.launch_20241217100145.xml | 9 ++++ .../sample_data.launch_20241217100401.xml | 9 ++++ .../sample_data.launch_20241217100515.xml | 9 ++++ .../sample_data.launch_20241217100647.xml | 9 ++++ .../sample_data.launch_20241217100726.xml | 9 ++++ .../sample_data.launch_20241217101034.xml | 9 ++++ .../sample_data.launch_20241217101335.xml | 10 ++++ .../sample_data.launch_20241217101636.xml | 9 ++++ .../sample_data.launch_20241217101711.xml | 10 ++++ .../sample_data.launch_20241217101729.xml | 10 ++++ .../sample_data.launch_20241217101938.xml | 9 ++++ .../sample_data.launch_20241217101941.xml | 9 ++++ .../sample_data.launch_20241217104852.xml | 9 ++++ .../sample_data.launch_20241217104941.xml | 9 ++++ .../sample_data.launch_20241217105013.xml | 9 ++++ .../sample_data.launch_20241217105728.xml | 9 ++++ .../sample_data.launch_20241217105923.xml | 10 ++++ .../sample_data.launch_20241217105958.xml | 10 ++++ .../sample_data.launch_20241217110012.xml | 8 ++++ .../sample_data.launch_20241217110015.xml | 8 ++++ .../sample_data.launch_20241217110221.py | 0 .../sample_data.launch_20241217110328.py | 39 ++++++++++++++++ .../sample_data.launch_20241217111512.xml | 7 +++ .../sample_data.launch_20241217112220.py | 22 +++++++++ .../sample_data.launch_20241217112508.py | 26 +++++++++++ .../sample_data.launch_20241217112602.py | 26 +++++++++++ .../sample_data.launch_20241217112824.py | 25 ++++++++++ .../sample_data.launch_20241217112831.py | 25 ++++++++++ .../sample_data.launch_20241217113329.xml | 7 +++ .../sample_data.launch_20241217113333.py | 25 ++++++++++ .../sample_data.launch_20241217113410.py | 25 ++++++++++ .../sample_data.launch_20241217113437.py | 25 ++++++++++ .../sample_data.launch_20241217113453.py | 25 ++++++++++ .../sample_data.launch_20241217114100.py | 25 ++++++++++ .../sample_data.launch_20241217114845.xml | 7 +++ .../sample_data.launch_20241217115301.xml | 7 +++ .../sample_data.launch_20241217115430.xml | 9 ++++ .../sample_data.launch_20241217115941.xml | 9 ++++ .../sample_data.launch_20241217123416.xml | 9 ++++ .../sample_data.launch_20241217123424.xml | 9 ++++ .../sample_data.launch_20241217123458.xml | 9 ++++ .../sample_data.launch_20241217123518.xml | 9 ++++ .../test/README_20241217094923.md | 32 +++++++++++++ .../test/README_20241217121634.md | 40 ++++++++++++++++ .../test/README_20241217123656.md | 46 +++++++++++++++++++ .../launch/sample_data.launch.xml | 8 ++-- inorbit_republisher/test/README.md | 21 ++++++++- 48 files changed, 714 insertions(+), 5 deletions(-) create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110221.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110328.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112220.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112508.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112602.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112824.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112831.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113333.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113410.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113437.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113453.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217114100.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml create mode 100644 .history/inorbit_republisher/test/README_20241217094923.md create mode 100644 .history/inorbit_republisher/test/README_20241217121634.md create mode 100644 .history/inorbit_republisher/test/README_20241217123656.md diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml new file mode 100644 index 0000000..bed10be --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml new file mode 100644 index 0000000..dcc4f8c --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml new file mode 100644 index 0000000..e54f648 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml new file mode 100644 index 0000000..f5f9377 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml new file mode 100644 index 0000000..e13a886 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml new file mode 100644 index 0000000..c6c2f80 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml new file mode 100644 index 0000000..1a6453d --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml new file mode 100644 index 0000000..04f4692 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml new file mode 100644 index 0000000..74a1e3d --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml new file mode 100644 index 0000000..1f4fa78 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml new file mode 100644 index 0000000..1f4fa78 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml new file mode 100644 index 0000000..95faa19 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml new file mode 100644 index 0000000..95faa19 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml new file mode 100644 index 0000000..4597645 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml new file mode 100644 index 0000000..f4ed34d --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml new file mode 100644 index 0000000..0b82762 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml new file mode 100644 index 0000000..3d5ba21 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml new file mode 100644 index 0000000..efbe43c --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml new file mode 100644 index 0000000..2fb31e7 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml new file mode 100644 index 0000000..6864e6c --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml new file mode 100644 index 0000000..118fed9 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110221.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217110221.py new file mode 100644 index 0000000..e69de29 diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110328.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217110328.py new file mode 100644 index 0000000..e3efd80 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217110328.py @@ -0,0 +1,39 @@ +import launch +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, LogInfo +from launch.substitutions import LaunchConfiguration, PathJoinSubstitution +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + # Declaración de argumentos + DeclareLaunchArgument( + 'config_path', + default_value=PathJoinSubstitution([launch.substitutions.LaunchConfiguration('package_share_directory'), 'test', 'sample_data', 'config.yaml']), + description='Path to the config file' + ), + DeclareLaunchArgument( + 'rosbag_path', + default_value=PathJoinSubstitution([launch.substitutions.LaunchConfiguration('package_share_directory'), 'test', 'sample_data', 'harcodedRosbag', 'rosbag2_2024_12_13-19_33_34_0.db3']), + description='Path to the rosbag file' + ), + + # Primer nodo: inorbit_republisher + Node( + name='inorbit_republisher', + package='inorbit_republisher', + executable='republisher', + output='screen', + parameters=[{'config': LaunchConfiguration('config_path')}], + ), + + # Segundo nodo: rosbag2 player + Node( + package='rosbag2', + executable='play', + name='player', + output='screen', + arguments=['-l', LaunchConfiguration('rosbag_path')], + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml new file mode 100644 index 0000000..3539baa --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112220.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112220.py new file mode 100644 index 0000000..fe1b159 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217112220.py @@ -0,0 +1,22 @@ +import launch +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': '/root/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml'}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112508.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112508.py new file mode 100644 index 0000000..04bfc43 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217112508.py @@ -0,0 +1,26 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess +import os + +def generate_launch_description(): + # Define las rutas absolutas a los archivos + config_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112602.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112602.py new file mode 100644 index 0000000..f27002e --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217112602.py @@ -0,0 +1,26 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess +import os + +def generate_launch_description(): + # Define las rutas absolutas a los archivos + config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112824.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112824.py new file mode 100644 index 0000000..c61a5cc --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217112824.py @@ -0,0 +1,25 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + # Rutas absolutas de tus archivos + config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112831.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112831.py new file mode 100644 index 0000000..8419f12 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217112831.py @@ -0,0 +1,25 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + # Rutas absolutas de tus archivos + config_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml new file mode 100644 index 0000000..410d847 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113333.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113333.py new file mode 100644 index 0000000..c61a5cc --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217113333.py @@ -0,0 +1,25 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + # Rutas absolutas de tus archivos + config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113410.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113410.py new file mode 100644 index 0000000..3f4031a --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217113410.py @@ -0,0 +1,25 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + # Rutas absolutas de tus archivos + config_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113437.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113437.py new file mode 100644 index 0000000..c9b17f9 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217113437.py @@ -0,0 +1,25 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + # Rutas absolutas de tus archivos + config_file = "~/ros2_ws/src/inorbit_republisher/test/pep/config.yaml" + rosbag_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113453.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113453.py new file mode 100644 index 0000000..3f4031a --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217113453.py @@ -0,0 +1,25 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + # Rutas absolutas de tus archivos + config_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217114100.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217114100.py new file mode 100644 index 0000000..c61a5cc --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217114100.py @@ -0,0 +1,25 @@ +import launch +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess + +def generate_launch_description(): + # Rutas absolutas de tus archivos + config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" + rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" + + return LaunchDescription([ + # Nodo inorbit_republisher + Node( + package='inorbit_republisher', + executable='republisher', + name='inorbit_republisher', + parameters=[{'config': config_file}], + ), + + # Comando para reproducir rosbag2 + ExecuteProcess( + cmd=['ros2', 'bag', 'play', rosbag_file], + output='screen' + ), + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml new file mode 100644 index 0000000..6f25bcf --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml new file mode 100644 index 0000000..6f25bcf --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml new file mode 100644 index 0000000..a9c2581 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml new file mode 100644 index 0000000..0857004 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml new file mode 100644 index 0000000..7018ab9 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml new file mode 100644 index 0000000..0857004 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml new file mode 100644 index 0000000..a9c2581 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml new file mode 100644 index 0000000..a9c2581 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/test/README_20241217094923.md b/.history/inorbit_republisher/test/README_20241217094923.md new file mode 100644 index 0000000..72ca7a0 --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241217094923.md @@ -0,0 +1,32 @@ +1. A. generar nuestro propio rosbag, para eso: + ros2 bag record /my_magnetic_field /my_temperature + B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + usando ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path +2. Corremos el package: + primeor hay que buildearlo... + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-instal + source /opt/ros/humble/setup.bash + luego, coror el file + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + +3. Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature + +IRi del lunes: + Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: + ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" +Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo +Tengo que crear un docker en humble xq elimine el mio g \ No newline at end of file diff --git a/.history/inorbit_republisher/test/README_20241217121634.md b/.history/inorbit_republisher/test/README_20241217121634.md new file mode 100644 index 0000000..f10501a --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241217121634.md @@ -0,0 +1,40 @@ +1. A. generar nuestro propio rosbag, para eso: + ros2 bag record /my_magnetic_field /my_temperature + B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + usando ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path +2. Corremos el package: + primeor hay que buildearlo... + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-instal + source install/setup.bash + luego, coror el file + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + +3. Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature + +IRi del lunes: + Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: + ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" +Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo +Tengo que crear un docker en humble xq elimine el mio g + +Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> + cd + cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher +/// alternativa a mi launch.xml que no funciona +1. corro mi rosbag haciendo esto en una terminal: + cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag + ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 diff --git a/.history/inorbit_republisher/test/README_20241217123656.md b/.history/inorbit_republisher/test/README_20241217123656.md new file mode 100644 index 0000000..a65e2c2 --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241217123656.md @@ -0,0 +1,46 @@ +1. A. generar nuestro propio rosbag, para eso: + ros2 bag record /my_magnetic_field /my_temperature + B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + usando ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path +2. Corremos el package: + primeor hay que buildearlo... + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-instal + source install/setup.bash + luego, coror el file + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + +3. Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature + +IRi del lunes: + Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: + ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" +Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo +Tengo que crear un docker en humble xq elimine el mio g + +Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> + cd + cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher +/// alternativa a mi launch.xml que no funciona +1. corro mi rosbag haciendo esto en una terminal: + cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag + ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 + en otra terminal: + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature +////// + Pyuede ser qyue no funcione xq mi rosbag es finito_ + \ No newline at end of file diff --git a/inorbit_republisher/launch/sample_data.launch.xml b/inorbit_republisher/launch/sample_data.launch.xml index 1527175..a9c2581 100644 --- a/inorbit_republisher/launch/sample_data.launch.xml +++ b/inorbit_republisher/launch/sample_data.launch.xml @@ -1,9 +1,9 @@ - - - + + + - + diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index f4c50b0..a65e2c2 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -10,6 +10,11 @@ usando ros2 bag record /my_magnetic_field /my_temperature como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path 2. Corremos el package: + primeor hay que buildearlo... + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-instal + source install/setup.bash + luego, coror el file cd ros2_ws/src/inorbit_republisher/test/sample_data ros2 launch inorbit_republisher sample_data.launch.xml Segun ros2, debe estar en la crpeta de luinch. @@ -24,4 +29,18 @@ IRi del lunes: Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo -Tengo que crear un docker en humble xq elimine el mio g \ No newline at end of file +Tengo que crear un docker en humble xq elimine el mio g + +Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> + cd + cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher +/// alternativa a mi launch.xml que no funciona +1. corro mi rosbag haciendo esto en una terminal: + cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag + ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 + en otra terminal: + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature +////// + Pyuede ser qyue no funcione xq mi rosbag es finito_ + \ No newline at end of file From a603e78c8c2618756713937834e5a8d9059a74a0 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Tue, 17 Dec 2024 14:18:15 -0300 Subject: [PATCH 03/21] Trying to fix launch file error, unsuccessfully --- .../sample_data.launch_20241217123845.xml | 11 +++++ .../sample_data.launch_20241217123854.xml | 11 +++++ .../sample_data.launch_20241217124149.xml | 9 ++++ .../sample_data.launch_20241217124220.py | 26 +++++++++++ .../sample_data.launch_20241217124420.py | 25 ++++++++++ .../sample_data.launch_20241217124736.py | 29 ++++++++++++ .../sample_data.launch_20241217125321.xml | 9 ++++ .../sample_data.launch_20241217125338.xml | 9 ++++ .../sample_data.launch_20241217125743.xml | 9 ++++ .../sample_data.launch_20241217125930.xml | 9 ++++ .../sample_data.launch_20241217125954.xml | 9 ++++ .../sample_data.launch_20241217130002.xml | 9 ++++ .../test/README_20241217130401.md | 46 +++++++++++++++++++ .../launch/sample_data.launch.py | 29 ++++++++++++ .../launch/sample_data.launch.xml | 4 +- inorbit_republisher/test/README.md | 2 +- 16 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124220.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124420.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124736.py create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml create mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml create mode 100644 .history/inorbit_republisher/test/README_20241217130401.md create mode 100644 inorbit_republisher/launch/sample_data.launch.py diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml new file mode 100644 index 0000000..f604bf7 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml new file mode 100644 index 0000000..d219e59 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml new file mode 100644 index 0000000..2cfbd63 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124220.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217124220.py new file mode 100644 index 0000000..274f62b --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217124220.py @@ -0,0 +1,26 @@ +import os +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, LogInfo, ExecuteProcess +from launch.substitutions import LaunchConfiguration + + +def generate_launch_description(): + return LaunchDescription([ + # Primer nodo: inorbit_republisher + DeclareLaunchArgument('config_file', default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', description='Configuración de archivo'), + + LogInfo(condition=LaunchConfiguration('config_file')), + + ExecuteProcess( + cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], + name='inorbit_republisher', + output='screen' + ), + + # Segundo nodo: rosbag2 player + ExecuteProcess( + cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], + name='rosbag_player', + output='screen' + ) + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124420.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217124420.py new file mode 100644 index 0000000..a921f9d --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217124420.py @@ -0,0 +1,25 @@ +import os +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, ExecuteProcess +from launch.substitutions import LaunchConfiguration + + +def generate_launch_description(): + return LaunchDescription([ + # Primer nodo: inorbit_republisher + DeclareLaunchArgument('config_file', default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', description='Archivo de configuración'), + + # Ejecutar el nodo inorbit_republisher + ExecuteProcess( + cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], + name='inorbit_republisher', + output='screen' + ), + + # Ejecutar rosbag2 player + ExecuteProcess( + cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], + name='rosbag_player', + output='screen' + ) + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124736.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217124736.py new file mode 100644 index 0000000..9451b6c --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217124736.py @@ -0,0 +1,29 @@ +import os +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, ExecuteProcess +from launch.substitutions import LaunchConfiguration + + +def generate_launch_description(): + return LaunchDescription([ + # Declarar el argumento 'config_file' con su valor por defecto + DeclareLaunchArgument( + 'config_file', + default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', + description='Ruta al archivo de configuración del republisher' + ), + + # Ejecutar el nodo inorbit_republisher + ExecuteProcess( + cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], + name='inorbit_republisher', + output='screen' + ), + + # Ejecutar rosbag2 player + ExecuteProcess( + cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], + name='rosbag_player', + output='screen' + ) + ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml new file mode 100644 index 0000000..d64b1ff --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml new file mode 100644 index 0000000..4431661 --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml new file mode 100644 index 0000000..452a62b --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml new file mode 100644 index 0000000..918a1de --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml new file mode 100644 index 0000000..4cf20aa --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml new file mode 100644 index 0000000..918a1de --- /dev/null +++ b/.history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.history/inorbit_republisher/test/README_20241217130401.md b/.history/inorbit_republisher/test/README_20241217130401.md new file mode 100644 index 0000000..aac438a --- /dev/null +++ b/.history/inorbit_republisher/test/README_20241217130401.md @@ -0,0 +1,46 @@ +1. A. generar nuestro propio rosbag, para eso: + ros2 bag record /my_magnetic_field /my_temperature + B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-install + source /opt/ros/humble/setup.bash + cd ros2_ws/src/inorbit_republisher/inorbit_republisher + ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" + NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag + usando ros2 bag record /my_magnetic_field /my_temperature + como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path +2. Corremos el package: + primeor hay que buildearlo... + cd ros2_ws/src + colcon build --packages-select inorbit_republisher --symlink-instal + source install/setup.bash + luego, coror el file + cd ros2_ws/src/inorbit_republisher/test/sample_data + ros2 launch inorbit_republisher sample_data.launch.xml + Segun ros2, debe estar en la crpeta de luinch. + Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: + +3. Abro otra terminal: + cd ros2_ws/src/inorbit_republisher/test/sample_data + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature + +IRi del lunes: + Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: + ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" +Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo +Tengo que crear un docker en humble xq elimine el mio g + +Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> + cd + cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher +/// alternativa a mi launch.xml que no funciona +1. corro mi rosbag haciendo esto en una terminal: + cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag + ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 + en otra terminal: + source /opt/ros/humble/setup.bash + ros2 topic echo my_temperature +////// + Pyuede ser qyue no funcione xq mi rosbag es finito_ + - AttributeError: Attribute 'exec' of type '' not found in Entity 'node' este es el error diff --git a/inorbit_republisher/launch/sample_data.launch.py b/inorbit_republisher/launch/sample_data.launch.py new file mode 100644 index 0000000..9451b6c --- /dev/null +++ b/inorbit_republisher/launch/sample_data.launch.py @@ -0,0 +1,29 @@ +import os +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, ExecuteProcess +from launch.substitutions import LaunchConfiguration + + +def generate_launch_description(): + return LaunchDescription([ + # Declarar el argumento 'config_file' con su valor por defecto + DeclareLaunchArgument( + 'config_file', + default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', + description='Ruta al archivo de configuración del republisher' + ), + + # Ejecutar el nodo inorbit_republisher + ExecuteProcess( + cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], + name='inorbit_republisher', + output='screen' + ), + + # Ejecutar rosbag2 player + ExecuteProcess( + cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], + name='rosbag_player', + output='screen' + ) + ]) diff --git a/inorbit_republisher/launch/sample_data.launch.xml b/inorbit_republisher/launch/sample_data.launch.xml index a9c2581..918a1de 100644 --- a/inorbit_republisher/launch/sample_data.launch.xml +++ b/inorbit_republisher/launch/sample_data.launch.xml @@ -4,6 +4,6 @@ - - + + diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index a65e2c2..aac438a 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -43,4 +43,4 @@ Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inor ros2 topic echo my_temperature ////// Pyuede ser qyue no funcione xq mi rosbag es finito_ - \ No newline at end of file + - AttributeError: Attribute 'exec' of type '' not found in Entity 'node' este es el error From 2c8308bfece41242d743a89de3b7694228497423 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Wed, 18 Dec 2024 10:14:35 -0300 Subject: [PATCH 04/21] Added a gitignore file --- .history/.gitignore_20241213093407 | 1 + .history/.gitignore_20241217153146 | 5 +++++ .history/.gitignore_20241217153602 | 6 ++++++ 3 files changed, 12 insertions(+) create mode 100644 .history/.gitignore_20241213093407 create mode 100644 .history/.gitignore_20241217153146 create mode 100644 .history/.gitignore_20241217153602 diff --git a/.history/.gitignore_20241213093407 b/.history/.gitignore_20241213093407 new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.history/.gitignore_20241213093407 @@ -0,0 +1 @@ +__pycache__/ diff --git a/.history/.gitignore_20241217153146 b/.history/.gitignore_20241217153146 new file mode 100644 index 0000000..a4df222 --- /dev/null +++ b/.history/.gitignore_20241217153146 @@ -0,0 +1,5 @@ +__pycache__/ +/inorbit_republisher/test/sample_data/build/ +/inorbit_republisher/test/sample_data/hardcodedRosbag/ +/inorbit_republisher/test/sample_data/install/ +/inorbit_republisher/test/sample_data/log/ diff --git a/.history/.gitignore_20241217153602 b/.history/.gitignore_20241217153602 new file mode 100644 index 0000000..c776db8 --- /dev/null +++ b/.history/.gitignore_20241217153602 @@ -0,0 +1,6 @@ +__pycache__/ +/inorbit_republisher/test/sample_data/build/ +/inorbit_republisher/test/sample_data/hardcodedRosbag/ +/inorbit_republisher/test/sample_data/install/ +/inorbit_republisher/test/sample_data/log/ +.history/ From 43133c582781bf207ddea00d6c2719a05e4ba222 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Wed, 18 Dec 2024 14:20:59 -0300 Subject: [PATCH 05/21] sample_data.launch.xml file raise an exception in launch, still fixing it. --- .../launch/sample_data.launch.py | 31 +++++++++---------- .../launch/sample_data.launch.xml | 17 +++++----- inorbit_republisher/test/README.md | 24 +++++++++++--- 3 files changed, 42 insertions(+), 30 deletions(-) mode change 100644 => 100755 inorbit_republisher/launch/sample_data.launch.py diff --git a/inorbit_republisher/launch/sample_data.launch.py b/inorbit_republisher/launch/sample_data.launch.py old mode 100644 new mode 100755 index 9451b6c..711088f --- a/inorbit_republisher/launch/sample_data.launch.py +++ b/inorbit_republisher/launch/sample_data.launch.py @@ -1,26 +1,23 @@ -import os -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, ExecuteProcess -from launch.substitutions import LaunchConfiguration +# sample_data.launch.py +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.actions import ExecuteProcess def generate_launch_description(): return LaunchDescription([ - # Declarar el argumento 'config_file' con su valor por defecto - DeclareLaunchArgument( - 'config_file', - default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', - description='Ruta al archivo de configuración del republisher' - ), - - # Ejecutar el nodo inorbit_republisher - ExecuteProcess( - cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], + # Primer nodo: inorbit_republisher + Node( name='inorbit_republisher', - output='screen' + package='inorbit_republisher', + executable='republisher', + output='screen', + parameters=[{ + 'config': '/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml' + }] ), - - # Ejecutar rosbag2 player + + # Segundo proceso: Ejecutar ros2 bag play ExecuteProcess( cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], name='rosbag_player', diff --git a/inorbit_republisher/launch/sample_data.launch.xml b/inorbit_republisher/launch/sample_data.launch.xml index 918a1de..62e96d6 100644 --- a/inorbit_republisher/launch/sample_data.launch.xml +++ b/inorbit_republisher/launch/sample_data.launch.xml @@ -1,9 +1,10 @@ - - - - - - - - + + + + + + + diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index aac438a..5783315 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -25,15 +25,12 @@ source /opt/ros/humble/setup.bash ros2 topic echo my_temperature -IRi del lunes: - Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: - ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" -Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo -Tengo que crear un docker en humble xq elimine el mio g Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> cd cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher + + cp ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml /root/ros2_ws/src/inorbit_republisher/test/sample_data/config/ /// alternativa a mi launch.xml que no funciona 1. corro mi rosbag haciendo esto en una terminal: cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag @@ -44,3 +41,20 @@ Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inor ////// Pyuede ser qyue no funcione xq mi rosbag es finito_ - AttributeError: Attribute 'exec' of type '' not found in Entity 'node' este es el error + + +/// +Consola de colores: + cd + apt update && apt install nano -y + nano ~/.bashrc + Dentro del bashrc, abajo de todo, copio> + force_color_prompt=yes + GUardo y cierro el file + alias ls='ls --color=auto' + source ~/.bashrc +Para dejarlo predeterminado> + + +Puede ser que el error se de x altgo de paquetres no instlados o mal instalado... + From c44ebe159cab12d030074e98ba63e51a48f5dc15 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Wed, 18 Dec 2024 17:23:40 -0300 Subject: [PATCH 06/21] rosbag test on Humble working properly --- .../launch/sample_data.launch.py | 26 ----- .../launch/sample_data.launch.xml | 6 +- inorbit_republisher/test/README.md | 110 ++++++++---------- .../test/sample_data/config.yaml | 2 +- 4 files changed, 52 insertions(+), 92 deletions(-) delete mode 100755 inorbit_republisher/launch/sample_data.launch.py diff --git a/inorbit_republisher/launch/sample_data.launch.py b/inorbit_republisher/launch/sample_data.launch.py deleted file mode 100755 index 711088f..0000000 --- a/inorbit_republisher/launch/sample_data.launch.py +++ /dev/null @@ -1,26 +0,0 @@ -# sample_data.launch.py - -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - return LaunchDescription([ - # Primer nodo: inorbit_republisher - Node( - name='inorbit_republisher', - package='inorbit_republisher', - executable='republisher', - output='screen', - parameters=[{ - 'config': '/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml' - }] - ), - - # Segundo proceso: Ejecutar ros2 bag play - ExecuteProcess( - cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], - name='rosbag_player', - output='screen' - ) - ]) diff --git a/inorbit_republisher/launch/sample_data.launch.xml b/inorbit_republisher/launch/sample_data.launch.xml index 62e96d6..3716fdc 100644 --- a/inorbit_republisher/launch/sample_data.launch.xml +++ b/inorbit_republisher/launch/sample_data.launch.xml @@ -2,9 +2,5 @@ - + - - diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index 5783315..d87d27e 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -1,60 +1,50 @@ -1. A. generar nuestro propio rosbag, para eso: - ros2 bag record /my_magnetic_field /my_temperature - B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - usando ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path -2. Corremos el package: - primeor hay que buildearlo... - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-instal - source install/setup.bash - luego, coror el file - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - -3. Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature - - -Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> - cd - cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher - - cp ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml /root/ros2_ws/src/inorbit_republisher/test/sample_data/config/ -/// alternativa a mi launch.xml que no funciona -1. corro mi rosbag haciendo esto en una terminal: - cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag - ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 - en otra terminal: - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature -////// - Pyuede ser qyue no funcione xq mi rosbag es finito_ - - AttributeError: Attribute 'exec' of type '' not found in Entity 'node' este es el error - - -/// -Consola de colores: - cd - apt update && apt install nano -y - nano ~/.bashrc - Dentro del bashrc, abajo de todo, copio> - force_color_prompt=yes - GUardo y cierro el file - alias ls='ls --color=auto' - source ~/.bashrc -Para dejarlo predeterminado> - - -Puede ser que el error se de x altgo de paquetres no instlados o mal instalado... - +# Sample data for testing + +A very simple ``rosbag`` with hardcoded data for smoke testing the transformer node. + +```bash +$root@7c94d2cf9659:~# ros2 bag info ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 + +closing. +[INFO] [1734553121.938063653] [rosbag2_storage]: Opened database 'ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3' for READ_ONLY. + +Files: ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 +Bag size: 24.0 KiB +Storage id: sqlite3 +Duration: 16.005861016s +Start: Dec 13 2024 19:45:00.085674077 (1734119100.085674077) +End: Dec 13 2024 19:45:16.091535093 (1734119116.091535093) +Messages: 34 +Topic information: Topic: /my_magnetic_field | Type: sensor_msgs/msg/MagneticField | Count: 17 | Serialization Format: cdr + Topic: /my_temperature | Type: sensor_msgs/msg/Temperature | Count: 17 | Serialization Format: cdr + +``` + +To validate the node works launch the sample by using the ``sample_data.launch.xml`` launch file and look at ``out`` topic: ``ros2 topic echo my_temperature``. + +```bash +cd ros2_ws/src +colcon build --packages-select inorbit_republisher --symlink-instal +source install/setup.bash +cd +ros2 launch inorbit_republisher sample_data.launch.xml +# On a different terminal windows +source /opt/ros/humble/setup.bash +$ ros2 topic echo my_temperature +header: + stamp: + sec: 0 + nanosec: 0 + frame_id: '' +temperature: 29.068787468933582 +variance: 0.0 +--- +header: + stamp: + sec: 0 + nanosec: 0 + frame_id: '' +temperature: 22.9644622619558 +variance: 0.0 +--- +``` diff --git a/inorbit_republisher/test/sample_data/config.yaml b/inorbit_republisher/test/sample_data/config.yaml index c7eccf9..95fc5e0 100644 --- a/inorbit_republisher/test/sample_data/config.yaml +++ b/inorbit_republisher/test/sample_data/config.yaml @@ -20,4 +20,4 @@ republishers: - field: "temperature" out: topic: "/inorbit/custom_data" - key: "my_temperature" \ No newline at end of file + key: "my_temperature" From b827a2883b17fc680237c146eb68bb7fdeee41df Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Wed, 18 Dec 2024 17:27:46 -0300 Subject: [PATCH 07/21] corrected colcon sentence as it was missing an 'l' in install --- inorbit_republisher/test/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index d87d27e..f6d914f 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -24,7 +24,7 @@ To validate the node works launch the sample by using the ``sample_data.launch.x ```bash cd ros2_ws/src -colcon build --packages-select inorbit_republisher --symlink-instal +colcon build --packages-select inorbit_republisher --symlink-install source install/setup.bash cd ros2 launch inorbit_republisher sample_data.launch.xml From 7df9e31d8a787c30b2387457880ab7cf0ea29d75 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Wed, 18 Dec 2024 18:04:27 -0300 Subject: [PATCH 08/21] Rosbag sample test for Jazzy working --- inorbit_republisher/CHANGELOG.rst | 14 -- inorbit_republisher/README.md | 210 ------------------ inorbit_republisher/package.xml | 13 -- .../resource/inorbit_republisher | 0 inorbit_republisher/setup.cfg | 4 - inorbit_republisher/setup.py | 30 --- inorbit_republisher/test/README.md | 2 +- 7 files changed, 1 insertion(+), 272 deletions(-) delete mode 100644 inorbit_republisher/CHANGELOG.rst delete mode 100644 inorbit_republisher/README.md delete mode 100644 inorbit_republisher/package.xml delete mode 100644 inorbit_republisher/resource/inorbit_republisher delete mode 100644 inorbit_republisher/setup.cfg delete mode 100644 inorbit_republisher/setup.py diff --git a/inorbit_republisher/CHANGELOG.rst b/inorbit_republisher/CHANGELOG.rst deleted file mode 100644 index 0849b8c..0000000 --- a/inorbit_republisher/CHANGELOG.rst +++ /dev/null @@ -1,14 +0,0 @@ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Changelog for package inorbit_republisher -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -0.4.1 (2023-09-07) ------------------- -* Fix variable shadowing on message `callback` method (`#21 `_) -* Contributors: Leandro - -0.4.0 (2023-08-18) ------------------- -* First pass at porting republisher to ROS 2 (`#20 `_) - Ported from noetic-devel -* Contributors: Julian Cerruti, Elvio Aruta diff --git a/inorbit_republisher/README.md b/inorbit_republisher/README.md deleted file mode 100644 index c24b053..0000000 --- a/inorbit_republisher/README.md +++ /dev/null @@ -1,210 +0,0 @@ -# InOrbit republisher for ROS 2 - -This directory includes a republisher that allows mapping from arbitrary ROS2 values to ``InOrbit`` [custom data](https://www.inorbit.ai/faq#publish-custom-data) key/value pairs for application-specific observability. - -Currently only mapping from ROS2 topics is supported. The republisher could be extended to map actions, services and parameters. - -## Usage - -Create a YAML config file specifying the mappings you would like to use using this format: - -```yaml - republishers: - - topic: "/fruits_per_cubic_m" - qos: 5 - msg_type: "fruit_msgs/msg/Citrus" - mappings: - - field: "num_oranges" - mapping_type: "single_field" - out: - topic: "/inorbit/custom_data" - key: "oranges" - - topic: "/hardware/status" - msg_type: "hw_msgs/msg/HardwareStatus" - mappings: - - field: "status" - mapping_options: - fields: ["lidar", "motor", "battery"] - filter: 'lambda x: (x.status == 1)' - mapping_type: "array_of_fields" - out: - topic: "/inorbit/custom_data" - key: "hardware_error" - - topic: "/cmd_vel" - qos: 10 - msg_type: "geometry_msgs/msg/Twist" - mappings: - - field: "linear" - mapping_type: "json_of_fields" - mapping_options: - fields: ["x", "y", "z"] - filter: 'lambda vel: (vel["x"] > 0)' - out: - topic: "/inorbit/linear_vel_test" - key: "linear_vel" - - topic: "/navsat" - msg_type: "sensor_msgs/NavSatFix" - mappings: - - mapping_type: "serialize" - mapping_options: - fields: ["status", "latitude", "longitude", "position_covariance_type"] - out: - topic: "/inorbit/custom_data" - key: "navsat" - static_publishers: - - value: "this is a fixed string" - out: - topic: "/inorbit/custom_data" - key: "greeting" - - value_from: - environment_variable: "PATH" - out: - topic: "/inorbit/custom_data" - key: "env_path" -``` - -Then launch the ``republisher.py`` script passing the config file as the ``config`` param. - -A suggested way to organize this is by creating the config file and launch file in your package, then the corresponding launch file would like like this: - -```xml - - - - - -``` - -## Mapping ROS2 topics - -The republisher can map the ROS2 values to single field (e.g. ``'fruit=apple'``) or to an array of fields (e.g. ``'fruits=[{fruit1: apple, fruit2: orange}, {fruit1: melon, fruit2: apple}]'``). The former is useful to capture simple fields and the latter to get data from an array of values. - -### Single field: mapping options - -When republishing a single field, you can include a set of ``mapping_options`` for each ``mapping``. These include: - -* `mapping_type`: this mapping option should be set to `single_field`. -* `filter`: a lambda expression that can be used to control whether or not the value is published based on a condition. For example, if you'd like to republish only String values that are different than ``SPAMMY STRING``, you can do it with: - - ```yaml - mapping_options: - filter: 'lambda x: (x != "SPAMMY STRING")' - ``` - -### Array of fields: mapping options - -When republishing an array of fields, you can include a set of ``mapping_options`` for each ``mapping``. These include: - -* `mapping_type`: this mapping option should be set to `array_of_fields`. -* `fields`: a set of fields that you'd like to capture from each array element. For example, if each array element contains the elements ``[a, c, d, e]`` and you'd like to get ``a`` and ``c`` only, you can specify it as: - - ```yaml - mapping_options: - fields: ["a", "c"] - ``` - - If no fields are specified, the republisher will get all the fields in each array element. - -* `filter`: a lambda expression that can be used to pick certain array elements based on a condition. For example, if you'd like to republish array elements where ``c > 5`` only, you can do it with: - - ```yaml - mapping_options: - filter: 'lambda x: (x > 5)' - ``` - -### JSON of fields: mapping options - -When republishing several fields of a nested structure, this mapping type allows to bundle them together in a single JSON message instead of republishing all the fields of interest separately. - -The `mapping_options` for this type include: - -* `mapping_type`: this mapping option should be set to `json_of_fields`. -* `fields`: a set of fields that you'd like to capture from the nested message. For example, if your message definition looks like [Twist](http://docs.ros.org/en/api/geometry_msgs/html/msg/Twist.html): - - setting - - ```yaml - mapping_options: - fields: ["x", "y", "z"] - ``` - - would output a JSON object with the fields as keys with their respective values for the message - - ```text - data: "linear_vel={\"y\": 0.00013548378774430603, \"x\": 0.0732172280550003, \"z\": 0.0}" - ``` - - * `filter`: a lambda expression that can be used to control whether or not the JSON object is published based on a condition. For example, if you'd like to republish only JSON objects that have a value for the key ``z`` different than ``0``, you can do it with: - - ```yaml - mapping_options: - filter: 'lambda linear_vel: (linear_vel["z"] != 0)' - ``` - -### Serialize: mapping options - -This mapping option transforms the entire ROS message to a JSON string. - -The `mapping_options` for this type include: - -* `mapping_type`: this mapping option should be set to `serialize`. -* `fields`: (optional) a set of first level fields or keys to keep. If not provided, all fields are kept. For example, using the following mapping option for serializing 4 [NavSatFix](https://docs.ros2.org/latest/api/sensor_msgs/msg/NavSatFix.html) fields: - - ```yaml - mapping_options: - fields: ["status", "latitude", "longitude", "position_covariance_type"] - ``` - - would output a JSON object with the fields as keys with their respective values for the message - - ```text - data: 'navsat={"status": {"status": 0, "service": 0}, "latitude": 0.0, "longitude": 0.0, "position_covariance_type": 0}' - ``` - -## Publishing fixed values - -Sometimes it is also useful to publish fixed values to facilitate fleet-wide observability. It is possible to publish environment variables, package versions or fixed values using the `static_publishers` array. - -See the included example configuration in `config/example.yaml` for specific examples. - -These values will be published as latched and delivered only once every time a subscriber connects to the republisher. - -## Building and running locally - -Find below instructions for building the package and running the node using the the code on the workspace (see also [colcon](https://colcon.readthedocs.io/en/released/reference/verb/build.html)). - -### Start ROS2 docker container (optional) - -You can run the commands below for building and running the republisher inside a docker container. - -```bash -docker run -ti --rm \ - --workdir /root/ros2_ws/ \ - -v .:/root/ros2_ws/src/inorbit_republisher \ - osrf/ros:foxy-desktop -``` - -### Build - -```bash -cd ~/ros2_ws -rosdep install --from-paths src -y --ignore-src -colcon build --packages-select inorbit_republisher --symlink-install -``` - -### Run - -```bash -source install/local_setup.bash -# Using the launch file under the 'launch' directory -ros2 launch inorbit_republisher example.launch.xml -``` - -## TODO - -* Schema validation -* Better documentation -* Error handling -* Proper logging -* Latched topic support -* Mapping of ROS parameters diff --git a/inorbit_republisher/package.xml b/inorbit_republisher/package.xml deleted file mode 100644 index d7d9df8..0000000 --- a/inorbit_republisher/package.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - inorbit_republisher - 0.4.1 - ROS2 to InOrbit topic republisher - InOrbit - MIT - ros2launch - - ament_python - - diff --git a/inorbit_republisher/resource/inorbit_republisher b/inorbit_republisher/resource/inorbit_republisher deleted file mode 100644 index e69de29..0000000 diff --git a/inorbit_republisher/setup.cfg b/inorbit_republisher/setup.cfg deleted file mode 100644 index 9336dd8..0000000 --- a/inorbit_republisher/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/inorbit_republisher -[install] -install-scripts=$base/lib/inorbit_republisher diff --git a/inorbit_republisher/setup.py b/inorbit_republisher/setup.py deleted file mode 100644 index 5a4ee20..0000000 --- a/inorbit_republisher/setup.py +++ /dev/null @@ -1,30 +0,0 @@ -from setuptools import setup -import os -from glob import glob - -package_name = 'inorbit_republisher' - -setup( - name=package_name, - version='0.4.1', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - (os.path.join('share', package_name), glob('launch/*')), - (os.path.join('share', package_name, 'config'), glob('config/*')) - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='InOrbit', - maintainer_email='support@inorbit.ai', - description='ROS2 to InOrbit topic republisher', - license='MIT', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - 'republisher = inorbit_republisher.republisher:main' - ], - }, -) diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index f6d914f..e688b6b 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -29,7 +29,7 @@ source install/setup.bash cd ros2 launch inorbit_republisher sample_data.launch.xml # On a different terminal windows -source /opt/ros/humble/setup.bash +source /opt/ros/jazzy/setup.bash $ ros2 topic echo my_temperature header: stamp: From 5782f90dc16a8fe93fd83e60637a7af41dde6164 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Wed, 18 Dec 2024 18:06:52 -0300 Subject: [PATCH 09/21] Deleted irrelevant folders --- .../test/sample_data/build/.built_by | 1 - .../test/sample_data/build/COLCON_IGNORE | 0 .../install/.colcon_install_layout | 1 - .../test/sample_data/install/COLCON_IGNORE | 0 .../install/_local_setup_util_ps1.py | 407 ------------------ .../install/_local_setup_util_sh.py | 407 ------------------ .../test/sample_data/install/local_setup.bash | 121 ------ .../test/sample_data/install/local_setup.ps1 | 55 --- .../test/sample_data/install/local_setup.sh | 137 ------ .../test/sample_data/install/local_setup.zsh | 134 ------ .../test/sample_data/install/setup.bash | 37 -- .../test/sample_data/install/setup.ps1 | 31 -- .../test/sample_data/install/setup.sh | 53 --- .../test/sample_data/install/setup.zsh | 37 -- .../test/sample_data/log/COLCON_IGNORE | 0 .../log/build_2024-12-13_20-02-50/events.log | 2 - .../build_2024-12-13_20-02-50/logger_all.log | 77 ---- .../log/build_2024-12-13_20-49-52/events.log | 2 - .../build_2024-12-13_20-49-52/logger_all.log | 76 ---- .../test/sample_data/log/latest | 1 - .../test/sample_data/log/latest_build | 1 - 21 files changed, 1580 deletions(-) delete mode 100644 inorbit_republisher/test/sample_data/build/.built_by delete mode 100644 inorbit_republisher/test/sample_data/build/COLCON_IGNORE delete mode 100644 inorbit_republisher/test/sample_data/install/.colcon_install_layout delete mode 100644 inorbit_republisher/test/sample_data/install/COLCON_IGNORE delete mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py delete mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.bash delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.ps1 delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.sh delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.zsh delete mode 100644 inorbit_republisher/test/sample_data/install/setup.bash delete mode 100644 inorbit_republisher/test/sample_data/install/setup.ps1 delete mode 100644 inorbit_republisher/test/sample_data/install/setup.sh delete mode 100644 inorbit_republisher/test/sample_data/install/setup.zsh delete mode 100644 inorbit_republisher/test/sample_data/log/COLCON_IGNORE delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log delete mode 120000 inorbit_republisher/test/sample_data/log/latest delete mode 120000 inorbit_republisher/test/sample_data/log/latest_build diff --git a/inorbit_republisher/test/sample_data/build/.built_by b/inorbit_republisher/test/sample_data/build/.built_by deleted file mode 100644 index 06e74ac..0000000 --- a/inorbit_republisher/test/sample_data/build/.built_by +++ /dev/null @@ -1 +0,0 @@ -colcon diff --git a/inorbit_republisher/test/sample_data/build/COLCON_IGNORE b/inorbit_republisher/test/sample_data/build/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/inorbit_republisher/test/sample_data/install/.colcon_install_layout b/inorbit_republisher/test/sample_data/install/.colcon_install_layout deleted file mode 100644 index 3aad533..0000000 --- a/inorbit_republisher/test/sample_data/install/.colcon_install_layout +++ /dev/null @@ -1 +0,0 @@ -isolated diff --git a/inorbit_republisher/test/sample_data/install/COLCON_IGNORE b/inorbit_republisher/test/sample_data/install/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py deleted file mode 100644 index 3c6d9e8..0000000 --- a/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py +++ /dev/null @@ -1,407 +0,0 @@ -# Copyright 2016-2019 Dirk Thomas -# Licensed under the Apache License, Version 2.0 - -import argparse -from collections import OrderedDict -import os -from pathlib import Path -import sys - - -FORMAT_STR_COMMENT_LINE = '# {comment}' -FORMAT_STR_SET_ENV_VAR = 'Set-Item -Path "Env:{name}" -Value "{value}"' -FORMAT_STR_USE_ENV_VAR = '$env:{name}' -FORMAT_STR_INVOKE_SCRIPT = '_colcon_prefix_powershell_source_script "{script_path}"' # noqa: E501 -FORMAT_STR_REMOVE_LEADING_SEPARATOR = '' # noqa: E501 -FORMAT_STR_REMOVE_TRAILING_SEPARATOR = '' # noqa: E501 - -DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' -DSV_TYPE_SET = 'set' -DSV_TYPE_SET_IF_UNSET = 'set-if-unset' -DSV_TYPE_SOURCE = 'source' - - -def main(argv=sys.argv[1:]): # noqa: D103 - parser = argparse.ArgumentParser( - description='Output shell commands for the packages in topological ' - 'order') - parser.add_argument( - 'primary_extension', - help='The file extension of the primary shell') - parser.add_argument( - 'additional_extension', nargs='?', - help='The additional file extension to be considered') - parser.add_argument( - '--merged-install', action='store_true', - help='All install prefixes are merged into a single location') - args = parser.parse_args(argv) - - packages = get_packages(Path(__file__).parent, args.merged_install) - - ordered_packages = order_packages(packages) - for pkg_name in ordered_packages: - if _include_comments(): - print( - FORMAT_STR_COMMENT_LINE.format_map( - {'comment': 'Package: ' + pkg_name})) - prefix = os.path.abspath(os.path.dirname(__file__)) - if not args.merged_install: - prefix = os.path.join(prefix, pkg_name) - for line in get_commands( - pkg_name, prefix, args.primary_extension, - args.additional_extension - ): - print(line) - - for line in _remove_ending_separators(): - print(line) - - -def get_packages(prefix_path, merged_install): - """ - Find packages based on colcon-specific files created during installation. - - :param Path prefix_path: The install prefix path of all packages - :param bool merged_install: The flag if the packages are all installed - directly in the prefix or if each package is installed in a subdirectory - named after the package - :returns: A mapping from the package name to the set of runtime - dependencies - :rtype: dict - """ - packages = {} - # since importing colcon_core isn't feasible here the following constant - # must match colcon_core.location.get_relative_package_index_path() - subdirectory = 'share/colcon-core/packages' - if merged_install: - # return if workspace is empty - if not (prefix_path / subdirectory).is_dir(): - return packages - # find all files in the subdirectory - for p in (prefix_path / subdirectory).iterdir(): - if not p.is_file(): - continue - if p.name.startswith('.'): - continue - add_package_runtime_dependencies(p, packages) - else: - # for each subdirectory look for the package specific file - for p in prefix_path.iterdir(): - if not p.is_dir(): - continue - if p.name.startswith('.'): - continue - p = p / subdirectory / p.name - if p.is_file(): - add_package_runtime_dependencies(p, packages) - - # remove unknown dependencies - pkg_names = set(packages.keys()) - for k in packages.keys(): - packages[k] = {d for d in packages[k] if d in pkg_names} - - return packages - - -def add_package_runtime_dependencies(path, packages): - """ - Check the path and if it exists extract the packages runtime dependencies. - - :param Path path: The resource file containing the runtime dependencies - :param dict packages: A mapping from package names to the sets of runtime - dependencies to add to - """ - content = path.read_text() - dependencies = set(content.split(os.pathsep) if content else []) - packages[path.name] = dependencies - - -def order_packages(packages): - """ - Order packages topologically. - - :param dict packages: A mapping from package name to the set of runtime - dependencies - :returns: The package names - :rtype: list - """ - # select packages with no dependencies in alphabetical order - to_be_ordered = list(packages.keys()) - ordered = [] - while to_be_ordered: - pkg_names_without_deps = [ - name for name in to_be_ordered if not packages[name]] - if not pkg_names_without_deps: - reduce_cycle_set(packages) - raise RuntimeError( - 'Circular dependency between: ' + ', '.join(sorted(packages))) - pkg_names_without_deps.sort() - pkg_name = pkg_names_without_deps[0] - to_be_ordered.remove(pkg_name) - ordered.append(pkg_name) - # remove item from dependency lists - for k in list(packages.keys()): - if pkg_name in packages[k]: - packages[k].remove(pkg_name) - return ordered - - -def reduce_cycle_set(packages): - """ - Reduce the set of packages to the ones part of the circular dependency. - - :param dict packages: A mapping from package name to the set of runtime - dependencies which is modified in place - """ - last_depended = None - while len(packages) > 0: - # get all remaining dependencies - depended = set() - for pkg_name, dependencies in packages.items(): - depended = depended.union(dependencies) - # remove all packages which are not dependent on - for name in list(packages.keys()): - if name not in depended: - del packages[name] - if last_depended: - # if remaining packages haven't changed return them - if last_depended == depended: - return packages.keys() - # otherwise reduce again - last_depended = depended - - -def _include_comments(): - # skipping comment lines when COLCON_TRACE is not set speeds up the - # processing especially on Windows - return bool(os.environ.get('COLCON_TRACE')) - - -def get_commands(pkg_name, prefix, primary_extension, additional_extension): - commands = [] - package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') - if os.path.exists(package_dsv_path): - commands += process_dsv_file( - package_dsv_path, prefix, primary_extension, additional_extension) - return commands - - -def process_dsv_file( - dsv_path, prefix, primary_extension=None, additional_extension=None -): - commands = [] - if _include_comments(): - commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) - with open(dsv_path, 'r') as h: - content = h.read() - lines = content.splitlines() - - basenames = OrderedDict() - for i, line in enumerate(lines): - # skip over empty or whitespace-only lines - if not line.strip(): - continue - # skip over comments - if line.startswith('#'): - continue - try: - type_, remainder = line.split(';', 1) - except ValueError: - raise RuntimeError( - "Line %d in '%s' doesn't contain a semicolon separating the " - 'type from the arguments' % (i + 1, dsv_path)) - if type_ != DSV_TYPE_SOURCE: - # handle non-source lines - try: - commands += handle_dsv_types_except_source( - type_, remainder, prefix) - except RuntimeError as e: - raise RuntimeError( - "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e - else: - # group remaining source lines by basename - path_without_ext, ext = os.path.splitext(remainder) - if path_without_ext not in basenames: - basenames[path_without_ext] = set() - assert ext.startswith('.') - ext = ext[1:] - if ext in (primary_extension, additional_extension): - basenames[path_without_ext].add(ext) - - # add the dsv extension to each basename if the file exists - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if os.path.exists(basename + '.dsv'): - extensions.add('dsv') - - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if 'dsv' in extensions: - # process dsv files recursively - commands += process_dsv_file( - basename + '.dsv', prefix, primary_extension=primary_extension, - additional_extension=additional_extension) - elif primary_extension in extensions and len(extensions) == 1: - # source primary-only files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + primary_extension})] - elif additional_extension in extensions: - # source non-primary files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + additional_extension})] - - return commands - - -def handle_dsv_types_except_source(type_, remainder, prefix): - commands = [] - if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): - try: - env_name, value = remainder.split(';', 1) - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the value') - try_prefixed_value = os.path.join(prefix, value) if value else prefix - if os.path.exists(try_prefixed_value): - value = try_prefixed_value - if type_ == DSV_TYPE_SET: - commands += _set(env_name, value) - elif type_ == DSV_TYPE_SET_IF_UNSET: - commands += _set_if_unset(env_name, value) - else: - assert False - elif type_ in ( - DSV_TYPE_APPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS - ): - try: - env_name_and_values = remainder.split(';') - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the values') - env_name = env_name_and_values[0] - values = env_name_and_values[1:] - for value in values: - if not value: - value = prefix - elif not os.path.isabs(value): - value = os.path.join(prefix, value) - if ( - type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and - not os.path.exists(value) - ): - comment = f'skip extending {env_name} with not existing ' \ - f'path: {value}' - if _include_comments(): - commands.append( - FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) - elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: - commands += _append_unique_value(env_name, value) - else: - commands += _prepend_unique_value(env_name, value) - else: - raise RuntimeError( - 'contains an unknown environment hook type: ' + type_) - return commands - - -env_state = {} - - -def _append_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # append even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional leading separator - extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': extend + value}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -def _prepend_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # prepend even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional trailing separator - extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value + extend}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -# generate commands for removing prepended underscores -def _remove_ending_separators(): - # do nothing if the shell extension does not implement the logic - if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: - return [] - - global env_state - commands = [] - for name in env_state: - # skip variables that already had values before this script started prepending - if name in os.environ: - continue - commands += [ - FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), - FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] - return commands - - -def _set(name, value): - global env_state - env_state[name] = value - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - return [line] - - -def _set_if_unset(name, value): - global env_state - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - if env_state.get(name, os.environ.get(name)): - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -if __name__ == '__main__': # pragma: no cover - try: - rc = main() - except RuntimeError as e: - print(str(e), file=sys.stderr) - rc = 1 - sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py deleted file mode 100644 index f67eaa9..0000000 --- a/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py +++ /dev/null @@ -1,407 +0,0 @@ -# Copyright 2016-2019 Dirk Thomas -# Licensed under the Apache License, Version 2.0 - -import argparse -from collections import OrderedDict -import os -from pathlib import Path -import sys - - -FORMAT_STR_COMMENT_LINE = '# {comment}' -FORMAT_STR_SET_ENV_VAR = 'export {name}="{value}"' -FORMAT_STR_USE_ENV_VAR = '${name}' -FORMAT_STR_INVOKE_SCRIPT = 'COLCON_CURRENT_PREFIX="{prefix}" _colcon_prefix_sh_source_script "{script_path}"' # noqa: E501 -FORMAT_STR_REMOVE_LEADING_SEPARATOR = 'if [ "$(echo -n ${name} | head -c 1)" = ":" ]; then export {name}=${{{name}#?}} ; fi' # noqa: E501 -FORMAT_STR_REMOVE_TRAILING_SEPARATOR = 'if [ "$(echo -n ${name} | tail -c 1)" = ":" ]; then export {name}=${{{name}%?}} ; fi' # noqa: E501 - -DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' -DSV_TYPE_SET = 'set' -DSV_TYPE_SET_IF_UNSET = 'set-if-unset' -DSV_TYPE_SOURCE = 'source' - - -def main(argv=sys.argv[1:]): # noqa: D103 - parser = argparse.ArgumentParser( - description='Output shell commands for the packages in topological ' - 'order') - parser.add_argument( - 'primary_extension', - help='The file extension of the primary shell') - parser.add_argument( - 'additional_extension', nargs='?', - help='The additional file extension to be considered') - parser.add_argument( - '--merged-install', action='store_true', - help='All install prefixes are merged into a single location') - args = parser.parse_args(argv) - - packages = get_packages(Path(__file__).parent, args.merged_install) - - ordered_packages = order_packages(packages) - for pkg_name in ordered_packages: - if _include_comments(): - print( - FORMAT_STR_COMMENT_LINE.format_map( - {'comment': 'Package: ' + pkg_name})) - prefix = os.path.abspath(os.path.dirname(__file__)) - if not args.merged_install: - prefix = os.path.join(prefix, pkg_name) - for line in get_commands( - pkg_name, prefix, args.primary_extension, - args.additional_extension - ): - print(line) - - for line in _remove_ending_separators(): - print(line) - - -def get_packages(prefix_path, merged_install): - """ - Find packages based on colcon-specific files created during installation. - - :param Path prefix_path: The install prefix path of all packages - :param bool merged_install: The flag if the packages are all installed - directly in the prefix or if each package is installed in a subdirectory - named after the package - :returns: A mapping from the package name to the set of runtime - dependencies - :rtype: dict - """ - packages = {} - # since importing colcon_core isn't feasible here the following constant - # must match colcon_core.location.get_relative_package_index_path() - subdirectory = 'share/colcon-core/packages' - if merged_install: - # return if workspace is empty - if not (prefix_path / subdirectory).is_dir(): - return packages - # find all files in the subdirectory - for p in (prefix_path / subdirectory).iterdir(): - if not p.is_file(): - continue - if p.name.startswith('.'): - continue - add_package_runtime_dependencies(p, packages) - else: - # for each subdirectory look for the package specific file - for p in prefix_path.iterdir(): - if not p.is_dir(): - continue - if p.name.startswith('.'): - continue - p = p / subdirectory / p.name - if p.is_file(): - add_package_runtime_dependencies(p, packages) - - # remove unknown dependencies - pkg_names = set(packages.keys()) - for k in packages.keys(): - packages[k] = {d for d in packages[k] if d in pkg_names} - - return packages - - -def add_package_runtime_dependencies(path, packages): - """ - Check the path and if it exists extract the packages runtime dependencies. - - :param Path path: The resource file containing the runtime dependencies - :param dict packages: A mapping from package names to the sets of runtime - dependencies to add to - """ - content = path.read_text() - dependencies = set(content.split(os.pathsep) if content else []) - packages[path.name] = dependencies - - -def order_packages(packages): - """ - Order packages topologically. - - :param dict packages: A mapping from package name to the set of runtime - dependencies - :returns: The package names - :rtype: list - """ - # select packages with no dependencies in alphabetical order - to_be_ordered = list(packages.keys()) - ordered = [] - while to_be_ordered: - pkg_names_without_deps = [ - name for name in to_be_ordered if not packages[name]] - if not pkg_names_without_deps: - reduce_cycle_set(packages) - raise RuntimeError( - 'Circular dependency between: ' + ', '.join(sorted(packages))) - pkg_names_without_deps.sort() - pkg_name = pkg_names_without_deps[0] - to_be_ordered.remove(pkg_name) - ordered.append(pkg_name) - # remove item from dependency lists - for k in list(packages.keys()): - if pkg_name in packages[k]: - packages[k].remove(pkg_name) - return ordered - - -def reduce_cycle_set(packages): - """ - Reduce the set of packages to the ones part of the circular dependency. - - :param dict packages: A mapping from package name to the set of runtime - dependencies which is modified in place - """ - last_depended = None - while len(packages) > 0: - # get all remaining dependencies - depended = set() - for pkg_name, dependencies in packages.items(): - depended = depended.union(dependencies) - # remove all packages which are not dependent on - for name in list(packages.keys()): - if name not in depended: - del packages[name] - if last_depended: - # if remaining packages haven't changed return them - if last_depended == depended: - return packages.keys() - # otherwise reduce again - last_depended = depended - - -def _include_comments(): - # skipping comment lines when COLCON_TRACE is not set speeds up the - # processing especially on Windows - return bool(os.environ.get('COLCON_TRACE')) - - -def get_commands(pkg_name, prefix, primary_extension, additional_extension): - commands = [] - package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') - if os.path.exists(package_dsv_path): - commands += process_dsv_file( - package_dsv_path, prefix, primary_extension, additional_extension) - return commands - - -def process_dsv_file( - dsv_path, prefix, primary_extension=None, additional_extension=None -): - commands = [] - if _include_comments(): - commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) - with open(dsv_path, 'r') as h: - content = h.read() - lines = content.splitlines() - - basenames = OrderedDict() - for i, line in enumerate(lines): - # skip over empty or whitespace-only lines - if not line.strip(): - continue - # skip over comments - if line.startswith('#'): - continue - try: - type_, remainder = line.split(';', 1) - except ValueError: - raise RuntimeError( - "Line %d in '%s' doesn't contain a semicolon separating the " - 'type from the arguments' % (i + 1, dsv_path)) - if type_ != DSV_TYPE_SOURCE: - # handle non-source lines - try: - commands += handle_dsv_types_except_source( - type_, remainder, prefix) - except RuntimeError as e: - raise RuntimeError( - "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e - else: - # group remaining source lines by basename - path_without_ext, ext = os.path.splitext(remainder) - if path_without_ext not in basenames: - basenames[path_without_ext] = set() - assert ext.startswith('.') - ext = ext[1:] - if ext in (primary_extension, additional_extension): - basenames[path_without_ext].add(ext) - - # add the dsv extension to each basename if the file exists - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if os.path.exists(basename + '.dsv'): - extensions.add('dsv') - - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if 'dsv' in extensions: - # process dsv files recursively - commands += process_dsv_file( - basename + '.dsv', prefix, primary_extension=primary_extension, - additional_extension=additional_extension) - elif primary_extension in extensions and len(extensions) == 1: - # source primary-only files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + primary_extension})] - elif additional_extension in extensions: - # source non-primary files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + additional_extension})] - - return commands - - -def handle_dsv_types_except_source(type_, remainder, prefix): - commands = [] - if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): - try: - env_name, value = remainder.split(';', 1) - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the value') - try_prefixed_value = os.path.join(prefix, value) if value else prefix - if os.path.exists(try_prefixed_value): - value = try_prefixed_value - if type_ == DSV_TYPE_SET: - commands += _set(env_name, value) - elif type_ == DSV_TYPE_SET_IF_UNSET: - commands += _set_if_unset(env_name, value) - else: - assert False - elif type_ in ( - DSV_TYPE_APPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS - ): - try: - env_name_and_values = remainder.split(';') - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the values') - env_name = env_name_and_values[0] - values = env_name_and_values[1:] - for value in values: - if not value: - value = prefix - elif not os.path.isabs(value): - value = os.path.join(prefix, value) - if ( - type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and - not os.path.exists(value) - ): - comment = f'skip extending {env_name} with not existing ' \ - f'path: {value}' - if _include_comments(): - commands.append( - FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) - elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: - commands += _append_unique_value(env_name, value) - else: - commands += _prepend_unique_value(env_name, value) - else: - raise RuntimeError( - 'contains an unknown environment hook type: ' + type_) - return commands - - -env_state = {} - - -def _append_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # append even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional leading separator - extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': extend + value}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -def _prepend_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # prepend even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional trailing separator - extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value + extend}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -# generate commands for removing prepended underscores -def _remove_ending_separators(): - # do nothing if the shell extension does not implement the logic - if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: - return [] - - global env_state - commands = [] - for name in env_state: - # skip variables that already had values before this script started prepending - if name in os.environ: - continue - commands += [ - FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), - FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] - return commands - - -def _set(name, value): - global env_state - env_state[name] = value - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - return [line] - - -def _set_if_unset(name, value): - global env_state - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - if env_state.get(name, os.environ.get(name)): - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -if __name__ == '__main__': # pragma: no cover - try: - rc = main() - except RuntimeError as e: - print(str(e), file=sys.stderr) - rc = 1 - sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/local_setup.bash b/inorbit_republisher/test/sample_data/install/local_setup.bash deleted file mode 100644 index 03f0025..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.bash +++ /dev/null @@ -1,121 +0,0 @@ -# generated from colcon_bash/shell/template/prefix.bash.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# a bash script is able to determine its own path if necessary -if [ -z "$COLCON_CURRENT_PREFIX" ]; then - _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" -else - _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -fi - -# function to prepend a value to a variable -# which uses colons as separators -# duplicates as well as trailing separators are avoided -# first argument: the name of the result variable -# second argument: the value to be prepended -_colcon_prefix_bash_prepend_unique_value() { - # arguments - _listname="$1" - _value="$2" - - # get values from variable - eval _values=\"\$$_listname\" - # backup the field separator - _colcon_prefix_bash_prepend_unique_value_IFS="$IFS" - IFS=":" - # start with the new value - _all_values="$_value" - _contained_value="" - # iterate over existing values in the variable - for _item in $_values; do - # ignore empty strings - if [ -z "$_item" ]; then - continue - fi - # ignore duplicates of _value - if [ "$_item" = "$_value" ]; then - _contained_value=1 - continue - fi - # keep non-duplicate values - _all_values="$_all_values:$_item" - done - unset _item - if [ -z "$_contained_value" ]; then - if [ -n "$COLCON_TRACE" ]; then - if [ "$_all_values" = "$_value" ]; then - echo "export $_listname=$_value" - else - echo "export $_listname=$_value:\$$_listname" - fi - fi - fi - unset _contained_value - # restore the field separator - IFS="$_colcon_prefix_bash_prepend_unique_value_IFS" - unset _colcon_prefix_bash_prepend_unique_value_IFS - # export the updated variable - eval export $_listname=\"$_all_values\" - unset _all_values - unset _values - - unset _value - unset _listname -} - -# add this prefix to the COLCON_PREFIX_PATH -_colcon_prefix_bash_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX" -unset _colcon_prefix_bash_prepend_unique_value - -# check environment variable for custom Python executable -if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then - if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then - echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" - return 1 - fi - _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" -else - # try the Python executable known at configure time - _colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if [ ! -f "$_colcon_python_executable" ]; then - if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then - echo "error: unable to find python3 executable" - return 1 - fi - _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` - fi -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# get all commands in topological order -_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh bash)" -unset _colcon_python_executable -if [ -n "$COLCON_TRACE" ]; then - echo "$(declare -f _colcon_prefix_sh_source_script)" - echo "# Execute generated script:" - echo "# <<<" - echo "${_colcon_ordered_commands}" - echo "# >>>" - echo "unset _colcon_prefix_sh_source_script" -fi -eval "${_colcon_ordered_commands}" -unset _colcon_ordered_commands - -unset _colcon_prefix_sh_source_script - -unset _colcon_prefix_bash_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.ps1 b/inorbit_republisher/test/sample_data/install/local_setup.ps1 deleted file mode 100644 index 6f68c8d..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -# generated from colcon_powershell/shell/template/prefix.ps1.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# check environment variable for custom Python executable -if ($env:COLCON_PYTHON_EXECUTABLE) { - if (!(Test-Path "$env:COLCON_PYTHON_EXECUTABLE" -PathType Leaf)) { - echo "error: COLCON_PYTHON_EXECUTABLE '$env:COLCON_PYTHON_EXECUTABLE' doesn't exist" - exit 1 - } - $_colcon_python_executable="$env:COLCON_PYTHON_EXECUTABLE" -} else { - # use the Python executable known at configure time - $_colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if (!(Test-Path "$_colcon_python_executable" -PathType Leaf)) { - if (!(Get-Command "python3" -ErrorAction SilentlyContinue)) { - echo "error: unable to find python3 executable" - exit 1 - } - $_colcon_python_executable="python3" - } -} - -# function to source another script with conditional trace output -# first argument: the path of the script -function _colcon_prefix_powershell_source_script { - param ( - $_colcon_prefix_powershell_source_script_param - ) - # source script with conditional trace output - if (Test-Path $_colcon_prefix_powershell_source_script_param) { - if ($env:COLCON_TRACE) { - echo ". '$_colcon_prefix_powershell_source_script_param'" - } - . "$_colcon_prefix_powershell_source_script_param" - } else { - Write-Error "not found: '$_colcon_prefix_powershell_source_script_param'" - } -} - -# get all commands in topological order -$_colcon_ordered_commands = & "$_colcon_python_executable" "$(Split-Path $PSCommandPath -Parent)/_local_setup_util_ps1.py" ps1 - -# execute all commands in topological order -if ($env:COLCON_TRACE) { - echo "Execute generated script:" - echo "<<<" - $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Write-Output - echo ">>>" -} -if ($_colcon_ordered_commands) { - $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Invoke-Expression -} diff --git a/inorbit_republisher/test/sample_data/install/local_setup.sh b/inorbit_republisher/test/sample_data/install/local_setup.sh deleted file mode 100644 index d40d34d..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.sh +++ /dev/null @@ -1,137 +0,0 @@ -# generated from colcon_core/shell/template/prefix.sh.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# since a plain shell script can't determine its own path when being sourced -# either use the provided COLCON_CURRENT_PREFIX -# or fall back to the build time prefix (if it exists) -_colcon_prefix_sh_COLCON_CURRENT_PREFIX="/root/ros2_ws/src/inorbit_republisher/test/sample_data/install" -if [ -z "$COLCON_CURRENT_PREFIX" ]; then - if [ ! -d "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" ]; then - echo "The build time path \"$_colcon_prefix_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 - unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX - return 1 - fi -else - _colcon_prefix_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -fi - -# function to prepend a value to a variable -# which uses colons as separators -# duplicates as well as trailing separators are avoided -# first argument: the name of the result variable -# second argument: the value to be prepended -_colcon_prefix_sh_prepend_unique_value() { - # arguments - _listname="$1" - _value="$2" - - # get values from variable - eval _values=\"\$$_listname\" - # backup the field separator - _colcon_prefix_sh_prepend_unique_value_IFS="$IFS" - IFS=":" - # start with the new value - _all_values="$_value" - _contained_value="" - # iterate over existing values in the variable - for _item in $_values; do - # ignore empty strings - if [ -z "$_item" ]; then - continue - fi - # ignore duplicates of _value - if [ "$_item" = "$_value" ]; then - _contained_value=1 - continue - fi - # keep non-duplicate values - _all_values="$_all_values:$_item" - done - unset _item - if [ -z "$_contained_value" ]; then - if [ -n "$COLCON_TRACE" ]; then - if [ "$_all_values" = "$_value" ]; then - echo "export $_listname=$_value" - else - echo "export $_listname=$_value:\$$_listname" - fi - fi - fi - unset _contained_value - # restore the field separator - IFS="$_colcon_prefix_sh_prepend_unique_value_IFS" - unset _colcon_prefix_sh_prepend_unique_value_IFS - # export the updated variable - eval export $_listname=\"$_all_values\" - unset _all_values - unset _values - - unset _value - unset _listname -} - -# add this prefix to the COLCON_PREFIX_PATH -_colcon_prefix_sh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" -unset _colcon_prefix_sh_prepend_unique_value - -# check environment variable for custom Python executable -if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then - if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then - echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" - return 1 - fi - _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" -else - # try the Python executable known at configure time - _colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if [ ! -f "$_colcon_python_executable" ]; then - if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then - echo "error: unable to find python3 executable" - return 1 - fi - _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` - fi -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# get all commands in topological order -_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh)" -unset _colcon_python_executable -if [ -n "$COLCON_TRACE" ]; then - echo "_colcon_prefix_sh_source_script() { - if [ -f \"\$1\" ]; then - if [ -n \"\$COLCON_TRACE\" ]; then - echo \"# . \\\"\$1\\\"\" - fi - . \"\$1\" - else - echo \"not found: \\\"\$1\\\"\" 1>&2 - fi - }" - echo "# Execute generated script:" - echo "# <<<" - echo "${_colcon_ordered_commands}" - echo "# >>>" - echo "unset _colcon_prefix_sh_source_script" -fi -eval "${_colcon_ordered_commands}" -unset _colcon_ordered_commands - -unset _colcon_prefix_sh_source_script - -unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.zsh b/inorbit_republisher/test/sample_data/install/local_setup.zsh deleted file mode 100644 index b648710..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.zsh +++ /dev/null @@ -1,134 +0,0 @@ -# generated from colcon_zsh/shell/template/prefix.zsh.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# a zsh script is able to determine its own path if necessary -if [ -z "$COLCON_CURRENT_PREFIX" ]; then - _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" -else - _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -fi - -# function to convert array-like strings into arrays -# to workaround SH_WORD_SPLIT not being set -_colcon_prefix_zsh_convert_to_array() { - local _listname=$1 - local _dollar="$" - local _split="{=" - local _to_array="(\"$_dollar$_split$_listname}\")" - eval $_listname=$_to_array -} - -# function to prepend a value to a variable -# which uses colons as separators -# duplicates as well as trailing separators are avoided -# first argument: the name of the result variable -# second argument: the value to be prepended -_colcon_prefix_zsh_prepend_unique_value() { - # arguments - _listname="$1" - _value="$2" - - # get values from variable - eval _values=\"\$$_listname\" - # backup the field separator - _colcon_prefix_zsh_prepend_unique_value_IFS="$IFS" - IFS=":" - # start with the new value - _all_values="$_value" - _contained_value="" - # workaround SH_WORD_SPLIT not being set - _colcon_prefix_zsh_convert_to_array _values - # iterate over existing values in the variable - for _item in $_values; do - # ignore empty strings - if [ -z "$_item" ]; then - continue - fi - # ignore duplicates of _value - if [ "$_item" = "$_value" ]; then - _contained_value=1 - continue - fi - # keep non-duplicate values - _all_values="$_all_values:$_item" - done - unset _item - if [ -z "$_contained_value" ]; then - if [ -n "$COLCON_TRACE" ]; then - if [ "$_all_values" = "$_value" ]; then - echo "export $_listname=$_value" - else - echo "export $_listname=$_value:\$$_listname" - fi - fi - fi - unset _contained_value - # restore the field separator - IFS="$_colcon_prefix_zsh_prepend_unique_value_IFS" - unset _colcon_prefix_zsh_prepend_unique_value_IFS - # export the updated variable - eval export $_listname=\"$_all_values\" - unset _all_values - unset _values - - unset _value - unset _listname -} - -# add this prefix to the COLCON_PREFIX_PATH -_colcon_prefix_zsh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX" -unset _colcon_prefix_zsh_prepend_unique_value -unset _colcon_prefix_zsh_convert_to_array - -# check environment variable for custom Python executable -if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then - if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then - echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" - return 1 - fi - _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" -else - # try the Python executable known at configure time - _colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if [ ! -f "$_colcon_python_executable" ]; then - if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then - echo "error: unable to find python3 executable" - return 1 - fi - _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` - fi -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# get all commands in topological order -_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh zsh)" -unset _colcon_python_executable -if [ -n "$COLCON_TRACE" ]; then - echo "$(declare -f _colcon_prefix_sh_source_script)" - echo "# Execute generated script:" - echo "# <<<" - echo "${_colcon_ordered_commands}" - echo "# >>>" - echo "unset _colcon_prefix_sh_source_script" -fi -eval "${_colcon_ordered_commands}" -unset _colcon_ordered_commands - -unset _colcon_prefix_sh_source_script - -unset _colcon_prefix_zsh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.bash b/inorbit_republisher/test/sample_data/install/setup.bash deleted file mode 100644 index a648296..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.bash +++ /dev/null @@ -1,37 +0,0 @@ -# generated from colcon_bash/shell/template/prefix_chain.bash.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_chain_bash_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# source chained prefixes -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/opt/ros/humble" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/install" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" - -# source this prefix -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" - -unset COLCON_CURRENT_PREFIX -unset _colcon_prefix_chain_bash_source_script diff --git a/inorbit_republisher/test/sample_data/install/setup.ps1 b/inorbit_republisher/test/sample_data/install/setup.ps1 deleted file mode 100644 index 8c90c86..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -# generated from colcon_powershell/shell/template/prefix_chain.ps1.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# function to source another script with conditional trace output -# first argument: the path of the script -function _colcon_prefix_chain_powershell_source_script { - param ( - $_colcon_prefix_chain_powershell_source_script_param - ) - # source script with conditional trace output - if (Test-Path $_colcon_prefix_chain_powershell_source_script_param) { - if ($env:COLCON_TRACE) { - echo ". '$_colcon_prefix_chain_powershell_source_script_param'" - } - . "$_colcon_prefix_chain_powershell_source_script_param" - } else { - Write-Error "not found: '$_colcon_prefix_chain_powershell_source_script_param'" - } -} - -# source chained prefixes -_colcon_prefix_chain_powershell_source_script "/opt/ros/humble\local_setup.ps1" -_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/install\local_setup.ps1" -_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/src/install\local_setup.ps1" - -# source this prefix -$env:COLCON_CURRENT_PREFIX=(Split-Path $PSCommandPath -Parent) -_colcon_prefix_chain_powershell_source_script "$env:COLCON_CURRENT_PREFIX\local_setup.ps1" diff --git a/inorbit_republisher/test/sample_data/install/setup.sh b/inorbit_republisher/test/sample_data/install/setup.sh deleted file mode 100644 index e4196d7..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.sh +++ /dev/null @@ -1,53 +0,0 @@ -# generated from colcon_core/shell/template/prefix_chain.sh.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# since a plain shell script can't determine its own path when being sourced -# either use the provided COLCON_CURRENT_PREFIX -# or fall back to the build time prefix (if it exists) -_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX=/root/ros2_ws/src/inorbit_republisher/test/sample_data/install -if [ ! -z "$COLCON_CURRENT_PREFIX" ]; then - _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -elif [ ! -d "$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" ]; then - echo "The build time path \"$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 - unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX - return 1 -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_chain_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# source chained prefixes -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="/opt/ros/humble" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/install" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - - -# source this prefix -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - -unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX -unset _colcon_prefix_chain_sh_source_script -unset COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.zsh b/inorbit_republisher/test/sample_data/install/setup.zsh deleted file mode 100644 index c478d8a..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.zsh +++ /dev/null @@ -1,37 +0,0 @@ -# generated from colcon_zsh/shell/template/prefix_chain.zsh.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_chain_zsh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# source chained prefixes -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/opt/ros/humble" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/install" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" - -# source this prefix -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" - -unset COLCON_CURRENT_PREFIX -unset _colcon_prefix_chain_zsh_source_script diff --git a/inorbit_republisher/test/sample_data/log/COLCON_IGNORE b/inorbit_republisher/test/sample_data/log/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log deleted file mode 100644 index 08ed030..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log +++ /dev/null @@ -1,2 +0,0 @@ -[0.000000] (-) TimerEvent: {} -[0.000379] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log deleted file mode 100644 index fe428ee..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log +++ /dev/null @@ -1,77 +0,0 @@ -[0.165s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build', '--packages-select', 'inorbit_republisher', '--symlink-install'] -[0.165s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=True, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=['inorbit_republisher'], packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) -[0.361s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters -[0.362s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' -[0.363s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover -[0.363s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored -[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] -[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' -[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults -[0.380s] WARNING:colcon.colcon_core.package_selection:ignoring unknown package 'inorbit_republisher' in --packages-select -[0.410s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor -[0.411s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete -[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop -[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed -[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' -[0.412s] DEBUG:colcon.colcon_core.event_reactor:joining thread -[0.418s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' -[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems -[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems -[0.419s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' -[0.419s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 -[0.419s] DEBUG:colcon.colcon_core.event_reactor:joined thread -[0.422s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems -[0.422s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' -[0.423s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' -[0.425s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' -[0.428s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' -[0.428s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' -[0.429s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' -[0.430s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' -[0.431s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' -[0.432s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' -[0.433s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log deleted file mode 100644 index ffcb674..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log +++ /dev/null @@ -1,2 +0,0 @@ -[0.000000] (-) TimerEvent: {} -[0.000588] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log deleted file mode 100644 index dad4847..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log +++ /dev/null @@ -1,76 +0,0 @@ -[0.181s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build'] -[0.181s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=False, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=None, packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) -[0.389s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters -[0.390s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' -[0.391s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover -[0.392s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] -[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' -[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] -[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults -[0.438s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' -[0.441s] DEBUG:colcon.colcon_core.event_reactor:joining thread -[0.447s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' -[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems -[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems -[0.448s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' -[0.448s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 -[0.448s] DEBUG:colcon.colcon_core.event_reactor:joined thread -[0.451s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems -[0.451s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' -[0.453s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' -[0.455s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' -[0.457s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' -[0.458s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' -[0.458s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' -[0.460s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' -[0.460s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' -[0.462s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' -[0.462s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/latest b/inorbit_republisher/test/sample_data/log/latest deleted file mode 120000 index b57d247..0000000 --- a/inorbit_republisher/test/sample_data/log/latest +++ /dev/null @@ -1 +0,0 @@ -latest_build \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/log/latest_build b/inorbit_republisher/test/sample_data/log/latest_build deleted file mode 120000 index 4ba36b2..0000000 --- a/inorbit_republisher/test/sample_data/log/latest_build +++ /dev/null @@ -1 +0,0 @@ -build_2024-12-13_20-49-52 \ No newline at end of file From 8a2aca2b303799de5caeb7570d60e1525dfd2258 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Wed, 18 Dec 2024 18:09:17 -0300 Subject: [PATCH 10/21] Deleted irrelevant files --- inorbit_republisher/config/example.yaml | 78 ------------------------- inorbit_republisher/test/README.md | 50 ---------------- 2 files changed, 128 deletions(-) delete mode 100644 inorbit_republisher/config/example.yaml delete mode 100644 inorbit_republisher/test/README.md diff --git a/inorbit_republisher/config/example.yaml b/inorbit_republisher/config/example.yaml deleted file mode 100644 index d198a52..0000000 --- a/inorbit_republisher/config/example.yaml +++ /dev/null @@ -1,78 +0,0 @@ -republishers: -- topic: "/rosout" - msg_type: "rcl_interfaces/msg/Log" - mappings: - - field: "msg" - mapping_type: "single_field" - mapping_options: - filter: 'lambda x: x != "Go"' - out: - topic: "/inorbit/custom_data" - key: "rosout_msg" - -- topic: "/diagnostics" - qos: 10 - msg_type: "diagnostic_msgs/msg/DiagnosticArray" - mappings: - - field: "status" - mapping_type: "array_of_fields" - mapping_options: - fields: ["level", "hardware_id"] - filter: 'lambda x: (x.level == bytes(1) or x.level == bytes(0))' - out: - topic: "/inorbit/diagnostics_test" - key: "diagnostics_status" - -- topic: "/cmd_vel" - qos: 10 - msg_type: "geometry_msgs/msg/Twist" - mappings: - - field: "linear" - mapping_type: "json_of_fields" - mapping_options: - fields: ["x", "y", "z"] - filter: 'lambda vel: (vel["x"] > 0)' - out: - topic: "/inorbit/linear_vel_test" - key: "linear_vel" - -- topic: "/map_metadata" - latched: true - msg_type: "nav_msgs/msg/MapMetaData" - mappings: - - field: "resolution" - mapping_type: "single_field" - out: - topic: "/inorbit/map_res_test" - key: "map_resolution" - -- topic: "/navsat" - msg_type: "sensor_msgs/NavSatFix" - mappings: - - mapping_type: "serialize" - mapping_options: - fields: ["status", "latitude", "longitude", "position_covariance_type"] - out: - topic: "/inorbit/custom_data" - key: "navsat" - -static_publishers: -# - value_from: -# package_version: "rospy" -# out: -# topic: "/inorbit/custom_data/0" -# key: "rospy_version" -# - value_from: -# package_version: "inorbit_republisher" -# out: -# topic: "/inorbit/custom_data/0" -# key: "inorbit_republisher_version" -- value_from: - environment_variable: "PYTHONPATH" - out: - topic: "/inorbit/custom_data/static" - key: "python_path" -- value: "let's republish in orbit" - out: - topic: "/inorbit/custom_data/static" - key: "greeting" \ No newline at end of file diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md deleted file mode 100644 index e688b6b..0000000 --- a/inorbit_republisher/test/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Sample data for testing - -A very simple ``rosbag`` with hardcoded data for smoke testing the transformer node. - -```bash -$root@7c94d2cf9659:~# ros2 bag info ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 - -closing. -[INFO] [1734553121.938063653] [rosbag2_storage]: Opened database 'ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3' for READ_ONLY. - -Files: ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 -Bag size: 24.0 KiB -Storage id: sqlite3 -Duration: 16.005861016s -Start: Dec 13 2024 19:45:00.085674077 (1734119100.085674077) -End: Dec 13 2024 19:45:16.091535093 (1734119116.091535093) -Messages: 34 -Topic information: Topic: /my_magnetic_field | Type: sensor_msgs/msg/MagneticField | Count: 17 | Serialization Format: cdr - Topic: /my_temperature | Type: sensor_msgs/msg/Temperature | Count: 17 | Serialization Format: cdr - -``` - -To validate the node works launch the sample by using the ``sample_data.launch.xml`` launch file and look at ``out`` topic: ``ros2 topic echo my_temperature``. - -```bash -cd ros2_ws/src -colcon build --packages-select inorbit_republisher --symlink-install -source install/setup.bash -cd -ros2 launch inorbit_republisher sample_data.launch.xml -# On a different terminal windows -source /opt/ros/jazzy/setup.bash -$ ros2 topic echo my_temperature -header: - stamp: - sec: 0 - nanosec: 0 - frame_id: '' -temperature: 29.068787468933582 -variance: 0.0 ---- -header: - stamp: - sec: 0 - nanosec: 0 - frame_id: '' -temperature: 22.9644622619558 -variance: 0.0 ---- -``` From 5642afc69eee847baa46896a614e0efcb544c9a9 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 10:24:41 -0300 Subject: [PATCH 11/21] Added a README file and modified .gitignore file --- .gitignore | 24 ++++++++++++++ inorbit_republisher/test/README.md | 50 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 inorbit_republisher/test/README.md diff --git a/.gitignore b/.gitignore index c18dd8d..f637901 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,25 @@ +# Launch files +*build/ +*devel/ +*install/ +*log/ + +# Python files __pycache__/ +*.pyc +*.pyo +*.pyd + +# Git history +*.history/ + +# VS files +.vscode/ +.idea/ +*.swp + +# Dependencies +venv/ +*.egg-info/ +*.eggs/ +pip-log.txt \ No newline at end of file diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md new file mode 100644 index 0000000..9da5619 --- /dev/null +++ b/inorbit_republisher/test/README.md @@ -0,0 +1,50 @@ +# Sample data for testing + +A very simple ``rosbag`` with hardcoded data for smoke testing the transformer node. + +```bash +$root@7c94d2cf9659:~# ros2 bag info ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 + +closing. +[INFO] [1734553121.938063653] [rosbag2_storage]: Opened database 'ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3' for READ_ONLY. + +Files: ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 +Bag size: 24.0 KiB +Storage id: sqlite3 +Duration: 16.005861016s +Start: Dec 13 2024 19:45:00.085674077 (1734119100.085674077) +End: Dec 13 2024 19:45:16.091535093 (1734119116.091535093) +Messages: 34 +Topic information: Topic: /my_magnetic_field | Type: sensor_msgs/msg/MagneticField | Count: 17 | Serialization Format: cdr + Topic: /my_temperature | Type: sensor_msgs/msg/Temperature | Count: 17 | Serialization Format: cdr + +``` + +To validate the node works launch the sample by using the ``sample_data.launch.xml`` launch file and look at ``out`` topic: ``ros2 topic echo my_temperature``. + +```bash +cd ros2_ws/src +colcon build --packages-select inorbit_republisher --symlink-install +source install/setup.bash +cd +ros2 launch inorbit_republisher sample_data.launch.xml +# On a different terminal windows +source /opt/ros/humble/setup.bash +$ ros2 topic echo my_temperature +header: + stamp: + sec: 0 + nanosec: 0 + frame_id: '' +temperature: 29.068787468933582 +variance: 0.0 +--- +header: + stamp: + sec: 0 + nanosec: 0 + frame_id: '' +temperature: 22.9644622619558 +variance: 0.0 +--- +``` \ No newline at end of file From e8313ddab27d88e822bd35be384a92774222a6c1 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 10:33:57 -0300 Subject: [PATCH 12/21] Deleted .history folder and updated gitignore file --- .history/.gitignore_20241213093407 | 1 - .history/.gitignore_20241217153146 | 5 - .history/.gitignore_20241217153602 | 6 - .../fake_sensor_sample_rep_20241213162920.py | 0 .../fake_sensor_sample_rep_20241213162928.py | 24 -- .../fake_sensor_sample_rep_20241213163048.py | 50 --- .../fake_sensor_sample_rep_20241213163652.py | 50 --- .../fake_sensor_sample_rep_20241213163836.py | 50 --- .../republisher_20241213161527.py | 303 ------------------ .../republisher_20241213164444.py | 50 --- .../republisher_20241213164541.py | 303 ------------------ .../republisher_20241213164629.py | 303 ------------------ .../sample_data.launch_20241213172505.xml | 8 - .../sample_data.launch_20241213174002.xml | 8 - .../sample_data.launch_20241213174830.xml | 8 - .../sample_data.launch_20241213174900.xml | 8 - .../sample_data.launch_20241213175417.xml | 9 - .../sample_data.launch_20241213175425.xml | 9 - .../sample_data.launch_20241217094439.xml | 19 -- .../sample_data.launch_20241217100145.xml | 9 - .../sample_data.launch_20241217100401.xml | 9 - .../sample_data.launch_20241217100515.xml | 9 - .../sample_data.launch_20241217100647.xml | 9 - .../sample_data.launch_20241217100726.xml | 9 - .../sample_data.launch_20241217101034.xml | 9 - .../sample_data.launch_20241217101335.xml | 10 - .../sample_data.launch_20241217101636.xml | 9 - .../sample_data.launch_20241217101711.xml | 10 - .../sample_data.launch_20241217101729.xml | 10 - .../sample_data.launch_20241217101938.xml | 9 - .../sample_data.launch_20241217101941.xml | 9 - .../sample_data.launch_20241217104852.xml | 9 - .../sample_data.launch_20241217104941.xml | 9 - .../sample_data.launch_20241217105013.xml | 9 - .../sample_data.launch_20241217105728.xml | 9 - .../sample_data.launch_20241217105923.xml | 10 - .../sample_data.launch_20241217105958.xml | 10 - .../sample_data.launch_20241217110012.xml | 8 - .../sample_data.launch_20241217110015.xml | 8 - .../sample_data.launch_20241217110221.py | 0 .../sample_data.launch_20241217110328.py | 39 --- .../sample_data.launch_20241217111512.xml | 7 - .../sample_data.launch_20241217112220.py | 22 -- .../sample_data.launch_20241217112508.py | 26 -- .../sample_data.launch_20241217112602.py | 26 -- .../sample_data.launch_20241217112824.py | 25 -- .../sample_data.launch_20241217112831.py | 25 -- .../sample_data.launch_20241217113329.xml | 7 - .../sample_data.launch_20241217113333.py | 25 -- .../sample_data.launch_20241217113410.py | 25 -- .../sample_data.launch_20241217113437.py | 25 -- .../sample_data.launch_20241217113453.py | 25 -- .../sample_data.launch_20241217114100.py | 25 -- .../sample_data.launch_20241217114845.xml | 7 - .../sample_data.launch_20241217115301.xml | 7 - .../sample_data.launch_20241217115430.xml | 9 - .../sample_data.launch_20241217115941.xml | 9 - .../sample_data.launch_20241217123416.xml | 9 - .../sample_data.launch_20241217123424.xml | 9 - .../sample_data.launch_20241217123458.xml | 9 - .../sample_data.launch_20241217123518.xml | 9 - .../sample_data.launch_20241217123845.xml | 11 - .../sample_data.launch_20241217123854.xml | 11 - .../sample_data.launch_20241217124149.xml | 9 - .../sample_data.launch_20241217124220.py | 26 -- .../sample_data.launch_20241217124420.py | 25 -- .../sample_data.launch_20241217124736.py | 29 -- .../sample_data.launch_20241217125321.xml | 9 - .../sample_data.launch_20241217125338.xml | 9 - .../sample_data.launch_20241217125743.xml | 9 - .../sample_data.launch_20241217125930.xml | 9 - .../sample_data.launch_20241217125954.xml | 9 - .../sample_data.launch_20241217130002.xml | 9 - .../setup_20241213161527.py | 30 -- .../setup_20241213172142.py | 30 -- .../setup_20241213172214.py | 30 -- .../test/README_20241213162953.md | 0 .../test/README_20241213163651.md | 10 - .../test/README_20241213175317.md | 17 - .../test/README_20241213175932.md | 22 -- .../test/README_20241213180602.md | 26 -- .../test/README_20241213180720.md | 27 -- .../test/README_20241217094923.md | 32 -- .../test/README_20241217121634.md | 40 --- .../test/README_20241217123656.md | 46 --- .../test/README_20241217130401.md | 46 --- .../sample_data/config_20241213162657.yaml | 0 .../sample_data/config_20241213165503.yaml | 23 -- .../sample_data.launch_20241213174001.xml | 8 - .../sample_data.launch_20241213174614.xml | 8 - .../sample_data_launch_20241213162714.xml | 0 .../sample_data_launch_20241213162848.xml | 6 - .../sample_data_launch_20241213165700.xml | 6 - .../sample_data_launch_20241213165739.xml | 6 - .../sample_data_launch_20241213172506.xml | 8 - 95 files changed, 2353 deletions(-) delete mode 100644 .history/.gitignore_20241213093407 delete mode 100644 .history/.gitignore_20241217153146 delete mode 100644 .history/.gitignore_20241217153602 delete mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162920.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py delete mode 100644 .history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110221.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217110328.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112220.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112508.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112602.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112824.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217112831.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113333.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113410.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113437.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217113453.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217114100.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124220.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124420.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217124736.py delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml delete mode 100644 .history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml delete mode 100644 .history/inorbit_republisher/setup_20241213161527.py delete mode 100644 .history/inorbit_republisher/setup_20241213172142.py delete mode 100644 .history/inorbit_republisher/setup_20241213172214.py delete mode 100644 .history/inorbit_republisher/test/README_20241213162953.md delete mode 100644 .history/inorbit_republisher/test/README_20241213163651.md delete mode 100644 .history/inorbit_republisher/test/README_20241213175317.md delete mode 100644 .history/inorbit_republisher/test/README_20241213175932.md delete mode 100644 .history/inorbit_republisher/test/README_20241213180602.md delete mode 100644 .history/inorbit_republisher/test/README_20241213180720.md delete mode 100644 .history/inorbit_republisher/test/README_20241217094923.md delete mode 100644 .history/inorbit_republisher/test/README_20241217121634.md delete mode 100644 .history/inorbit_republisher/test/README_20241217123656.md delete mode 100644 .history/inorbit_republisher/test/README_20241217130401.md delete mode 100644 .history/inorbit_republisher/test/sample_data/config_20241213162657.yaml delete mode 100644 .history/inorbit_republisher/test/sample_data/config_20241213165503.yaml delete mode 100644 .history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml delete mode 100644 .history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml delete mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162714.xml delete mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml delete mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml delete mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml delete mode 100644 .history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml diff --git a/.history/.gitignore_20241213093407 b/.history/.gitignore_20241213093407 deleted file mode 100644 index c18dd8d..0000000 --- a/.history/.gitignore_20241213093407 +++ /dev/null @@ -1 +0,0 @@ -__pycache__/ diff --git a/.history/.gitignore_20241217153146 b/.history/.gitignore_20241217153146 deleted file mode 100644 index a4df222..0000000 --- a/.history/.gitignore_20241217153146 +++ /dev/null @@ -1,5 +0,0 @@ -__pycache__/ -/inorbit_republisher/test/sample_data/build/ -/inorbit_republisher/test/sample_data/hardcodedRosbag/ -/inorbit_republisher/test/sample_data/install/ -/inorbit_republisher/test/sample_data/log/ diff --git a/.history/.gitignore_20241217153602 b/.history/.gitignore_20241217153602 deleted file mode 100644 index c776db8..0000000 --- a/.history/.gitignore_20241217153602 +++ /dev/null @@ -1,6 +0,0 @@ -__pycache__/ -/inorbit_republisher/test/sample_data/build/ -/inorbit_republisher/test/sample_data/hardcodedRosbag/ -/inorbit_republisher/test/sample_data/install/ -/inorbit_republisher/test/sample_data/log/ -.history/ diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162920.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162920.py deleted file mode 100644 index e69de29..0000000 diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py deleted file mode 100644 index 6c6bcc9..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213162928.py +++ /dev/null @@ -1,24 +0,0 @@ -import launch -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, LogInfo, Node -from launch.substitutions import LaunchConfiguration, PathJoinSubstitution - -def generate_launch_description(): - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher.py', # Cambia 'republisher' por 'republisher.py' si es un script Python - name='inorbit_republisher', - parameters=[{'config': PathJoinSubstitution([LaunchConfiguration('config_dir'), 'config.yaml'])}], - ), - - # Nodo rosbag - Node( - package='rosbag2', - executable='play', - name='player', - output='screen', - arguments=['-l', PathJoinSubstitution([LaunchConfiguration('config_dir'), 'fake_sensors_sample.bag'])], - ), - ]) diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py deleted file mode 100644 index 7fe77d3..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163048.py +++ /dev/null @@ -1,50 +0,0 @@ -import rclpy -from rclpy.node import Node -from sensor_msgs.msg import MagneticField, Temperature -from std_msgs.msg import String -import random -import time - -class FakeSensorPublisher(Node): - def __init__(self): - super().__init__('fake_sensor_publisher') - - # Publicadores de los sensores - self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) - self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) - - # Timer para publicar los mensajes cada 1 segundo - self.timer = self.create_timer(1.0, self.publish_fake_data) - - def publish_fake_data(self): - # Publicar datos simulados para el campo magnético - magnetic_field_msg = MagneticField() - magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) - self.magnetic_field_publisher.publish(magnetic_field_msg) - self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " - f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") - - # Publicar datos simulados para la temperatura - temperature_msg = Temperature() - temperature_msg.temperature = random.uniform(20.0, 30.0) - self.temperature_publisher.publish(temperature_msg) - self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") - - -def main(args=None): - rclpy.init(args=args) - node = FakeSensorPublisher() - - try: - rclpy.spin(node) - except KeyboardInterrupt: - pass - - # Destruir el nodo después de detener el spin - node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py deleted file mode 100644 index 7fe77d3..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163652.py +++ /dev/null @@ -1,50 +0,0 @@ -import rclpy -from rclpy.node import Node -from sensor_msgs.msg import MagneticField, Temperature -from std_msgs.msg import String -import random -import time - -class FakeSensorPublisher(Node): - def __init__(self): - super().__init__('fake_sensor_publisher') - - # Publicadores de los sensores - self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) - self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) - - # Timer para publicar los mensajes cada 1 segundo - self.timer = self.create_timer(1.0, self.publish_fake_data) - - def publish_fake_data(self): - # Publicar datos simulados para el campo magnético - magnetic_field_msg = MagneticField() - magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) - self.magnetic_field_publisher.publish(magnetic_field_msg) - self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " - f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") - - # Publicar datos simulados para la temperatura - temperature_msg = Temperature() - temperature_msg.temperature = random.uniform(20.0, 30.0) - self.temperature_publisher.publish(temperature_msg) - self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") - - -def main(args=None): - rclpy.init(args=args) - node = FakeSensorPublisher() - - try: - rclpy.spin(node) - except KeyboardInterrupt: - pass - - # Destruir el nodo después de detener el spin - node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() diff --git a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py b/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py deleted file mode 100644 index 7fe77d3..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/fake_sensor_sample_rep_20241213163836.py +++ /dev/null @@ -1,50 +0,0 @@ -import rclpy -from rclpy.node import Node -from sensor_msgs.msg import MagneticField, Temperature -from std_msgs.msg import String -import random -import time - -class FakeSensorPublisher(Node): - def __init__(self): - super().__init__('fake_sensor_publisher') - - # Publicadores de los sensores - self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) - self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) - - # Timer para publicar los mensajes cada 1 segundo - self.timer = self.create_timer(1.0, self.publish_fake_data) - - def publish_fake_data(self): - # Publicar datos simulados para el campo magnético - magnetic_field_msg = MagneticField() - magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) - self.magnetic_field_publisher.publish(magnetic_field_msg) - self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " - f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") - - # Publicar datos simulados para la temperatura - temperature_msg = Temperature() - temperature_msg.temperature = random.uniform(20.0, 30.0) - self.temperature_publisher.publish(temperature_msg) - self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") - - -def main(args=None): - rclpy.init(args=args) - node = FakeSensorPublisher() - - try: - rclpy.spin(node) - except KeyboardInterrupt: - pass - - # Destruir el nodo después de detener el spin - node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py deleted file mode 100644 index d81aa30..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213161527.py +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2021 InOrbit, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# ROS to InOrbit republisher node sample -# -# It uses a YAML-based configuration to map between arbitrary -# ROS topics into InOrbit key/value custom data topics. - -import json -import rclpy -from rosidl_runtime_py.utilities import get_message -import yaml -import os -from rosidl_runtime_py.convert import message_to_ordereddict -from std_msgs.msg import String -from builtin_interfaces.msg import Time -from operator import attrgetter - -# Types of mappings allowed -MAPPING_TYPE_SINGLE_FIELD = "single_field" -MAPPING_TYPE_ARRAY_OF_FIELDS = "array_of_fields" -MAPPING_TYPE_JSON_OF_FIELDS = "json_of_fields" -MAPPING_TYPE_SERIALIZE = "serialize" - -# Supported static publisher value sources -STATIC_VALUE_FROM_PACKAGE_VERSION = "package_version" -STATIC_VALUE_FROM_ENVIRONMENT_VAR = "environment_variable" - -""" -Custom JSON encoder to deal with types found on ROS 2 messages that are not -serializable to string by default. -For now this includes: - - bytes objects to decoded String objects -""" -class ROS2JSONEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, bytes): - return obj.decode() - return json.JSONEncoder.default(self, obj) - -""" -Main node entry point. - -Currently a simple function that does everything. -We can later turn it into a class and divide in proper methods -as complexity increases. -""" -def main(args = None): - # Start the ROS node - rclpy.init(args=args) - node = rclpy.create_node('inorbit_republisher') - # Declares the "config" parameter, it contains the path of the config file - node.declare_parameter('config') - # Read republisher configuration from the 'config_file' or 'config' parameter - # TODO(adamantivm) Error handling and schema checking - if node.has_parameter('config'): - config_file = node.get_parameter( - 'config').get_parameter_value().string_value - node.get_logger().info("Using config from config file: {}".format(config_file)) - config_yaml = open(config_file, "r") - config = yaml.safe_load(config_yaml) - - # Go through republisher configurations - # For each of them: create a publisher if necessary - only one per InOrbit - # custom data field - and a matching subscriber to receive and republish - # the desired fields. - - # Dictionary of publisher instances by topic name - pubs = {} - - # Dictionary of subscriber instances by topic name - subs = {} - - # TODO(adamantivm) Port ability to publish package versions from ROS 1 Noetic to ROS 2 Foxy - # # In case we want to query ROS package options - # rospack = rospkg.RosPack() - - # Set-up ROS topic republishers - republishers = config.get('republishers', ()) - for repub in republishers: - - # Load subscriber message type - msg_class = get_message(repub['msg_type']) - if msg_class is None: - node.get_logger().warning('Failed to load msg class for {}'.format(repub['msg_type'])) - continue - - # Create publisher for each new seen outgoing topic - for mapping in repub['mappings']: - out_topic = mapping['out']['topic'] - if not out_topic in pubs: - # NOTE(adamantivm) Using QOS = 10 to match InOrbit Custom Data topic spec - pubs[out_topic] = node.create_publisher(String, out_topic, 10) - # 'field' mapping is not defined when serializing messages - if 'field' in mapping: - mapping['attrgetter'] = attrgetter(mapping['field']) - - # Prepare callback to relay messages through InOrbit custom data - def callback(msg, repub=repub): - - for mapping in repub['mappings']: - key = mapping['out']['key'] - val = None - mapping_type = mapping.get('mapping_type', MAPPING_TYPE_SINGLE_FIELD) - topic = mapping['out']['topic'] - - if mapping_type == MAPPING_TYPE_SINGLE_FIELD: - # TODO(adamantivm) Exception handling - field = extract_value(msg, attrgetter(mapping['field'])) - val = process_single_field(field, mapping) - # Time values can't be cleanly serialized into JSON. convert them to milliseconds - if isinstance(val, Time): - val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 - - elif mapping_type == MAPPING_TYPE_ARRAY_OF_FIELDS: - field = extract_value(msg, attrgetter(mapping['field'])) - val = process_array(field, mapping) - - elif mapping_type == MAPPING_TYPE_JSON_OF_FIELDS: - try: - val = extract_values_as_dict(msg, mapping, node) - # extract_values_as_dict has the ability to filter messages and - # returns None when an element doesn't pass the filter - if val: - val = json.dumps(val, cls=ROS2JSONEncoder) - except TypeError as e: - node.get_logger().warning(f"Failed to serialize message: {e}") - elif mapping_type == MAPPING_TYPE_SERIALIZE: - try: - val = serialize(msg, mapping) - if val: - val = json.dumps(val, cls=ROS2JSONEncoder) - except TypeError as e: - node.get_logger().warning(f"Failed to serialize message: {e}") - - if val is not None: - pubs[topic].publish(String(data=f"{key}={val}")) - - in_topic = repub['topic'] - # Reads QoS from the topic settings - in_qos = getattr(repub, 'qos', 10) - - # subscribe - subs[in_topic] = node.create_subscription(msg_class, in_topic, callback, in_qos) - - # Set-up static publishers - static_publishers = config.get('static_publishers', ()) - for static_pub_config in static_publishers: - key = static_pub_config['out']['key'] - topic = static_pub_config['out']['topic'] - - # If a literal value is provided, it takes highest precendence - val = static_pub_config.get('value') - - # Otherwise, fetch the value from the specified source - if val is None: - value_from = static_pub_config.get('value_from') - if STATIC_VALUE_FROM_ENVIRONMENT_VAR in value_from: - var_name = value_from[STATIC_VALUE_FROM_ENVIRONMENT_VAR] - val = os.environ.get(var_name) - # TODO(adamantivm) Implement publishing of package version for ROS 2 - # elif STATIC_VALUE_FROM_PACKAGE_VERSION in value_from: - # pkg_name = value_from[STATIC_VALUE_FROM_PACKAGE_VERSION] - # # TODO(adamantivm) Exception handling - # pkg_manifest = rospack.get_manifest(pkg_name) - # val = pkg_manifest.version - - # If there is a value to publish, publish it using once per subscriber - # TODO(adamantivm) Make these values latched - if val is not None: - pub = node.create_publisher(String, topic, 10) - pub.publish(String(data=f"{key}={val}")) - - node.get_logger().info("Republisher started") - rclpy.spin(node) - node.get_logger().info("Republisher shutting down") - - node.destroy_node() - rclpy.shutdown() - node.get_logger().info("Shutdown complete") - -""" -Extracts a value from the given message using the provided getter function -""" -def extract_value(msg, getter_fn): - # TODO(adamantivm) Graceful handling of missing values to extract - # TODO(adamantivm) Allow serialization of complex values - val = getter_fn(msg) - return val - - -""" -Extracts several values from a given nested msg field and returns a dictionary of - elements -""" -# TODO(elvioaruta): after refactoring and using Node as classes -# remove the node from this function and figure out a better way -# to log warnings inside -def extract_values_as_dict(msg, mapping, node): - values = {} - base_getter_fn = attrgetter(mapping['field']) - base_value = base_getter_fn(msg) - fields = mapping.get('mapping_options', {}).get('fields') - for field in fields: - getter_fn = attrgetter(field) - try: - val = getter_fn(base_value) - # Time values aren't cleanly serialized into JSON. - # Convert them to milliseconds - if isinstance(val, Time): - val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 - # TODO(diegobatt): Make it possible to use a different key than the field - values[field] = val - except AttributeError as e: - node.get_logger().warning(f"Couldn\'t get attribute {field}: {e}") - filter_fn = mapping.get('mapping_options', {}).get('filter') - return values if not filter_fn or eval(filter_fn)(values) else None - -""" -Processes a scalar value before publishing according to mapping options - - If a 'filter' function is provided, it returns the value only if the - result of passing the field value through the filter function is True, - otherwise it returns None -""" -def process_single_field(field_value, mapping): - filter_fn = mapping.get('mapping_options', {}).get('filter') - return field_value if not filter_fn or eval(filter_fn)(field_value) else None - -""" -Processes a given array field from the ROS message and: - - Filters it using the 'filter' function (if provided) - - For each element, it gets the set of keys defined by array_fields - - Returns a key/value with the value being a json string containing - the resulting array of objects. - -Note that the array fields to retrieve should have a String value in order to -serialize them properly. -""" -def process_array(field, mapping): - # Output array of objects - values = { - 'data': [] - } - - filter_fn = mapping.get('mapping_options', {}).get('filter') - if filter_fn: - # Apply the filter function if any - filtered_array = list(filter(eval(filter_fn), field)) - else: - filtered_array = field - - # Get only the array_fields specified. If none was specified, return the whole array - # TODO(FlorGrosso): check that the array fields are Strings and discard those which - # are not. - if 'fields' in mapping.get('mapping_options', {}): - fields = mapping['mapping_options']['fields'] - values['data'] = [{f: extract_value(elem, attrgetter(f)) for f in fields} for elem in filtered_array] - else: - values['data'] = filtered_array - return json.dumps(values, cls=ROS2JSONEncoder) - -""" -Transforms the ROS message to json and: - - Filters out fields on the top level of the json only. -""" -def serialize(msg, mapping): - # TODO: design filtering support and implement it. It should be possible - # to leverage jq to do so. However, this would require adding a new rosdep - # rule for `pyjq`: https://pypi.org/project/pyjq/. - # filter = mapping.get('mapping_options', {}).get('filter') - - # Get fields configuration - fields = mapping.get('mapping_options', {}).get('fields') - # Transform ROS message to dict - msg_dict = message_to_ordereddict(msg) - - # Shrink output by keeping only selected fields or keys - if fields: - msg_dict = { k: v for k, v in msg_dict.items() if k in fields} - - return msg_dict - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py deleted file mode 100644 index 7fe77d3..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164444.py +++ /dev/null @@ -1,50 +0,0 @@ -import rclpy -from rclpy.node import Node -from sensor_msgs.msg import MagneticField, Temperature -from std_msgs.msg import String -import random -import time - -class FakeSensorPublisher(Node): - def __init__(self): - super().__init__('fake_sensor_publisher') - - # Publicadores de los sensores - self.magnetic_field_publisher = self.create_publisher(MagneticField, '/my_magnetic_field', 10) - self.temperature_publisher = self.create_publisher(Temperature, '/my_temperature', 10) - - # Timer para publicar los mensajes cada 1 segundo - self.timer = self.create_timer(1.0, self.publish_fake_data) - - def publish_fake_data(self): - # Publicar datos simulados para el campo magnético - magnetic_field_msg = MagneticField() - magnetic_field_msg.magnetic_field.x = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.y = random.uniform(-10.0, 10.0) - magnetic_field_msg.magnetic_field.z = random.uniform(-10.0, 10.0) - self.magnetic_field_publisher.publish(magnetic_field_msg) - self.get_logger().info(f"Publishing MagneticField: {magnetic_field_msg.magnetic_field.x}, " - f"{magnetic_field_msg.magnetic_field.y}, {magnetic_field_msg.magnetic_field.z}") - - # Publicar datos simulados para la temperatura - temperature_msg = Temperature() - temperature_msg.temperature = random.uniform(20.0, 30.0) - self.temperature_publisher.publish(temperature_msg) - self.get_logger().info(f"Publishing Temperature: {temperature_msg.temperature} °C") - - -def main(args=None): - rclpy.init(args=args) - node = FakeSensorPublisher() - - try: - rclpy.spin(node) - except KeyboardInterrupt: - pass - - # Destruir el nodo después de detener el spin - node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py deleted file mode 100644 index d81aa30..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164541.py +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2021 InOrbit, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# ROS to InOrbit republisher node sample -# -# It uses a YAML-based configuration to map between arbitrary -# ROS topics into InOrbit key/value custom data topics. - -import json -import rclpy -from rosidl_runtime_py.utilities import get_message -import yaml -import os -from rosidl_runtime_py.convert import message_to_ordereddict -from std_msgs.msg import String -from builtin_interfaces.msg import Time -from operator import attrgetter - -# Types of mappings allowed -MAPPING_TYPE_SINGLE_FIELD = "single_field" -MAPPING_TYPE_ARRAY_OF_FIELDS = "array_of_fields" -MAPPING_TYPE_JSON_OF_FIELDS = "json_of_fields" -MAPPING_TYPE_SERIALIZE = "serialize" - -# Supported static publisher value sources -STATIC_VALUE_FROM_PACKAGE_VERSION = "package_version" -STATIC_VALUE_FROM_ENVIRONMENT_VAR = "environment_variable" - -""" -Custom JSON encoder to deal with types found on ROS 2 messages that are not -serializable to string by default. -For now this includes: - - bytes objects to decoded String objects -""" -class ROS2JSONEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, bytes): - return obj.decode() - return json.JSONEncoder.default(self, obj) - -""" -Main node entry point. - -Currently a simple function that does everything. -We can later turn it into a class and divide in proper methods -as complexity increases. -""" -def main(args = None): - # Start the ROS node - rclpy.init(args=args) - node = rclpy.create_node('inorbit_republisher') - # Declares the "config" parameter, it contains the path of the config file - node.declare_parameter('config') - # Read republisher configuration from the 'config_file' or 'config' parameter - # TODO(adamantivm) Error handling and schema checking - if node.has_parameter('config'): - config_file = node.get_parameter( - 'config').get_parameter_value().string_value - node.get_logger().info("Using config from config file: {}".format(config_file)) - config_yaml = open(config_file, "r") - config = yaml.safe_load(config_yaml) - - # Go through republisher configurations - # For each of them: create a publisher if necessary - only one per InOrbit - # custom data field - and a matching subscriber to receive and republish - # the desired fields. - - # Dictionary of publisher instances by topic name - pubs = {} - - # Dictionary of subscriber instances by topic name - subs = {} - - # TODO(adamantivm) Port ability to publish package versions from ROS 1 Noetic to ROS 2 Foxy - # # In case we want to query ROS package options - # rospack = rospkg.RosPack() - - # Set-up ROS topic republishers - republishers = config.get('republishers', ()) - for repub in republishers: - - # Load subscriber message type - msg_class = get_message(repub['msg_type']) - if msg_class is None: - node.get_logger().warning('Failed to load msg class for {}'.format(repub['msg_type'])) - continue - - # Create publisher for each new seen outgoing topic - for mapping in repub['mappings']: - out_topic = mapping['out']['topic'] - if not out_topic in pubs: - # NOTE(adamantivm) Using QOS = 10 to match InOrbit Custom Data topic spec - pubs[out_topic] = node.create_publisher(String, out_topic, 10) - # 'field' mapping is not defined when serializing messages - if 'field' in mapping: - mapping['attrgetter'] = attrgetter(mapping['field']) - - # Prepare callback to relay messages through InOrbit custom data - def callback(msg, repub=repub): - - for mapping in repub['mappings']: - key = mapping['out']['key'] - val = None - mapping_type = mapping.get('mapping_type', MAPPING_TYPE_SINGLE_FIELD) - topic = mapping['out']['topic'] - - if mapping_type == MAPPING_TYPE_SINGLE_FIELD: - # TODO(adamantivm) Exception handling - field = extract_value(msg, attrgetter(mapping['field'])) - val = process_single_field(field, mapping) - # Time values can't be cleanly serialized into JSON. convert them to milliseconds - if isinstance(val, Time): - val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 - - elif mapping_type == MAPPING_TYPE_ARRAY_OF_FIELDS: - field = extract_value(msg, attrgetter(mapping['field'])) - val = process_array(field, mapping) - - elif mapping_type == MAPPING_TYPE_JSON_OF_FIELDS: - try: - val = extract_values_as_dict(msg, mapping, node) - # extract_values_as_dict has the ability to filter messages and - # returns None when an element doesn't pass the filter - if val: - val = json.dumps(val, cls=ROS2JSONEncoder) - except TypeError as e: - node.get_logger().warning(f"Failed to serialize message: {e}") - elif mapping_type == MAPPING_TYPE_SERIALIZE: - try: - val = serialize(msg, mapping) - if val: - val = json.dumps(val, cls=ROS2JSONEncoder) - except TypeError as e: - node.get_logger().warning(f"Failed to serialize message: {e}") - - if val is not None: - pubs[topic].publish(String(data=f"{key}={val}")) - - in_topic = repub['topic'] - # Reads QoS from the topic settings - in_qos = getattr(repub, 'qos', 10) - - # subscribe - subs[in_topic] = node.create_subscription(msg_class, in_topic, callback, in_qos) - - # Set-up static publishers - static_publishers = config.get('static_publishers', ()) - for static_pub_config in static_publishers: - key = static_pub_config['out']['key'] - topic = static_pub_config['out']['topic'] - - # If a literal value is provided, it takes highest precendence - val = static_pub_config.get('value') - - # Otherwise, fetch the value from the specified source - if val is None: - value_from = static_pub_config.get('value_from') - if STATIC_VALUE_FROM_ENVIRONMENT_VAR in value_from: - var_name = value_from[STATIC_VALUE_FROM_ENVIRONMENT_VAR] - val = os.environ.get(var_name) - # TODO(adamantivm) Implement publishing of package version for ROS 2 - # elif STATIC_VALUE_FROM_PACKAGE_VERSION in value_from: - # pkg_name = value_from[STATIC_VALUE_FROM_PACKAGE_VERSION] - # # TODO(adamantivm) Exception handling - # pkg_manifest = rospack.get_manifest(pkg_name) - # val = pkg_manifest.version - - # If there is a value to publish, publish it using once per subscriber - # TODO(adamantivm) Make these values latched - if val is not None: - pub = node.create_publisher(String, topic, 10) - pub.publish(String(data=f"{key}={val}")) - - node.get_logger().info("Republisher started") - rclpy.spin(node) - node.get_logger().info("Republisher shutting down") - - node.destroy_node() - rclpy.shutdown() - node.get_logger().info("Shutdown complete") - -""" -Extracts a value from the given message using the provided getter function -""" -def extract_value(msg, getter_fn): - # TODO(adamantivm) Graceful handling of missing values to extract - # TODO(adamantivm) Allow serialization of complex values - val = getter_fn(msg) - return val - - -""" -Extracts several values from a given nested msg field and returns a dictionary of - elements -""" -# TODO(elvioaruta): after refactoring and using Node as classes -# remove the node from this function and figure out a better way -# to log warnings inside -def extract_values_as_dict(msg, mapping, node): - values = {} - base_getter_fn = attrgetter(mapping['field']) - base_value = base_getter_fn(msg) - fields = mapping.get('mapping_options', {}).get('fields') - for field in fields: - getter_fn = attrgetter(field) - try: - val = getter_fn(base_value) - # Time values aren't cleanly serialized into JSON. - # Convert them to milliseconds - if isinstance(val, Time): - val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 - # TODO(diegobatt): Make it possible to use a different key than the field - values[field] = val - except AttributeError as e: - node.get_logger().warning(f"Couldn\'t get attribute {field}: {e}") - filter_fn = mapping.get('mapping_options', {}).get('filter') - return values if not filter_fn or eval(filter_fn)(values) else None - -""" -Processes a scalar value before publishing according to mapping options - - If a 'filter' function is provided, it returns the value only if the - result of passing the field value through the filter function is True, - otherwise it returns None -""" -def process_single_field(field_value, mapping): - filter_fn = mapping.get('mapping_options', {}).get('filter') - return field_value if not filter_fn or eval(filter_fn)(field_value) else None - -""" -Processes a given array field from the ROS message and: - - Filters it using the 'filter' function (if provided) - - For each element, it gets the set of keys defined by array_fields - - Returns a key/value with the value being a json string containing - the resulting array of objects. - -Note that the array fields to retrieve should have a String value in order to -serialize them properly. -""" -def process_array(field, mapping): - # Output array of objects - values = { - 'data': [] - } - - filter_fn = mapping.get('mapping_options', {}).get('filter') - if filter_fn: - # Apply the filter function if any - filtered_array = list(filter(eval(filter_fn), field)) - else: - filtered_array = field - - # Get only the array_fields specified. If none was specified, return the whole array - # TODO(FlorGrosso): check that the array fields are Strings and discard those which - # are not. - if 'fields' in mapping.get('mapping_options', {}): - fields = mapping['mapping_options']['fields'] - values['data'] = [{f: extract_value(elem, attrgetter(f)) for f in fields} for elem in filtered_array] - else: - values['data'] = filtered_array - return json.dumps(values, cls=ROS2JSONEncoder) - -""" -Transforms the ROS message to json and: - - Filters out fields on the top level of the json only. -""" -def serialize(msg, mapping): - # TODO: design filtering support and implement it. It should be possible - # to leverage jq to do so. However, this would require adding a new rosdep - # rule for `pyjq`: https://pypi.org/project/pyjq/. - # filter = mapping.get('mapping_options', {}).get('filter') - - # Get fields configuration - fields = mapping.get('mapping_options', {}).get('fields') - # Transform ROS message to dict - msg_dict = message_to_ordereddict(msg) - - # Shrink output by keeping only selected fields or keys - if fields: - msg_dict = { k: v for k, v in msg_dict.items() if k in fields} - - return msg_dict - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py b/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py deleted file mode 100644 index d81aa30..0000000 --- a/.history/inorbit_republisher/inorbit_republisher/republisher_20241213164629.py +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2021 InOrbit, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# ROS to InOrbit republisher node sample -# -# It uses a YAML-based configuration to map between arbitrary -# ROS topics into InOrbit key/value custom data topics. - -import json -import rclpy -from rosidl_runtime_py.utilities import get_message -import yaml -import os -from rosidl_runtime_py.convert import message_to_ordereddict -from std_msgs.msg import String -from builtin_interfaces.msg import Time -from operator import attrgetter - -# Types of mappings allowed -MAPPING_TYPE_SINGLE_FIELD = "single_field" -MAPPING_TYPE_ARRAY_OF_FIELDS = "array_of_fields" -MAPPING_TYPE_JSON_OF_FIELDS = "json_of_fields" -MAPPING_TYPE_SERIALIZE = "serialize" - -# Supported static publisher value sources -STATIC_VALUE_FROM_PACKAGE_VERSION = "package_version" -STATIC_VALUE_FROM_ENVIRONMENT_VAR = "environment_variable" - -""" -Custom JSON encoder to deal with types found on ROS 2 messages that are not -serializable to string by default. -For now this includes: - - bytes objects to decoded String objects -""" -class ROS2JSONEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, bytes): - return obj.decode() - return json.JSONEncoder.default(self, obj) - -""" -Main node entry point. - -Currently a simple function that does everything. -We can later turn it into a class and divide in proper methods -as complexity increases. -""" -def main(args = None): - # Start the ROS node - rclpy.init(args=args) - node = rclpy.create_node('inorbit_republisher') - # Declares the "config" parameter, it contains the path of the config file - node.declare_parameter('config') - # Read republisher configuration from the 'config_file' or 'config' parameter - # TODO(adamantivm) Error handling and schema checking - if node.has_parameter('config'): - config_file = node.get_parameter( - 'config').get_parameter_value().string_value - node.get_logger().info("Using config from config file: {}".format(config_file)) - config_yaml = open(config_file, "r") - config = yaml.safe_load(config_yaml) - - # Go through republisher configurations - # For each of them: create a publisher if necessary - only one per InOrbit - # custom data field - and a matching subscriber to receive and republish - # the desired fields. - - # Dictionary of publisher instances by topic name - pubs = {} - - # Dictionary of subscriber instances by topic name - subs = {} - - # TODO(adamantivm) Port ability to publish package versions from ROS 1 Noetic to ROS 2 Foxy - # # In case we want to query ROS package options - # rospack = rospkg.RosPack() - - # Set-up ROS topic republishers - republishers = config.get('republishers', ()) - for repub in republishers: - - # Load subscriber message type - msg_class = get_message(repub['msg_type']) - if msg_class is None: - node.get_logger().warning('Failed to load msg class for {}'.format(repub['msg_type'])) - continue - - # Create publisher for each new seen outgoing topic - for mapping in repub['mappings']: - out_topic = mapping['out']['topic'] - if not out_topic in pubs: - # NOTE(adamantivm) Using QOS = 10 to match InOrbit Custom Data topic spec - pubs[out_topic] = node.create_publisher(String, out_topic, 10) - # 'field' mapping is not defined when serializing messages - if 'field' in mapping: - mapping['attrgetter'] = attrgetter(mapping['field']) - - # Prepare callback to relay messages through InOrbit custom data - def callback(msg, repub=repub): - - for mapping in repub['mappings']: - key = mapping['out']['key'] - val = None - mapping_type = mapping.get('mapping_type', MAPPING_TYPE_SINGLE_FIELD) - topic = mapping['out']['topic'] - - if mapping_type == MAPPING_TYPE_SINGLE_FIELD: - # TODO(adamantivm) Exception handling - field = extract_value(msg, attrgetter(mapping['field'])) - val = process_single_field(field, mapping) - # Time values can't be cleanly serialized into JSON. convert them to milliseconds - if isinstance(val, Time): - val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 - - elif mapping_type == MAPPING_TYPE_ARRAY_OF_FIELDS: - field = extract_value(msg, attrgetter(mapping['field'])) - val = process_array(field, mapping) - - elif mapping_type == MAPPING_TYPE_JSON_OF_FIELDS: - try: - val = extract_values_as_dict(msg, mapping, node) - # extract_values_as_dict has the ability to filter messages and - # returns None when an element doesn't pass the filter - if val: - val = json.dumps(val, cls=ROS2JSONEncoder) - except TypeError as e: - node.get_logger().warning(f"Failed to serialize message: {e}") - elif mapping_type == MAPPING_TYPE_SERIALIZE: - try: - val = serialize(msg, mapping) - if val: - val = json.dumps(val, cls=ROS2JSONEncoder) - except TypeError as e: - node.get_logger().warning(f"Failed to serialize message: {e}") - - if val is not None: - pubs[topic].publish(String(data=f"{key}={val}")) - - in_topic = repub['topic'] - # Reads QoS from the topic settings - in_qos = getattr(repub, 'qos', 10) - - # subscribe - subs[in_topic] = node.create_subscription(msg_class, in_topic, callback, in_qos) - - # Set-up static publishers - static_publishers = config.get('static_publishers', ()) - for static_pub_config in static_publishers: - key = static_pub_config['out']['key'] - topic = static_pub_config['out']['topic'] - - # If a literal value is provided, it takes highest precendence - val = static_pub_config.get('value') - - # Otherwise, fetch the value from the specified source - if val is None: - value_from = static_pub_config.get('value_from') - if STATIC_VALUE_FROM_ENVIRONMENT_VAR in value_from: - var_name = value_from[STATIC_VALUE_FROM_ENVIRONMENT_VAR] - val = os.environ.get(var_name) - # TODO(adamantivm) Implement publishing of package version for ROS 2 - # elif STATIC_VALUE_FROM_PACKAGE_VERSION in value_from: - # pkg_name = value_from[STATIC_VALUE_FROM_PACKAGE_VERSION] - # # TODO(adamantivm) Exception handling - # pkg_manifest = rospack.get_manifest(pkg_name) - # val = pkg_manifest.version - - # If there is a value to publish, publish it using once per subscriber - # TODO(adamantivm) Make these values latched - if val is not None: - pub = node.create_publisher(String, topic, 10) - pub.publish(String(data=f"{key}={val}")) - - node.get_logger().info("Republisher started") - rclpy.spin(node) - node.get_logger().info("Republisher shutting down") - - node.destroy_node() - rclpy.shutdown() - node.get_logger().info("Shutdown complete") - -""" -Extracts a value from the given message using the provided getter function -""" -def extract_value(msg, getter_fn): - # TODO(adamantivm) Graceful handling of missing values to extract - # TODO(adamantivm) Allow serialization of complex values - val = getter_fn(msg) - return val - - -""" -Extracts several values from a given nested msg field and returns a dictionary of - elements -""" -# TODO(elvioaruta): after refactoring and using Node as classes -# remove the node from this function and figure out a better way -# to log warnings inside -def extract_values_as_dict(msg, mapping, node): - values = {} - base_getter_fn = attrgetter(mapping['field']) - base_value = base_getter_fn(msg) - fields = mapping.get('mapping_options', {}).get('fields') - for field in fields: - getter_fn = attrgetter(field) - try: - val = getter_fn(base_value) - # Time values aren't cleanly serialized into JSON. - # Convert them to milliseconds - if isinstance(val, Time): - val = rclpy.time.Time.from_msg(val).nanoseconds / 1000000 - # TODO(diegobatt): Make it possible to use a different key than the field - values[field] = val - except AttributeError as e: - node.get_logger().warning(f"Couldn\'t get attribute {field}: {e}") - filter_fn = mapping.get('mapping_options', {}).get('filter') - return values if not filter_fn or eval(filter_fn)(values) else None - -""" -Processes a scalar value before publishing according to mapping options - - If a 'filter' function is provided, it returns the value only if the - result of passing the field value through the filter function is True, - otherwise it returns None -""" -def process_single_field(field_value, mapping): - filter_fn = mapping.get('mapping_options', {}).get('filter') - return field_value if not filter_fn or eval(filter_fn)(field_value) else None - -""" -Processes a given array field from the ROS message and: - - Filters it using the 'filter' function (if provided) - - For each element, it gets the set of keys defined by array_fields - - Returns a key/value with the value being a json string containing - the resulting array of objects. - -Note that the array fields to retrieve should have a String value in order to -serialize them properly. -""" -def process_array(field, mapping): - # Output array of objects - values = { - 'data': [] - } - - filter_fn = mapping.get('mapping_options', {}).get('filter') - if filter_fn: - # Apply the filter function if any - filtered_array = list(filter(eval(filter_fn), field)) - else: - filtered_array = field - - # Get only the array_fields specified. If none was specified, return the whole array - # TODO(FlorGrosso): check that the array fields are Strings and discard those which - # are not. - if 'fields' in mapping.get('mapping_options', {}): - fields = mapping['mapping_options']['fields'] - values['data'] = [{f: extract_value(elem, attrgetter(f)) for f in fields} for elem in filtered_array] - else: - values['data'] = filtered_array - return json.dumps(values, cls=ROS2JSONEncoder) - -""" -Transforms the ROS message to json and: - - Filters out fields on the top level of the json only. -""" -def serialize(msg, mapping): - # TODO: design filtering support and implement it. It should be possible - # to leverage jq to do so. However, this would require adding a new rosdep - # rule for `pyjq`: https://pypi.org/project/pyjq/. - # filter = mapping.get('mapping_options', {}).get('filter') - - # Get fields configuration - fields = mapping.get('mapping_options', {}).get('fields') - # Transform ROS message to dict - msg_dict = message_to_ordereddict(msg) - - # Shrink output by keeping only selected fields or keys - if fields: - msg_dict = { k: v for k, v in msg_dict.items() if k in fields} - - return msg_dict - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml deleted file mode 100644 index e9ae845..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241213172505.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml deleted file mode 100644 index e9ae845..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241213174002.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml deleted file mode 100644 index e331473..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241213174830.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml deleted file mode 100644 index e331473..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241213174900.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml deleted file mode 100644 index 1527175..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241213175417.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml deleted file mode 100644 index 1527175..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241213175425.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml deleted file mode 100644 index bed10be..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217094439.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml deleted file mode 100644 index dcc4f8c..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217100145.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml deleted file mode 100644 index e54f648..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217100401.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml deleted file mode 100644 index f5f9377..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217100515.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml deleted file mode 100644 index e13a886..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217100647.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml deleted file mode 100644 index c6c2f80..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217100726.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml deleted file mode 100644 index 1a6453d..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217101034.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml deleted file mode 100644 index 04f4692..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217101335.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml deleted file mode 100644 index 74a1e3d..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217101636.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml deleted file mode 100644 index 1f4fa78..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217101711.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml deleted file mode 100644 index 1f4fa78..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217101729.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml deleted file mode 100644 index 95faa19..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217101938.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml deleted file mode 100644 index 95faa19..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217101941.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml deleted file mode 100644 index 4597645..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217104852.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml deleted file mode 100644 index f4ed34d..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217104941.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml deleted file mode 100644 index 0b82762..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217105013.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml deleted file mode 100644 index 3d5ba21..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217105728.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml deleted file mode 100644 index efbe43c..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217105923.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml deleted file mode 100644 index 2fb31e7..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217105958.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml deleted file mode 100644 index 6864e6c..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217110012.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml deleted file mode 100644 index 118fed9..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217110015.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110221.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217110221.py deleted file mode 100644 index e69de29..0000000 diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217110328.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217110328.py deleted file mode 100644 index e3efd80..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217110328.py +++ /dev/null @@ -1,39 +0,0 @@ -import launch -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, LogInfo -from launch.substitutions import LaunchConfiguration, PathJoinSubstitution -from launch_ros.actions import Node - - -def generate_launch_description(): - return LaunchDescription([ - # Declaración de argumentos - DeclareLaunchArgument( - 'config_path', - default_value=PathJoinSubstitution([launch.substitutions.LaunchConfiguration('package_share_directory'), 'test', 'sample_data', 'config.yaml']), - description='Path to the config file' - ), - DeclareLaunchArgument( - 'rosbag_path', - default_value=PathJoinSubstitution([launch.substitutions.LaunchConfiguration('package_share_directory'), 'test', 'sample_data', 'harcodedRosbag', 'rosbag2_2024_12_13-19_33_34_0.db3']), - description='Path to the rosbag file' - ), - - # Primer nodo: inorbit_republisher - Node( - name='inorbit_republisher', - package='inorbit_republisher', - executable='republisher', - output='screen', - parameters=[{'config': LaunchConfiguration('config_path')}], - ), - - # Segundo nodo: rosbag2 player - Node( - package='rosbag2', - executable='play', - name='player', - output='screen', - arguments=['-l', LaunchConfiguration('rosbag_path')], - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml deleted file mode 100644 index 3539baa..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217111512.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112220.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112220.py deleted file mode 100644 index fe1b159..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217112220.py +++ /dev/null @@ -1,22 +0,0 @@ -import launch -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': '/root/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml'}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112508.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112508.py deleted file mode 100644 index 04bfc43..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217112508.py +++ /dev/null @@ -1,26 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess -import os - -def generate_launch_description(): - # Define las rutas absolutas a los archivos - config_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112602.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112602.py deleted file mode 100644 index f27002e..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217112602.py +++ /dev/null @@ -1,26 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess -import os - -def generate_launch_description(): - # Define las rutas absolutas a los archivos - config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112824.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112824.py deleted file mode 100644 index c61a5cc..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217112824.py +++ /dev/null @@ -1,25 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - # Rutas absolutas de tus archivos - config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217112831.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217112831.py deleted file mode 100644 index 8419f12..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217112831.py +++ /dev/null @@ -1,25 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - # Rutas absolutas de tus archivos - config_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml deleted file mode 100644 index 410d847..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217113329.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113333.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113333.py deleted file mode 100644 index c61a5cc..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217113333.py +++ /dev/null @@ -1,25 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - # Rutas absolutas de tus archivos - config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113410.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113410.py deleted file mode 100644 index 3f4031a..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217113410.py +++ /dev/null @@ -1,25 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - # Rutas absolutas de tus archivos - config_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113437.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113437.py deleted file mode 100644 index c9b17f9..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217113437.py +++ /dev/null @@ -1,25 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - # Rutas absolutas de tus archivos - config_file = "~/ros2_ws/src/inorbit_republisher/test/pep/config.yaml" - rosbag_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217113453.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217113453.py deleted file mode 100644 index 3f4031a..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217113453.py +++ /dev/null @@ -1,25 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - # Rutas absolutas de tus archivos - config_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "~/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217114100.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217114100.py deleted file mode 100644 index c61a5cc..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217114100.py +++ /dev/null @@ -1,25 +0,0 @@ -import launch -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import ExecuteProcess - -def generate_launch_description(): - # Rutas absolutas de tus archivos - config_file = "ros2_ws/src/inorbit_republisher/test/sample_data/config.yaml" - rosbag_file = "ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3" - - return LaunchDescription([ - # Nodo inorbit_republisher - Node( - package='inorbit_republisher', - executable='republisher', - name='inorbit_republisher', - parameters=[{'config': config_file}], - ), - - # Comando para reproducir rosbag2 - ExecuteProcess( - cmd=['ros2', 'bag', 'play', rosbag_file], - output='screen' - ), - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml deleted file mode 100644 index 6f25bcf..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217114845.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml deleted file mode 100644 index 6f25bcf..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217115301.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml deleted file mode 100644 index a9c2581..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217115430.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml deleted file mode 100644 index 0857004..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217115941.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml deleted file mode 100644 index 7018ab9..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217123416.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml deleted file mode 100644 index 0857004..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217123424.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml deleted file mode 100644 index a9c2581..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217123458.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml deleted file mode 100644 index a9c2581..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217123518.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml deleted file mode 100644 index f604bf7..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217123845.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml deleted file mode 100644 index d219e59..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217123854.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml deleted file mode 100644 index 2cfbd63..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217124149.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124220.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217124220.py deleted file mode 100644 index 274f62b..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217124220.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, LogInfo, ExecuteProcess -from launch.substitutions import LaunchConfiguration - - -def generate_launch_description(): - return LaunchDescription([ - # Primer nodo: inorbit_republisher - DeclareLaunchArgument('config_file', default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', description='Configuración de archivo'), - - LogInfo(condition=LaunchConfiguration('config_file')), - - ExecuteProcess( - cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], - name='inorbit_republisher', - output='screen' - ), - - # Segundo nodo: rosbag2 player - ExecuteProcess( - cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], - name='rosbag_player', - output='screen' - ) - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124420.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217124420.py deleted file mode 100644 index a921f9d..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217124420.py +++ /dev/null @@ -1,25 +0,0 @@ -import os -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, ExecuteProcess -from launch.substitutions import LaunchConfiguration - - -def generate_launch_description(): - return LaunchDescription([ - # Primer nodo: inorbit_republisher - DeclareLaunchArgument('config_file', default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', description='Archivo de configuración'), - - # Ejecutar el nodo inorbit_republisher - ExecuteProcess( - cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], - name='inorbit_republisher', - output='screen' - ), - - # Ejecutar rosbag2 player - ExecuteProcess( - cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], - name='rosbag_player', - output='screen' - ) - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217124736.py b/.history/inorbit_republisher/launch/sample_data.launch_20241217124736.py deleted file mode 100644 index 9451b6c..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217124736.py +++ /dev/null @@ -1,29 +0,0 @@ -import os -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, ExecuteProcess -from launch.substitutions import LaunchConfiguration - - -def generate_launch_description(): - return LaunchDescription([ - # Declarar el argumento 'config_file' con su valor por defecto - DeclareLaunchArgument( - 'config_file', - default_value='/root/ros2_ws/src/inorbit_republisher/test/sample_data/config/example.yaml', - description='Ruta al archivo de configuración del republisher' - ), - - # Ejecutar el nodo inorbit_republisher - ExecuteProcess( - cmd=['ros2', 'run', 'inorbit_republisher', 'republisher', '--ros-args', '--param', 'config:=' + LaunchConfiguration('config_file')], - name='inorbit_republisher', - output='screen' - ), - - # Ejecutar rosbag2 player - ExecuteProcess( - cmd=['ros2', 'bag', 'play', '/root/ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3'], - name='rosbag_player', - output='screen' - ) - ]) diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml deleted file mode 100644 index d64b1ff..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217125321.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml deleted file mode 100644 index 4431661..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217125338.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml deleted file mode 100644 index 452a62b..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217125743.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml deleted file mode 100644 index 918a1de..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217125930.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml deleted file mode 100644 index 4cf20aa..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217125954.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml b/.history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml deleted file mode 100644 index 918a1de..0000000 --- a/.history/inorbit_republisher/launch/sample_data.launch_20241217130002.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.history/inorbit_republisher/setup_20241213161527.py b/.history/inorbit_republisher/setup_20241213161527.py deleted file mode 100644 index 5a4ee20..0000000 --- a/.history/inorbit_republisher/setup_20241213161527.py +++ /dev/null @@ -1,30 +0,0 @@ -from setuptools import setup -import os -from glob import glob - -package_name = 'inorbit_republisher' - -setup( - name=package_name, - version='0.4.1', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - (os.path.join('share', package_name), glob('launch/*')), - (os.path.join('share', package_name, 'config'), glob('config/*')) - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='InOrbit', - maintainer_email='support@inorbit.ai', - description='ROS2 to InOrbit topic republisher', - license='MIT', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - 'republisher = inorbit_republisher.republisher:main' - ], - }, -) diff --git a/.history/inorbit_republisher/setup_20241213172142.py b/.history/inorbit_republisher/setup_20241213172142.py deleted file mode 100644 index 5a4ee20..0000000 --- a/.history/inorbit_republisher/setup_20241213172142.py +++ /dev/null @@ -1,30 +0,0 @@ -from setuptools import setup -import os -from glob import glob - -package_name = 'inorbit_republisher' - -setup( - name=package_name, - version='0.4.1', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - (os.path.join('share', package_name), glob('launch/*')), - (os.path.join('share', package_name, 'config'), glob('config/*')) - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='InOrbit', - maintainer_email='support@inorbit.ai', - description='ROS2 to InOrbit topic republisher', - license='MIT', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - 'republisher = inorbit_republisher.republisher:main' - ], - }, -) diff --git a/.history/inorbit_republisher/setup_20241213172214.py b/.history/inorbit_republisher/setup_20241213172214.py deleted file mode 100644 index 5a4ee20..0000000 --- a/.history/inorbit_republisher/setup_20241213172214.py +++ /dev/null @@ -1,30 +0,0 @@ -from setuptools import setup -import os -from glob import glob - -package_name = 'inorbit_republisher' - -setup( - name=package_name, - version='0.4.1', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - (os.path.join('share', package_name), glob('launch/*')), - (os.path.join('share', package_name, 'config'), glob('config/*')) - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='InOrbit', - maintainer_email='support@inorbit.ai', - description='ROS2 to InOrbit topic republisher', - license='MIT', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - 'republisher = inorbit_republisher.republisher:main' - ], - }, -) diff --git a/.history/inorbit_republisher/test/README_20241213162953.md b/.history/inorbit_republisher/test/README_20241213162953.md deleted file mode 100644 index e69de29..0000000 diff --git a/.history/inorbit_republisher/test/README_20241213163651.md b/.history/inorbit_republisher/test/README_20241213163651.md deleted file mode 100644 index 01379ea..0000000 --- a/.history/inorbit_republisher/test/README_20241213163651.md +++ /dev/null @@ -1,10 +0,0 @@ -1. generar nuestro propio rosbag, para eso: -ros2 bag record /my_magnetic_field /my_temperature -y en otro tab -corremos el archivo fake_sensor_sample_rep-pu - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - diff --git a/.history/inorbit_republisher/test/README_20241213175317.md b/.history/inorbit_republisher/test/README_20241213175317.md deleted file mode 100644 index bbfca11..0000000 --- a/.history/inorbit_republisher/test/README_20241213175317.md +++ /dev/null @@ -1,17 +0,0 @@ -1. generar nuestro propio rosbag, para eso: -ros2 bag record /my_magnetic_field /my_temperature -y en otro tab -corremos el archivo fake_sensor_sample_rep-pu - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - con ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recorde desde ros2_ws/src, lo movi a donde queria con mv "file" path -Corremos el package: - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: \ No newline at end of file diff --git a/.history/inorbit_republisher/test/README_20241213175932.md b/.history/inorbit_republisher/test/README_20241213175932.md deleted file mode 100644 index 9229e8f..0000000 --- a/.history/inorbit_republisher/test/README_20241213175932.md +++ /dev/null @@ -1,22 +0,0 @@ -1. generar nuestro propio rosbag, para eso: -ros2 bag record /my_magnetic_field /my_temperature -y en otro tab -corremos el archivo fake_sensor_sample_rep-pu - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - con ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recorde desde ros2_ws/src, lo movi a donde queria con mv "file" path -Corremos el package: - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - - 3.Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature diff --git a/.history/inorbit_republisher/test/README_20241213180602.md b/.history/inorbit_republisher/test/README_20241213180602.md deleted file mode 100644 index 6631616..0000000 --- a/.history/inorbit_republisher/test/README_20241213180602.md +++ /dev/null @@ -1,26 +0,0 @@ -1. A. generar nuestro propio rosbag, para eso: - ros2 bag record /my_magnetic_field /my_temperature - B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - usando ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path -2. Corremos el package: - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - -3. Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature - -IRi del lunes: - Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: - ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" -Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo diff --git a/.history/inorbit_republisher/test/README_20241213180720.md b/.history/inorbit_republisher/test/README_20241213180720.md deleted file mode 100644 index f4c50b0..0000000 --- a/.history/inorbit_republisher/test/README_20241213180720.md +++ /dev/null @@ -1,27 +0,0 @@ -1. A. generar nuestro propio rosbag, para eso: - ros2 bag record /my_magnetic_field /my_temperature - B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - usando ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path -2. Corremos el package: - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - -3. Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature - -IRi del lunes: - Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: - ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" -Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo -Tengo que crear un docker en humble xq elimine el mio g \ No newline at end of file diff --git a/.history/inorbit_republisher/test/README_20241217094923.md b/.history/inorbit_republisher/test/README_20241217094923.md deleted file mode 100644 index 72ca7a0..0000000 --- a/.history/inorbit_republisher/test/README_20241217094923.md +++ /dev/null @@ -1,32 +0,0 @@ -1. A. generar nuestro propio rosbag, para eso: - ros2 bag record /my_magnetic_field /my_temperature - B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - usando ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path -2. Corremos el package: - primeor hay que buildearlo... - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-instal - source /opt/ros/humble/setup.bash - luego, coror el file - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - -3. Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature - -IRi del lunes: - Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: - ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" -Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo -Tengo que crear un docker en humble xq elimine el mio g \ No newline at end of file diff --git a/.history/inorbit_republisher/test/README_20241217121634.md b/.history/inorbit_republisher/test/README_20241217121634.md deleted file mode 100644 index f10501a..0000000 --- a/.history/inorbit_republisher/test/README_20241217121634.md +++ /dev/null @@ -1,40 +0,0 @@ -1. A. generar nuestro propio rosbag, para eso: - ros2 bag record /my_magnetic_field /my_temperature - B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - usando ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path -2. Corremos el package: - primeor hay que buildearlo... - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-instal - source install/setup.bash - luego, coror el file - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - -3. Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature - -IRi del lunes: - Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: - ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" -Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo -Tengo que crear un docker en humble xq elimine el mio g - -Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> - cd - cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher -/// alternativa a mi launch.xml que no funciona -1. corro mi rosbag haciendo esto en una terminal: - cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag - ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 diff --git a/.history/inorbit_republisher/test/README_20241217123656.md b/.history/inorbit_republisher/test/README_20241217123656.md deleted file mode 100644 index a65e2c2..0000000 --- a/.history/inorbit_republisher/test/README_20241217123656.md +++ /dev/null @@ -1,46 +0,0 @@ -1. A. generar nuestro propio rosbag, para eso: - ros2 bag record /my_magnetic_field /my_temperature - B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - usando ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path -2. Corremos el package: - primeor hay que buildearlo... - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-instal - source install/setup.bash - luego, coror el file - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - -3. Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature - -IRi del lunes: - Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: - ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" -Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo -Tengo que crear un docker en humble xq elimine el mio g - -Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> - cd - cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher -/// alternativa a mi launch.xml que no funciona -1. corro mi rosbag haciendo esto en una terminal: - cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag - ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 - en otra terminal: - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature -////// - Pyuede ser qyue no funcione xq mi rosbag es finito_ - \ No newline at end of file diff --git a/.history/inorbit_republisher/test/README_20241217130401.md b/.history/inorbit_republisher/test/README_20241217130401.md deleted file mode 100644 index aac438a..0000000 --- a/.history/inorbit_republisher/test/README_20241217130401.md +++ /dev/null @@ -1,46 +0,0 @@ -1. A. generar nuestro propio rosbag, para eso: - ros2 bag record /my_magnetic_field /my_temperature - B. en otro tab corremos el archivo fake_sensor_sample_rep-pu: - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-install - source /opt/ros/humble/setup.bash - cd ros2_ws/src/inorbit_republisher/inorbit_republisher - ros2 run inorbit_republisher fake_sensor_sample_rep --ros-args -p config:="/root/ros2_ws/src/inorbit_republisher/config/example.yaml" - NO ME ENCUENTRA EL EJECUTABLE --> edite republisher.py para que publique lo que YO quiera.... y me hago mi rosbag - usando ros2 bag record /my_magnetic_field /my_temperature - como hice el ros2 bag recordie desde ros2_ws/src, lo movi a donde queria con mv "file" path -2. Corremos el package: - primeor hay que buildearlo... - cd ros2_ws/src - colcon build --packages-select inorbit_republisher --symlink-instal - source install/setup.bash - luego, coror el file - cd ros2_ws/src/inorbit_republisher/test/sample_data - ros2 launch inorbit_republisher sample_data.launch.xml - Segun ros2, debe estar en la crpeta de luinch. - Igualmente no me lo reconoce. Pero si corro ros2 launch inorbit_republisher sample_data.launch SI LO RECONOCE: - -3. Abro otra terminal: - cd ros2_ws/src/inorbit_republisher/test/sample_data - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature - -IRi del lunes: - Si hardcodeo el publish haciendo en una terminal lo siguiente, cuando hago el echo me funciona de perlas: - ros2 topic pub /my_temperature std_msgs/msg/Float64 "data: 25.0" -Pero es como que el rosbag no lo lee se ve, seguir probrnado, animo animo -Tengo que crear un docker en humble xq elimine el mio g - -Si me tira errores wtf: vuelvo a copiar mi file en root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher> - cd - cp ros2_ws/src/inorbit_republisher/launch/sample_data.launch.xml /root/ros2_ws/src/install/inorbit_republisher/share/inorbit_republisher -/// alternativa a mi launch.xml que no funciona -1. corro mi rosbag haciendo esto en una terminal: - cd /ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag - ros2 bag play rosbag2_2024_12_13-19_33_34_0.db3 - en otra terminal: - source /opt/ros/humble/setup.bash - ros2 topic echo my_temperature -////// - Pyuede ser qyue no funcione xq mi rosbag es finito_ - - AttributeError: Attribute 'exec' of type '' not found in Entity 'node' este es el error diff --git a/.history/inorbit_republisher/test/sample_data/config_20241213162657.yaml b/.history/inorbit_republisher/test/sample_data/config_20241213162657.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/.history/inorbit_republisher/test/sample_data/config_20241213165503.yaml b/.history/inorbit_republisher/test/sample_data/config_20241213165503.yaml deleted file mode 100644 index c7eccf9..0000000 --- a/.history/inorbit_republisher/test/sample_data/config_20241213165503.yaml +++ /dev/null @@ -1,23 +0,0 @@ -republishers: - - topic: "/my_magnetic_field" - msg_type: "sensor_msgs/MagneticField" - mappings: - - field: "magnetic_field.x" - out: - topic: "/inorbit/custom_data" - key: "my_magnetic_field_x" - - field: "magnetic_field.y" - out: - topic: "/inorbit/custom_data" - key: "my_magnetic_field_y" - - field: "magnetic_field.z" - out: - topic: "/inorbit/custom_data" - key: "my_magnetic_field_z" - - topic: "/my_temperature" - msg_type: "sensor_msgs/Temperature" - mappings: - - field: "temperature" - out: - topic: "/inorbit/custom_data" - key: "my_temperature" \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml b/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml deleted file mode 100644 index e9ae845..0000000 --- a/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174001.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml b/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml deleted file mode 100644 index e331473..0000000 --- a/.history/inorbit_republisher/test/sample_data/sample_data.launch_20241213174614.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162714.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162714.xml deleted file mode 100644 index e69de29..0000000 diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml deleted file mode 100644 index 62822e8..0000000 --- a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213162848.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml deleted file mode 100644 index 31d7d22..0000000 --- a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165700.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml deleted file mode 100644 index 31d7d22..0000000 --- a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213165739.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml b/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml deleted file mode 100644 index e9ae845..0000000 --- a/.history/inorbit_republisher/test/sample_data/sample_data_launch_20241213172506.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From 976496bb81f1bbd64c0ae81716589dc0d417de01 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 10:34:08 -0300 Subject: [PATCH 13/21] Updated gitignore file --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index f637901..437ce29 100644 --- a/.gitignore +++ b/.gitignore @@ -10,9 +10,6 @@ __pycache__/ *.pyo *.pyd -# Git history -*.history/ - # VS files .vscode/ .idea/ From 7e4f8f27750d3304ff5776300cb1b1a8e337aa70 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 10:59:52 -0300 Subject: [PATCH 14/21] Revert "Deleted irrelevant folders" This reverts commit 5782f90dc16a8fe93fd83e60637a7af41dde6164. --- .../test/sample_data/build/.built_by | 1 + .../test/sample_data/build/COLCON_IGNORE | 0 .../install/.colcon_install_layout | 1 + .../test/sample_data/install/COLCON_IGNORE | 0 .../install/_local_setup_util_ps1.py | 407 ++++++++++++++++++ .../install/_local_setup_util_sh.py | 407 ++++++++++++++++++ .../test/sample_data/install/local_setup.bash | 121 ++++++ .../test/sample_data/install/local_setup.ps1 | 55 +++ .../test/sample_data/install/local_setup.sh | 137 ++++++ .../test/sample_data/install/local_setup.zsh | 134 ++++++ .../test/sample_data/install/setup.bash | 37 ++ .../test/sample_data/install/setup.ps1 | 31 ++ .../test/sample_data/install/setup.sh | 53 +++ .../test/sample_data/install/setup.zsh | 37 ++ .../test/sample_data/log/COLCON_IGNORE | 0 .../log/build_2024-12-13_20-02-50/events.log | 2 + .../build_2024-12-13_20-02-50/logger_all.log | 77 ++++ .../log/build_2024-12-13_20-49-52/events.log | 2 + .../build_2024-12-13_20-49-52/logger_all.log | 76 ++++ .../test/sample_data/log/latest | 1 + .../test/sample_data/log/latest_build | 1 + 21 files changed, 1580 insertions(+) create mode 100644 inorbit_republisher/test/sample_data/build/.built_by create mode 100644 inorbit_republisher/test/sample_data/build/COLCON_IGNORE create mode 100644 inorbit_republisher/test/sample_data/install/.colcon_install_layout create mode 100644 inorbit_republisher/test/sample_data/install/COLCON_IGNORE create mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py create mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.bash create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.ps1 create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.sh create mode 100644 inorbit_republisher/test/sample_data/install/local_setup.zsh create mode 100644 inorbit_republisher/test/sample_data/install/setup.bash create mode 100644 inorbit_republisher/test/sample_data/install/setup.ps1 create mode 100644 inorbit_republisher/test/sample_data/install/setup.sh create mode 100644 inorbit_republisher/test/sample_data/install/setup.zsh create mode 100644 inorbit_republisher/test/sample_data/log/COLCON_IGNORE create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log create mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log create mode 120000 inorbit_republisher/test/sample_data/log/latest create mode 120000 inorbit_republisher/test/sample_data/log/latest_build diff --git a/inorbit_republisher/test/sample_data/build/.built_by b/inorbit_republisher/test/sample_data/build/.built_by new file mode 100644 index 0000000..06e74ac --- /dev/null +++ b/inorbit_republisher/test/sample_data/build/.built_by @@ -0,0 +1 @@ +colcon diff --git a/inorbit_republisher/test/sample_data/build/COLCON_IGNORE b/inorbit_republisher/test/sample_data/build/COLCON_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/inorbit_republisher/test/sample_data/install/.colcon_install_layout b/inorbit_republisher/test/sample_data/install/.colcon_install_layout new file mode 100644 index 0000000..3aad533 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/.colcon_install_layout @@ -0,0 +1 @@ +isolated diff --git a/inorbit_republisher/test/sample_data/install/COLCON_IGNORE b/inorbit_republisher/test/sample_data/install/COLCON_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py new file mode 100644 index 0000000..3c6d9e8 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py @@ -0,0 +1,407 @@ +# Copyright 2016-2019 Dirk Thomas +# Licensed under the Apache License, Version 2.0 + +import argparse +from collections import OrderedDict +import os +from pathlib import Path +import sys + + +FORMAT_STR_COMMENT_LINE = '# {comment}' +FORMAT_STR_SET_ENV_VAR = 'Set-Item -Path "Env:{name}" -Value "{value}"' +FORMAT_STR_USE_ENV_VAR = '$env:{name}' +FORMAT_STR_INVOKE_SCRIPT = '_colcon_prefix_powershell_source_script "{script_path}"' # noqa: E501 +FORMAT_STR_REMOVE_LEADING_SEPARATOR = '' # noqa: E501 +FORMAT_STR_REMOVE_TRAILING_SEPARATOR = '' # noqa: E501 + +DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' +DSV_TYPE_SET = 'set' +DSV_TYPE_SET_IF_UNSET = 'set-if-unset' +DSV_TYPE_SOURCE = 'source' + + +def main(argv=sys.argv[1:]): # noqa: D103 + parser = argparse.ArgumentParser( + description='Output shell commands for the packages in topological ' + 'order') + parser.add_argument( + 'primary_extension', + help='The file extension of the primary shell') + parser.add_argument( + 'additional_extension', nargs='?', + help='The additional file extension to be considered') + parser.add_argument( + '--merged-install', action='store_true', + help='All install prefixes are merged into a single location') + args = parser.parse_args(argv) + + packages = get_packages(Path(__file__).parent, args.merged_install) + + ordered_packages = order_packages(packages) + for pkg_name in ordered_packages: + if _include_comments(): + print( + FORMAT_STR_COMMENT_LINE.format_map( + {'comment': 'Package: ' + pkg_name})) + prefix = os.path.abspath(os.path.dirname(__file__)) + if not args.merged_install: + prefix = os.path.join(prefix, pkg_name) + for line in get_commands( + pkg_name, prefix, args.primary_extension, + args.additional_extension + ): + print(line) + + for line in _remove_ending_separators(): + print(line) + + +def get_packages(prefix_path, merged_install): + """ + Find packages based on colcon-specific files created during installation. + + :param Path prefix_path: The install prefix path of all packages + :param bool merged_install: The flag if the packages are all installed + directly in the prefix or if each package is installed in a subdirectory + named after the package + :returns: A mapping from the package name to the set of runtime + dependencies + :rtype: dict + """ + packages = {} + # since importing colcon_core isn't feasible here the following constant + # must match colcon_core.location.get_relative_package_index_path() + subdirectory = 'share/colcon-core/packages' + if merged_install: + # return if workspace is empty + if not (prefix_path / subdirectory).is_dir(): + return packages + # find all files in the subdirectory + for p in (prefix_path / subdirectory).iterdir(): + if not p.is_file(): + continue + if p.name.startswith('.'): + continue + add_package_runtime_dependencies(p, packages) + else: + # for each subdirectory look for the package specific file + for p in prefix_path.iterdir(): + if not p.is_dir(): + continue + if p.name.startswith('.'): + continue + p = p / subdirectory / p.name + if p.is_file(): + add_package_runtime_dependencies(p, packages) + + # remove unknown dependencies + pkg_names = set(packages.keys()) + for k in packages.keys(): + packages[k] = {d for d in packages[k] if d in pkg_names} + + return packages + + +def add_package_runtime_dependencies(path, packages): + """ + Check the path and if it exists extract the packages runtime dependencies. + + :param Path path: The resource file containing the runtime dependencies + :param dict packages: A mapping from package names to the sets of runtime + dependencies to add to + """ + content = path.read_text() + dependencies = set(content.split(os.pathsep) if content else []) + packages[path.name] = dependencies + + +def order_packages(packages): + """ + Order packages topologically. + + :param dict packages: A mapping from package name to the set of runtime + dependencies + :returns: The package names + :rtype: list + """ + # select packages with no dependencies in alphabetical order + to_be_ordered = list(packages.keys()) + ordered = [] + while to_be_ordered: + pkg_names_without_deps = [ + name for name in to_be_ordered if not packages[name]] + if not pkg_names_without_deps: + reduce_cycle_set(packages) + raise RuntimeError( + 'Circular dependency between: ' + ', '.join(sorted(packages))) + pkg_names_without_deps.sort() + pkg_name = pkg_names_without_deps[0] + to_be_ordered.remove(pkg_name) + ordered.append(pkg_name) + # remove item from dependency lists + for k in list(packages.keys()): + if pkg_name in packages[k]: + packages[k].remove(pkg_name) + return ordered + + +def reduce_cycle_set(packages): + """ + Reduce the set of packages to the ones part of the circular dependency. + + :param dict packages: A mapping from package name to the set of runtime + dependencies which is modified in place + """ + last_depended = None + while len(packages) > 0: + # get all remaining dependencies + depended = set() + for pkg_name, dependencies in packages.items(): + depended = depended.union(dependencies) + # remove all packages which are not dependent on + for name in list(packages.keys()): + if name not in depended: + del packages[name] + if last_depended: + # if remaining packages haven't changed return them + if last_depended == depended: + return packages.keys() + # otherwise reduce again + last_depended = depended + + +def _include_comments(): + # skipping comment lines when COLCON_TRACE is not set speeds up the + # processing especially on Windows + return bool(os.environ.get('COLCON_TRACE')) + + +def get_commands(pkg_name, prefix, primary_extension, additional_extension): + commands = [] + package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') + if os.path.exists(package_dsv_path): + commands += process_dsv_file( + package_dsv_path, prefix, primary_extension, additional_extension) + return commands + + +def process_dsv_file( + dsv_path, prefix, primary_extension=None, additional_extension=None +): + commands = [] + if _include_comments(): + commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) + with open(dsv_path, 'r') as h: + content = h.read() + lines = content.splitlines() + + basenames = OrderedDict() + for i, line in enumerate(lines): + # skip over empty or whitespace-only lines + if not line.strip(): + continue + # skip over comments + if line.startswith('#'): + continue + try: + type_, remainder = line.split(';', 1) + except ValueError: + raise RuntimeError( + "Line %d in '%s' doesn't contain a semicolon separating the " + 'type from the arguments' % (i + 1, dsv_path)) + if type_ != DSV_TYPE_SOURCE: + # handle non-source lines + try: + commands += handle_dsv_types_except_source( + type_, remainder, prefix) + except RuntimeError as e: + raise RuntimeError( + "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e + else: + # group remaining source lines by basename + path_without_ext, ext = os.path.splitext(remainder) + if path_without_ext not in basenames: + basenames[path_without_ext] = set() + assert ext.startswith('.') + ext = ext[1:] + if ext in (primary_extension, additional_extension): + basenames[path_without_ext].add(ext) + + # add the dsv extension to each basename if the file exists + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if os.path.exists(basename + '.dsv'): + extensions.add('dsv') + + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if 'dsv' in extensions: + # process dsv files recursively + commands += process_dsv_file( + basename + '.dsv', prefix, primary_extension=primary_extension, + additional_extension=additional_extension) + elif primary_extension in extensions and len(extensions) == 1: + # source primary-only files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + primary_extension})] + elif additional_extension in extensions: + # source non-primary files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + additional_extension})] + + return commands + + +def handle_dsv_types_except_source(type_, remainder, prefix): + commands = [] + if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): + try: + env_name, value = remainder.split(';', 1) + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the value') + try_prefixed_value = os.path.join(prefix, value) if value else prefix + if os.path.exists(try_prefixed_value): + value = try_prefixed_value + if type_ == DSV_TYPE_SET: + commands += _set(env_name, value) + elif type_ == DSV_TYPE_SET_IF_UNSET: + commands += _set_if_unset(env_name, value) + else: + assert False + elif type_ in ( + DSV_TYPE_APPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS + ): + try: + env_name_and_values = remainder.split(';') + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the values') + env_name = env_name_and_values[0] + values = env_name_and_values[1:] + for value in values: + if not value: + value = prefix + elif not os.path.isabs(value): + value = os.path.join(prefix, value) + if ( + type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and + not os.path.exists(value) + ): + comment = f'skip extending {env_name} with not existing ' \ + f'path: {value}' + if _include_comments(): + commands.append( + FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) + elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: + commands += _append_unique_value(env_name, value) + else: + commands += _prepend_unique_value(env_name, value) + else: + raise RuntimeError( + 'contains an unknown environment hook type: ' + type_) + return commands + + +env_state = {} + + +def _append_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # append even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional leading separator + extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': extend + value}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +def _prepend_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # prepend even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional trailing separator + extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value + extend}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +# generate commands for removing prepended underscores +def _remove_ending_separators(): + # do nothing if the shell extension does not implement the logic + if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: + return [] + + global env_state + commands = [] + for name in env_state: + # skip variables that already had values before this script started prepending + if name in os.environ: + continue + commands += [ + FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), + FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] + return commands + + +def _set(name, value): + global env_state + env_state[name] = value + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + return [line] + + +def _set_if_unset(name, value): + global env_state + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + if env_state.get(name, os.environ.get(name)): + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +if __name__ == '__main__': # pragma: no cover + try: + rc = main() + except RuntimeError as e: + print(str(e), file=sys.stderr) + rc = 1 + sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py new file mode 100644 index 0000000..f67eaa9 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py @@ -0,0 +1,407 @@ +# Copyright 2016-2019 Dirk Thomas +# Licensed under the Apache License, Version 2.0 + +import argparse +from collections import OrderedDict +import os +from pathlib import Path +import sys + + +FORMAT_STR_COMMENT_LINE = '# {comment}' +FORMAT_STR_SET_ENV_VAR = 'export {name}="{value}"' +FORMAT_STR_USE_ENV_VAR = '${name}' +FORMAT_STR_INVOKE_SCRIPT = 'COLCON_CURRENT_PREFIX="{prefix}" _colcon_prefix_sh_source_script "{script_path}"' # noqa: E501 +FORMAT_STR_REMOVE_LEADING_SEPARATOR = 'if [ "$(echo -n ${name} | head -c 1)" = ":" ]; then export {name}=${{{name}#?}} ; fi' # noqa: E501 +FORMAT_STR_REMOVE_TRAILING_SEPARATOR = 'if [ "$(echo -n ${name} | tail -c 1)" = ":" ]; then export {name}=${{{name}%?}} ; fi' # noqa: E501 + +DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' +DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' +DSV_TYPE_SET = 'set' +DSV_TYPE_SET_IF_UNSET = 'set-if-unset' +DSV_TYPE_SOURCE = 'source' + + +def main(argv=sys.argv[1:]): # noqa: D103 + parser = argparse.ArgumentParser( + description='Output shell commands for the packages in topological ' + 'order') + parser.add_argument( + 'primary_extension', + help='The file extension of the primary shell') + parser.add_argument( + 'additional_extension', nargs='?', + help='The additional file extension to be considered') + parser.add_argument( + '--merged-install', action='store_true', + help='All install prefixes are merged into a single location') + args = parser.parse_args(argv) + + packages = get_packages(Path(__file__).parent, args.merged_install) + + ordered_packages = order_packages(packages) + for pkg_name in ordered_packages: + if _include_comments(): + print( + FORMAT_STR_COMMENT_LINE.format_map( + {'comment': 'Package: ' + pkg_name})) + prefix = os.path.abspath(os.path.dirname(__file__)) + if not args.merged_install: + prefix = os.path.join(prefix, pkg_name) + for line in get_commands( + pkg_name, prefix, args.primary_extension, + args.additional_extension + ): + print(line) + + for line in _remove_ending_separators(): + print(line) + + +def get_packages(prefix_path, merged_install): + """ + Find packages based on colcon-specific files created during installation. + + :param Path prefix_path: The install prefix path of all packages + :param bool merged_install: The flag if the packages are all installed + directly in the prefix or if each package is installed in a subdirectory + named after the package + :returns: A mapping from the package name to the set of runtime + dependencies + :rtype: dict + """ + packages = {} + # since importing colcon_core isn't feasible here the following constant + # must match colcon_core.location.get_relative_package_index_path() + subdirectory = 'share/colcon-core/packages' + if merged_install: + # return if workspace is empty + if not (prefix_path / subdirectory).is_dir(): + return packages + # find all files in the subdirectory + for p in (prefix_path / subdirectory).iterdir(): + if not p.is_file(): + continue + if p.name.startswith('.'): + continue + add_package_runtime_dependencies(p, packages) + else: + # for each subdirectory look for the package specific file + for p in prefix_path.iterdir(): + if not p.is_dir(): + continue + if p.name.startswith('.'): + continue + p = p / subdirectory / p.name + if p.is_file(): + add_package_runtime_dependencies(p, packages) + + # remove unknown dependencies + pkg_names = set(packages.keys()) + for k in packages.keys(): + packages[k] = {d for d in packages[k] if d in pkg_names} + + return packages + + +def add_package_runtime_dependencies(path, packages): + """ + Check the path and if it exists extract the packages runtime dependencies. + + :param Path path: The resource file containing the runtime dependencies + :param dict packages: A mapping from package names to the sets of runtime + dependencies to add to + """ + content = path.read_text() + dependencies = set(content.split(os.pathsep) if content else []) + packages[path.name] = dependencies + + +def order_packages(packages): + """ + Order packages topologically. + + :param dict packages: A mapping from package name to the set of runtime + dependencies + :returns: The package names + :rtype: list + """ + # select packages with no dependencies in alphabetical order + to_be_ordered = list(packages.keys()) + ordered = [] + while to_be_ordered: + pkg_names_without_deps = [ + name for name in to_be_ordered if not packages[name]] + if not pkg_names_without_deps: + reduce_cycle_set(packages) + raise RuntimeError( + 'Circular dependency between: ' + ', '.join(sorted(packages))) + pkg_names_without_deps.sort() + pkg_name = pkg_names_without_deps[0] + to_be_ordered.remove(pkg_name) + ordered.append(pkg_name) + # remove item from dependency lists + for k in list(packages.keys()): + if pkg_name in packages[k]: + packages[k].remove(pkg_name) + return ordered + + +def reduce_cycle_set(packages): + """ + Reduce the set of packages to the ones part of the circular dependency. + + :param dict packages: A mapping from package name to the set of runtime + dependencies which is modified in place + """ + last_depended = None + while len(packages) > 0: + # get all remaining dependencies + depended = set() + for pkg_name, dependencies in packages.items(): + depended = depended.union(dependencies) + # remove all packages which are not dependent on + for name in list(packages.keys()): + if name not in depended: + del packages[name] + if last_depended: + # if remaining packages haven't changed return them + if last_depended == depended: + return packages.keys() + # otherwise reduce again + last_depended = depended + + +def _include_comments(): + # skipping comment lines when COLCON_TRACE is not set speeds up the + # processing especially on Windows + return bool(os.environ.get('COLCON_TRACE')) + + +def get_commands(pkg_name, prefix, primary_extension, additional_extension): + commands = [] + package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') + if os.path.exists(package_dsv_path): + commands += process_dsv_file( + package_dsv_path, prefix, primary_extension, additional_extension) + return commands + + +def process_dsv_file( + dsv_path, prefix, primary_extension=None, additional_extension=None +): + commands = [] + if _include_comments(): + commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) + with open(dsv_path, 'r') as h: + content = h.read() + lines = content.splitlines() + + basenames = OrderedDict() + for i, line in enumerate(lines): + # skip over empty or whitespace-only lines + if not line.strip(): + continue + # skip over comments + if line.startswith('#'): + continue + try: + type_, remainder = line.split(';', 1) + except ValueError: + raise RuntimeError( + "Line %d in '%s' doesn't contain a semicolon separating the " + 'type from the arguments' % (i + 1, dsv_path)) + if type_ != DSV_TYPE_SOURCE: + # handle non-source lines + try: + commands += handle_dsv_types_except_source( + type_, remainder, prefix) + except RuntimeError as e: + raise RuntimeError( + "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e + else: + # group remaining source lines by basename + path_without_ext, ext = os.path.splitext(remainder) + if path_without_ext not in basenames: + basenames[path_without_ext] = set() + assert ext.startswith('.') + ext = ext[1:] + if ext in (primary_extension, additional_extension): + basenames[path_without_ext].add(ext) + + # add the dsv extension to each basename if the file exists + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if os.path.exists(basename + '.dsv'): + extensions.add('dsv') + + for basename, extensions in basenames.items(): + if not os.path.isabs(basename): + basename = os.path.join(prefix, basename) + if 'dsv' in extensions: + # process dsv files recursively + commands += process_dsv_file( + basename + '.dsv', prefix, primary_extension=primary_extension, + additional_extension=additional_extension) + elif primary_extension in extensions and len(extensions) == 1: + # source primary-only files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + primary_extension})] + elif additional_extension in extensions: + # source non-primary files + commands += [ + FORMAT_STR_INVOKE_SCRIPT.format_map({ + 'prefix': prefix, + 'script_path': basename + '.' + additional_extension})] + + return commands + + +def handle_dsv_types_except_source(type_, remainder, prefix): + commands = [] + if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): + try: + env_name, value = remainder.split(';', 1) + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the value') + try_prefixed_value = os.path.join(prefix, value) if value else prefix + if os.path.exists(try_prefixed_value): + value = try_prefixed_value + if type_ == DSV_TYPE_SET: + commands += _set(env_name, value) + elif type_ == DSV_TYPE_SET_IF_UNSET: + commands += _set_if_unset(env_name, value) + else: + assert False + elif type_ in ( + DSV_TYPE_APPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE, + DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS + ): + try: + env_name_and_values = remainder.split(';') + except ValueError: + raise RuntimeError( + "doesn't contain a semicolon separating the environment name " + 'from the values') + env_name = env_name_and_values[0] + values = env_name_and_values[1:] + for value in values: + if not value: + value = prefix + elif not os.path.isabs(value): + value = os.path.join(prefix, value) + if ( + type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and + not os.path.exists(value) + ): + comment = f'skip extending {env_name} with not existing ' \ + f'path: {value}' + if _include_comments(): + commands.append( + FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) + elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: + commands += _append_unique_value(env_name, value) + else: + commands += _prepend_unique_value(env_name, value) + else: + raise RuntimeError( + 'contains an unknown environment hook type: ' + type_) + return commands + + +env_state = {} + + +def _append_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # append even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional leading separator + extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': extend + value}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +def _prepend_unique_value(name, value): + global env_state + if name not in env_state: + if os.environ.get(name): + env_state[name] = set(os.environ[name].split(os.pathsep)) + else: + env_state[name] = set() + # prepend even if the variable has not been set yet, in case a shell script sets the + # same variable without the knowledge of this Python script. + # later _remove_ending_separators() will cleanup any unintentional trailing separator + extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value + extend}) + if value not in env_state[name]: + env_state[name].add(value) + else: + if not _include_comments(): + return [] + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +# generate commands for removing prepended underscores +def _remove_ending_separators(): + # do nothing if the shell extension does not implement the logic + if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: + return [] + + global env_state + commands = [] + for name in env_state: + # skip variables that already had values before this script started prepending + if name in os.environ: + continue + commands += [ + FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), + FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] + return commands + + +def _set(name, value): + global env_state + env_state[name] = value + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + return [line] + + +def _set_if_unset(name, value): + global env_state + line = FORMAT_STR_SET_ENV_VAR.format_map( + {'name': name, 'value': value}) + if env_state.get(name, os.environ.get(name)): + line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) + return [line] + + +if __name__ == '__main__': # pragma: no cover + try: + rc = main() + except RuntimeError as e: + print(str(e), file=sys.stderr) + rc = 1 + sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/local_setup.bash b/inorbit_republisher/test/sample_data/install/local_setup.bash new file mode 100644 index 0000000..03f0025 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.bash @@ -0,0 +1,121 @@ +# generated from colcon_bash/shell/template/prefix.bash.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# a bash script is able to determine its own path if necessary +if [ -z "$COLCON_CURRENT_PREFIX" ]; then + _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" +else + _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +fi + +# function to prepend a value to a variable +# which uses colons as separators +# duplicates as well as trailing separators are avoided +# first argument: the name of the result variable +# second argument: the value to be prepended +_colcon_prefix_bash_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + + # get values from variable + eval _values=\"\$$_listname\" + # backup the field separator + _colcon_prefix_bash_prepend_unique_value_IFS="$IFS" + IFS=":" + # start with the new value + _all_values="$_value" + _contained_value="" + # iterate over existing values in the variable + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + # ignore duplicates of _value + if [ "$_item" = "$_value" ]; then + _contained_value=1 + continue + fi + # keep non-duplicate values + _all_values="$_all_values:$_item" + done + unset _item + if [ -z "$_contained_value" ]; then + if [ -n "$COLCON_TRACE" ]; then + if [ "$_all_values" = "$_value" ]; then + echo "export $_listname=$_value" + else + echo "export $_listname=$_value:\$$_listname" + fi + fi + fi + unset _contained_value + # restore the field separator + IFS="$_colcon_prefix_bash_prepend_unique_value_IFS" + unset _colcon_prefix_bash_prepend_unique_value_IFS + # export the updated variable + eval export $_listname=\"$_all_values\" + unset _all_values + unset _values + + unset _value + unset _listname +} + +# add this prefix to the COLCON_PREFIX_PATH +_colcon_prefix_bash_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX" +unset _colcon_prefix_bash_prepend_unique_value + +# check environment variable for custom Python executable +if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then + if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then + echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" + return 1 + fi + _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" +else + # try the Python executable known at configure time + _colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if [ ! -f "$_colcon_python_executable" ]; then + if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then + echo "error: unable to find python3 executable" + return 1 + fi + _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` + fi +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# get all commands in topological order +_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh bash)" +unset _colcon_python_executable +if [ -n "$COLCON_TRACE" ]; then + echo "$(declare -f _colcon_prefix_sh_source_script)" + echo "# Execute generated script:" + echo "# <<<" + echo "${_colcon_ordered_commands}" + echo "# >>>" + echo "unset _colcon_prefix_sh_source_script" +fi +eval "${_colcon_ordered_commands}" +unset _colcon_ordered_commands + +unset _colcon_prefix_sh_source_script + +unset _colcon_prefix_bash_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.ps1 b/inorbit_republisher/test/sample_data/install/local_setup.ps1 new file mode 100644 index 0000000..6f68c8d --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.ps1 @@ -0,0 +1,55 @@ +# generated from colcon_powershell/shell/template/prefix.ps1.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# check environment variable for custom Python executable +if ($env:COLCON_PYTHON_EXECUTABLE) { + if (!(Test-Path "$env:COLCON_PYTHON_EXECUTABLE" -PathType Leaf)) { + echo "error: COLCON_PYTHON_EXECUTABLE '$env:COLCON_PYTHON_EXECUTABLE' doesn't exist" + exit 1 + } + $_colcon_python_executable="$env:COLCON_PYTHON_EXECUTABLE" +} else { + # use the Python executable known at configure time + $_colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if (!(Test-Path "$_colcon_python_executable" -PathType Leaf)) { + if (!(Get-Command "python3" -ErrorAction SilentlyContinue)) { + echo "error: unable to find python3 executable" + exit 1 + } + $_colcon_python_executable="python3" + } +} + +# function to source another script with conditional trace output +# first argument: the path of the script +function _colcon_prefix_powershell_source_script { + param ( + $_colcon_prefix_powershell_source_script_param + ) + # source script with conditional trace output + if (Test-Path $_colcon_prefix_powershell_source_script_param) { + if ($env:COLCON_TRACE) { + echo ". '$_colcon_prefix_powershell_source_script_param'" + } + . "$_colcon_prefix_powershell_source_script_param" + } else { + Write-Error "not found: '$_colcon_prefix_powershell_source_script_param'" + } +} + +# get all commands in topological order +$_colcon_ordered_commands = & "$_colcon_python_executable" "$(Split-Path $PSCommandPath -Parent)/_local_setup_util_ps1.py" ps1 + +# execute all commands in topological order +if ($env:COLCON_TRACE) { + echo "Execute generated script:" + echo "<<<" + $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Write-Output + echo ">>>" +} +if ($_colcon_ordered_commands) { + $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Invoke-Expression +} diff --git a/inorbit_republisher/test/sample_data/install/local_setup.sh b/inorbit_republisher/test/sample_data/install/local_setup.sh new file mode 100644 index 0000000..d40d34d --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.sh @@ -0,0 +1,137 @@ +# generated from colcon_core/shell/template/prefix.sh.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# since a plain shell script can't determine its own path when being sourced +# either use the provided COLCON_CURRENT_PREFIX +# or fall back to the build time prefix (if it exists) +_colcon_prefix_sh_COLCON_CURRENT_PREFIX="/root/ros2_ws/src/inorbit_republisher/test/sample_data/install" +if [ -z "$COLCON_CURRENT_PREFIX" ]; then + if [ ! -d "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" ]; then + echo "The build time path \"$_colcon_prefix_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 + unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX + return 1 + fi +else + _colcon_prefix_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +fi + +# function to prepend a value to a variable +# which uses colons as separators +# duplicates as well as trailing separators are avoided +# first argument: the name of the result variable +# second argument: the value to be prepended +_colcon_prefix_sh_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + + # get values from variable + eval _values=\"\$$_listname\" + # backup the field separator + _colcon_prefix_sh_prepend_unique_value_IFS="$IFS" + IFS=":" + # start with the new value + _all_values="$_value" + _contained_value="" + # iterate over existing values in the variable + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + # ignore duplicates of _value + if [ "$_item" = "$_value" ]; then + _contained_value=1 + continue + fi + # keep non-duplicate values + _all_values="$_all_values:$_item" + done + unset _item + if [ -z "$_contained_value" ]; then + if [ -n "$COLCON_TRACE" ]; then + if [ "$_all_values" = "$_value" ]; then + echo "export $_listname=$_value" + else + echo "export $_listname=$_value:\$$_listname" + fi + fi + fi + unset _contained_value + # restore the field separator + IFS="$_colcon_prefix_sh_prepend_unique_value_IFS" + unset _colcon_prefix_sh_prepend_unique_value_IFS + # export the updated variable + eval export $_listname=\"$_all_values\" + unset _all_values + unset _values + + unset _value + unset _listname +} + +# add this prefix to the COLCON_PREFIX_PATH +_colcon_prefix_sh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" +unset _colcon_prefix_sh_prepend_unique_value + +# check environment variable for custom Python executable +if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then + if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then + echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" + return 1 + fi + _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" +else + # try the Python executable known at configure time + _colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if [ ! -f "$_colcon_python_executable" ]; then + if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then + echo "error: unable to find python3 executable" + return 1 + fi + _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` + fi +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# get all commands in topological order +_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh)" +unset _colcon_python_executable +if [ -n "$COLCON_TRACE" ]; then + echo "_colcon_prefix_sh_source_script() { + if [ -f \"\$1\" ]; then + if [ -n \"\$COLCON_TRACE\" ]; then + echo \"# . \\\"\$1\\\"\" + fi + . \"\$1\" + else + echo \"not found: \\\"\$1\\\"\" 1>&2 + fi + }" + echo "# Execute generated script:" + echo "# <<<" + echo "${_colcon_ordered_commands}" + echo "# >>>" + echo "unset _colcon_prefix_sh_source_script" +fi +eval "${_colcon_ordered_commands}" +unset _colcon_ordered_commands + +unset _colcon_prefix_sh_source_script + +unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.zsh b/inorbit_republisher/test/sample_data/install/local_setup.zsh new file mode 100644 index 0000000..b648710 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/local_setup.zsh @@ -0,0 +1,134 @@ +# generated from colcon_zsh/shell/template/prefix.zsh.em + +# This script extends the environment with all packages contained in this +# prefix path. + +# a zsh script is able to determine its own path if necessary +if [ -z "$COLCON_CURRENT_PREFIX" ]; then + _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" +else + _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +fi + +# function to convert array-like strings into arrays +# to workaround SH_WORD_SPLIT not being set +_colcon_prefix_zsh_convert_to_array() { + local _listname=$1 + local _dollar="$" + local _split="{=" + local _to_array="(\"$_dollar$_split$_listname}\")" + eval $_listname=$_to_array +} + +# function to prepend a value to a variable +# which uses colons as separators +# duplicates as well as trailing separators are avoided +# first argument: the name of the result variable +# second argument: the value to be prepended +_colcon_prefix_zsh_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + + # get values from variable + eval _values=\"\$$_listname\" + # backup the field separator + _colcon_prefix_zsh_prepend_unique_value_IFS="$IFS" + IFS=":" + # start with the new value + _all_values="$_value" + _contained_value="" + # workaround SH_WORD_SPLIT not being set + _colcon_prefix_zsh_convert_to_array _values + # iterate over existing values in the variable + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + # ignore duplicates of _value + if [ "$_item" = "$_value" ]; then + _contained_value=1 + continue + fi + # keep non-duplicate values + _all_values="$_all_values:$_item" + done + unset _item + if [ -z "$_contained_value" ]; then + if [ -n "$COLCON_TRACE" ]; then + if [ "$_all_values" = "$_value" ]; then + echo "export $_listname=$_value" + else + echo "export $_listname=$_value:\$$_listname" + fi + fi + fi + unset _contained_value + # restore the field separator + IFS="$_colcon_prefix_zsh_prepend_unique_value_IFS" + unset _colcon_prefix_zsh_prepend_unique_value_IFS + # export the updated variable + eval export $_listname=\"$_all_values\" + unset _all_values + unset _values + + unset _value + unset _listname +} + +# add this prefix to the COLCON_PREFIX_PATH +_colcon_prefix_zsh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX" +unset _colcon_prefix_zsh_prepend_unique_value +unset _colcon_prefix_zsh_convert_to_array + +# check environment variable for custom Python executable +if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then + if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then + echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" + return 1 + fi + _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" +else + # try the Python executable known at configure time + _colcon_python_executable="/usr/bin/python3" + # if it doesn't exist try a fall back + if [ ! -f "$_colcon_python_executable" ]; then + if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then + echo "error: unable to find python3 executable" + return 1 + fi + _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` + fi +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# get all commands in topological order +_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh zsh)" +unset _colcon_python_executable +if [ -n "$COLCON_TRACE" ]; then + echo "$(declare -f _colcon_prefix_sh_source_script)" + echo "# Execute generated script:" + echo "# <<<" + echo "${_colcon_ordered_commands}" + echo "# >>>" + echo "unset _colcon_prefix_sh_source_script" +fi +eval "${_colcon_ordered_commands}" +unset _colcon_ordered_commands + +unset _colcon_prefix_sh_source_script + +unset _colcon_prefix_zsh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.bash b/inorbit_republisher/test/sample_data/install/setup.bash new file mode 100644 index 0000000..a648296 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.bash @@ -0,0 +1,37 @@ +# generated from colcon_bash/shell/template/prefix_chain.bash.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_chain_bash_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# source chained prefixes +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/opt/ros/humble" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/install" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" + +# source this prefix +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" +_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" + +unset COLCON_CURRENT_PREFIX +unset _colcon_prefix_chain_bash_source_script diff --git a/inorbit_republisher/test/sample_data/install/setup.ps1 b/inorbit_republisher/test/sample_data/install/setup.ps1 new file mode 100644 index 0000000..8c90c86 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.ps1 @@ -0,0 +1,31 @@ +# generated from colcon_powershell/shell/template/prefix_chain.ps1.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# function to source another script with conditional trace output +# first argument: the path of the script +function _colcon_prefix_chain_powershell_source_script { + param ( + $_colcon_prefix_chain_powershell_source_script_param + ) + # source script with conditional trace output + if (Test-Path $_colcon_prefix_chain_powershell_source_script_param) { + if ($env:COLCON_TRACE) { + echo ". '$_colcon_prefix_chain_powershell_source_script_param'" + } + . "$_colcon_prefix_chain_powershell_source_script_param" + } else { + Write-Error "not found: '$_colcon_prefix_chain_powershell_source_script_param'" + } +} + +# source chained prefixes +_colcon_prefix_chain_powershell_source_script "/opt/ros/humble\local_setup.ps1" +_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/install\local_setup.ps1" +_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/src/install\local_setup.ps1" + +# source this prefix +$env:COLCON_CURRENT_PREFIX=(Split-Path $PSCommandPath -Parent) +_colcon_prefix_chain_powershell_source_script "$env:COLCON_CURRENT_PREFIX\local_setup.ps1" diff --git a/inorbit_republisher/test/sample_data/install/setup.sh b/inorbit_republisher/test/sample_data/install/setup.sh new file mode 100644 index 0000000..e4196d7 --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.sh @@ -0,0 +1,53 @@ +# generated from colcon_core/shell/template/prefix_chain.sh.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# since a plain shell script can't determine its own path when being sourced +# either use the provided COLCON_CURRENT_PREFIX +# or fall back to the build time prefix (if it exists) +_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX=/root/ros2_ws/src/inorbit_republisher/test/sample_data/install +if [ ! -z "$COLCON_CURRENT_PREFIX" ]; then + _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" +elif [ ! -d "$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" ]; then + echo "The build time path \"$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 + unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX + return 1 +fi + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_chain_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# source chained prefixes +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="/opt/ros/humble" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/install" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + + +# source this prefix +# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script +COLCON_CURRENT_PREFIX="$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" +_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" + +unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX +unset _colcon_prefix_chain_sh_source_script +unset COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.zsh b/inorbit_republisher/test/sample_data/install/setup.zsh new file mode 100644 index 0000000..c478d8a --- /dev/null +++ b/inorbit_republisher/test/sample_data/install/setup.zsh @@ -0,0 +1,37 @@ +# generated from colcon_zsh/shell/template/prefix_chain.zsh.em + +# This script extends the environment with the environment of other prefix +# paths which were sourced when this file was generated as well as all packages +# contained in this prefix path. + +# function to source another script with conditional trace output +# first argument: the path of the script +_colcon_prefix_chain_zsh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$1" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# source chained prefixes +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/opt/ros/humble" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/install" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" + +# source this prefix +# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script +COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" +_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" + +unset COLCON_CURRENT_PREFIX +unset _colcon_prefix_chain_zsh_source_script diff --git a/inorbit_republisher/test/sample_data/log/COLCON_IGNORE b/inorbit_republisher/test/sample_data/log/COLCON_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log new file mode 100644 index 0000000..08ed030 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log @@ -0,0 +1,2 @@ +[0.000000] (-) TimerEvent: {} +[0.000379] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log new file mode 100644 index 0000000..fe428ee --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log @@ -0,0 +1,77 @@ +[0.165s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build', '--packages-select', 'inorbit_republisher', '--symlink-install'] +[0.165s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=True, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=['inorbit_republisher'], packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) +[0.361s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters +[0.362s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' +[0.363s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover +[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover +[0.363s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] +[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] +[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' +[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored +[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] +[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' +[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover +[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults +[0.380s] WARNING:colcon.colcon_core.package_selection:ignoring unknown package 'inorbit_republisher' in --packages-select +[0.410s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor +[0.411s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete +[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop +[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed +[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' +[0.412s] DEBUG:colcon.colcon_core.event_reactor:joining thread +[0.418s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' +[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems +[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems +[0.419s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' +[0.419s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 +[0.419s] DEBUG:colcon.colcon_core.event_reactor:joined thread +[0.422s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems +[0.422s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' +[0.423s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' +[0.425s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' +[0.428s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' +[0.428s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' +[0.429s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' +[0.430s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' +[0.431s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' +[0.432s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' +[0.433s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log new file mode 100644 index 0000000..ffcb674 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log @@ -0,0 +1,2 @@ +[0.000000] (-) TimerEvent: {} +[0.000588] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log new file mode 100644 index 0000000..dad4847 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log @@ -0,0 +1,76 @@ +[0.181s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build'] +[0.181s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=False, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=None, packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) +[0.389s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters +[0.390s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' +[0.391s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover +[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover +[0.392s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' +[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] +[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' +[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] +[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' +[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] +[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' +[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover +[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults +[0.438s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed +[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' +[0.441s] DEBUG:colcon.colcon_core.event_reactor:joining thread +[0.447s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' +[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems +[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems +[0.448s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' +[0.448s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 +[0.448s] DEBUG:colcon.colcon_core.event_reactor:joined thread +[0.451s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems +[0.451s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' +[0.453s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' +[0.455s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' +[0.457s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' +[0.458s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' +[0.458s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' +[0.460s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' +[0.460s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' +[0.462s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' +[0.462s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/latest b/inorbit_republisher/test/sample_data/log/latest new file mode 120000 index 0000000..b57d247 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/latest @@ -0,0 +1 @@ +latest_build \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/log/latest_build b/inorbit_republisher/test/sample_data/log/latest_build new file mode 120000 index 0000000..4ba36b2 --- /dev/null +++ b/inorbit_republisher/test/sample_data/log/latest_build @@ -0,0 +1 @@ +build_2024-12-13_20-49-52 \ No newline at end of file From dcbada97ced38c463dfd88650282c251a631861c Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 11:01:57 -0300 Subject: [PATCH 15/21] Revert "Deleted irrelevant files" This reverts commit 8a2aca2b303799de5caeb7570d60e1525dfd2258. --- inorbit_republisher/config/example.yaml | 78 +++++++++++++++++++++++++ inorbit_republisher/test/README.md | 50 ---------------- 2 files changed, 78 insertions(+), 50 deletions(-) create mode 100644 inorbit_republisher/config/example.yaml diff --git a/inorbit_republisher/config/example.yaml b/inorbit_republisher/config/example.yaml new file mode 100644 index 0000000..d198a52 --- /dev/null +++ b/inorbit_republisher/config/example.yaml @@ -0,0 +1,78 @@ +republishers: +- topic: "/rosout" + msg_type: "rcl_interfaces/msg/Log" + mappings: + - field: "msg" + mapping_type: "single_field" + mapping_options: + filter: 'lambda x: x != "Go"' + out: + topic: "/inorbit/custom_data" + key: "rosout_msg" + +- topic: "/diagnostics" + qos: 10 + msg_type: "diagnostic_msgs/msg/DiagnosticArray" + mappings: + - field: "status" + mapping_type: "array_of_fields" + mapping_options: + fields: ["level", "hardware_id"] + filter: 'lambda x: (x.level == bytes(1) or x.level == bytes(0))' + out: + topic: "/inorbit/diagnostics_test" + key: "diagnostics_status" + +- topic: "/cmd_vel" + qos: 10 + msg_type: "geometry_msgs/msg/Twist" + mappings: + - field: "linear" + mapping_type: "json_of_fields" + mapping_options: + fields: ["x", "y", "z"] + filter: 'lambda vel: (vel["x"] > 0)' + out: + topic: "/inorbit/linear_vel_test" + key: "linear_vel" + +- topic: "/map_metadata" + latched: true + msg_type: "nav_msgs/msg/MapMetaData" + mappings: + - field: "resolution" + mapping_type: "single_field" + out: + topic: "/inorbit/map_res_test" + key: "map_resolution" + +- topic: "/navsat" + msg_type: "sensor_msgs/NavSatFix" + mappings: + - mapping_type: "serialize" + mapping_options: + fields: ["status", "latitude", "longitude", "position_covariance_type"] + out: + topic: "/inorbit/custom_data" + key: "navsat" + +static_publishers: +# - value_from: +# package_version: "rospy" +# out: +# topic: "/inorbit/custom_data/0" +# key: "rospy_version" +# - value_from: +# package_version: "inorbit_republisher" +# out: +# topic: "/inorbit/custom_data/0" +# key: "inorbit_republisher_version" +- value_from: + environment_variable: "PYTHONPATH" + out: + topic: "/inorbit/custom_data/static" + key: "python_path" +- value: "let's republish in orbit" + out: + topic: "/inorbit/custom_data/static" + key: "greeting" \ No newline at end of file diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index 9da5619..e69de29 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -1,50 +0,0 @@ -# Sample data for testing - -A very simple ``rosbag`` with hardcoded data for smoke testing the transformer node. - -```bash -$root@7c94d2cf9659:~# ros2 bag info ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 - -closing. -[INFO] [1734553121.938063653] [rosbag2_storage]: Opened database 'ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3' for READ_ONLY. - -Files: ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 -Bag size: 24.0 KiB -Storage id: sqlite3 -Duration: 16.005861016s -Start: Dec 13 2024 19:45:00.085674077 (1734119100.085674077) -End: Dec 13 2024 19:45:16.091535093 (1734119116.091535093) -Messages: 34 -Topic information: Topic: /my_magnetic_field | Type: sensor_msgs/msg/MagneticField | Count: 17 | Serialization Format: cdr - Topic: /my_temperature | Type: sensor_msgs/msg/Temperature | Count: 17 | Serialization Format: cdr - -``` - -To validate the node works launch the sample by using the ``sample_data.launch.xml`` launch file and look at ``out`` topic: ``ros2 topic echo my_temperature``. - -```bash -cd ros2_ws/src -colcon build --packages-select inorbit_republisher --symlink-install -source install/setup.bash -cd -ros2 launch inorbit_republisher sample_data.launch.xml -# On a different terminal windows -source /opt/ros/humble/setup.bash -$ ros2 topic echo my_temperature -header: - stamp: - sec: 0 - nanosec: 0 - frame_id: '' -temperature: 29.068787468933582 -variance: 0.0 ---- -header: - stamp: - sec: 0 - nanosec: 0 - frame_id: '' -temperature: 22.9644622619558 -variance: 0.0 ---- -``` \ No newline at end of file From 3b91470171d690e12daa384d16e326088dce55ac Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 11:07:42 -0300 Subject: [PATCH 16/21] Added missing files --- inorbit_republisher/package.xml | 13 + inorbit_republisher/setup.cfg | 4 + inorbit_republisher/setup.py | 30 ++ .../test/sample_data/build/.built_by | 1 - .../test/sample_data/build/COLCON_IGNORE | 0 .../install/.colcon_install_layout | 1 - .../test/sample_data/install/COLCON_IGNORE | 0 .../install/_local_setup_util_ps1.py | 407 ------------------ .../install/_local_setup_util_sh.py | 407 ------------------ .../test/sample_data/install/local_setup.bash | 121 ------ .../test/sample_data/install/local_setup.ps1 | 55 --- .../test/sample_data/install/local_setup.sh | 137 ------ .../test/sample_data/install/local_setup.zsh | 134 ------ .../test/sample_data/install/setup.bash | 37 -- .../test/sample_data/install/setup.ps1 | 31 -- .../test/sample_data/install/setup.sh | 53 --- .../test/sample_data/install/setup.zsh | 37 -- .../test/sample_data/log/COLCON_IGNORE | 0 .../log/build_2024-12-13_20-02-50/events.log | 2 - .../build_2024-12-13_20-02-50/logger_all.log | 77 ---- .../log/build_2024-12-13_20-49-52/events.log | 2 - .../build_2024-12-13_20-49-52/logger_all.log | 76 ---- .../test/sample_data/log/latest | 1 - .../test/sample_data/log/latest_build | 1 - 24 files changed, 47 insertions(+), 1580 deletions(-) create mode 100644 inorbit_republisher/package.xml create mode 100644 inorbit_republisher/setup.cfg create mode 100644 inorbit_republisher/setup.py delete mode 100644 inorbit_republisher/test/sample_data/build/.built_by delete mode 100644 inorbit_republisher/test/sample_data/build/COLCON_IGNORE delete mode 100644 inorbit_republisher/test/sample_data/install/.colcon_install_layout delete mode 100644 inorbit_republisher/test/sample_data/install/COLCON_IGNORE delete mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py delete mode 100644 inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.bash delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.ps1 delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.sh delete mode 100644 inorbit_republisher/test/sample_data/install/local_setup.zsh delete mode 100644 inorbit_republisher/test/sample_data/install/setup.bash delete mode 100644 inorbit_republisher/test/sample_data/install/setup.ps1 delete mode 100644 inorbit_republisher/test/sample_data/install/setup.sh delete mode 100644 inorbit_republisher/test/sample_data/install/setup.zsh delete mode 100644 inorbit_republisher/test/sample_data/log/COLCON_IGNORE delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log delete mode 100644 inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log delete mode 120000 inorbit_republisher/test/sample_data/log/latest delete mode 120000 inorbit_republisher/test/sample_data/log/latest_build diff --git a/inorbit_republisher/package.xml b/inorbit_republisher/package.xml new file mode 100644 index 0000000..9037ff1 --- /dev/null +++ b/inorbit_republisher/package.xml @@ -0,0 +1,13 @@ + + + + inorbit_republisher + 0.4.1 + ROS2 to InOrbit topic republisher + InOrbit + MIT + ros2launch + + ament_python + + \ No newline at end of file diff --git a/inorbit_republisher/setup.cfg b/inorbit_republisher/setup.cfg new file mode 100644 index 0000000..d56f2c7 --- /dev/null +++ b/inorbit_republisher/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/inorbit_republisher +[install] +install-scripts=$base/lib/inorbit_republisher \ No newline at end of file diff --git a/inorbit_republisher/setup.py b/inorbit_republisher/setup.py new file mode 100644 index 0000000..9ac166f --- /dev/null +++ b/inorbit_republisher/setup.py @@ -0,0 +1,30 @@ +from setuptools import setup +import os +from glob import glob + +package_name = 'inorbit_republisher' + +setup( + name=package_name, + version='0.4.1', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + (os.path.join('share', package_name), glob('launch/*')), + (os.path.join('share', package_name, 'config'), glob('config/*')) + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='InOrbit', + maintainer_email='support@inorbit.ai', + description='ROS2 to InOrbit topic republisher', + license='MIT', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'republisher = inorbit_republisher.republisher:main' + ], + }, +) \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/build/.built_by b/inorbit_republisher/test/sample_data/build/.built_by deleted file mode 100644 index 06e74ac..0000000 --- a/inorbit_republisher/test/sample_data/build/.built_by +++ /dev/null @@ -1 +0,0 @@ -colcon diff --git a/inorbit_republisher/test/sample_data/build/COLCON_IGNORE b/inorbit_republisher/test/sample_data/build/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/inorbit_republisher/test/sample_data/install/.colcon_install_layout b/inorbit_republisher/test/sample_data/install/.colcon_install_layout deleted file mode 100644 index 3aad533..0000000 --- a/inorbit_republisher/test/sample_data/install/.colcon_install_layout +++ /dev/null @@ -1 +0,0 @@ -isolated diff --git a/inorbit_republisher/test/sample_data/install/COLCON_IGNORE b/inorbit_republisher/test/sample_data/install/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py deleted file mode 100644 index 3c6d9e8..0000000 --- a/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py +++ /dev/null @@ -1,407 +0,0 @@ -# Copyright 2016-2019 Dirk Thomas -# Licensed under the Apache License, Version 2.0 - -import argparse -from collections import OrderedDict -import os -from pathlib import Path -import sys - - -FORMAT_STR_COMMENT_LINE = '# {comment}' -FORMAT_STR_SET_ENV_VAR = 'Set-Item -Path "Env:{name}" -Value "{value}"' -FORMAT_STR_USE_ENV_VAR = '$env:{name}' -FORMAT_STR_INVOKE_SCRIPT = '_colcon_prefix_powershell_source_script "{script_path}"' # noqa: E501 -FORMAT_STR_REMOVE_LEADING_SEPARATOR = '' # noqa: E501 -FORMAT_STR_REMOVE_TRAILING_SEPARATOR = '' # noqa: E501 - -DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' -DSV_TYPE_SET = 'set' -DSV_TYPE_SET_IF_UNSET = 'set-if-unset' -DSV_TYPE_SOURCE = 'source' - - -def main(argv=sys.argv[1:]): # noqa: D103 - parser = argparse.ArgumentParser( - description='Output shell commands for the packages in topological ' - 'order') - parser.add_argument( - 'primary_extension', - help='The file extension of the primary shell') - parser.add_argument( - 'additional_extension', nargs='?', - help='The additional file extension to be considered') - parser.add_argument( - '--merged-install', action='store_true', - help='All install prefixes are merged into a single location') - args = parser.parse_args(argv) - - packages = get_packages(Path(__file__).parent, args.merged_install) - - ordered_packages = order_packages(packages) - for pkg_name in ordered_packages: - if _include_comments(): - print( - FORMAT_STR_COMMENT_LINE.format_map( - {'comment': 'Package: ' + pkg_name})) - prefix = os.path.abspath(os.path.dirname(__file__)) - if not args.merged_install: - prefix = os.path.join(prefix, pkg_name) - for line in get_commands( - pkg_name, prefix, args.primary_extension, - args.additional_extension - ): - print(line) - - for line in _remove_ending_separators(): - print(line) - - -def get_packages(prefix_path, merged_install): - """ - Find packages based on colcon-specific files created during installation. - - :param Path prefix_path: The install prefix path of all packages - :param bool merged_install: The flag if the packages are all installed - directly in the prefix or if each package is installed in a subdirectory - named after the package - :returns: A mapping from the package name to the set of runtime - dependencies - :rtype: dict - """ - packages = {} - # since importing colcon_core isn't feasible here the following constant - # must match colcon_core.location.get_relative_package_index_path() - subdirectory = 'share/colcon-core/packages' - if merged_install: - # return if workspace is empty - if not (prefix_path / subdirectory).is_dir(): - return packages - # find all files in the subdirectory - for p in (prefix_path / subdirectory).iterdir(): - if not p.is_file(): - continue - if p.name.startswith('.'): - continue - add_package_runtime_dependencies(p, packages) - else: - # for each subdirectory look for the package specific file - for p in prefix_path.iterdir(): - if not p.is_dir(): - continue - if p.name.startswith('.'): - continue - p = p / subdirectory / p.name - if p.is_file(): - add_package_runtime_dependencies(p, packages) - - # remove unknown dependencies - pkg_names = set(packages.keys()) - for k in packages.keys(): - packages[k] = {d for d in packages[k] if d in pkg_names} - - return packages - - -def add_package_runtime_dependencies(path, packages): - """ - Check the path and if it exists extract the packages runtime dependencies. - - :param Path path: The resource file containing the runtime dependencies - :param dict packages: A mapping from package names to the sets of runtime - dependencies to add to - """ - content = path.read_text() - dependencies = set(content.split(os.pathsep) if content else []) - packages[path.name] = dependencies - - -def order_packages(packages): - """ - Order packages topologically. - - :param dict packages: A mapping from package name to the set of runtime - dependencies - :returns: The package names - :rtype: list - """ - # select packages with no dependencies in alphabetical order - to_be_ordered = list(packages.keys()) - ordered = [] - while to_be_ordered: - pkg_names_without_deps = [ - name for name in to_be_ordered if not packages[name]] - if not pkg_names_without_deps: - reduce_cycle_set(packages) - raise RuntimeError( - 'Circular dependency between: ' + ', '.join(sorted(packages))) - pkg_names_without_deps.sort() - pkg_name = pkg_names_without_deps[0] - to_be_ordered.remove(pkg_name) - ordered.append(pkg_name) - # remove item from dependency lists - for k in list(packages.keys()): - if pkg_name in packages[k]: - packages[k].remove(pkg_name) - return ordered - - -def reduce_cycle_set(packages): - """ - Reduce the set of packages to the ones part of the circular dependency. - - :param dict packages: A mapping from package name to the set of runtime - dependencies which is modified in place - """ - last_depended = None - while len(packages) > 0: - # get all remaining dependencies - depended = set() - for pkg_name, dependencies in packages.items(): - depended = depended.union(dependencies) - # remove all packages which are not dependent on - for name in list(packages.keys()): - if name not in depended: - del packages[name] - if last_depended: - # if remaining packages haven't changed return them - if last_depended == depended: - return packages.keys() - # otherwise reduce again - last_depended = depended - - -def _include_comments(): - # skipping comment lines when COLCON_TRACE is not set speeds up the - # processing especially on Windows - return bool(os.environ.get('COLCON_TRACE')) - - -def get_commands(pkg_name, prefix, primary_extension, additional_extension): - commands = [] - package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') - if os.path.exists(package_dsv_path): - commands += process_dsv_file( - package_dsv_path, prefix, primary_extension, additional_extension) - return commands - - -def process_dsv_file( - dsv_path, prefix, primary_extension=None, additional_extension=None -): - commands = [] - if _include_comments(): - commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) - with open(dsv_path, 'r') as h: - content = h.read() - lines = content.splitlines() - - basenames = OrderedDict() - for i, line in enumerate(lines): - # skip over empty or whitespace-only lines - if not line.strip(): - continue - # skip over comments - if line.startswith('#'): - continue - try: - type_, remainder = line.split(';', 1) - except ValueError: - raise RuntimeError( - "Line %d in '%s' doesn't contain a semicolon separating the " - 'type from the arguments' % (i + 1, dsv_path)) - if type_ != DSV_TYPE_SOURCE: - # handle non-source lines - try: - commands += handle_dsv_types_except_source( - type_, remainder, prefix) - except RuntimeError as e: - raise RuntimeError( - "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e - else: - # group remaining source lines by basename - path_without_ext, ext = os.path.splitext(remainder) - if path_without_ext not in basenames: - basenames[path_without_ext] = set() - assert ext.startswith('.') - ext = ext[1:] - if ext in (primary_extension, additional_extension): - basenames[path_without_ext].add(ext) - - # add the dsv extension to each basename if the file exists - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if os.path.exists(basename + '.dsv'): - extensions.add('dsv') - - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if 'dsv' in extensions: - # process dsv files recursively - commands += process_dsv_file( - basename + '.dsv', prefix, primary_extension=primary_extension, - additional_extension=additional_extension) - elif primary_extension in extensions and len(extensions) == 1: - # source primary-only files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + primary_extension})] - elif additional_extension in extensions: - # source non-primary files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + additional_extension})] - - return commands - - -def handle_dsv_types_except_source(type_, remainder, prefix): - commands = [] - if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): - try: - env_name, value = remainder.split(';', 1) - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the value') - try_prefixed_value = os.path.join(prefix, value) if value else prefix - if os.path.exists(try_prefixed_value): - value = try_prefixed_value - if type_ == DSV_TYPE_SET: - commands += _set(env_name, value) - elif type_ == DSV_TYPE_SET_IF_UNSET: - commands += _set_if_unset(env_name, value) - else: - assert False - elif type_ in ( - DSV_TYPE_APPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS - ): - try: - env_name_and_values = remainder.split(';') - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the values') - env_name = env_name_and_values[0] - values = env_name_and_values[1:] - for value in values: - if not value: - value = prefix - elif not os.path.isabs(value): - value = os.path.join(prefix, value) - if ( - type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and - not os.path.exists(value) - ): - comment = f'skip extending {env_name} with not existing ' \ - f'path: {value}' - if _include_comments(): - commands.append( - FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) - elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: - commands += _append_unique_value(env_name, value) - else: - commands += _prepend_unique_value(env_name, value) - else: - raise RuntimeError( - 'contains an unknown environment hook type: ' + type_) - return commands - - -env_state = {} - - -def _append_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # append even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional leading separator - extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': extend + value}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -def _prepend_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # prepend even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional trailing separator - extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value + extend}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -# generate commands for removing prepended underscores -def _remove_ending_separators(): - # do nothing if the shell extension does not implement the logic - if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: - return [] - - global env_state - commands = [] - for name in env_state: - # skip variables that already had values before this script started prepending - if name in os.environ: - continue - commands += [ - FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), - FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] - return commands - - -def _set(name, value): - global env_state - env_state[name] = value - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - return [line] - - -def _set_if_unset(name, value): - global env_state - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - if env_state.get(name, os.environ.get(name)): - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -if __name__ == '__main__': # pragma: no cover - try: - rc = main() - except RuntimeError as e: - print(str(e), file=sys.stderr) - rc = 1 - sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py b/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py deleted file mode 100644 index f67eaa9..0000000 --- a/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py +++ /dev/null @@ -1,407 +0,0 @@ -# Copyright 2016-2019 Dirk Thomas -# Licensed under the Apache License, Version 2.0 - -import argparse -from collections import OrderedDict -import os -from pathlib import Path -import sys - - -FORMAT_STR_COMMENT_LINE = '# {comment}' -FORMAT_STR_SET_ENV_VAR = 'export {name}="{value}"' -FORMAT_STR_USE_ENV_VAR = '${name}' -FORMAT_STR_INVOKE_SCRIPT = 'COLCON_CURRENT_PREFIX="{prefix}" _colcon_prefix_sh_source_script "{script_path}"' # noqa: E501 -FORMAT_STR_REMOVE_LEADING_SEPARATOR = 'if [ "$(echo -n ${name} | head -c 1)" = ":" ]; then export {name}=${{{name}#?}} ; fi' # noqa: E501 -FORMAT_STR_REMOVE_TRAILING_SEPARATOR = 'if [ "$(echo -n ${name} | tail -c 1)" = ":" ]; then export {name}=${{{name}%?}} ; fi' # noqa: E501 - -DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate' -DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists' -DSV_TYPE_SET = 'set' -DSV_TYPE_SET_IF_UNSET = 'set-if-unset' -DSV_TYPE_SOURCE = 'source' - - -def main(argv=sys.argv[1:]): # noqa: D103 - parser = argparse.ArgumentParser( - description='Output shell commands for the packages in topological ' - 'order') - parser.add_argument( - 'primary_extension', - help='The file extension of the primary shell') - parser.add_argument( - 'additional_extension', nargs='?', - help='The additional file extension to be considered') - parser.add_argument( - '--merged-install', action='store_true', - help='All install prefixes are merged into a single location') - args = parser.parse_args(argv) - - packages = get_packages(Path(__file__).parent, args.merged_install) - - ordered_packages = order_packages(packages) - for pkg_name in ordered_packages: - if _include_comments(): - print( - FORMAT_STR_COMMENT_LINE.format_map( - {'comment': 'Package: ' + pkg_name})) - prefix = os.path.abspath(os.path.dirname(__file__)) - if not args.merged_install: - prefix = os.path.join(prefix, pkg_name) - for line in get_commands( - pkg_name, prefix, args.primary_extension, - args.additional_extension - ): - print(line) - - for line in _remove_ending_separators(): - print(line) - - -def get_packages(prefix_path, merged_install): - """ - Find packages based on colcon-specific files created during installation. - - :param Path prefix_path: The install prefix path of all packages - :param bool merged_install: The flag if the packages are all installed - directly in the prefix or if each package is installed in a subdirectory - named after the package - :returns: A mapping from the package name to the set of runtime - dependencies - :rtype: dict - """ - packages = {} - # since importing colcon_core isn't feasible here the following constant - # must match colcon_core.location.get_relative_package_index_path() - subdirectory = 'share/colcon-core/packages' - if merged_install: - # return if workspace is empty - if not (prefix_path / subdirectory).is_dir(): - return packages - # find all files in the subdirectory - for p in (prefix_path / subdirectory).iterdir(): - if not p.is_file(): - continue - if p.name.startswith('.'): - continue - add_package_runtime_dependencies(p, packages) - else: - # for each subdirectory look for the package specific file - for p in prefix_path.iterdir(): - if not p.is_dir(): - continue - if p.name.startswith('.'): - continue - p = p / subdirectory / p.name - if p.is_file(): - add_package_runtime_dependencies(p, packages) - - # remove unknown dependencies - pkg_names = set(packages.keys()) - for k in packages.keys(): - packages[k] = {d for d in packages[k] if d in pkg_names} - - return packages - - -def add_package_runtime_dependencies(path, packages): - """ - Check the path and if it exists extract the packages runtime dependencies. - - :param Path path: The resource file containing the runtime dependencies - :param dict packages: A mapping from package names to the sets of runtime - dependencies to add to - """ - content = path.read_text() - dependencies = set(content.split(os.pathsep) if content else []) - packages[path.name] = dependencies - - -def order_packages(packages): - """ - Order packages topologically. - - :param dict packages: A mapping from package name to the set of runtime - dependencies - :returns: The package names - :rtype: list - """ - # select packages with no dependencies in alphabetical order - to_be_ordered = list(packages.keys()) - ordered = [] - while to_be_ordered: - pkg_names_without_deps = [ - name for name in to_be_ordered if not packages[name]] - if not pkg_names_without_deps: - reduce_cycle_set(packages) - raise RuntimeError( - 'Circular dependency between: ' + ', '.join(sorted(packages))) - pkg_names_without_deps.sort() - pkg_name = pkg_names_without_deps[0] - to_be_ordered.remove(pkg_name) - ordered.append(pkg_name) - # remove item from dependency lists - for k in list(packages.keys()): - if pkg_name in packages[k]: - packages[k].remove(pkg_name) - return ordered - - -def reduce_cycle_set(packages): - """ - Reduce the set of packages to the ones part of the circular dependency. - - :param dict packages: A mapping from package name to the set of runtime - dependencies which is modified in place - """ - last_depended = None - while len(packages) > 0: - # get all remaining dependencies - depended = set() - for pkg_name, dependencies in packages.items(): - depended = depended.union(dependencies) - # remove all packages which are not dependent on - for name in list(packages.keys()): - if name not in depended: - del packages[name] - if last_depended: - # if remaining packages haven't changed return them - if last_depended == depended: - return packages.keys() - # otherwise reduce again - last_depended = depended - - -def _include_comments(): - # skipping comment lines when COLCON_TRACE is not set speeds up the - # processing especially on Windows - return bool(os.environ.get('COLCON_TRACE')) - - -def get_commands(pkg_name, prefix, primary_extension, additional_extension): - commands = [] - package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv') - if os.path.exists(package_dsv_path): - commands += process_dsv_file( - package_dsv_path, prefix, primary_extension, additional_extension) - return commands - - -def process_dsv_file( - dsv_path, prefix, primary_extension=None, additional_extension=None -): - commands = [] - if _include_comments(): - commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path})) - with open(dsv_path, 'r') as h: - content = h.read() - lines = content.splitlines() - - basenames = OrderedDict() - for i, line in enumerate(lines): - # skip over empty or whitespace-only lines - if not line.strip(): - continue - # skip over comments - if line.startswith('#'): - continue - try: - type_, remainder = line.split(';', 1) - except ValueError: - raise RuntimeError( - "Line %d in '%s' doesn't contain a semicolon separating the " - 'type from the arguments' % (i + 1, dsv_path)) - if type_ != DSV_TYPE_SOURCE: - # handle non-source lines - try: - commands += handle_dsv_types_except_source( - type_, remainder, prefix) - except RuntimeError as e: - raise RuntimeError( - "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e - else: - # group remaining source lines by basename - path_without_ext, ext = os.path.splitext(remainder) - if path_without_ext not in basenames: - basenames[path_without_ext] = set() - assert ext.startswith('.') - ext = ext[1:] - if ext in (primary_extension, additional_extension): - basenames[path_without_ext].add(ext) - - # add the dsv extension to each basename if the file exists - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if os.path.exists(basename + '.dsv'): - extensions.add('dsv') - - for basename, extensions in basenames.items(): - if not os.path.isabs(basename): - basename = os.path.join(prefix, basename) - if 'dsv' in extensions: - # process dsv files recursively - commands += process_dsv_file( - basename + '.dsv', prefix, primary_extension=primary_extension, - additional_extension=additional_extension) - elif primary_extension in extensions and len(extensions) == 1: - # source primary-only files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + primary_extension})] - elif additional_extension in extensions: - # source non-primary files - commands += [ - FORMAT_STR_INVOKE_SCRIPT.format_map({ - 'prefix': prefix, - 'script_path': basename + '.' + additional_extension})] - - return commands - - -def handle_dsv_types_except_source(type_, remainder, prefix): - commands = [] - if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET): - try: - env_name, value = remainder.split(';', 1) - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the value') - try_prefixed_value = os.path.join(prefix, value) if value else prefix - if os.path.exists(try_prefixed_value): - value = try_prefixed_value - if type_ == DSV_TYPE_SET: - commands += _set(env_name, value) - elif type_ == DSV_TYPE_SET_IF_UNSET: - commands += _set_if_unset(env_name, value) - else: - assert False - elif type_ in ( - DSV_TYPE_APPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE, - DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS - ): - try: - env_name_and_values = remainder.split(';') - except ValueError: - raise RuntimeError( - "doesn't contain a semicolon separating the environment name " - 'from the values') - env_name = env_name_and_values[0] - values = env_name_and_values[1:] - for value in values: - if not value: - value = prefix - elif not os.path.isabs(value): - value = os.path.join(prefix, value) - if ( - type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and - not os.path.exists(value) - ): - comment = f'skip extending {env_name} with not existing ' \ - f'path: {value}' - if _include_comments(): - commands.append( - FORMAT_STR_COMMENT_LINE.format_map({'comment': comment})) - elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE: - commands += _append_unique_value(env_name, value) - else: - commands += _prepend_unique_value(env_name, value) - else: - raise RuntimeError( - 'contains an unknown environment hook type: ' + type_) - return commands - - -env_state = {} - - -def _append_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # append even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional leading separator - extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': extend + value}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -def _prepend_unique_value(name, value): - global env_state - if name not in env_state: - if os.environ.get(name): - env_state[name] = set(os.environ[name].split(os.pathsep)) - else: - env_state[name] = set() - # prepend even if the variable has not been set yet, in case a shell script sets the - # same variable without the knowledge of this Python script. - # later _remove_ending_separators() will cleanup any unintentional trailing separator - extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value + extend}) - if value not in env_state[name]: - env_state[name].add(value) - else: - if not _include_comments(): - return [] - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -# generate commands for removing prepended underscores -def _remove_ending_separators(): - # do nothing if the shell extension does not implement the logic - if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None: - return [] - - global env_state - commands = [] - for name in env_state: - # skip variables that already had values before this script started prepending - if name in os.environ: - continue - commands += [ - FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}), - FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})] - return commands - - -def _set(name, value): - global env_state - env_state[name] = value - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - return [line] - - -def _set_if_unset(name, value): - global env_state - line = FORMAT_STR_SET_ENV_VAR.format_map( - {'name': name, 'value': value}) - if env_state.get(name, os.environ.get(name)): - line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line}) - return [line] - - -if __name__ == '__main__': # pragma: no cover - try: - rc = main() - except RuntimeError as e: - print(str(e), file=sys.stderr) - rc = 1 - sys.exit(rc) diff --git a/inorbit_republisher/test/sample_data/install/local_setup.bash b/inorbit_republisher/test/sample_data/install/local_setup.bash deleted file mode 100644 index 03f0025..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.bash +++ /dev/null @@ -1,121 +0,0 @@ -# generated from colcon_bash/shell/template/prefix.bash.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# a bash script is able to determine its own path if necessary -if [ -z "$COLCON_CURRENT_PREFIX" ]; then - _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" -else - _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -fi - -# function to prepend a value to a variable -# which uses colons as separators -# duplicates as well as trailing separators are avoided -# first argument: the name of the result variable -# second argument: the value to be prepended -_colcon_prefix_bash_prepend_unique_value() { - # arguments - _listname="$1" - _value="$2" - - # get values from variable - eval _values=\"\$$_listname\" - # backup the field separator - _colcon_prefix_bash_prepend_unique_value_IFS="$IFS" - IFS=":" - # start with the new value - _all_values="$_value" - _contained_value="" - # iterate over existing values in the variable - for _item in $_values; do - # ignore empty strings - if [ -z "$_item" ]; then - continue - fi - # ignore duplicates of _value - if [ "$_item" = "$_value" ]; then - _contained_value=1 - continue - fi - # keep non-duplicate values - _all_values="$_all_values:$_item" - done - unset _item - if [ -z "$_contained_value" ]; then - if [ -n "$COLCON_TRACE" ]; then - if [ "$_all_values" = "$_value" ]; then - echo "export $_listname=$_value" - else - echo "export $_listname=$_value:\$$_listname" - fi - fi - fi - unset _contained_value - # restore the field separator - IFS="$_colcon_prefix_bash_prepend_unique_value_IFS" - unset _colcon_prefix_bash_prepend_unique_value_IFS - # export the updated variable - eval export $_listname=\"$_all_values\" - unset _all_values - unset _values - - unset _value - unset _listname -} - -# add this prefix to the COLCON_PREFIX_PATH -_colcon_prefix_bash_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX" -unset _colcon_prefix_bash_prepend_unique_value - -# check environment variable for custom Python executable -if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then - if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then - echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" - return 1 - fi - _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" -else - # try the Python executable known at configure time - _colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if [ ! -f "$_colcon_python_executable" ]; then - if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then - echo "error: unable to find python3 executable" - return 1 - fi - _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` - fi -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# get all commands in topological order -_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh bash)" -unset _colcon_python_executable -if [ -n "$COLCON_TRACE" ]; then - echo "$(declare -f _colcon_prefix_sh_source_script)" - echo "# Execute generated script:" - echo "# <<<" - echo "${_colcon_ordered_commands}" - echo "# >>>" - echo "unset _colcon_prefix_sh_source_script" -fi -eval "${_colcon_ordered_commands}" -unset _colcon_ordered_commands - -unset _colcon_prefix_sh_source_script - -unset _colcon_prefix_bash_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.ps1 b/inorbit_republisher/test/sample_data/install/local_setup.ps1 deleted file mode 100644 index 6f68c8d..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -# generated from colcon_powershell/shell/template/prefix.ps1.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# check environment variable for custom Python executable -if ($env:COLCON_PYTHON_EXECUTABLE) { - if (!(Test-Path "$env:COLCON_PYTHON_EXECUTABLE" -PathType Leaf)) { - echo "error: COLCON_PYTHON_EXECUTABLE '$env:COLCON_PYTHON_EXECUTABLE' doesn't exist" - exit 1 - } - $_colcon_python_executable="$env:COLCON_PYTHON_EXECUTABLE" -} else { - # use the Python executable known at configure time - $_colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if (!(Test-Path "$_colcon_python_executable" -PathType Leaf)) { - if (!(Get-Command "python3" -ErrorAction SilentlyContinue)) { - echo "error: unable to find python3 executable" - exit 1 - } - $_colcon_python_executable="python3" - } -} - -# function to source another script with conditional trace output -# first argument: the path of the script -function _colcon_prefix_powershell_source_script { - param ( - $_colcon_prefix_powershell_source_script_param - ) - # source script with conditional trace output - if (Test-Path $_colcon_prefix_powershell_source_script_param) { - if ($env:COLCON_TRACE) { - echo ". '$_colcon_prefix_powershell_source_script_param'" - } - . "$_colcon_prefix_powershell_source_script_param" - } else { - Write-Error "not found: '$_colcon_prefix_powershell_source_script_param'" - } -} - -# get all commands in topological order -$_colcon_ordered_commands = & "$_colcon_python_executable" "$(Split-Path $PSCommandPath -Parent)/_local_setup_util_ps1.py" ps1 - -# execute all commands in topological order -if ($env:COLCON_TRACE) { - echo "Execute generated script:" - echo "<<<" - $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Write-Output - echo ">>>" -} -if ($_colcon_ordered_commands) { - $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Invoke-Expression -} diff --git a/inorbit_republisher/test/sample_data/install/local_setup.sh b/inorbit_republisher/test/sample_data/install/local_setup.sh deleted file mode 100644 index d40d34d..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.sh +++ /dev/null @@ -1,137 +0,0 @@ -# generated from colcon_core/shell/template/prefix.sh.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# since a plain shell script can't determine its own path when being sourced -# either use the provided COLCON_CURRENT_PREFIX -# or fall back to the build time prefix (if it exists) -_colcon_prefix_sh_COLCON_CURRENT_PREFIX="/root/ros2_ws/src/inorbit_republisher/test/sample_data/install" -if [ -z "$COLCON_CURRENT_PREFIX" ]; then - if [ ! -d "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" ]; then - echo "The build time path \"$_colcon_prefix_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 - unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX - return 1 - fi -else - _colcon_prefix_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -fi - -# function to prepend a value to a variable -# which uses colons as separators -# duplicates as well as trailing separators are avoided -# first argument: the name of the result variable -# second argument: the value to be prepended -_colcon_prefix_sh_prepend_unique_value() { - # arguments - _listname="$1" - _value="$2" - - # get values from variable - eval _values=\"\$$_listname\" - # backup the field separator - _colcon_prefix_sh_prepend_unique_value_IFS="$IFS" - IFS=":" - # start with the new value - _all_values="$_value" - _contained_value="" - # iterate over existing values in the variable - for _item in $_values; do - # ignore empty strings - if [ -z "$_item" ]; then - continue - fi - # ignore duplicates of _value - if [ "$_item" = "$_value" ]; then - _contained_value=1 - continue - fi - # keep non-duplicate values - _all_values="$_all_values:$_item" - done - unset _item - if [ -z "$_contained_value" ]; then - if [ -n "$COLCON_TRACE" ]; then - if [ "$_all_values" = "$_value" ]; then - echo "export $_listname=$_value" - else - echo "export $_listname=$_value:\$$_listname" - fi - fi - fi - unset _contained_value - # restore the field separator - IFS="$_colcon_prefix_sh_prepend_unique_value_IFS" - unset _colcon_prefix_sh_prepend_unique_value_IFS - # export the updated variable - eval export $_listname=\"$_all_values\" - unset _all_values - unset _values - - unset _value - unset _listname -} - -# add this prefix to the COLCON_PREFIX_PATH -_colcon_prefix_sh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" -unset _colcon_prefix_sh_prepend_unique_value - -# check environment variable for custom Python executable -if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then - if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then - echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" - return 1 - fi - _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" -else - # try the Python executable known at configure time - _colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if [ ! -f "$_colcon_python_executable" ]; then - if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then - echo "error: unable to find python3 executable" - return 1 - fi - _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` - fi -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# get all commands in topological order -_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh)" -unset _colcon_python_executable -if [ -n "$COLCON_TRACE" ]; then - echo "_colcon_prefix_sh_source_script() { - if [ -f \"\$1\" ]; then - if [ -n \"\$COLCON_TRACE\" ]; then - echo \"# . \\\"\$1\\\"\" - fi - . \"\$1\" - else - echo \"not found: \\\"\$1\\\"\" 1>&2 - fi - }" - echo "# Execute generated script:" - echo "# <<<" - echo "${_colcon_ordered_commands}" - echo "# >>>" - echo "unset _colcon_prefix_sh_source_script" -fi -eval "${_colcon_ordered_commands}" -unset _colcon_ordered_commands - -unset _colcon_prefix_sh_source_script - -unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/local_setup.zsh b/inorbit_republisher/test/sample_data/install/local_setup.zsh deleted file mode 100644 index b648710..0000000 --- a/inorbit_republisher/test/sample_data/install/local_setup.zsh +++ /dev/null @@ -1,134 +0,0 @@ -# generated from colcon_zsh/shell/template/prefix.zsh.em - -# This script extends the environment with all packages contained in this -# prefix path. - -# a zsh script is able to determine its own path if necessary -if [ -z "$COLCON_CURRENT_PREFIX" ]; then - _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" -else - _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -fi - -# function to convert array-like strings into arrays -# to workaround SH_WORD_SPLIT not being set -_colcon_prefix_zsh_convert_to_array() { - local _listname=$1 - local _dollar="$" - local _split="{=" - local _to_array="(\"$_dollar$_split$_listname}\")" - eval $_listname=$_to_array -} - -# function to prepend a value to a variable -# which uses colons as separators -# duplicates as well as trailing separators are avoided -# first argument: the name of the result variable -# second argument: the value to be prepended -_colcon_prefix_zsh_prepend_unique_value() { - # arguments - _listname="$1" - _value="$2" - - # get values from variable - eval _values=\"\$$_listname\" - # backup the field separator - _colcon_prefix_zsh_prepend_unique_value_IFS="$IFS" - IFS=":" - # start with the new value - _all_values="$_value" - _contained_value="" - # workaround SH_WORD_SPLIT not being set - _colcon_prefix_zsh_convert_to_array _values - # iterate over existing values in the variable - for _item in $_values; do - # ignore empty strings - if [ -z "$_item" ]; then - continue - fi - # ignore duplicates of _value - if [ "$_item" = "$_value" ]; then - _contained_value=1 - continue - fi - # keep non-duplicate values - _all_values="$_all_values:$_item" - done - unset _item - if [ -z "$_contained_value" ]; then - if [ -n "$COLCON_TRACE" ]; then - if [ "$_all_values" = "$_value" ]; then - echo "export $_listname=$_value" - else - echo "export $_listname=$_value:\$$_listname" - fi - fi - fi - unset _contained_value - # restore the field separator - IFS="$_colcon_prefix_zsh_prepend_unique_value_IFS" - unset _colcon_prefix_zsh_prepend_unique_value_IFS - # export the updated variable - eval export $_listname=\"$_all_values\" - unset _all_values - unset _values - - unset _value - unset _listname -} - -# add this prefix to the COLCON_PREFIX_PATH -_colcon_prefix_zsh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX" -unset _colcon_prefix_zsh_prepend_unique_value -unset _colcon_prefix_zsh_convert_to_array - -# check environment variable for custom Python executable -if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then - if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then - echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" - return 1 - fi - _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" -else - # try the Python executable known at configure time - _colcon_python_executable="/usr/bin/python3" - # if it doesn't exist try a fall back - if [ ! -f "$_colcon_python_executable" ]; then - if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then - echo "error: unable to find python3 executable" - return 1 - fi - _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` - fi -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# get all commands in topological order -_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh zsh)" -unset _colcon_python_executable -if [ -n "$COLCON_TRACE" ]; then - echo "$(declare -f _colcon_prefix_sh_source_script)" - echo "# Execute generated script:" - echo "# <<<" - echo "${_colcon_ordered_commands}" - echo "# >>>" - echo "unset _colcon_prefix_sh_source_script" -fi -eval "${_colcon_ordered_commands}" -unset _colcon_ordered_commands - -unset _colcon_prefix_sh_source_script - -unset _colcon_prefix_zsh_COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.bash b/inorbit_republisher/test/sample_data/install/setup.bash deleted file mode 100644 index a648296..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.bash +++ /dev/null @@ -1,37 +0,0 @@ -# generated from colcon_bash/shell/template/prefix_chain.bash.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_chain_bash_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# source chained prefixes -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/opt/ros/humble" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/install" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" - -# source this prefix -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" -_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" - -unset COLCON_CURRENT_PREFIX -unset _colcon_prefix_chain_bash_source_script diff --git a/inorbit_republisher/test/sample_data/install/setup.ps1 b/inorbit_republisher/test/sample_data/install/setup.ps1 deleted file mode 100644 index 8c90c86..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -# generated from colcon_powershell/shell/template/prefix_chain.ps1.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# function to source another script with conditional trace output -# first argument: the path of the script -function _colcon_prefix_chain_powershell_source_script { - param ( - $_colcon_prefix_chain_powershell_source_script_param - ) - # source script with conditional trace output - if (Test-Path $_colcon_prefix_chain_powershell_source_script_param) { - if ($env:COLCON_TRACE) { - echo ". '$_colcon_prefix_chain_powershell_source_script_param'" - } - . "$_colcon_prefix_chain_powershell_source_script_param" - } else { - Write-Error "not found: '$_colcon_prefix_chain_powershell_source_script_param'" - } -} - -# source chained prefixes -_colcon_prefix_chain_powershell_source_script "/opt/ros/humble\local_setup.ps1" -_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/install\local_setup.ps1" -_colcon_prefix_chain_powershell_source_script "/root/ros2_ws/src/install\local_setup.ps1" - -# source this prefix -$env:COLCON_CURRENT_PREFIX=(Split-Path $PSCommandPath -Parent) -_colcon_prefix_chain_powershell_source_script "$env:COLCON_CURRENT_PREFIX\local_setup.ps1" diff --git a/inorbit_republisher/test/sample_data/install/setup.sh b/inorbit_republisher/test/sample_data/install/setup.sh deleted file mode 100644 index e4196d7..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.sh +++ /dev/null @@ -1,53 +0,0 @@ -# generated from colcon_core/shell/template/prefix_chain.sh.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# since a plain shell script can't determine its own path when being sourced -# either use the provided COLCON_CURRENT_PREFIX -# or fall back to the build time prefix (if it exists) -_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX=/root/ros2_ws/src/inorbit_republisher/test/sample_data/install -if [ ! -z "$COLCON_CURRENT_PREFIX" ]; then - _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" -elif [ ! -d "$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" ]; then - echo "The build time path \"$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 - unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX - return 1 -fi - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_chain_sh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# source chained prefixes -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="/opt/ros/humble" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/install" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - - -# source this prefix -# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script -COLCON_CURRENT_PREFIX="$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" -_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh" - -unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX -unset _colcon_prefix_chain_sh_source_script -unset COLCON_CURRENT_PREFIX diff --git a/inorbit_republisher/test/sample_data/install/setup.zsh b/inorbit_republisher/test/sample_data/install/setup.zsh deleted file mode 100644 index c478d8a..0000000 --- a/inorbit_republisher/test/sample_data/install/setup.zsh +++ /dev/null @@ -1,37 +0,0 @@ -# generated from colcon_zsh/shell/template/prefix_chain.zsh.em - -# This script extends the environment with the environment of other prefix -# paths which were sourced when this file was generated as well as all packages -# contained in this prefix path. - -# function to source another script with conditional trace output -# first argument: the path of the script -_colcon_prefix_chain_zsh_source_script() { - if [ -f "$1" ]; then - if [ -n "$COLCON_TRACE" ]; then - echo "# . \"$1\"" - fi - . "$1" - else - echo "not found: \"$1\"" 1>&2 - fi -} - -# source chained prefixes -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/opt/ros/humble" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/install" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="/root/ros2_ws/src/install" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" - -# source this prefix -# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script -COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)" -_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh" - -unset COLCON_CURRENT_PREFIX -unset _colcon_prefix_chain_zsh_source_script diff --git a/inorbit_republisher/test/sample_data/log/COLCON_IGNORE b/inorbit_republisher/test/sample_data/log/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log deleted file mode 100644 index 08ed030..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/events.log +++ /dev/null @@ -1,2 +0,0 @@ -[0.000000] (-) TimerEvent: {} -[0.000379] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log deleted file mode 100644 index fe428ee..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-02-50/logger_all.log +++ /dev/null @@ -1,77 +0,0 @@ -[0.165s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build', '--packages-select', 'inorbit_republisher', '--symlink-install'] -[0.165s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=True, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=['inorbit_republisher'], packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) -[0.361s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters -[0.362s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' -[0.363s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover -[0.363s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover -[0.363s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] -[0.363s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] -[0.378s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' -[0.379s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored -[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] -[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' -[0.380s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover -[0.380s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults -[0.380s] WARNING:colcon.colcon_core.package_selection:ignoring unknown package 'inorbit_republisher' in --packages-select -[0.410s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor -[0.411s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete -[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop -[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed -[0.412s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' -[0.412s] DEBUG:colcon.colcon_core.event_reactor:joining thread -[0.418s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' -[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems -[0.419s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems -[0.419s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' -[0.419s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 -[0.419s] DEBUG:colcon.colcon_core.event_reactor:joined thread -[0.422s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems -[0.422s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' -[0.423s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' -[0.425s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' -[0.428s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' -[0.428s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' -[0.429s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' -[0.430s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' -[0.431s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' -[0.432s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' -[0.433s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log deleted file mode 100644 index ffcb674..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/events.log +++ /dev/null @@ -1,2 +0,0 @@ -[0.000000] (-) TimerEvent: {} -[0.000588] (-) EventReactorShutdown: {} diff --git a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log b/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log deleted file mode 100644 index dad4847..0000000 --- a/inorbit_republisher/test/sample_data/log/build_2024-12-13_20-49-52/logger_all.log +++ /dev/null @@ -1,76 +0,0 @@ -[0.181s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build'] -[0.181s] DEBUG:colcon:Parsed command line arguments: Namespace(log_base=None, log_level=None, verb_name='build', build_base='build', install_base='install', merge_install=False, symlink_install=False, test_result_base=None, continue_on_error=False, executor='parallel', parallel_workers=4, event_handlers=None, ignore_user_meta=False, metas=['./colcon.meta'], base_paths=['.'], packages_ignore=None, packages_ignore_regex=None, paths=None, packages_up_to=None, packages_up_to_regex=None, packages_above=None, packages_above_and_dependencies=None, packages_above_depth=None, packages_select_by_dep=None, packages_skip_by_dep=None, packages_skip_up_to=None, packages_select_build_failed=False, packages_skip_build_finished=False, packages_select_test_failures=False, packages_skip_test_passed=False, packages_select=None, packages_skip=None, packages_select_regex=None, packages_skip_regex=None, packages_start=None, packages_end=None, cmake_args=None, cmake_target=None, cmake_target_skip_unavailable=False, cmake_clean_cache=False, cmake_clean_first=False, cmake_force_configure=False, ament_cmake_args=None, catkin_cmake_args=None, catkin_skip_building_tests=False, mixin_files=None, mixin=None, verb_parser=, verb_extension=, main=>, mixin_verb=('build',)) -[0.389s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters -[0.390s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/Gazebo.meta' -[0.391s] INFO:colcon.colcon_metadata.package_discovery.colcon_meta:Using configuration from '/root/.colcon/metadata/default/fastrtps.meta' -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover -[0.392s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover -[0.392s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/root/ros2_ws/src/inorbit_republisher/test/sample_data' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' -[0.392s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] -[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' -[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] -[0.393s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' -[0.407s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ignore', 'ignore_ament_install'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ignore_ament_install' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_pkg'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_pkg' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['colcon_meta'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'colcon_meta' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['ros'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'ros' -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['cmake', 'python'] -[0.408s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'cmake' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extensions ['python_setup_py'] -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(hardcodedRosbag) by extension 'python_setup_py' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' -[0.409s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover -[0.409s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults -[0.438s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed -[0.440s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' -[0.441s] DEBUG:colcon.colcon_core.event_reactor:joining thread -[0.447s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.notify_send': Could not find 'notify-send' -[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems -[0.448s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems -[0.448s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' -[0.448s] DEBUG:colcon.colcon_notification.desktop_notification.notify2:Failed to initialize notify2: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11 -[0.448s] DEBUG:colcon.colcon_core.event_reactor:joined thread -[0.451s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems -[0.451s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.ps1' -[0.453s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_ps1.py' -[0.455s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.ps1' -[0.457s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.sh' -[0.458s] INFO:colcon.colcon_core.shell:Creating prefix util module '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/_local_setup_util_sh.py' -[0.458s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.sh' -[0.460s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.bash' -[0.460s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.bash' -[0.462s] INFO:colcon.colcon_core.shell:Creating prefix script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/local_setup.zsh' -[0.462s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/root/ros2_ws/src/inorbit_republisher/test/sample_data/install/setup.zsh' diff --git a/inorbit_republisher/test/sample_data/log/latest b/inorbit_republisher/test/sample_data/log/latest deleted file mode 120000 index b57d247..0000000 --- a/inorbit_republisher/test/sample_data/log/latest +++ /dev/null @@ -1 +0,0 @@ -latest_build \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/log/latest_build b/inorbit_republisher/test/sample_data/log/latest_build deleted file mode 120000 index 4ba36b2..0000000 --- a/inorbit_republisher/test/sample_data/log/latest_build +++ /dev/null @@ -1 +0,0 @@ -build_2024-12-13_20-49-52 \ No newline at end of file From bf52bd3b47baa847a24d9b7ef2d6d15737980d51 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 11:11:00 -0300 Subject: [PATCH 17/21] Added a README file that was missing, corrected extra line on config file --- inorbit_republisher/CHANGELOG.rst | 14 ++ inorbit_republisher/README.md | 210 ++++++++++++++++++ .../test/sample_data/config.yaml | 2 +- 3 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 inorbit_republisher/CHANGELOG.rst create mode 100644 inorbit_republisher/README.md diff --git a/inorbit_republisher/CHANGELOG.rst b/inorbit_republisher/CHANGELOG.rst new file mode 100644 index 0000000..71d60a4 --- /dev/null +++ b/inorbit_republisher/CHANGELOG.rst @@ -0,0 +1,14 @@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Changelog for package inorbit_republisher +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +0.4.1 (2023-09-07) +------------------ +* Fix variable shadowing on message `callback` method (`#21 `_) +* Contributors: Leandro + +0.4.0 (2023-08-18) +------------------ +* First pass at porting republisher to ROS 2 (`#20 `_) + Ported from noetic-devel +* Contributors: Julian Cerruti, Elvio Aruta \ No newline at end of file diff --git a/inorbit_republisher/README.md b/inorbit_republisher/README.md new file mode 100644 index 0000000..d731e52 --- /dev/null +++ b/inorbit_republisher/README.md @@ -0,0 +1,210 @@ +# InOrbit republisher for ROS 2 + +This directory includes a republisher that allows mapping from arbitrary ROS 2 values to ``InOrbit`` [custom data](https://www.inorbit.ai/faq#publish-custom-data) key/value pairs for application-specific observability. + +Currently only mapping from ROS 2 topics is supported. The republisher could be extended to map actions, services and parameters. + +## Usage + +Create a YAML config file specifying the mappings you would like to use using this format: + +```yaml + republishers: + - topic: "/fruits_per_cubic_m" + qos: 5 + msg_type: "fruit_msgs/msg/Citrus" + mappings: + - field: "num_oranges" + mapping_type: "single_field" + out: + topic: "/inorbit/custom_data" + key: "oranges" + - topic: "/hardware/status" + msg_type: "hw_msgs/msg/HardwareStatus" + mappings: + - field: "status" + mapping_options: + fields: ["lidar", "motor", "battery"] + filter: 'lambda x: (x.status == 1)' + mapping_type: "array_of_fields" + out: + topic: "/inorbit/custom_data" + key: "hardware_error" + - topic: "/cmd_vel" + qos: 10 + msg_type: "geometry_msgs/msg/Twist" + mappings: + - field: "linear" + mapping_type: "json_of_fields" + mapping_options: + fields: ["x", "y", "z"] + filter: 'lambda vel: (vel["x"] > 0)' + out: + topic: "/inorbit/linear_vel_test" + key: "linear_vel" + - topic: "/navsat" + msg_type: "sensor_msgs/NavSatFix" + mappings: + - mapping_type: "serialize" + mapping_options: + fields: ["status", "latitude", "longitude", "position_covariance_type"] + out: + topic: "/inorbit/custom_data" + key: "navsat" + static_publishers: + - value: "this is a fixed string" + out: + topic: "/inorbit/custom_data" + key: "greeting" + - value_from: + environment_variable: "PATH" + out: + topic: "/inorbit/custom_data" + key: "env_path" +``` + +Then launch the ``republisher.py`` script passing the config file as the ``config`` param. + +A suggested way to organize this is by creating the config file and launch file in your package, then the corresponding launch file would like like this: + +```xml + + + + + +``` + +## Mapping ROS 2 topics + +The republisher can map the ROS 2 values to single field (e.g. ``'fruit=apple'``) or to an array of fields (e.g. ``'fruits=[{fruit1: apple, fruit2: orange}, {fruit1: melon, fruit2: apple}]'``). The former is useful to capture simple fields and the latter to get data from an array of values. + +### Single field: mapping options + +When republishing a single field, you can include a set of ``mapping_options`` for each ``mapping``. These include: + +* `mapping_type`: this mapping option should be set to `single_field`. +* `filter`: a lambda expression that can be used to control whether or not the value is published based on a condition. For example, if you'd like to republish only String values that are different than ``SPAMMY STRING``, you can do it with: + + ```yaml + mapping_options: + filter: 'lambda x: (x != "SPAMMY STRING")' + ``` + +### Array of fields: mapping options + +When republishing an array of fields, you can include a set of ``mapping_options`` for each ``mapping``. These include: + +* `mapping_type`: this mapping option should be set to `array_of_fields`. +* `fields`: a set of fields that you'd like to capture from each array element. For example, if each array element contains the elements ``[a, c, d, e]`` and you'd like to get ``a`` and ``c`` only, you can specify it as: + + ```yaml + mapping_options: + fields: ["a", "c"] + ``` + + If no fields are specified, the republisher will get all the fields in each array element. + +* `filter`: a lambda expression that can be used to pick certain array elements based on a condition. For example, if you'd like to republish array elements where ``c > 5`` only, you can do it with: + + ```yaml + mapping_options: + filter: 'lambda x: (x > 5)' + ``` + +### JSON of fields: mapping options + +When republishing several fields of a nested structure, this mapping type allows to bundle them together in a single JSON message instead of republishing all the fields of interest separately. + +The `mapping_options` for this type include: + +* `mapping_type`: this mapping option should be set to `json_of_fields`. +* `fields`: a set of fields that you'd like to capture from the nested message. For example, if your message definition looks like [Twist](http://docs.ros.org/en/api/geometry_msgs/html/msg/Twist.html): + + setting + + ```yaml + mapping_options: + fields: ["x", "y", "z"] + ``` + + would output a JSON object with the fields as keys with their respective values for the message + + ```text + data: "linear_vel={\"y\": 0.00013548378774430603, \"x\": 0.0732172280550003, \"z\": 0.0}" + ``` + + * `filter`: a lambda expression that can be used to control whether or not the JSON object is published based on a condition. For example, if you'd like to republish only JSON objects that have a value for the key ``z`` different than ``0``, you can do it with: + + ```yaml + mapping_options: + filter: 'lambda linear_vel: (linear_vel["z"] != 0)' + ``` + +### Serialize: mapping options + +This mapping option transforms the entire ROS message to a JSON string. + +The `mapping_options` for this type include: + +* `mapping_type`: this mapping option should be set to `serialize`. +* `fields`: (optional) a set of first level fields or keys to keep. If not provided, all fields are kept. For example, using the following mapping option for serializing 4 [NavSatFix](https://docs.ros2.org/latest/api/sensor_msgs/msg/NavSatFix.html) fields: + + ```yaml + mapping_options: + fields: ["status", "latitude", "longitude", "position_covariance_type"] + ``` + + would output a JSON object with the fields as keys with their respective values for the message + + ```text + data: 'navsat={"status": {"status": 0, "service": 0}, "latitude": 0.0, "longitude": 0.0, "position_covariance_type": 0}' + ``` + +## Publishing fixed values + +Sometimes it is also useful to publish fixed values to facilitate fleet-wide observability. It is possible to publish environment variables, package versions or fixed values using the `static_publishers` array. + +See the included example configuration in `config/example.yaml` for specific examples. + +These values will be published as latched and delivered only once every time a subscriber connects to the republisher. + +## Building and running locally + +Find below instructions for building the package and running the node using the the code on the workspace (see also [colcon](https://colcon.readthedocs.io/en/released/reference/verb/build.html)). + +### Start ROS 2 docker container (optional) + +You can run the commands below for building and running the republisher inside a docker container. + +```bash +docker run -ti --rm \ + --workdir /root/ros2_ws/ \ + -v .:/root/ros2_ws/src/inorbit_republisher \ + osrf/ros:jazzy-desktop +``` + +### Build + +```bash +cd ~/ros2_ws +rosdep install --from-paths src -y --ignore-src +colcon build --packages-select inorbit_republisher --symlink-install +``` + +### Run + +```bash +source install/local_setup.bash +# Using the launch file under the 'launch' directory +ros2 launch inorbit_republisher example.launch.xml +``` + +## TODO + +* Schema validation +* Better documentation +* Error handling +* Proper logging +* Latched topic support +* Mapping of ROS parameters \ No newline at end of file diff --git a/inorbit_republisher/test/sample_data/config.yaml b/inorbit_republisher/test/sample_data/config.yaml index 95fc5e0..c7eccf9 100644 --- a/inorbit_republisher/test/sample_data/config.yaml +++ b/inorbit_republisher/test/sample_data/config.yaml @@ -20,4 +20,4 @@ republishers: - field: "temperature" out: topic: "/inorbit/custom_data" - key: "my_temperature" + key: "my_temperature" \ No newline at end of file From 682d3793184a62fa516c8e034c4413dda3b85765 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 19:39:47 -0300 Subject: [PATCH 18/21] Updated README to echo another topic --- inorbit_republisher/test/README.md | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index e69de29..4fa2c02 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -0,0 +1,50 @@ +# Sample data for testing + +A very simple ``rosbag`` with hardcoded data for smoke testing the transformer node. + +```bash +$root@7c94d2cf9659:~# ros2 bag info ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 + +closing. +[INFO] [1734553121.938063653] [rosbag2_storage]: Opened database 'ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3' for READ_ONLY. + +Files: ros2_ws/src/inorbit_republisher/test/sample_data/hardcodedRosbag/rosbag2_2024_12_13-19_33_34_0.db3 +Bag size: 24.0 KiB +Storage id: sqlite3 +Duration: 16.005861016s +Start: Dec 13 2024 19:45:00.085674077 (1734119100.085674077) +End: Dec 13 2024 19:45:16.091535093 (1734119116.091535093) +Messages: 34 +Topic information: Topic: /my_magnetic_field | Type: sensor_msgs/msg/MagneticField | Count: 17 | Serialization Format: cdr + Topic: /my_temperature | Type: sensor_msgs/msg/Temperature | Count: 17 | Serialization Format: cdr + +``` + +To validate the node works launch the sample by using the ``sample_data.launch.xml`` launch file and look at ``out`` topic: ``ros2 topic echo my_temperature``. + +```bash +cd ros2_ws/src +colcon build --packages-select inorbit_republisher --symlink-install +source install/setup.bash +cd +ros2 launch inorbit_republisher sample_data.launch.xml +# On a different terminal windows +source /opt/ros/jazzy/setup.bash +ros2 topic echo inorbit/custom_data +data: my_magnetic_field_x=1.233536973711507 +--- +data: my_magnetic_field_y=6.557449696128689 +--- +data: my_magnetic_field_z=-1.6201375987982995 +--- +data: my_temperature=29.562268283427592 +--- +data: my_magnetic_field_x=-3.071746389301242 +--- +data: my_magnetic_field_y=6.080682955949868 +--- +data: my_magnetic_field_z=3.952488443512035 +--- +data: my_temperature=21.159168808582983 +--- +``` \ No newline at end of file From 001912b78c8e30d9fe70ebbd99b9214e981952f5 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 23 Dec 2024 19:53:38 -0300 Subject: [PATCH 19/21] Added resource folder as it was not running the package without it --- inorbit_republisher/resource/inorbit_republisher | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 inorbit_republisher/resource/inorbit_republisher diff --git a/inorbit_republisher/resource/inorbit_republisher b/inorbit_republisher/resource/inorbit_republisher new file mode 100644 index 0000000..e69de29 From eca36380eceb99f916a76fc217c16aca20faffa7 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Thu, 26 Dec 2024 11:49:01 -0300 Subject: [PATCH 20/21] Updated README, i added a first step to build a docker before running the node --- inorbit_republisher/test/README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/inorbit_republisher/test/README.md b/inorbit_republisher/test/README.md index 4fa2c02..1c425d3 100644 --- a/inorbit_republisher/test/README.md +++ b/inorbit_republisher/test/README.md @@ -21,7 +21,22 @@ Topic information: Topic: /my_magnetic_field | Type: sensor_msgs/msg/MagneticFie ``` To validate the node works launch the sample by using the ``sample_data.launch.xml`` launch file and look at ``out`` topic: ``ros2 topic echo my_temperature``. - +1. **Start ROS2 docker container (optional)**: +You can run the commands below for building and running the republisher inside a docker container. + ```bash + docker run -ti --rm \ + --workdir /root/ros2_ws/ \ + -v .:/root/ros2_ws/src/inorbit_republisher \ + osrf/ros:jazzy-desktop + ``` +2. **Build the Workspace**: + Ensure the workspace is built and the environment is sourced: + ```bash + cd ~/ros2_ws + rosdep install --from-paths src -y --ignore-src + colcon build --packages-select inorbit_republisher --symlink-install + ``` +3. **Source and Run the Workspace**: ```bash cd ros2_ws/src colcon build --packages-select inorbit_republisher --symlink-install From ba35871a1880662360616a2c85ec2f4fab505666 Mon Sep 17 00:00:00 2001 From: irinaterebiznik Date: Mon, 6 Jan 2025 14:32:16 -0300 Subject: [PATCH 21/21] Added a unit test to the republisher --- .../config/example_unit_test.yaml | 29 +++++++ .../launch/test_republisher.launch.xml | 5 ++ inorbit_republisher/test/unit_test/README.md | 38 ++++++++++ .../test/unit_test/test_republisher.py | 75 +++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 inorbit_republisher/config/example_unit_test.yaml create mode 100644 inorbit_republisher/launch/test_republisher.launch.xml create mode 100644 inorbit_republisher/test/unit_test/README.md create mode 100644 inorbit_republisher/test/unit_test/test_republisher.py diff --git a/inorbit_republisher/config/example_unit_test.yaml b/inorbit_republisher/config/example_unit_test.yaml new file mode 100644 index 0000000..0135bf8 --- /dev/null +++ b/inorbit_republisher/config/example_unit_test.yaml @@ -0,0 +1,29 @@ +republishers: +- topic: "/input_topic" + msg_type: "std_msgs/String" + mappings: + - field: "data" + mapping_type: "single_field" + out: + topic: "/output_topic" + key: "input_to_output" +static_publishers: +- value_from: + package_version: "rospy" + out: + topic: "/inorbit/custom_data" + key: "rospy_version" +- value_from: + package_version: "inorbit_republisher" + out: + topic: "/inorbit/custom_data" + key: "inorbit_republisher_version" +- value_from: + environment_variable: "PYTHONPATH" + out: + topic: "/inorbit/custom_data" + key: "python_path" +- value: "let's republish in orbit" + out: + topic: "/inorbit/custom_data" + key: "greeting" \ No newline at end of file diff --git a/inorbit_republisher/launch/test_republisher.launch.xml b/inorbit_republisher/launch/test_republisher.launch.xml new file mode 100644 index 0000000..36ba4d1 --- /dev/null +++ b/inorbit_republisher/launch/test_republisher.launch.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/inorbit_republisher/test/unit_test/README.md b/inorbit_republisher/test/unit_test/README.md new file mode 100644 index 0000000..c6d075a --- /dev/null +++ b/inorbit_republisher/test/unit_test/README.md @@ -0,0 +1,38 @@ +# Unit Test for ROS Republisher Node + +This repository contains a unit test for a ROS node that republishes messages from `/input_topic` to `/output_topic`. The test ensures the republisher node processes and republishes messages correctly. + +## Test Description + +The unit test is implemented in `test_republisher.py` and uses the `unittest` framework along with `rostest`. It includes the following test cases: + +- **`test_message_republishing`**: + - Publishes a test message (`key=value`) to `/input_topic`. + - Verifies that the republisher node republishes the message with the correct prefix (`input_to_output=`) to `/output_topic`. + +- **`test_no_message`**: + - Ensures that no messages are received on `/output_topic` at the start of the test. + +The test subscribes to `/output_topic` and collects received messages for validation. + +## Running the Unit Test +1. **Start ROS 2 docker container (optional)**: +You can run the commands below for building and running the republisher inside a docker container. + ```bash + docker run -ti --rm \ + --workdir /root/ros2_ws/ \ + -v .:/root/ros2_ws/src/inorbit_republisher \ + osrf/ros:jazzy-desktop + ``` +2. **Build the Workspace**: + Ensure the workspace is built and the environment is sourced: + ```bash + cd ~/ros2_ws + rosdep install --from-paths src -y --ignore-src + colcon build --packages-select inorbit_republisher --symlink-install + ``` +3. **Source and Run the Workspace**: + ```bash + source install/local_setup.bash + colcon test --packages-select inorbit_republisher --event-handlers console_cohesion+ console_direct+ + ``` \ No newline at end of file diff --git a/inorbit_republisher/test/unit_test/test_republisher.py b/inorbit_republisher/test/unit_test/test_republisher.py new file mode 100644 index 0000000..ca83de9 --- /dev/null +++ b/inorbit_republisher/test/unit_test/test_republisher.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +import os +import time +import unittest +import pytest +import rclpy +from rclpy.node import Node +from std_msgs.msg import String +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import AnyLaunchDescriptionSource +import launch_testing +from ament_index_python.packages import get_package_share_directory + + +@pytest.mark.launch_test +def generate_test_description(): + # Use dynamic path instead of hardcoded absolute path + launch_file_path = os.path.join( + get_package_share_directory("inorbit_republisher"), + "test_republisher.launch.xml" + ) + return LaunchDescription([ + IncludeLaunchDescription( + AnyLaunchDescriptionSource(launch_file_path) + ), + launch_testing.actions.ReadyToTest(), + ]) + + +class TestRepublisher(unittest.TestCase): + + def setUp(self): + rclpy.init() + self.node = rclpy.create_node('test_republisher') + self.test_pub = self.node.create_publisher(String, '/input_topic', 10) + self.received_messages = [] + + self.node.create_subscription(String, '/output_topic', self.callback, 10) + # Wait up to 5 seconds for at least one subscriber on /input_topic + end_time = time.time() + 5 + while time.time() < end_time: + if self.test_pub.get_subscription_count() > 0: + break + rclpy.spin_once(self.node, timeout_sec=0.1) + else: + self.fail("Test setup failed: Publisher connection timeout.") + + def callback(self, msg): + self.received_messages.append(msg.data) + + def test_message_republishing(self): + test_message = "key=value" + expected_message = f"input_to_output={test_message}" + self.node.get_logger().info(f"Publishing: {test_message} to /input_topic") + + self.test_pub.publish(String(data=test_message)) + + # Spin for up to 5 seconds waiting for the republished message + end_time = time.time() + 5 + while time.time() < end_time: + rclpy.spin_once(self.node, timeout_sec=0.1) + if expected_message in self.received_messages: + break + + self.node.get_logger().info(f"Messages received: {self.received_messages}") + self.assertIn(expected_message, self.received_messages) + + def tearDown(self): + self.node.destroy_node() + rclpy.shutdown() + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file