From 1148914c868a71a216a86b45f3858e64d5e1ee02 Mon Sep 17 00:00:00 2001 From: IvanCG14 Date: Wed, 3 Sep 2025 20:22:24 -0500 Subject: [PATCH 1/7] limpieza --- controllers/controllers/__init__.py | 0 controllers/controllers/build/.built_by | 1 - controllers/controllers/build/COLCON_IGNORE | 0 controllers/controllers/gap_node.py | 71 - controllers/controllers/graficas.py | 124 - .../install/.colcon_install_layout | 1 - controllers/controllers/install/COLCON_IGNORE | 0 .../install/_local_setup_util_ps1.py | 407 - .../install/_local_setup_util_sh.py | 407 - .../controllers/install/local_setup.bash | 121 - .../controllers/install/local_setup.ps1 | 55 - .../controllers/install/local_setup.sh | 137 - .../controllers/install/local_setup.zsh | 134 - controllers/controllers/install/setup.bash | 31 - controllers/controllers/install/setup.ps1 | 29 - controllers/controllers/install/setup.sh | 45 - controllers/controllers/install/setup.zsh | 31 - controllers/controllers/log/COLCON_IGNORE | 0 .../log/build_2025-08-07_23-05-56/events.log | 2 - .../build_2025-08-07_23-05-56/logger_all.log | 62 - .../log/build_2025-08-07_23-06-01/events.log | 2 - .../build_2025-08-07_23-06-01/logger_all.log | 63 - controllers/controllers/log/latest | 1 - controllers/controllers/log/latest_build | 1 - controllers/controllers/mpc_node.py | 429 - controllers/controllers/obstaculosFTG.py | 264 - controllers/controllers/obstaculosWF.py | 179 - controllers/controllers/pid_node.py | 108 - controllers/controllers/proyectoFTG.py | 261 - controllers/controllers/proyectoObstaculos.py | 404 - controllers/controllers/proyectoRob.py | 147 - controllers/controllers/proyectoWF.py | 182 - controllers/controllers/purepursuit_node.py | 40 - controllers/controllers/rrt_node.py | 218 - controllers/controllers/temporizador.py | 52 - controllers/controllers/ttc_node.py | 54 - controllers/package.xml | 28 - controllers/resource/controllers | 0 controllers/setup.cfg | 4 - controllers/setup.py | 39 - controllers/test/test_copyright.py | 25 - controllers/test/test_flake8.py | 25 - controllers/test/test_pep257.py | 23 - f1tenth_gym_ros/LICENSE | 21 - .../config/ackermann_controllers.yaml | 76 - f1tenth_gym_ros/config/gazebo_params.yaml | 16 - f1tenth_gym_ros/config/sim.yaml | 62 - f1tenth_gym_ros/f1tenth_gym_ros/__init__.py | 0 f1tenth_gym_ros/f1tenth_gym_ros/gym_bridge.py | 420 - f1tenth_gym_ros/launch/camera.launch.py | 21 - f1tenth_gym_ros/launch/ego_racecar.xacro | 129 - f1tenth_gym_ros/launch/gazebo_racecar.xacro | 382 - f1tenth_gym_ros/launch/gazebo_test.launch.py | 197 - f1tenth_gym_ros/launch/gym_bridge.rviz | 322 - f1tenth_gym_ros/launch/gym_bridge_launch.py | 95 - f1tenth_gym_ros/launch/opp_racecar.xacro | 129 - .../launch/ros2_control_ackermann.xacro | 68 - f1tenth_gym_ros/launch/rplidar.launch.py | 20 - f1tenth_gym_ros/maps/SaoPaulo_map.png | Bin 92014 -> 0 bytes f1tenth_gym_ros/maps/SaoPaulo_map.yaml | 6 - f1tenth_gym_ros/maps/Spielberg_map.png | Bin 62176 -> 0 bytes f1tenth_gym_ros/maps/Spielberg_map.yaml | 6 - f1tenth_gym_ros/maps/Spielberg_obs_map.png | Bin 95482 -> 0 bytes f1tenth_gym_ros/maps/Spielberg_obs_map.yaml | 6 - f1tenth_gym_ros/maps/levine.png | Bin 13273 -> 0 bytes f1tenth_gym_ros/maps/levine.yaml | 6 - f1tenth_gym_ros/maps/levineB.png | Bin 8405 -> 0 bytes f1tenth_gym_ros/maps/levineB.yaml | 6 - f1tenth_gym_ros/package.xml | 39 - f1tenth_gym_ros/resource/f1tenth_gym_ros | 0 f1tenth_gym_ros/setup.cfg | 4 - f1tenth_gym_ros/setup.py | 32 - f1tenth_gym_ros/test/test_copyright.py | 23 - f1tenth_gym_ros/test/test_flake8.py | 25 - f1tenth_gym_ros/test/test_pep257.py | 23 - f1tenth_gym_ros/worlds/empty.world | 13 - f1tenth_gym_ros/worlds/levine.world | 9025 ----------------- f1tenth_gym_ros/worlds/obstacles.world | 937 -- path_planning/package.xml | 24 - path_planning/path_planning/__init__.py | 0 .../path_planning/waypoint_recorder.py | 67 - path_planning/resource/path_planning | 0 path_planning/setup.cfg | 4 - path_planning/setup.py | 26 - path_planning/test/test_copyright.py | 25 - path_planning/test/test_flake8.py | 25 - path_planning/test/test_pep257.py | 23 - waypoints/levine_path.csv | 1152 --- 88 files changed, 17662 deletions(-) delete mode 100644 controllers/controllers/__init__.py delete mode 100644 controllers/controllers/build/.built_by delete mode 100644 controllers/controllers/build/COLCON_IGNORE delete mode 100644 controllers/controllers/gap_node.py delete mode 100644 controllers/controllers/graficas.py delete mode 100644 controllers/controllers/install/.colcon_install_layout delete mode 100644 controllers/controllers/install/COLCON_IGNORE delete mode 100644 controllers/controllers/install/_local_setup_util_ps1.py delete mode 100644 controllers/controllers/install/_local_setup_util_sh.py delete mode 100644 controllers/controllers/install/local_setup.bash delete mode 100644 controllers/controllers/install/local_setup.ps1 delete mode 100644 controllers/controllers/install/local_setup.sh delete mode 100644 controllers/controllers/install/local_setup.zsh delete mode 100644 controllers/controllers/install/setup.bash delete mode 100644 controllers/controllers/install/setup.ps1 delete mode 100644 controllers/controllers/install/setup.sh delete mode 100644 controllers/controllers/install/setup.zsh delete mode 100644 controllers/controllers/log/COLCON_IGNORE delete mode 100644 controllers/controllers/log/build_2025-08-07_23-05-56/events.log delete mode 100644 controllers/controllers/log/build_2025-08-07_23-05-56/logger_all.log delete mode 100644 controllers/controllers/log/build_2025-08-07_23-06-01/events.log delete mode 100644 controllers/controllers/log/build_2025-08-07_23-06-01/logger_all.log delete mode 120000 controllers/controllers/log/latest delete mode 120000 controllers/controllers/log/latest_build delete mode 100644 controllers/controllers/mpc_node.py delete mode 100644 controllers/controllers/obstaculosFTG.py delete mode 100644 controllers/controllers/obstaculosWF.py delete mode 100644 controllers/controllers/pid_node.py delete mode 100644 controllers/controllers/proyectoFTG.py delete mode 100644 controllers/controllers/proyectoObstaculos.py delete mode 100644 controllers/controllers/proyectoRob.py delete mode 100644 controllers/controllers/proyectoWF.py delete mode 100644 controllers/controllers/purepursuit_node.py delete mode 100644 controllers/controllers/rrt_node.py delete mode 100644 controllers/controllers/temporizador.py delete mode 100644 controllers/controllers/ttc_node.py delete mode 100644 controllers/package.xml delete mode 100644 controllers/resource/controllers delete mode 100644 controllers/setup.cfg delete mode 100644 controllers/setup.py delete mode 100644 controllers/test/test_copyright.py delete mode 100644 controllers/test/test_flake8.py delete mode 100644 controllers/test/test_pep257.py delete mode 100644 f1tenth_gym_ros/LICENSE delete mode 100644 f1tenth_gym_ros/config/ackermann_controllers.yaml delete mode 100644 f1tenth_gym_ros/config/gazebo_params.yaml delete mode 100644 f1tenth_gym_ros/config/sim.yaml delete mode 100644 f1tenth_gym_ros/f1tenth_gym_ros/__init__.py delete mode 100644 f1tenth_gym_ros/f1tenth_gym_ros/gym_bridge.py delete mode 100644 f1tenth_gym_ros/launch/camera.launch.py delete mode 100644 f1tenth_gym_ros/launch/ego_racecar.xacro delete mode 100644 f1tenth_gym_ros/launch/gazebo_racecar.xacro delete mode 100644 f1tenth_gym_ros/launch/gazebo_test.launch.py delete mode 100644 f1tenth_gym_ros/launch/gym_bridge.rviz delete mode 100644 f1tenth_gym_ros/launch/gym_bridge_launch.py delete mode 100644 f1tenth_gym_ros/launch/opp_racecar.xacro delete mode 100644 f1tenth_gym_ros/launch/ros2_control_ackermann.xacro delete mode 100644 f1tenth_gym_ros/launch/rplidar.launch.py delete mode 100644 f1tenth_gym_ros/maps/SaoPaulo_map.png delete mode 100644 f1tenth_gym_ros/maps/SaoPaulo_map.yaml delete mode 100644 f1tenth_gym_ros/maps/Spielberg_map.png delete mode 100644 f1tenth_gym_ros/maps/Spielberg_map.yaml delete mode 100644 f1tenth_gym_ros/maps/Spielberg_obs_map.png delete mode 100644 f1tenth_gym_ros/maps/Spielberg_obs_map.yaml delete mode 100644 f1tenth_gym_ros/maps/levine.png delete mode 100644 f1tenth_gym_ros/maps/levine.yaml delete mode 100644 f1tenth_gym_ros/maps/levineB.png delete mode 100644 f1tenth_gym_ros/maps/levineB.yaml delete mode 100644 f1tenth_gym_ros/package.xml delete mode 100644 f1tenth_gym_ros/resource/f1tenth_gym_ros delete mode 100644 f1tenth_gym_ros/setup.cfg delete mode 100644 f1tenth_gym_ros/setup.py delete mode 100644 f1tenth_gym_ros/test/test_copyright.py delete mode 100644 f1tenth_gym_ros/test/test_flake8.py delete mode 100644 f1tenth_gym_ros/test/test_pep257.py delete mode 100644 f1tenth_gym_ros/worlds/empty.world delete mode 100644 f1tenth_gym_ros/worlds/levine.world delete mode 100644 f1tenth_gym_ros/worlds/obstacles.world delete mode 100644 path_planning/package.xml delete mode 100644 path_planning/path_planning/__init__.py delete mode 100755 path_planning/path_planning/waypoint_recorder.py delete mode 100644 path_planning/resource/path_planning delete mode 100644 path_planning/setup.cfg delete mode 100644 path_planning/setup.py delete mode 100644 path_planning/test/test_copyright.py delete mode 100644 path_planning/test/test_flake8.py delete mode 100644 path_planning/test/test_pep257.py delete mode 100644 waypoints/levine_path.csv diff --git a/controllers/controllers/__init__.py b/controllers/controllers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/controllers/controllers/build/.built_by b/controllers/controllers/build/.built_by deleted file mode 100644 index 06e74ac..0000000 --- a/controllers/controllers/build/.built_by +++ /dev/null @@ -1 +0,0 @@ -colcon diff --git a/controllers/controllers/build/COLCON_IGNORE b/controllers/controllers/build/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/controllers/controllers/gap_node.py b/controllers/controllers/gap_node.py deleted file mode 100644 index 24a49e7..0000000 --- a/controllers/controllers/gap_node.py +++ /dev/null @@ -1,71 +0,0 @@ -import rclpy -from rclpy.node import Node - -import numpy as np -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped, AckermannDrive - -class ReactiveFollowGap(Node): - """ - Implement Wall Following on the car - This is just a template, you are free to implement your own node! - """ - def __init__(self): - super().__init__('reactive_node') - # Topics & Subs, Pubs - lidarscan_topic = '/scan' - drive_topic = '/drive' - - # TODO: Subscribe to LIDAR - # TODO: Publish to drive - - def preprocess_lidar(self, ranges): - """ Preprocess the LiDAR scan array. Expert implementation includes: - 1.Setting each value to the mean over some window - 2.Rejecting high values (eg. > 3m) - """ - proc_ranges = ranges - return proc_ranges - - def find_max_gap(self, free_space_ranges): - """ Return the start index & end index of the max gap in free_space_ranges - """ - return None - - def find_best_point(self, start_i, end_i, ranges): - """Start_i & end_i are start and end indicies of max-gap range, respectively - Return index of best point in ranges - Naive: Choose the furthest point within ranges and go there - """ - return None - - def lidar_callback(self, data): - """ Process each LiDAR scan as per the Follow Gap algorithm & publish an AckermannDriveStamped Message - """ - ranges = data.ranges - proc_ranges = self.preprocess_lidar(ranges) - - # TODO: - #Find closest point to LiDAR - - #Eliminate all points inside 'bubble' (set them to zero) - - #Find max length gap - - #Find the best point in the gap - - #Publish Drive message - - -def main(args=None): - rclpy.init(args=args) - print("WallFollow Initialized") - reactive_node = ReactiveFollowGap() - rclpy.spin(reactive_node) - - reactive_node.destroy_node() - rclpy.shutdown() - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/graficas.py b/controllers/controllers/graficas.py deleted file mode 100644 index fb636f2..0000000 --- a/controllers/controllers/graficas.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python3 -import rclpy -from rclpy.node import Node -from nav_msgs.msg import Odometry -from ackermann_msgs.msg import AckermannDriveStamped -from geometry_msgs.msg import Quaternion -import numpy as np -import matplotlib.pyplot as plt -import csv -import os -from datetime import datetime -import math - -def yaw_from_quat(q: Quaternion) -> float: - # Convierte quaternion a yaw (Z) en radianes - x, y, z, w = q.x, q.y, q.z, q.w - siny_cosp = 2.0 * (w*z + x*y) - cosy_cosp = 1.0 - 2.0 * (y*y + z*z) - return math.atan2(siny_cosp, cosy_cosp) - -class F1Logger(Node): - def __init__(self): - super().__init__('f1_logger') - - # Suscripciones - self.sub_odom = self.create_subscription(Odometry, '/ego_racecar/odom', self.on_odom, 10) - self.sub_drive = self.create_subscription(AckermannDriveStamped, '/drive', self.on_drive, 10) - - - # Buffers - self.t = [] - self.x = [] - self.y = [] - self.yaw = [] - self.v_linear = [] - self.steer = [] - - self.last_drive_msg = None - self.start_time = self.get_clock().now() - - # Parámetro opcional para nombre de salida - stamp = datetime.now().strftime('%Y%m%d_%H%M%S') - self.out_csv = f'f1tenth_run_{stamp}.csv' - self.get_logger().info('F1Logger listo. Grabando /odom y /drive... (Ctrl+C para terminar)') - - def now_secs(self): - return (self.get_clock().now() - self.start_time).nanoseconds * 1e-9 - - def on_odom(self, msg: Odometry): - t = self.now_secs() - p = msg.pose.pose.position - q = msg.pose.pose.orientation - yaw = yaw_from_quat(q) - - # Velocidad lineal aproximada desde odom (vector en base local) - vx = msg.twist.twist.linear.x - vy = msg.twist.twist.linear.y - v = math.hypot(vx, vy) - - # Último steering recibido (si hay) - steer = self.last_drive_msg.drive.steering_angle if self.last_drive_msg else float('nan') - - # Guardar - self.t.append(t) - self.x.append(p.x) - self.y.append(p.y) - self.yaw.append(yaw) - self.v_linear.append(v) - self.steer.append(steer) - - def on_drive(self, msg: AckermannDriveStamped): - self.last_drive_msg = msg - - def destroy_node(self): - # Guardar CSV - try: - with open(self.out_csv, 'w', newline='') as f: - w = csv.writer(f) - w.writerow(['t[s]','x[m]','y[m]','yaw[rad]','v[m/s]','steering[rad]']) - for i in range(len(self.t)): - w.writerow([self.t[i], self.x[i], self.y[i], self.yaw[i], self.v_linear[i], self.steer[i]]) - self.get_logger().info(f'CSV guardado: {os.path.abspath(self.out_csv)}') - except Exception as e: - self.get_logger().error(f'No se pudo guardar CSV: {e}') - - # Graficar - if len(self.t) > 5: - try: - fig1 = plt.figure(figsize=(6,6)) - plt.plot(self.x, self.y) - plt.axis('equal') - plt.xlabel('x [m]'); plt.ylabel('y [m]') - plt.title('Trayectoria (x,y)') - - fig2 = plt.figure(figsize=(7,4)) - plt.plot(self.t, self.steer) - plt.xlabel('tiempo [s]'); plt.ylabel('steering [rad]') - plt.title('Ángulo de dirección vs tiempo') - - fig3 = plt.figure(figsize=(7,4)) - plt.plot(self.t, self.v_linear) - plt.xlabel('tiempo [s]'); plt.ylabel('velocidad [m/s]') - plt.title('Velocidad lineal vs tiempo') - - plt.tight_layout() - plt.show() - except Exception as e: - self.get_logger().error(f'No se pudo graficar: {e}') - - super().destroy_node() - -def main(): - rclpy.init() - node = F1Logger() - try: - rclpy.spin(node) - except KeyboardInterrupt: - pass - finally: - node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/install/.colcon_install_layout b/controllers/controllers/install/.colcon_install_layout deleted file mode 100644 index 3aad533..0000000 --- a/controllers/controllers/install/.colcon_install_layout +++ /dev/null @@ -1 +0,0 @@ -isolated diff --git a/controllers/controllers/install/COLCON_IGNORE b/controllers/controllers/install/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/controllers/controllers/install/_local_setup_util_ps1.py b/controllers/controllers/install/_local_setup_util_ps1.py deleted file mode 100644 index 3c6d9e8..0000000 --- a/controllers/controllers/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/controllers/controllers/install/_local_setup_util_sh.py b/controllers/controllers/install/_local_setup_util_sh.py deleted file mode 100644 index f67eaa9..0000000 --- a/controllers/controllers/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/controllers/controllers/install/local_setup.bash b/controllers/controllers/install/local_setup.bash deleted file mode 100644 index 03f0025..0000000 --- a/controllers/controllers/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/controllers/controllers/install/local_setup.ps1 b/controllers/controllers/install/local_setup.ps1 deleted file mode 100644 index 6f68c8d..0000000 --- a/controllers/controllers/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/controllers/controllers/install/local_setup.sh b/controllers/controllers/install/local_setup.sh deleted file mode 100644 index 565d0b4..0000000 --- a/controllers/controllers/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="/home/maria/F1Tenth-Repository/src/controllers/controllers/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/controllers/controllers/install/local_setup.zsh b/controllers/controllers/install/local_setup.zsh deleted file mode 100644 index b648710..0000000 --- a/controllers/controllers/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/controllers/controllers/install/setup.bash b/controllers/controllers/install/setup.bash deleted file mode 100644 index 10ea0f7..0000000 --- a/controllers/controllers/install/setup.bash +++ /dev/null @@ -1,31 +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" - -# 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/controllers/controllers/install/setup.ps1 b/controllers/controllers/install/setup.ps1 deleted file mode 100644 index 558e9b9..0000000 --- a/controllers/controllers/install/setup.ps1 +++ /dev/null @@ -1,29 +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" - -# 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/controllers/controllers/install/setup.sh b/controllers/controllers/install/setup.sh deleted file mode 100644 index 43fd463..0000000 --- a/controllers/controllers/install/setup.sh +++ /dev/null @@ -1,45 +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=/home/maria/F1Tenth-Repository/src/controllers/controllers/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" - - -# 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/controllers/controllers/install/setup.zsh b/controllers/controllers/install/setup.zsh deleted file mode 100644 index 54799fd..0000000 --- a/controllers/controllers/install/setup.zsh +++ /dev/null @@ -1,31 +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" - -# 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/controllers/controllers/log/COLCON_IGNORE b/controllers/controllers/log/COLCON_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/controllers/controllers/log/build_2025-08-07_23-05-56/events.log b/controllers/controllers/log/build_2025-08-07_23-05-56/events.log deleted file mode 100644 index 2cd52d9..0000000 --- a/controllers/controllers/log/build_2025-08-07_23-05-56/events.log +++ /dev/null @@ -1,2 +0,0 @@ -[0.000000] (-) TimerEvent: {} -[0.000662] (-) EventReactorShutdown: {} diff --git a/controllers/controllers/log/build_2025-08-07_23-05-56/logger_all.log b/controllers/controllers/log/build_2025-08-07_23-05-56/logger_all.log deleted file mode 100644 index 3b3bf28..0000000 --- a/controllers/controllers/log/build_2025-08-07_23-05-56/logger_all.log +++ /dev/null @@ -1,62 +0,0 @@ -[0.233s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build'] -[0.233s] 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=12, 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, allow_overriding=[], 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.393s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters -[0.393s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters -[0.393s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters -[0.393s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters -[0.393s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover -[0.393s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover -[0.393s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/home/maria/F1Tenth-Repository/src/controllers/controllers' -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] -[0.394s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' -[0.401s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored -[0.401s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults -[0.401s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover -[0.401s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults -[0.401s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover -[0.401s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults -[0.424s] Level 1:colcon.colcon_core.package_discovery:discover_packages(prefix_path) check parameters -[0.424s] Level 1:colcon.colcon_core.package_discovery:discover_packages(prefix_path) discover -[0.426s] DEBUG:colcon.colcon_installed_package_information.package_discovery:Found 386 installed packages in /opt/ros/humble -[0.427s] Level 1:colcon.colcon_core.package_discovery:discover_packages(prefix_path) using defaults -[0.450s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor -[0.451s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete -[0.451s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop -[0.451s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed -[0.451s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' -[0.451s] DEBUG:colcon.colcon_core.event_reactor:joining thread -[0.456s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems -[0.456s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems -[0.456s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' -[0.468s] DEBUG:colcon.colcon_core.event_reactor:joined thread -[0.473s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems -[0.474s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.ps1' -[0.475s] INFO:colcon.colcon_core.shell:Creating prefix util module '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/_local_setup_util_ps1.py' -[0.477s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.ps1' -[0.479s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.sh' -[0.480s] INFO:colcon.colcon_core.shell:Creating prefix util module '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/_local_setup_util_sh.py' -[0.480s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.sh' -[0.482s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.bash' -[0.483s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.bash' -[0.485s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.zsh' -[0.486s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.zsh' diff --git a/controllers/controllers/log/build_2025-08-07_23-06-01/events.log b/controllers/controllers/log/build_2025-08-07_23-06-01/events.log deleted file mode 100644 index 4eeddaf..0000000 --- a/controllers/controllers/log/build_2025-08-07_23-06-01/events.log +++ /dev/null @@ -1,2 +0,0 @@ -[0.000000] (-) TimerEvent: {} -[0.000107] (-) EventReactorShutdown: {} diff --git a/controllers/controllers/log/build_2025-08-07_23-06-01/logger_all.log b/controllers/controllers/log/build_2025-08-07_23-06-01/logger_all.log deleted file mode 100644 index 478968d..0000000 --- a/controllers/controllers/log/build_2025-08-07_23-06-01/logger_all.log +++ /dev/null @@ -1,63 +0,0 @@ -[0.058s] DEBUG:colcon:Command line arguments: ['/usr/bin/colcon', 'build'] -[0.058s] 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=12, 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, allow_overriding=[], 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.149s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) check parameters -[0.149s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) check parameters -[0.149s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) check parameters -[0.149s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) check parameters -[0.149s] Level 1:colcon.colcon_core.package_discovery:discover_packages(colcon_meta) discover -[0.149s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) discover -[0.149s] INFO:colcon.colcon_core.package_discovery:Crawling recursively for packages in '/home/maria/F1Tenth-Repository/src/controllers/controllers' -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ignore', 'ignore_ament_install'] -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore' -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ignore_ament_install' -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_pkg'] -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_pkg' -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['colcon_meta'] -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'colcon_meta' -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['ros'] -[0.149s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'ros' -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['cmake', 'python'] -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'cmake' -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python' -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extensions ['python_setup_py'] -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(.) by extension 'python_setup_py' -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extensions ['ignore', 'ignore_ament_install'] -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(build) by extension 'ignore' -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(build) ignored -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extensions ['ignore', 'ignore_ament_install'] -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(install) by extension 'ignore' -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(install) ignored -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extensions ['ignore', 'ignore_ament_install'] -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(log) by extension 'ignore' -[0.155s] Level 1:colcon.colcon_core.package_identification:_identify(log) ignored -[0.155s] Level 1:colcon.colcon_core.package_discovery:discover_packages(recursive) using defaults -[0.155s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) discover -[0.155s] Level 1:colcon.colcon_core.package_discovery:discover_packages(ignore) using defaults -[0.156s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) discover -[0.156s] Level 1:colcon.colcon_core.package_discovery:discover_packages(path) using defaults -[0.174s] Level 1:colcon.colcon_core.package_discovery:discover_packages(prefix_path) check parameters -[0.174s] Level 1:colcon.colcon_core.package_discovery:discover_packages(prefix_path) discover -[0.175s] DEBUG:colcon.colcon_installed_package_information.package_discovery:Found 0 installed packages in /home/maria/F1Tenth-Repository/src/controllers/controllers/install -[0.175s] DEBUG:colcon.colcon_installed_package_information.package_discovery:Found 386 installed packages in /opt/ros/humble -[0.176s] Level 1:colcon.colcon_core.package_discovery:discover_packages(prefix_path) using defaults -[0.201s] INFO:colcon.colcon_core.executor:Executing jobs using 'parallel' executor -[0.202s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete -[0.202s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:closing loop -[0.202s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:loop closed -[0.202s] DEBUG:colcon.colcon_parallel_executor.executor.parallel:run_until_complete finished with '0' -[0.202s] DEBUG:colcon.colcon_core.event_reactor:joining thread -[0.205s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.terminal_notifier': Not used on non-Darwin systems -[0.205s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_notification.desktop_notification.win32': Not used on non-Windows systems -[0.205s] INFO:colcon.colcon_notification.desktop_notification:Sending desktop notification using 'notify2' -[0.211s] DEBUG:colcon.colcon_core.event_reactor:joined thread -[0.213s] INFO:colcon.colcon_core.plugin_system:Skipping extension 'colcon_core.shell.bat': Not used on non-Windows systems -[0.213s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.ps1' -[0.214s] INFO:colcon.colcon_core.shell:Creating prefix util module '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/_local_setup_util_ps1.py' -[0.215s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.ps1' -[0.215s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.sh' -[0.216s] INFO:colcon.colcon_core.shell:Creating prefix util module '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/_local_setup_util_sh.py' -[0.216s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.sh' -[0.216s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.bash' -[0.217s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.bash' -[0.217s] INFO:colcon.colcon_core.shell:Creating prefix script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/local_setup.zsh' -[0.217s] INFO:colcon.colcon_core.shell:Creating prefix chain script '/home/maria/F1Tenth-Repository/src/controllers/controllers/install/setup.zsh' diff --git a/controllers/controllers/log/latest b/controllers/controllers/log/latest deleted file mode 120000 index b57d247..0000000 --- a/controllers/controllers/log/latest +++ /dev/null @@ -1 +0,0 @@ -latest_build \ No newline at end of file diff --git a/controllers/controllers/log/latest_build b/controllers/controllers/log/latest_build deleted file mode 120000 index b15e59a..0000000 --- a/controllers/controllers/log/latest_build +++ /dev/null @@ -1 +0,0 @@ -build_2025-08-07_23-06-01 \ No newline at end of file diff --git a/controllers/controllers/mpc_node.py b/controllers/controllers/mpc_node.py deleted file mode 100644 index 6d30573..0000000 --- a/controllers/controllers/mpc_node.py +++ /dev/null @@ -1,429 +0,0 @@ -#!/usr/bin/env python3 -import math -from dataclasses import dataclass, field - -import cvxpy -import numpy as np -import rclpy -from ackermann_msgs.msg import AckermannDrive, AckermannDriveStamped -from geometry_msgs.msg import PoseStamped -from rclpy.node import Node -from scipy.linalg import block_diag -from scipy.sparse import block_diag, csc_matrix, diags -from sensor_msgs.msg import LaserScan -from utils import nearest_point - -# TODO CHECK: include needed ROS msg type headers and libraries - - -@dataclass -class mpc_config: - NXK: int = 4 # length of kinematic state vector: z = [x, y, v, yaw] - NU: int = 2 # length of input vector: u = = [steering speed, acceleration] - TK: int = 8 # finite time horizon length kinematic - - # --------------------------------------------------- - # TODO: you may need to tune the following matrices - Rk: list = field( - default_factory=lambda: np.diag([0.01, 100.0]) - ) # input cost matrix, penalty for inputs - [accel, steering_speed] - Rdk: list = field( - default_factory=lambda: np.diag([0.01, 100.0]) - ) # input difference cost matrix, penalty for change of inputs - [accel, steering_speed] - Qk: list = field( - default_factory=lambda: np.diag([13.5, 13.5, 5.5, 13.0]) - ) # state error cost matrix, for the the next (T) prediction time steps [x, y, delta, v, yaw, yaw-rate, beta] - Qfk: list = field( - default_factory=lambda: np.diag([13.5, 13.5, 5.5, 13.0]) - ) # final state error matrix, penalty for the final state constraints: [x, y, delta, v, yaw, yaw-rate, beta] - # --------------------------------------------------- - - N_IND_SEARCH: int = 20 # Search index number - DTK: float = 0.1 # time step [s] kinematic - dlk: float = 0.03 # dist step [m] kinematic - LENGTH: float = 0.58 # Length of the vehicle [m] - WIDTH: float = 0.31 # Width of the vehicle [m] - WB: float = 0.33 # Wheelbase [m] - MIN_STEER: float = -0.4189 # maximum steering angle [rad] - MAX_STEER: float = 0.4189 # maximum steering angle [rad] - MAX_DSTEER: float = np.deg2rad(180.0) # maximum steering speed [rad/s] - MAX_SPEED: float = 6.0 # maximum speed [m/s] - MIN_SPEED: float = 0.0 # minimum backward speed [m/s] - MAX_ACCEL: float = 3.0 # maximum acceleration [m/ss] - - -@dataclass -class State: - x: float = 0.0 - y: float = 0.0 - delta: float = 0.0 - v: float = 0.0 - yaw: float = 0.0 - yawrate: float = 0.0 - beta: float = 0.0 - -class MPC(Node): - """ - Implement Kinematic MPC on the car - This is just a template, you are free to implement your own node! - """ - def __init__(self): - super().__init__('mpc_node') - # TODO: create ROS subscribers and publishers - # use the MPC as a tracker (similar to pure pursuit) - # TODO: get waypoints here - self.waypoints = None - - self.config = mpc_config() - self.odelta_v = None - self.odelta = None - self.oa = None - self.init_flag = 0 - - # initialize MPC problem - self.mpc_prob_init() - - def pose_callback(self, pose_msg): - pass - # TODO: extract pose from ROS msg - vehicle_state = None - - # TODO: Calculate the next reference trajectory for the next T steps - # with current vehicle pose. - # ref_x, ref_y, ref_yaw, ref_v are columns of self.waypoints - ref_path = self.calc_ref_trajectory(self, vehicle_state, ref_x, ref_y, ref_yaw, ref_v) - x0 = [vehicle_state.x, vehicle_state.y, vehicle_state.v, vehicle_state.yaw] - - # TODO: solve the MPC control problem - ( - self.oa, - self.odelta_v, - ox, - oy, - oyaw, - ov, - state_predict, - ) = self.linear_mpc_control(ref_path, x0, self.oa, self.odelta_v) - - # TODO: publish drive message. - steer_output = self.odelta_v[0] - speed_output = vehicle_state.v + self.oa[0] * self.config.DTK - - def mpc_prob_init(self): - """ - Create MPC quadratic optimization problem using cvxpy, solver: OSQP - Will be solved every iteration for control. - More MPC problem information here: https://osqp.org/docs/examples/mpc.html - More QP example in CVXPY here: https://www.cvxpy.org/examples/basic/quadratic_program.html - """ - # Initialize and create vectors for the optimization problem - # Vehicle State Vector - self.xk = cvxpy.Variable( - (self.config.NXK, self.config.TK + 1) - ) - # Control Input vector - self.uk = cvxpy.Variable( - (self.config.NU, self.config.TK) - ) - objective = 0.0 # Objective value of the optimization problem - constraints = [] # Create constraints array - - # Initialize reference vectors - self.x0k = cvxpy.Parameter((self.config.NXK,)) - self.x0k.value = np.zeros((self.config.NXK,)) - - # Initialize reference trajectory parameter - self.ref_traj_k = cvxpy.Parameter((self.config.NXK, self.config.TK + 1)) - self.ref_traj_k.value = np.zeros((self.config.NXK, self.config.TK + 1)) - - # Initializes block diagonal form of R = [R, R, ..., R] (NU*T, NU*T) - R_block = block_diag(tuple([self.config.Rk] * self.config.TK)) - - # Initializes block diagonal form of Rd = [Rd, ..., Rd] (NU*(T-1), NU*(T-1)) - Rd_block = block_diag(tuple([self.config.Rdk] * (self.config.TK - 1))) - - # Initializes block diagonal form of Q = [Q, Q, ..., Qf] (NX*T, NX*T) - Q_block = [self.config.Qk] * (self.config.TK) - Q_block.append(self.config.Qfk) - Q_block = block_diag(tuple(Q_block)) - - # Formulate and create the finite-horizon optimal control problem (objective function) - # The FTOCP has the horizon of T timesteps - - # -------------------------------------------------------- - # TODO: fill in the objectives here, you should be using cvxpy.quad_form() somehwhere - - # TODO: Objective part 1: Influence of the control inputs: Inputs u multiplied by the penalty R - - # TODO: Objective part 2: Deviation of the vehicle from the reference trajectory weighted by Q, including final Timestep T weighted by Qf - - # TODO: Objective part 3: Difference from one control input to the next control input weighted by Rd - - # -------------------------------------------------------- - - # Constraints 1: Calculate the future vehicle behavior/states based on the vehicle dynamics model matrices - # Evaluate vehicle Dynamics for next T timesteps - A_block = [] - B_block = [] - C_block = [] - # init path to zeros - path_predict = np.zeros((self.config.NXK, self.config.TK + 1)) - for t in range(self.config.TK): - A, B, C = self.get_model_matrix( - path_predict[2, t], path_predict[3, t], 0.0 - ) - A_block.append(A) - B_block.append(B) - C_block.extend(C) - - A_block = block_diag(tuple(A_block)) - B_block = block_diag(tuple(B_block)) - C_block = np.array(C_block) - - # [AA] Sparse matrix to CVX parameter for proper stuffing - # Reference: https://github.com/cvxpy/cvxpy/issues/1159#issuecomment-718925710 - m, n = A_block.shape - self.Annz_k = cvxpy.Parameter(A_block.nnz) - data = np.ones(self.Annz_k.size) - rows = A_block.row * n + A_block.col - cols = np.arange(self.Annz_k.size) - Indexer = csc_matrix((data, (rows, cols)), shape=(m * n, self.Annz_k.size)) - - # Setting sparse matrix data - self.Annz_k.value = A_block.data - - # Now we use this sparse version instead of the old A_ block matrix - self.Ak_ = cvxpy.reshape(Indexer @ self.Annz_k, (m, n), order="C") - - # Same as A - m, n = B_block.shape - self.Bnnz_k = cvxpy.Parameter(B_block.nnz) - data = np.ones(self.Bnnz_k.size) - rows = B_block.row * n + B_block.col - cols = np.arange(self.Bnnz_k.size) - Indexer = csc_matrix((data, (rows, cols)), shape=(m * n, self.Bnnz_k.size)) - self.Bk_ = cvxpy.reshape(Indexer @ self.Bnnz_k, (m, n), order="C") - self.Bnnz_k.value = B_block.data - - # No need for sparse matrices for C as most values are parameters - self.Ck_ = cvxpy.Parameter(C_block.shape) - self.Ck_.value = C_block - - # ------------------------------------------------------------- - # TODO: Constraint part 1: - # Add dynamics constraints to the optimization problem - # This constraint should be based on a few variables: - # self.xk, self.Ak_, self.Bk_, self.uk, and self.Ck_ - - # TODO: Constraint part 2: - # Add constraints on steering, change in steering angle - # cannot exceed steering angle speed limit. Should be based on: - # self.uk, self.config.MAX_DSTEER, self.config.DTK - - # TODO: Constraint part 3: - # Add constraints on upper and lower bounds of states and inputs - # and initial state constraint, should be based on: - # self.xk, self.x0k, self.config.MAX_SPEED, self.config.MIN_SPEED, - # self.uk, self.config.MAX_ACCEL, self.config.MAX_STEER - - # ------------------------------------------------------------- - - # Create the optimization problem in CVXPY and setup the workspace - # Optimization goal: minimize the objective function - self.MPC_prob = cvxpy.Problem(cvxpy.Minimize(objective), constraints) - - def calc_ref_trajectory(self, state, cx, cy, cyaw, sp): - """ - calc referent trajectory ref_traj in T steps: [x, y, v, yaw] - using the current velocity, calc the T points along the reference path - :param cx: Course X-Position - :param cy: Course y-Position - :param cyaw: Course Heading - :param sp: speed profile - :dl: distance step - :pind: Setpoint Index - :return: reference trajectory ref_traj, reference steering angle - """ - - # Create placeholder Arrays for the reference trajectory for T steps - ref_traj = np.zeros((self.config.NXK, self.config.TK + 1)) - ncourse = len(cx) - - # Find nearest index/setpoint from where the trajectories are calculated - _, _, _, ind = nearest_point(np.array([state.x, state.y]), np.array([cx, cy]).T) - - # Load the initial parameters from the setpoint into the trajectory - ref_traj[0, 0] = cx[ind] - ref_traj[1, 0] = cy[ind] - ref_traj[2, 0] = sp[ind] - ref_traj[3, 0] = cyaw[ind] - - # based on current velocity, distance traveled on the ref line between time steps - travel = abs(state.v) * self.config.DTK - dind = travel / self.config.dlk - ind_list = int(ind) + np.insert( - np.cumsum(np.repeat(dind, self.config.TK)), 0, 0 - ).astype(int) - ind_list[ind_list >= ncourse] -= ncourse - ref_traj[0, :] = cx[ind_list] - ref_traj[1, :] = cy[ind_list] - ref_traj[2, :] = sp[ind_list] - cyaw[cyaw - state.yaw > 4.5] = np.abs( - cyaw[cyaw - state.yaw > 4.5] - (2 * np.pi) - ) - cyaw[cyaw - state.yaw < -4.5] = np.abs( - cyaw[cyaw - state.yaw < -4.5] + (2 * np.pi) - ) - ref_traj[3, :] = cyaw[ind_list] - - return ref_traj - - def predict_motion(self, x0, oa, od, xref): - path_predict = xref * 0.0 - for i, _ in enumerate(x0): - path_predict[i, 0] = x0[i] - - state = State(x=x0[0], y=x0[1], yaw=x0[3], v=x0[2]) - for (ai, di, i) in zip(oa, od, range(1, self.config.TK + 1)): - state = self.update_state(state, ai, di) - path_predict[0, i] = state.x - path_predict[1, i] = state.y - path_predict[2, i] = state.v - path_predict[3, i] = state.yaw - - return path_predict - - def update_state(self, state, a, delta): - - # input check - if delta >= self.config.MAX_STEER: - delta = self.config.MAX_STEER - elif delta <= -self.config.MAX_STEER: - delta = -self.config.MAX_STEER - - state.x = state.x + state.v * math.cos(state.yaw) * self.config.DTK - state.y = state.y + state.v * math.sin(state.yaw) * self.config.DTK - state.yaw = ( - state.yaw + (state.v / self.config.WB) * math.tan(delta) * self.config.DTK - ) - state.v = state.v + a * self.config.DTK - - if state.v > self.config.MAX_SPEED: - state.v = self.config.MAX_SPEED - elif state.v < self.config.MIN_SPEED: - state.v = self.config.MIN_SPEED - - return state - - def get_model_matrix(self, v, phi, delta): - """ - Calc linear and discrete time dynamic model-> Explicit discrete time-invariant - Linear System: Xdot = Ax +Bu + C - State vector: x=[x, y, v, yaw] - :param v: speed - :param phi: heading angle of the vehicle - :param delta: steering angle: delta_bar - :return: A, B, C - """ - - # State (or system) matrix A, 4x4 - A = np.zeros((self.config.NXK, self.config.NXK)) - A[0, 0] = 1.0 - A[1, 1] = 1.0 - A[2, 2] = 1.0 - A[3, 3] = 1.0 - A[0, 2] = self.config.DTK * math.cos(phi) - A[0, 3] = -self.config.DTK * v * math.sin(phi) - A[1, 2] = self.config.DTK * math.sin(phi) - A[1, 3] = self.config.DTK * v * math.cos(phi) - A[3, 2] = self.config.DTK * math.tan(delta) / self.config.WB - - # Input Matrix B; 4x2 - B = np.zeros((self.config.NXK, self.config.NU)) - B[2, 0] = self.config.DTK - B[3, 1] = self.config.DTK * v / (self.config.WB * math.cos(delta) ** 2) - - C = np.zeros(self.config.NXK) - C[0] = self.config.DTK * v * math.sin(phi) * phi - C[1] = -self.config.DTK * v * math.cos(phi) * phi - C[3] = -self.config.DTK * v * delta / (self.config.WB * math.cos(delta) ** 2) - - return A, B, C - - def mpc_prob_solve(self, ref_traj, path_predict, x0): - self.x0k.value = x0 - - A_block = [] - B_block = [] - C_block = [] - for t in range(self.config.TK): - A, B, C = self.get_model_matrix( - path_predict[2, t], path_predict[3, t], 0.0 - ) - A_block.append(A) - B_block.append(B) - C_block.extend(C) - - A_block = block_diag(tuple(A_block)) - B_block = block_diag(tuple(B_block)) - C_block = np.array(C_block) - - self.Annz_k.value = A_block.data - self.Bnnz_k.value = B_block.data - self.Ck_.value = C_block - - self.ref_traj_k.value = ref_traj - - # Solve the optimization problem in CVXPY - # Solver selections: cvxpy.OSQP; cvxpy.GUROBI - self.MPC_prob.solve(solver=cvxpy.OSQP, verbose=False, warm_start=True) - - if ( - self.MPC_prob.status == cvxpy.OPTIMAL - or self.MPC_prob.status == cvxpy.OPTIMAL_INACCURATE - ): - ox = np.array(self.xk.value[0, :]).flatten() - oy = np.array(self.xk.value[1, :]).flatten() - ov = np.array(self.xk.value[2, :]).flatten() - oyaw = np.array(self.xk.value[3, :]).flatten() - oa = np.array(self.uk.value[0, :]).flatten() - odelta = np.array(self.uk.value[1, :]).flatten() - - else: - print("Error: Cannot solve mpc..") - oa, odelta, ox, oy, oyaw, ov = None, None, None, None, None, None - - return oa, odelta, ox, oy, oyaw, ov - - def linear_mpc_control(self, ref_path, x0, oa, od): - """ - MPC contorl with updating operational point iteraitvely - :param ref_path: reference trajectory in T steps - :param x0: initial state vector - :param oa: acceleration of T steps of last time - :param od: delta of T steps of last time - """ - - if oa is None or od is None: - oa = [0.0] * self.config.TK - od = [0.0] * self.config.TK - - # Call the Motion Prediction function: Predict the vehicle motion for x-steps - path_predict = self.predict_motion(x0, oa, od, ref_path) - poa, pod = oa[:], od[:] - - # Run the MPC optimization: Create and solve the optimization problem - mpc_a, mpc_delta, mpc_x, mpc_y, mpc_yaw, mpc_v = self.mpc_prob_solve( - ref_path, path_predict, x0 - ) - - return mpc_a, mpc_delta, mpc_x, mpc_y, mpc_yaw, mpc_v, path_predict - -def main(args=None): - rclpy.init(args=args) - print("MPC Initialized") - mpc_node = MPC() - rclpy.spin(mpc_node) - - mpc_node.destroy_node() - rclpy.shutdown() diff --git a/controllers/controllers/obstaculosFTG.py b/controllers/controllers/obstaculosFTG.py deleted file mode 100644 index dea42d2..0000000 --- a/controllers/controllers/obstaculosFTG.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/env python3 - -import rclpy -from rclpy.node import Node -import numpy as np -import time -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped -from nav_msgs.msg import Odometry - -class ReactiveFollowGap(Node): - def __init__(self): - super().__init__('reactive_node') - - # Topics - lidarscan_topic = '/scan' - drive_topic = '/drive' - odom_topic = '/ego_racecar/odom' - - # Parámetros del algoritmo - self.base_speed = 4.0 # Velocidad base para moverse lentamente - self.max_speed = 5.0 # Velocidad máxima - self.min_speed = 3.0 # Velocidad mínima - self.max_lidar_range = 10 - self.bubble_radius_m = 2.0 # Aumentamos el radio de la burbuja de seguridad - self.min_clearance = 1.6 # Mayor clearance para buscar caminos más anchos - self.max_steering_angle = np.radians(30) - self.gap_threshold = 0.3 # Umbral reducido para aceptar gaps más estrechos - self.center_bias = 0.5 - self.speed_filter = self.base_speed - self.speed_filter_alpha = 0.7 - self.steering_filter = 0.0 - self.steering_filter_alpha = 0.8 - self.scan_initialized = False - self.scan_count = 0 - - # Control PID - self.kp_angle = 15 # Ganancia proporcional para el ángulo - self.ki_angle = 0.0 # Ganancia integral para el ángulo - self.kd_angle = 0.1 # Ganancia derivativa para el ángulo - - self.kp_speed = 0.02 # Ganancia proporcional para la velocidad - self.ki_speed = 0.0 # Ganancia integral para la velocidad - self.kd_speed = 0.1 # Ganancia derivativa para la velocidad - - self.last_error_angle = 0.0 - self.integral_angle = 0.0 - self.last_error_speed = 0.0 - self.integral_speed = 0.0 - - # Control de vueltas - self.lap_start_time = time.time() - self.lap_count = 0 - self.prev_in_start_zone = False - self.lap_times = [] - self.has_left_start_zone = False - - # Publishers & Subscribers - self.drive_pub = self.create_publisher(AckermannDriveStamped, drive_topic, 10) - self.scan_sub = self.create_subscription(LaserScan, lidarscan_topic, self.lidar_callback, 10) - self.odom_sub = self.create_subscription(Odometry, odom_topic, self.odom_callback, 10) - - self.get_logger().info("ReactiveFollowGap node initialized.") - - def preprocess_lidar(self, ranges): - #Preprocesa los datos del LiDAR: reemplaza valores inválidos y aplica un filtro - proc = np.array(ranges, dtype=np.float32) - invalid_mask = (proc == 0) | np.isinf(proc) | np.isnan(proc) - proc[invalid_mask] = self.max_lidar_range - proc = np.clip(proc, 0.1, self.max_lidar_range) - kernel = np.ones(3) / 3 - return np.convolve(proc, kernel, mode='same') - - def create_safety_bubble(self, ranges, closest_idx): - #Crea la burbuja de seguridad que ayuda a evitar obstaculos dentro del rango definido - bubble_ranges = np.copy(ranges) - angle_increment = 2 * np.pi / len(ranges) - bubble_radius_idx = int(self.bubble_radius_m / (ranges[closest_idx] * angle_increment)) - bubble_radius_idx = max(5, min(bubble_radius_idx, 20)) - start_idx = max(0, closest_idx - bubble_radius_idx) - end_idx = min(len(ranges) - 1, closest_idx + bubble_radius_idx) - bubble_ranges[start_idx:end_idx + 1] = 0.0 - return bubble_ranges - - def find_gaps(self, ranges): - #Detecta los huecos o gaps que el carrito puede usar para avanzar - free_mask = ranges >= self.min_clearance - gaps = [] - start_idx = None - for i, is_free in enumerate(free_mask): - if is_free and start_idx is None: - start_idx = i - elif not is_free and start_idx is not None: - gap_width_rad = (i - start_idx) * (2 * np.pi / len(ranges)) - gap_width_m = gap_width_rad * np.mean(ranges[start_idx:i]) - if gap_width_m >= self.gap_threshold: # Filtramos por el umbral de gap - gaps.append((start_idx, i - 1)) - start_idx = None - if start_idx is not None: - gap_width_rad = (len(free_mask) - start_idx) * (2 * np.pi / len(ranges)) - gap_width_m = gap_width_rad * np.mean(ranges[start_idx:]) - if gap_width_m >= self.gap_threshold: # Filtramos por el umbral de gap - gaps.append((start_idx, len(free_mask) - 1)) - return gaps - - def select_best_gap(self, gaps, ranges): - #Selecciona el mejor, el mas largo con espacio para cruzar, prioriza el gap mas largo - if not gaps: - return None - best_gap = None - best_score = -1 - center_idx = len(ranges) // 2 - for start_idx, end_idx in gaps: - gap_ranges = ranges[start_idx:end_idx + 1] - avg_distance = np.mean(gap_ranges) - max_distance = np.max(gap_ranges) - gap_width = end_idx - start_idx - gap_center = (start_idx + end_idx) // 2 - center_distance = abs(gap_center - center_idx) - distance_score = min(avg_distance / 5.0, 1.0) - width_score = min(gap_width / 50.0, 1.0) # Aumentamos la importancia del ancho - center_score = 1.0 - (center_distance / center_idx) * self.center_bias - total_score = (distance_score * 0.2 + width_score * 0.6 + center_score * 0.2) # Ajustamos peso - if total_score > best_score: - best_score = total_score - best_gap = (start_idx, end_idx) - return best_gap - - def get_target_point(self, start_idx, end_idx, ranges): - #Define un punto siguiente para que el carrito avance - if start_idx is None or end_idx is None: - return None - gap_ranges = ranges[start_idx:end_idx + 1] - max_dist_idx = np.argmax(gap_ranges) - target_idx = start_idx + max_dist_idx - gap_center = (start_idx + end_idx) // 2 - target_idx = gap_center # Centramos el robot en el gap más ancho - return target_idx - - def calculate_pid(self, error, last_error, integral, kp, ki, kd): - #Calcula el pid - integral += error - derivative = error - last_error - output = kp * error + ki * integral + kd * derivative - return output, integral - - def calculate_steering_angle(self, target_idx, scan_data): - #Obtiene el steering angle para acercarse al punto objetivo definido - if target_idx is None: - return 0.0 - target_angle = scan_data.angle_min + target_idx * scan_data.angle_increment - center_angle = scan_data.angle_min + (len(scan_data.ranges) // 2) * scan_data.angle_increment - error_angle = target_angle - center_angle - - # Aumentamos la ganancia proporcional si se detecta un obstáculo cerca - if abs(error_angle) > np.radians(10): # Si el error angular es grande, aumenta el giro - self.kp_angle = 1.5 # Aumentamos la ganancia proporcional para giros más rápidos - else: - self.kp_angle = 0.8 # Restablecemos la ganancia a su valor original si no hay obstáculo cercano - - # Calcular el control PID para el ángulo - steering_angle, self.integral_angle = self.calculate_pid(error_angle, self.last_error_angle, self.integral_angle, self.kp_angle, self.ki_angle, self.kd_angle) - self.last_error_angle = error_angle - - # Limitar el ángulo de dirección para evitar giros bruscos - return np.clip(steering_angle, -self.max_steering_angle, self.max_steering_angle) - - def calculate_speed(self, ranges, steering_angle): - #Adapta la velocidad adecuada del carrito - center_idx = len(ranges) // 2 - front_range = int(np.radians(30) / (2 * np.pi / len(ranges))) - front_distances = ranges[max(0, center_idx - front_range):min(len(ranges), center_idx + front_range)] - min_front_distance = np.min(front_distances) - avg_front_distance = np.mean(front_distances) - - # Ajuste de la velocidad con PID para evitar retrocesos - speed_error = avg_front_distance - 2.0 # Queremos mantener al menos 2 metros de distancia - speed, self.integral_speed = self.calculate_pid(speed_error, self.last_error_speed, self.integral_speed, self.kp_speed, self.ki_speed, self.kd_speed) - self.last_error_speed = speed_error - - # Limitar la velocidad y asegurarse que no retroceda - speed = max(self.min_speed, speed) # Aseguramos que la velocidad no sea menor a un mínimo - return np.clip(speed, self.min_speed, self.max_speed) - - def lidar_callback(self, data): - #Llama la informacion del lidar - self.scan_count += 1 - if self.scan_count < 5: - return - - ranges = self.preprocess_lidar(data.ranges) - closest_idx = np.argmin(ranges) - closest_distance = ranges[closest_idx] - - # Crear burbuja de seguridad solo si es necesario - bubble_ranges = (self.create_safety_bubble(ranges, closest_idx) - if closest_distance < 1.5 else ranges) - - gaps = self.find_gaps(bubble_ranges) - best_gap = self.select_best_gap(gaps, ranges) - - drive_msg = AckermannDriveStamped() - drive_msg.header.stamp = self.get_clock().now().to_msg() - drive_msg.header.frame_id = "base_link" - - if best_gap is not None: - start_idx, end_idx = best_gap - target_idx = self.get_target_point(start_idx, end_idx, ranges) - - if target_idx is not None: - steering_angle = self.calculate_steering_angle(target_idx, data) - speed = self.calculate_speed(ranges, steering_angle) - else: - speed = self.min_speed - steering_angle = 0.0 - else: - speed = self.min_speed - steering_angle = np.radians(10) - - drive_msg.drive.speed = float(speed) - drive_msg.drive.steering_angle = float(steering_angle) - self.drive_pub.publish(drive_msg) - - def odom_callback(self, msg): - #Llama la informacion de odometria del carrito - x = msg.pose.pose.position.x - y = msg.pose.pose.position.y - - # Zona de inicio - in_start_zone = (abs(x) < 2.0 and abs(y) < 2.0) - - #Contador de vueltas - if in_start_zone and not self.prev_in_start_zone and self.has_left_start_zone: - lap_end_time = time.time() - lap_duration = lap_end_time - self.lap_start_time - self.lap_times.append(lap_duration) - self.lap_count += 1 - - self.get_logger().info(f"🏁 Vuelta {self.lap_count} completada en {lap_duration:.2f} s.") - self.lap_start_time = lap_end_time - - - # Marcar que ya ha salido de la zona al menos una vez - if not in_start_zone: - self.has_left_start_zone = True - - # Guardar estado anterior - self.prev_in_start_zone = in_start_zone - - -def main(args=None): - rclpy.init(args=args) - node = ReactiveFollowGap() - try: - rclpy.spin(node) - except KeyboardInterrupt: - node.get_logger().info("Node stopped cleanly") - finally: - node.destroy_node() - rclpy.shutdown() - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/obstaculosWF.py b/controllers/controllers/obstaculosWF.py deleted file mode 100644 index c6d77c7..0000000 --- a/controllers/controllers/obstaculosWF.py +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/env python3 - -import rclpy -from rclpy.node import Node -import numpy as np -import time -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped -from nav_msgs.msg import Odometry - -class WallFollower(Node): - def __init__(self): - super().__init__('wall_follower_node') - - # Topics - lidarscan_topic = '/scan' - drive_topic = '/drive' - odom_topic = '/ego_racecar/odom' - - # Parámetros del algoritmo de seguimiento de pared - self.max_speed = 2.5 # Velocidad máxima reducida a la mitad - self.min_speed = 1.5 # Velocidad mínima ajustada - self.max_lidar_range = 10.0 - self.wall_distance_ref = 1.5 # Distancia de referencia a la pared aumentada a 2 metros - - # PID para el ángulo - self.steering_pid_kp = 0.7 - self.steering_pid_ki = 0.0 - self.steering_pid_kd = 0.1 - self.last_error_angle = 0.0 - self.integral_angle = 0.0 - - # PID para la velocidad - self.speed_pid_kp = 0.05 - self.speed_pid_ki = 0.0 - self.speed_pid_kd = 0.01 - self.last_error_speed = 0.0 - self.integral_speed = 0.0 - - # Control de vueltas (se mantiene sin cambios) - self.lap_start_time = time.time() - self.lap_count = 0 - self.prev_in_start_zone = False - self.lap_times = [] - self.has_left_start_zone = False - - # Publishers & Subscribers - self.drive_pub = self.create_publisher(AckermannDriveStamped, drive_topic, 10) - self.scan_sub = self.create_subscription(LaserScan, lidarscan_topic, self.lidar_callback, 10) - self.odom_sub = self.create_subscription(Odometry, odom_topic, self.odom_callback, 10) - - self.get_logger().info("WallFollower node initialized.") - - def preprocess_lidar(self, ranges): - #Preprocesa los datos del LiDAR: reemplaza valores inválidos y aplica un filtro - proc = np.array(ranges, dtype=np.float32) - invalid_mask = (proc == 0) | np.isinf(proc) | np.isnan(proc) - proc[invalid_mask] = self.max_lidar_range - proc = np.clip(proc, 0.1, self.max_lidar_range) - kernel = np.ones(3) / 3 - return np.convolve(proc, kernel, mode='same') - - def select_cleanest_wall(self, ranges, angle_increment): - #Selecciona el lado con la pared más 'limpia' (menos protuberancias) - num_ranges = len(ranges) - mid_idx = num_ranges // 2 - - # Rango de ángulos para considerar los lados derecho e izquierdo - angle_range_deg = 45 - points_to_check = int(np.radians(angle_range_deg) / angle_increment) - - right_ranges = ranges[mid_idx - points_to_check : mid_idx] - left_ranges = ranges[mid_idx : mid_idx + points_to_check] - - # Calcular la desviación estándar para cada lado - std_dev_right = np.std(right_ranges) - std_dev_left = np.std(left_ranges) - - # Si el lado derecho es más 'limpio' (menor desviación), lo seguimos. - if std_dev_right < std_dev_left: - return 'right', right_ranges - else: - return 'left', left_ranges - - def calculate_pid(self, error, last_error, integral, kp, ki, kd): - #Calculo de PID - integral += error - derivative = error - last_error - output = kp * error + ki * integral + kd * derivative - return output, integral - - def get_wall_following_angle(self, side_to_follow, side_ranges): - #Obtiene el angulo necesario para seguir la pared con menos obstaculos detectable - avg_dist = np.mean(side_ranges) - error = self.wall_distance_ref - avg_dist - - steering_angle, self.integral_angle = self.calculate_pid( - error, self.last_error_angle, self.integral_angle, - self.steering_pid_kp, self.steering_pid_ki, self.steering_pid_kd - ) - self.last_error_angle = error - - if side_to_follow == 'left': - steering_angle = -steering_angle - - return np.clip(steering_angle, -0.5, 0.5) - - def calculate_speed(self, ranges, steering_angle): - #Ajusta la velocidad en función de la distancia frontal y el ángulo de dirección - # Reducir la velocidad en curvas cerradas - speed = self.max_speed - abs(steering_angle) * 1.5 - - # Usa PID para ajustar la velocidad según la distancia frontal - front_range = int(np.radians(20) / (2 * np.pi / len(ranges))) - front_distances = ranges[len(ranges) // 2 - front_range : len(ranges) // 2 + front_range] - min_front_distance = np.min(front_distances) - - speed_error = min_front_distance - 2.0 - speed_adjustment, self.integral_speed = self.calculate_pid( - speed_error, self.last_error_speed, self.integral_speed, - self.speed_pid_kp, self.speed_pid_ki, self.speed_pid_kd - ) - self.last_error_speed = speed_error - - speed += speed_adjustment - - return np.clip(speed, self.min_speed, self.max_speed) - - def lidar_callback(self, data): - ranges = self.preprocess_lidar(data.ranges) - - # Seleccionar la pared más 'limpia' - side_to_follow, side_ranges = self.select_cleanest_wall(ranges, data.angle_increment) - - # Calcular ángulo y velocidad - steering_angle = self.get_wall_following_angle(side_to_follow, side_ranges) - speed = self.calculate_speed(ranges, steering_angle) - - drive_msg = AckermannDriveStamped() - drive_msg.header.stamp = self.get_clock().now().to_msg() - drive_msg.header.frame_id = "base_link" - drive_msg.drive.speed = float(speed) - drive_msg.drive.steering_angle = float(steering_angle) - - self.drive_pub.publish(drive_msg) - - def odom_callback(self, msg): - x = msg.pose.pose.position.x - y = msg.pose.pose.position.y - - in_start_zone = (abs(x) < 2.0 and abs(y) < 2.0) - - if in_start_zone and not self.prev_in_start_zone and self.has_left_start_zone: - lap_end_time = time.time() - lap_duration = lap_end_time - self.lap_start_time - self.lap_times.append(lap_duration) - self.lap_count += 1 - self.get_logger().info(f"🏁 Vuelta {self.lap_count} completada en {lap_duration:.2f} s.") - self.lap_start_time = lap_end_time - - - if not in_start_zone: - self.has_left_start_zone = True - - self.prev_in_start_zone = in_start_zone - -def main(args=None): - rclpy.init(args=args) - node = WallFollower() - try: - rclpy.spin(node) - except KeyboardInterrupt: - node.get_logger().info("Node stopped cleanly") - finally: - node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/pid_node.py b/controllers/controllers/pid_node.py deleted file mode 100644 index 3b651d4..0000000 --- a/controllers/controllers/pid_node.py +++ /dev/null @@ -1,108 +0,0 @@ -import rclpy -from rclpy.node import Node - -import numpy as np -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped - -class WallFollow(Node): - """ - Implement Wall Following on the car - """ - def __init__(self): - super().__init__('wall_follow_node') - - lidarscan_topic = '/scan' - drive_topic = '/drive' - - # TODO: create subscribers and publishers - - # TODO: set PID gains - # self.kp = - # self.kd = - # self.ki = - - # TODO: store history - # self.integral = - # self.prev_error = - # self.error = - - # TODO: store any necessary values you think you'll need - - def get_range(self, range_data, angle): - """ - Simple helper to return the corresponding range measurement at a given angle. Make sure you take care of NaNs and infs. - - Args: - range_data: single range array from the LiDAR - angle: between angle_min and angle_max of the LiDAR - - Returns: - range: range measurement in meters at the given angle - - """ - - #TODO: implement - return 0.0 - - def get_error(self, range_data, dist): - """ - Calculates the error to the wall. Follow the wall to the left (going counter clockwise in the Levine loop). You potentially will need to use get_range() - - Args: - range_data: single range array from the LiDAR - dist: desired distance to the wall - - Returns: - error: calculated error - """ - - #TODO:implement - return 0.0 - - def pid_control(self, error, velocity): - """ - Based on the calculated error, publish vehicle control - - Args: - error: calculated error - velocity: desired velocity - - Returns: - None - """ - angle = 0.0 - # TODO: Use kp, ki & kd to implement a PID controller - drive_msg = AckermannDriveStamped() - # TODO: fill in drive message and publish - - def scan_callback(self, msg): - """ - Callback function for LaserScan messages. Calculate the error and publish the drive message in this function. - - Args: - msg: Incoming LaserScan message - - Returns: - None - """ - error = 0.0 # TODO: replace with error calculated by get_error() - velocity = 0.0 # TODO: calculate desired car velocity based on error - self.pid_control(error, velocity) # TODO: actuate the car with PID - - -def main(args=None): - rclpy.init(args=args) - print("WallFollow Initialized") - wall_follow_node = WallFollow() - rclpy.spin(wall_follow_node) - - # Destroy the node explicitly - # (optional - otherwise it will be done automatically - # when the garbage collector destroys the node object) - wall_follow_node.destroy_node() - rclpy.shutdown() - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/proyectoFTG.py b/controllers/controllers/proyectoFTG.py deleted file mode 100644 index d54c607..0000000 --- a/controllers/controllers/proyectoFTG.py +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env python3 - -import rclpy -from rclpy.node import Node -import numpy as np -import time -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped -from nav_msgs.msg import Odometry - -class ReactiveFollowGap(Node): - def __init__(self): - super().__init__('reactive_node') - - # Topics - lidarscan_topic = '/scan' - drive_topic = '/drive' - odom_topic = '/ego_racecar/odom' - - # Parámetros del algoritmo - self.base_speed = 4.0 # Velocidad base para moverse lentamente - self.max_speed = 5.0 # Velocidad máxima - self.min_speed = 3.0 # Velocidad mínima - self.max_lidar_range = 10 - self.bubble_radius_m = 2.0 # Aumentamos el radio de la burbuja de seguridad - self.min_clearance = 1.6 # Mayor clearance para buscar caminos más anchos - self.max_steering_angle = np.radians(30) - self.gap_threshold = 0.3 # Umbral reducido para aceptar gaps más estrechos - self.center_bias = 0.5 - self.speed_filter = self.base_speed - self.speed_filter_alpha = 0.7 - self.steering_filter = 0.0 - self.steering_filter_alpha = 0.8 - self.scan_initialized = False - self.scan_count = 0 - - # Control PID - self.kp_angle = 15 # Ganancia proporcional para el ángulo - self.ki_angle = 0.0 # Ganancia integral para el ángulo - self.kd_angle = 0.1 # Ganancia derivativa para el ángulo - - self.kp_speed = 0.02 # Ganancia proporcional para la velocidad - self.ki_speed = 0.0 # Ganancia integral para la velocidad - self.kd_speed = 0.1 # Ganancia derivativa para la velocidad - - self.last_error_angle = 0.0 - self.integral_angle = 0.0 - self.last_error_speed = 0.0 - self.integral_speed = 0.0 - - # Control de vueltas - self.lap_start_time = time.time() - self.lap_count = 0 - self.prev_in_start_zone = False - self.lap_times = [] - self.has_left_start_zone = False - - # Publishers & Subscribers - self.drive_pub = self.create_publisher(AckermannDriveStamped, drive_topic, 10) - self.scan_sub = self.create_subscription(LaserScan, lidarscan_topic, self.lidar_callback, 10) - self.odom_sub = self.create_subscription(Odometry, odom_topic, self.odom_callback, 10) - - self.get_logger().info("ReactiveFollowGap node initialized.") - - def preprocess_lidar(self, ranges): - proc = np.array(ranges, dtype=np.float32) - invalid_mask = (proc == 0) | np.isinf(proc) | np.isnan(proc) - proc[invalid_mask] = self.max_lidar_range - proc = np.clip(proc, 0.1, self.max_lidar_range) - kernel = np.ones(3) / 3 - return np.convolve(proc, kernel, mode='same') - - def create_safety_bubble(self, ranges, closest_idx): - bubble_ranges = np.copy(ranges) - angle_increment = 2 * np.pi / len(ranges) - bubble_radius_idx = int(self.bubble_radius_m / (ranges[closest_idx] * angle_increment)) - bubble_radius_idx = max(5, min(bubble_radius_idx, 20)) - start_idx = max(0, closest_idx - bubble_radius_idx) - end_idx = min(len(ranges) - 1, closest_idx + bubble_radius_idx) - bubble_ranges[start_idx:end_idx + 1] = 0.0 - return bubble_ranges - - def find_gaps(self, ranges): - free_mask = ranges >= self.min_clearance - gaps = [] - start_idx = None - for i, is_free in enumerate(free_mask): - if is_free and start_idx is None: - start_idx = i - elif not is_free and start_idx is not None: - gap_width_rad = (i - start_idx) * (2 * np.pi / len(ranges)) - gap_width_m = gap_width_rad * np.mean(ranges[start_idx:i]) - if gap_width_m >= self.gap_threshold: # Filtramos por el umbral de gap - gaps.append((start_idx, i - 1)) - start_idx = None - if start_idx is not None: - gap_width_rad = (len(free_mask) - start_idx) * (2 * np.pi / len(ranges)) - gap_width_m = gap_width_rad * np.mean(ranges[start_idx:]) - if gap_width_m >= self.gap_threshold: # Filtramos por el umbral de gap - gaps.append((start_idx, len(free_mask) - 1)) - return gaps - - def select_best_gap(self, gaps, ranges): - if not gaps: - return None - best_gap = None - best_score = -1 - center_idx = len(ranges) // 2 - for start_idx, end_idx in gaps: - gap_ranges = ranges[start_idx:end_idx + 1] - avg_distance = np.mean(gap_ranges) - max_distance = np.max(gap_ranges) - gap_width = end_idx - start_idx - gap_center = (start_idx + end_idx) // 2 - center_distance = abs(gap_center - center_idx) - distance_score = min(avg_distance / 5.0, 1.0) - width_score = min(gap_width / 50.0, 1.0) # Aumentamos la importancia del ancho - center_score = 1.0 - (center_distance / center_idx) * self.center_bias - total_score = (distance_score * 0.2 + width_score * 0.6 + center_score * 0.2) # Ajustamos peso - if total_score > best_score: - best_score = total_score - best_gap = (start_idx, end_idx) - return best_gap - - def get_target_point(self, start_idx, end_idx, ranges): - if start_idx is None or end_idx is None: - return None - gap_ranges = ranges[start_idx:end_idx + 1] - max_dist_idx = np.argmax(gap_ranges) - target_idx = start_idx + max_dist_idx - gap_center = (start_idx + end_idx) // 2 - target_idx = gap_center # Centramos el robot en el gap más ancho - return target_idx - - def calculate_pid(self, error, last_error, integral, kp, ki, kd): - integral += error - derivative = error - last_error - output = kp * error + ki * integral + kd * derivative - return output, integral - - def calculate_steering_angle(self, target_idx, scan_data): - if target_idx is None: - return 0.0 - target_angle = scan_data.angle_min + target_idx * scan_data.angle_increment - center_angle = scan_data.angle_min + (len(scan_data.ranges) // 2) * scan_data.angle_increment - error_angle = target_angle - center_angle - - # Aumentamos la ganancia proporcional si se detecta un obstáculo cerca - if abs(error_angle) > np.radians(10): # Si el error angular es grande, aumentar el giro - self.kp_angle = 1.5 # Aumentamos la ganancia proporcional para giros más rápidos - else: - self.kp_angle = 0.8 # Restablecemos la ganancia a su valor original si no hay obstáculo cercano - - # Calcular el control PID para el ángulo - steering_angle, self.integral_angle = self.calculate_pid(error_angle, self.last_error_angle, self.integral_angle, self.kp_angle, self.ki_angle, self.kd_angle) - self.last_error_angle = error_angle - - # Limitar el ángulo de dirección para evitar giros bruscos - return np.clip(steering_angle, -self.max_steering_angle, self.max_steering_angle) - - def calculate_speed(self, ranges, steering_angle): - center_idx = len(ranges) // 2 - front_range = int(np.radians(30) / (2 * np.pi / len(ranges))) - front_distances = ranges[max(0, center_idx - front_range):min(len(ranges), center_idx + front_range)] - min_front_distance = np.min(front_distances) - avg_front_distance = np.mean(front_distances) - - # Ajuste de la velocidad con PID para evitar retrocesos - speed_error = avg_front_distance - 2.0 # Queremos mantener al menos 2 metros de distancia - speed, self.integral_speed = self.calculate_pid(speed_error, self.last_error_speed, self.integral_speed, self.kp_speed, self.ki_speed, self.kd_speed) - self.last_error_speed = speed_error - - # Limitar la velocidad y asegurarse que no retroceda - speed = max(self.min_speed, speed) # Aseguramos que la velocidad no sea menor a un mínimo - return np.clip(speed, self.min_speed, self.max_speed) - - def lidar_callback(self, data): - self.scan_count += 1 - if self.scan_count < 5: - return - - ranges = self.preprocess_lidar(data.ranges) - closest_idx = np.argmin(ranges) - closest_distance = ranges[closest_idx] - - # Crear burbuja de seguridad solo si es necesario - bubble_ranges = (self.create_safety_bubble(ranges, closest_idx) - if closest_distance < 1.5 else ranges) - - gaps = self.find_gaps(bubble_ranges) - best_gap = self.select_best_gap(gaps, ranges) - - drive_msg = AckermannDriveStamped() - drive_msg.header.stamp = self.get_clock().now().to_msg() - drive_msg.header.frame_id = "base_link" - - if best_gap is not None: - start_idx, end_idx = best_gap - target_idx = self.get_target_point(start_idx, end_idx, ranges) - - if target_idx is not None: - steering_angle = self.calculate_steering_angle(target_idx, data) - speed = self.calculate_speed(ranges, steering_angle) - else: - speed = self.min_speed - steering_angle = 0.0 - else: - speed = self.min_speed - steering_angle = np.radians(10) - - drive_msg.drive.speed = float(speed) - drive_msg.drive.steering_angle = float(steering_angle) - self.drive_pub.publish(drive_msg) - - def odom_callback(self, msg): - x = msg.pose.pose.position.x - y = msg.pose.pose.position.y - - # Zona de inicio - in_start_zone = (abs(x) < 2.0 and abs(y) < 2.0) - - # Solo cuenta vuelta si: - # - Ya salió de la zona alguna vez - # - Y acaba de volver a entrar - if in_start_zone and not self.prev_in_start_zone and self.has_left_start_zone: - lap_end_time = time.time() - lap_duration = lap_end_time - self.lap_start_time - self.lap_times.append(lap_duration) - self.lap_count += 1 - - self.get_logger().info(f"🏁 Vuelta {self.lap_count} completada en {lap_duration:.2f} s.") - self.lap_start_time = lap_end_time - - if self.lap_count == 10: - self.get_logger().info(f"Número de vueltas requerido alcanzado ({self.lap_count})") - shortest = min(self.lap_times) - self.get_logger().info(f"Tiempo de vuelta más corto: {shortest:.2f} segundos") - - # Marcar que ya ha salido de la zona al menos una vez - if not in_start_zone: - self.has_left_start_zone = True - - # Guardar estado anterior - self.prev_in_start_zone = in_start_zone - - -def main(args=None): - rclpy.init(args=args) - node = ReactiveFollowGap() - try: - rclpy.spin(node) - except KeyboardInterrupt: - node.get_logger().info("Node stopped cleanly") - finally: - node.destroy_node() - rclpy.shutdown() - - -if __name__ == '__main__': - main() - diff --git a/controllers/controllers/proyectoObstaculos.py b/controllers/controllers/proyectoObstaculos.py deleted file mode 100644 index 5f766ef..0000000 --- a/controllers/controllers/proyectoObstaculos.py +++ /dev/null @@ -1,404 +0,0 @@ -#!/usr/bin/env python3 - -import rclpy -from rclpy.node import Node -import numpy as np -import time -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped -from nav_msgs.msg import Odometry - -class ReactiveFollowGap(Node): - def __init__(self): - super().__init__('reactive_node') - - # Topics - lidarscan_topic = '/scan' - drive_topic = '/drive' - odom_topic = '/ego_racecar/odom' - - # Parámetros AGRESIVOS para pasillos estrechos - self.base_speed = 4.0 # Velocidad base más conservadora para control - self.max_speed = 8.0 # Velocidad máxima reducida para mejor control - self.min_speed = 1.0 # Velocidad mínima más baja - self.max_lidar_range = 10.0 - self.bubble_radius_m = 0.3 # Radio muy pequeño - MUY AGRESIVO - self.min_clearance = 0.6 # Clearance mínimo muy reducido - AGRESIVO - self.max_steering_angle = np.radians(45) # Ángulo máximo aumentado - self.gap_threshold = 0.15 # Threshold muy pequeño para gaps estrechos - self.center_bias = 0.1 # Bias mínimo - seguir el gap más grande - - # Filtros más responsivos - self.speed_filter = self.base_speed - self.speed_filter_alpha = 0.3 # MUY responsive - self.steering_filter = 0.0 - self.steering_filter_alpha = 0.4 # MUY responsive - - # Control de escaneado - self.scan_initialized = False - self.scan_count = 0 - - # Variables para evitar bucles - self.stuck_counter = 0 - self.position_history = [] - self.last_positions = [] - self.stuck_threshold = 20 # Número de scans para detectar si está atascado - self.escape_mode = False - self.escape_direction = 1 # 1 para derecha, -1 para izquierda - self.escape_counter = 0 - - # Variables para detección de progreso - self.prev_position = None - self.movement_threshold = 0.1 # Movimiento mínimo para no considerarse atascado - - # Control de vueltas - self.lap_start_time = time.time() - self.lap_count = 0 - self.prev_in_start_zone = False - self.lap_times = [] - self.has_left_start_zone = False - - # Publishers & Subscribers - self.drive_pub = self.create_publisher(AckermannDriveStamped, drive_topic, 10) - self.scan_sub = self.create_subscription(LaserScan, lidarscan_topic, self.lidar_callback, 10) - self.odom_sub = self.create_subscription(Odometry, odom_topic, self.odom_callback, 10) - - self.get_logger().info("AGGRESSIVE ReactiveFollowGap initialized for narrow passages.") - - def preprocess_lidar(self, ranges): - """Preprocesamiento mínimo para mantener detalles en pasillos estrechos""" - proc = np.array(ranges, dtype=np.float32) - - # Manejo de valores inválidos - invalid_mask = (proc == 0) | np.isinf(proc) | np.isnan(proc) - proc[invalid_mask] = self.max_lidar_range - proc = np.clip(proc, 0.05, self.max_lidar_range) # Permitir lecturas muy cercanas - - # Filtrado MUY suave para preservar detalles - kernel = np.array([0.1, 0.8, 0.1]) # Filtro muy suave - proc = np.convolve(proc, kernel, mode='same') - - return proc - - def create_safety_bubble(self, ranges, closest_idx): - """Burbuja de seguridad MÍNIMA - solo para obstáculos muy cercanos""" - bubble_ranges = np.copy(ranges) - - if closest_idx is None or closest_idx >= len(ranges): - return bubble_ranges - - closest_distance = ranges[closest_idx] - - # Solo crear burbuja si está MUY cerca - if closest_distance > 0.4: - return bubble_ranges - - # Burbuja muy pequeña - angle_increment = 2 * np.pi / len(ranges) - bubble_radius_idx = max(1, int(self.bubble_radius_m / (closest_distance * angle_increment + 0.01))) - bubble_radius_idx = min(bubble_radius_idx, 5) # Máximo 5 puntos - - start_idx = max(0, closest_idx - bubble_radius_idx) - end_idx = min(len(ranges) - 1, closest_idx + bubble_radius_idx) - - # Burbuja sin degradado - directa - bubble_ranges[start_idx:end_idx + 1] = 0.0 - - return bubble_ranges - - def find_gaps(self, ranges): - """Detección de gaps ULTRA AGRESIVA""" - # Clearance muy pequeño - free_mask = ranges >= self.min_clearance - gaps = [] - start_idx = None - - for i, is_free in enumerate(free_mask): - if is_free and start_idx is None: - start_idx = i - elif not is_free and start_idx is not None: - # Cualquier gap, por pequeño que sea - gaps.append((start_idx, i - 1)) - start_idx = None - - # Manejar gap que termina al final del array - if start_idx is not None: - gaps.append((start_idx, len(free_mask) - 1)) - - return gaps - - def select_best_gap(self, ranges): - """Selección de gap SIMPLIFICADA - el más grande y más lejano""" - gaps = self.find_gaps(ranges) - - if not gaps: - return None - - best_gap = None - best_score = -1 - - for start_idx, end_idx in gaps: - gap_width = end_idx - start_idx + 1 - gap_ranges = ranges[start_idx:end_idx + 1] - avg_distance = np.mean(gap_ranges) - - # Score simple: tamaño del gap * distancia promedio - score = gap_width * avg_distance - - if score > best_score: - best_score = score - best_gap = (start_idx, end_idx) - - return best_gap - - def get_target_point(self, start_idx, end_idx, ranges): - """Punto objetivo en el CENTRO del gap más profundo""" - if start_idx is None or end_idx is None: - return None - - gap_ranges = ranges[start_idx:end_idx + 1] - - # Encontrar el punto más lejano en el gap - max_dist_idx = np.argmax(gap_ranges) - target_idx = start_idx + max_dist_idx - - return target_idx - - def calculate_steering_angle(self, target_idx, scan_data): - """Cálculo de ángulo DIRECTO y AGRESIVO""" - if target_idx is None: - return 0.0 - - target_angle = scan_data.angle_min + target_idx * scan_data.angle_increment - center_angle = scan_data.angle_min + (len(scan_data.ranges) // 2) * scan_data.angle_increment - - # Ángulo directo sin mucho filtrado - steering_angle = (target_angle - center_angle) * 1.2 # Factor agresivo - - # Filtrado mínimo - steering_angle = (self.steering_filter_alpha * self.steering_filter + - (1 - self.steering_filter_alpha) * steering_angle) - self.steering_filter = steering_angle - - return np.clip(steering_angle, -self.max_steering_angle, self.max_steering_angle) - - def check_if_stuck(self, current_position): - """Detecta si el vehículo está atascado en un bucle""" - if current_position is None: - return False - - # Agregar posición actual al historial - self.position_history.append(current_position) - - # Mantener solo las últimas posiciones - if len(self.position_history) > self.stuck_threshold: - self.position_history.pop(0) - - # Si no tenemos suficiente historial, no está atascado - if len(self.position_history) < self.stuck_threshold: - return False - - # Calcular la varianza de posiciones - positions = np.array(self.position_history) - x_variance = np.var(positions[:, 0]) - y_variance = np.var(positions[:, 1]) - - # Si la varianza es muy pequeña, está atascado - total_variance = x_variance + y_variance - stuck = total_variance < 0.5 # Threshold para considerar que está atascado - - if stuck: - self.stuck_counter += 1 - else: - self.stuck_counter = 0 - - return self.stuck_counter > 5 - - def escape_behavior(self, ranges): - """Comportamiento de escape cuando está atascado""" - center_idx = len(ranges) // 2 - - # Analizar espacios a los lados - left_quarter = ranges[:center_idx//2] - right_quarter = ranges[-center_idx//2:] - - left_space = np.mean(left_quarter[left_quarter > 0.1]) - right_space = np.mean(right_quarter[right_quarter > 0.1]) - - # Elegir la dirección con más espacio - if left_space > right_space: - self.escape_direction = 1 # Izquierda - steering_angle = np.radians(35) - else: - self.escape_direction = -1 # Derecha - steering_angle = np.radians(-35) - - # Velocidad baja pero constante para el escape - speed = 2.0 - - self.get_logger().info(f"ESCAPE MODE: Going {'LEFT' if self.escape_direction == 1 else 'RIGHT'}") - - return speed, steering_angle - - def calculate_speed(self, ranges, steering_angle): - """Cálculo de velocidad AGRESIVO para pasillos estrechos""" - center_idx = len(ranges) // 2 - front_range = int(np.radians(20) / (2 * np.pi / len(ranges))) - - front_distances = ranges[max(0, center_idx - front_range): - min(len(ranges), center_idx + front_range)] - - min_front = np.min(front_distances) - avg_front = np.mean(front_distances) - - # Velocidad agresiva basada en distancia frontal - if min_front < 0.3: - target_speed = 0.5 # Muy cerca - casi parar - elif min_front < 0.6: - target_speed = 1.5 # Cerca - velocidad baja - elif min_front < 1.2: - target_speed = 2.5 # Media distancia - elif avg_front > 2.0: - target_speed = self.max_speed # Camino libre - acelerar - else: - target_speed = self.base_speed - - # Reducir velocidad menos por ángulo de dirección - angle_penalty = (abs(steering_angle) / self.max_steering_angle) * 0.2 - target_speed *= (1.0 - angle_penalty) - - target_speed = np.clip(target_speed, self.min_speed, self.max_speed) - - # Filtrado muy responsive - self.speed_filter = (self.speed_filter_alpha * self.speed_filter + - (1 - self.speed_filter_alpha) * target_speed) - - return self.speed_filter - - def lidar_callback(self, data): - """Callback principal con manejo de situaciones de atasco""" - self.scan_count += 1 - if self.scan_count < 2: # Inicialización rápida - return - - ranges = self.preprocess_lidar(data.ranges) - - # Preparar mensaje de drive - drive_msg = AckermannDriveStamped() - drive_msg.header.stamp = self.get_clock().now().to_msg() - drive_msg.header.frame_id = "base_link" - - # Verificar si está en modo escape - if self.escape_mode: - speed, steering_angle = self.escape_behavior(ranges) - self.escape_counter += 1 - - # Salir del modo escape después de un tiempo - if self.escape_counter > 30: # ~3 segundos - self.escape_mode = False - self.escape_counter = 0 - self.stuck_counter = 0 - self.position_history.clear() - self.get_logger().info("Exiting ESCAPE MODE") - - else: - # Comportamiento normal - closest_idx = np.argmin(ranges) - closest_distance = ranges[closest_idx] - - # Burbuja de seguridad mínima - if closest_distance < 0.3: - bubble_ranges = self.create_safety_bubble(ranges, closest_idx) - else: - bubble_ranges = ranges - - # Encontrar el mejor gap - best_gap = self.select_best_gap(bubble_ranges) - - if best_gap is not None: - start_idx, end_idx = best_gap - target_idx = self.get_target_point(start_idx, end_idx, ranges) - - if target_idx is not None: - steering_angle = self.calculate_steering_angle(target_idx, data) - speed = self.calculate_speed(ranges, steering_angle) - else: - speed = self.min_speed - steering_angle = 0.0 - else: - # No hay gaps - buscar el lado con más espacio - center_idx = len(ranges) // 2 - left_space = np.mean(ranges[:center_idx]) - right_space = np.mean(ranges[center_idx:]) - - speed = 1.5 - if left_space > right_space: - steering_angle = np.radians(25) - else: - steering_angle = np.radians(-25) - - self.get_logger().info(f"No gaps found. Turning {'LEFT' if left_space > right_space else 'RIGHT'}") - - # Verificar frenado de emergencia - center_idx = len(ranges) // 2 - emergency_range = int(np.radians(15) / (2 * np.pi / len(ranges))) - emergency_distances = ranges[max(0, center_idx - emergency_range): - min(len(ranges), center_idx + emergency_range)] - - if np.min(emergency_distances) < 0.2: # Obstáculo muy muy cerca - speed = 0.0 - self.get_logger().warn("EMERGENCY BRAKE!") - - drive_msg.drive.speed = float(speed) - drive_msg.drive.steering_angle = float(steering_angle) - self.drive_pub.publish(drive_msg) - - def odom_callback(self, msg): - """Callback de odometría con detección de atasco""" - x = msg.pose.pose.position.x - y = msg.pose.pose.position.y - current_position = (x, y) - - # Verificar si está atascado - if self.check_if_stuck(current_position) and not self.escape_mode: - self.escape_mode = True - self.escape_counter = 0 - self.get_logger().warn("STUCK DETECTED! Activating ESCAPE MODE") - - # Control de vueltas (zona de inicio ajustada) - in_start_zone = (abs(x) < 2.0 and abs(y) < 2.0) - - if in_start_zone and not self.prev_in_start_zone and self.has_left_start_zone: - lap_end_time = time.time() - lap_duration = lap_end_time - self.lap_start_time - self.lap_times.append(lap_duration) - self.lap_count += 1 - - self.get_logger().info(f"🏁 Vuelta {self.lap_count} completada en {lap_duration:.2f} s.") - - if self.lap_times: - best_time = min(self.lap_times) - self.get_logger().info(f"Mejor tiempo: {best_time:.2f}s") - - self.lap_start_time = lap_end_time - - if not in_start_zone: - self.has_left_start_zone = True - - self.prev_in_start_zone = in_start_zone - - -def main(args=None): - rclpy.init(args=args) - node = ReactiveFollowGap() - try: - rclpy.spin(node) - except KeyboardInterrupt: - node.get_logger().info("Node stopped cleanly") - finally: - node.destroy_node() - rclpy.shutdown() - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/proyectoRob.py b/controllers/controllers/proyectoRob.py deleted file mode 100644 index ce1f7c5..0000000 --- a/controllers/controllers/proyectoRob.py +++ /dev/null @@ -1,147 +0,0 @@ -import rclpy -from rclpy.node import Node -import numpy as np -import math -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped -from std_msgs.msg import String -from nav_msgs.msg import Odometry - -class FollowGapCarrera(Node): - def __init__(self): - super().__init__('follow_gap_carrera_node') - - self.VELOCIDAD_MAXIMA = 8.2 - self.VELOCIDAD_MINIMA = 3.5 - self.FACTOR_REDUCCION_CURVA = 1.2 - self.DISTANCIA_MAX_LIDAR = 3.5 - self.RADIO_BURBUJA = 0.25 - self.ANGULO_MAX_DIRECCION = np.radians(20) - self.PUNTO_LEJANO_BIAS = 0.8 - self.SUAVIZADO_DIRECCION = 0.9 - self.ultimo_angulo_direccion = 0.0 - - self.FINISH_LINE_X = 0.00 - self.FINISH_LINE_Y = 0.00 - self.FINISH_LINE_Y_RANGE = 5.0 - self.MIN_DISTANCE_TO_ARM = 0.2 - - self.last_pose = None - self.can_count_lap = True - self.race_started = True - - self.lap_publisher = self.create_publisher(String, '/lap_trigger', 10) - self.odom_sub = self.create_subscription(Odometry, '/ego_racecar/odom', self.odom_callback, 10) - msg_out = String() - msg_out.data = "Nueva vuelta" - self.lap_publisher.publish(msg_out) - - lidarscan_topic = '/scan' - drive_topic = '/drive' - self.drive_pub = self.create_publisher(AckermannDriveStamped, drive_topic, 10) - self.scan_sub = self.create_subscription(LaserScan, lidarscan_topic, self.lidar_callback, 10) - - - def odom_callback(self, msg: Odometry): - current_pose = msg.pose.pose - - if self.last_pose is None: - self.last_pose = current_pose - return - - last_x = self.last_pose.position.x - current_x = current_pose.position.x - current_y = current_pose.position.y - - crossed_finish_line = (last_x < self.FINISH_LINE_X and current_x >= self.FINISH_LINE_X) - on_finish_straight = abs(current_y - self.FINISH_LINE_Y) < self.FINISH_LINE_Y_RANGE - - if crossed_finish_line and on_finish_straight and self.can_count_lap: - msg_out = String() - msg_out.data = "Nueva vuelta" - self.lap_publisher.publish(msg_out) - - self.can_count_lap = False - - if not self.can_count_lap: - dist_from_finish = math.sqrt((current_pose.position.x - self.FINISH_LINE_X)**2) - if dist_from_finish > self.MIN_DISTANCE_TO_ARM: - self.can_count_lap = True - - self.last_pose = current_pose - - - def lidar_callback(self, msg): - ranges = np.array(msg.ranges, dtype=np.float32) - ranges[np.isinf(ranges) | np.isnan(ranges)] = self.DISTANCIA_MAX_LIDAR - ranges = np.clip(ranges, 0.0, self.DISTANCIA_MAX_LIDAR) - - idx_closest = np.argmin(ranges) - dist_closest = ranges[idx_closest] - - if dist_closest > 0.1: - angle_span = 2 * np.arctan2(self.RADIO_BURBUJA, dist_closest) - bubble_radius_idx = int(angle_span / msg.angle_increment) - else: - bubble_radius_idx = 30 - start_idx = max(0, idx_closest - bubble_radius_idx) - end_idx = min(len(ranges) - 1, idx_closest + bubble_radius_idx) - ranges[start_idx : end_idx + 1] = 0.0 - - max_len = 0 - best_start_idx = 0 - best_end_idx = 0 - current_len = 0 - current_start_idx = 0 - for i in range(len(ranges)): - if ranges[i] > 0.1: - if current_len == 0: - current_start_idx = i - current_len += 1 - else: - if current_len > max_len: - max_len = current_len - best_start_idx = current_start_idx - best_end_idx = i - 1 - current_len = 0 - if current_len > max_len: - max_len = current_len - best_start_idx = current_start_idx - best_end_idx = len(ranges) - 1 - - drive_msg = AckermannDriveStamped() - - if max_len > 0: - gap_ranges = ranges[best_start_idx : best_end_idx + 1] - idx_punto_lejano_relativo = np.argmax(gap_ranges) - idx_punto_lejano_absoluto = best_start_idx + idx_punto_lejano_relativo - idx_centro_gap = (best_start_idx + best_end_idx) // 2 - target_idx = int(self.PUNTO_LEJANO_BIAS * idx_punto_lejano_absoluto + (1 - self.PUNTO_LEJANO_BIAS) * idx_centro_gap) - target_angle = msg.angle_min + target_idx * msg.angle_increment - - steering_angle = self.SUAVIZADO_DIRECCION * self.ultimo_angulo_direccion + (1 - self.SUAVIZADO_DIRECCION) * target_angle - self.ultimo_angulo_direccion = steering_angle - steering_angle = np.clip(steering_angle, -self.ANGULO_MAX_DIRECCION, self.ANGULO_MAX_DIRECCION) - - severidad_curva = abs(target_angle) / self.ANGULO_MAX_DIRECCION - - severidad_curva = np.clip(severidad_curva, 0.0, 1.0) - - factor_reduccion = (1.0 - severidad_curva) ** self.FACTOR_REDUCCION_CURVA - speed = self.VELOCIDAD_MINIMA + (self.VELOCIDAD_MAXIMA - self.VELOCIDAD_MINIMA) * factor_reduccion - - drive_msg.drive.steering_angle = float(steering_angle) - drive_msg.drive.speed = float(speed) - else: - drive_msg.drive.steering_angle = 0.0 - drive_msg.drive.speed = 0.0 - self.ultimo_angulo_direccion = 0.0 - - self.drive_pub.publish(drive_msg) - -def main(args=None): - rclpy.init(args=args) - node = FollowGapCarrera() - rclpy.spin(node) - node.destroy_node() - rclpy.shutdown() \ No newline at end of file diff --git a/controllers/controllers/proyectoWF.py b/controllers/controllers/proyectoWF.py deleted file mode 100644 index e650f00..0000000 --- a/controllers/controllers/proyectoWF.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python3 - -import rclpy -from rclpy.node import Node -import numpy as np -import time -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped -from nav_msgs.msg import Odometry - -class WallFollower(Node): - def __init__(self): - super().__init__('wall_follower_node') - - # Topics - lidarscan_topic = '/scan' - drive_topic = '/drive' - odom_topic = '/ego_racecar/odom' - - # Parámetros del algoritmo de seguimiento de pared - self.max_speed = 2.5 # Velocidad máxima reducida a la mitad - self.min_speed = 1.5 # Velocidad mínima ajustada - self.max_lidar_range = 10.0 - self.wall_distance_ref = 1.20 # Distancia de referencia a la pared aumentada a 2 metros - - # PID para el ángulo - self.steering_pid_kp = 1.10 - self.steering_pid_ki = 0.00 - self.steering_pid_kd = 0.01 - self.last_error_angle = 0.0 - self.integral_angle = 0.0 - - # PID para la velocidad - self.speed_pid_kp = 0.5 - self.speed_pid_ki = 0.0 - self.speed_pid_kd = 0.01 - self.last_error_speed = 0.0 - self.integral_speed = 0.0 - - # Control de vueltas (se mantiene sin cambios) - self.lap_start_time = time.time() - self.lap_count = 0 - self.prev_in_start_zone = False - self.lap_times = [] - self.has_left_start_zone = False - - # Ángulo de detección - self.angle_range_deg = 45 # Ángulo configurable, 45 grados por defecto - - # Publishers & Subscribers - self.drive_pub = self.create_publisher(AckermannDriveStamped, drive_topic, 10) - self.scan_sub = self.create_subscription(LaserScan, lidarscan_topic, self.lidar_callback, 10) - self.odom_sub = self.create_subscription(Odometry, odom_topic, self.odom_callback, 10) - - self.get_logger().info("WallFollower node initialized.") - - def preprocess_lidar(self, ranges): - # Preprocesa los datos del LiDAR: reemplaza valores inválidos y aplica un filtro - proc = np.array(ranges, dtype=np.float32) - invalid_mask = (proc == 0) | np.isinf(proc) | np.isnan(proc) - proc[invalid_mask] = self.max_lidar_range - proc = np.clip(proc, 0.1, self.max_lidar_range) - kernel = np.ones(3) / 3 - return np.convolve(proc, kernel, mode='same') - - def select_cleanest_wall(self, ranges, angle_increment): - # Selecciona el lado con la pared más 'limpia' (menos protuberancias) - num_ranges = len(ranges) - mid_idx = num_ranges // 2 - - # Rango de ángulos para considerar los lados derecho e izquierdo - points_to_check = int(np.radians(self.angle_range_deg) / angle_increment) - - right_ranges = ranges[mid_idx - points_to_check : mid_idx] - left_ranges = ranges[mid_idx : mid_idx + points_to_check] - - # Calcular la desviación estándar para cada lado - std_dev_right = np.std(right_ranges) - std_dev_left = np.std(left_ranges) - - # Si el lado derecho es más 'limpio' (menor desviación), lo seguimos. - if std_dev_right < std_dev_left: - return 'right', right_ranges - else: - return 'left', left_ranges - - def calculate_pid(self, error, last_error, integral, kp, ki, kd): - # Cálculo de PID - integral += error - derivative = error - last_error - output = kp * error + ki * integral + kd * derivative - return output, integral - - def get_wall_following_angle(self, side_to_follow, side_ranges): - # Obtiene el ángulo necesario para seguir la pared con menos obstáculos detectables - avg_dist = np.mean(side_ranges) - error = self.wall_distance_ref - avg_dist - - steering_angle, self.integral_angle = self.calculate_pid( - error, self.last_error_angle, self.integral_angle, - self.steering_pid_kp, self.steering_pid_ki, self.steering_pid_kd - ) - self.last_error_angle = error - - if side_to_follow == 'left': - steering_angle = -steering_angle - - return np.clip(steering_angle, -0.20, 0.20) - - def calculate_speed(self, ranges, steering_angle): - # Ajusta la velocidad en función de la distancia frontal y el ángulo de dirección - # Reducir la velocidad en curvas cerradas - speed = self.max_speed - abs(steering_angle) * 1.5 - - # Usa PID para ajustar la velocidad según la distancia frontal - front_range = int(np.radians(20) / (2 * np.pi / len(ranges))) - front_distances = ranges[len(ranges) // 2 - front_range : len(ranges) // 2 + front_range] - min_front_distance = np.min(front_distances) - - speed_error = min_front_distance - 2.0 - speed_adjustment, self.integral_speed = self.calculate_pid( - speed_error, self.last_error_speed, self.integral_speed, - self.speed_pid_kp, self.speed_pid_ki, self.speed_pid_kd - ) - self.last_error_speed = speed_error - - speed += speed_adjustment - - return np.clip(speed, self.min_speed, self.max_speed) - - def lidar_callback(self, data): - ranges = self.preprocess_lidar(data.ranges) - - # Seleccionar la pared más 'limpia' - side_to_follow, side_ranges = self.select_cleanest_wall(ranges, data.angle_increment) - - # Calcular ángulo y velocidad - steering_angle = self.get_wall_following_angle(side_to_follow, side_ranges) - speed = self.calculate_speed(ranges, steering_angle) - - drive_msg = AckermannDriveStamped() - drive_msg.header.stamp = self.get_clock().now().to_msg() - drive_msg.header.frame_id = "base_link" - drive_msg.drive.speed = float(speed) - drive_msg.drive.steering_angle = float(steering_angle) - - self.drive_pub.publish(drive_msg) - - def odom_callback(self, msg): - x = msg.pose.pose.position.x - y = msg.pose.pose.position.y - - in_start_zone = (abs(x) < 2.0 and abs(y) < 2.0) - - if in_start_zone and not self.prev_in_start_zone and self.has_left_start_zone: - lap_end_time = time.time() - lap_duration = lap_end_time - self.lap_start_time - self.lap_times.append(lap_duration) - self.lap_count += 1 - self.get_logger().info(f"🏁 Vuelta {self.lap_count} completada en {lap_duration:.2f} s.") - self.lap_start_time = lap_end_time - - - if not in_start_zone: - self.has_left_start_zone = True - - self.prev_in_start_zone = in_start_zone - -def main(args=None): - rclpy.init(args=args) - node = WallFollower() - try: - rclpy.spin(node) - except KeyboardInterrupt: - node.get_logger().info("Node stopped cleanly") - finally: - node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() - diff --git a/controllers/controllers/purepursuit_node.py b/controllers/controllers/purepursuit_node.py deleted file mode 100644 index 25def76..0000000 --- a/controllers/controllers/purepursuit_node.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 -import rclpy -from rclpy.node import Node - -import numpy as np -from sensor_msgs.msg import LaserScan -from ackermann_msgs.msg import AckermannDriveStamped, AckermannDrive -# TODO CHECK: include needed ROS msg type headers and libraries - -class PurePursuit(Node): - """ - Implement Pure Pursuit on the car - This is just a template, you are free to implement your own node! - """ - def __init__(self): - super().__init__('pure_pursuit_node') - # TODO: create ROS subscribers and publishers - - def pose_callback(self, pose_msg): - pass - # TODO: find the current waypoint to track using methods mentioned in lecture - - # TODO: transform goal point to vehicle frame of reference - - # TODO: calculate curvature/steering angle - - # TODO: publish drive message, don't forget to limit the steering angle. - -def main(args=None): - rclpy.init(args=args) - print("PurePursuit Initialized") - pure_pursuit_node = PurePursuit() - rclpy.spin(pure_pursuit_node) - - pure_pursuit_node.destroy_node() - rclpy.shutdown() - - -if __name__ == '__main__': - main() diff --git a/controllers/controllers/rrt_node.py b/controllers/controllers/rrt_node.py deleted file mode 100644 index 91c9e48..0000000 --- a/controllers/controllers/rrt_node.py +++ /dev/null @@ -1,218 +0,0 @@ -""" -This file contains the class definition for tree nodes and RRT -Before you start, please read: https://arxiv.org/pdf/1105.1186.pdf -""" -import numpy as np -from numpy import linalg as LA -import math - -import rclpy -from rclpy.node import Node -from sensor_msgs.msg import LaserScan -from geometry_msgs.msg import PoseStamped -from geometry_msgs.msg import PointStamped -from geometry_msgs.msg import Pose -from geometry_msgs.msg import Point -from nav_msgs.msg import Odometry -from ackermann_msgs.msg import AckermannDriveStamped, AckermannDrive -from nav_msgs.msg import OccupancyGrid - -# TODO: import as you need - -# class def for tree nodes -# It's up to you if you want to use this -class Node(object): - def __init__(self): - self.x = None - self.y = None - self.parent = None - self.cost = None # only used in RRT* - self.is_root = False - -# class def for RRT -class RRT(Node): - def __init__(self): - # topics, not saved as attributes - # TODO: grab topics from param file, you'll need to change the yaml file - pose_topic = "ego_racecar/odom" - scan_topic = "/scan" - - # you could add your own parameters to the rrt_params.yaml file, - # and get them here as class attributes as shown above. - - # TODO: create subscribers - self.pose_sub_ = self.create_subscription( - PoseStamped, - pose_topic, - self.pose_callback, - 1) - self.pose_sub_ - - self.scan_sub_ = self.create_subscription( - LaserScan, - scan_topic, - self.scan_callback, - 1) - self.scan_sub_ - - # publishers - # TODO: create a drive message publisher, and other publishers that you might need - - # class attributes - # TODO: maybe create your occupancy grid here - - def scan_callback(self, scan_msg): - """ - LaserScan callback, you should update your occupancy grid here - - Args: - scan_msg (LaserScan): incoming message from subscribed topic - Returns: - - """ - - def pose_callback(self, pose_msg): - """ - The pose callback when subscribed to particle filter's inferred pose - Here is where the main RRT loop happens - - Args: - pose_msg (PoseStamped): incoming message from subscribed topic - Returns: - - """ - - return None - - def sample(self): - """ - This method should randomly sample the free space, and returns a viable point - - Args: - Returns: - (x, y) (float float): a tuple representing the sampled point - - """ - x = None - y = None - return (x, y) - - def nearest(self, tree, sampled_point): - """ - This method should return the nearest node on the tree to the sampled point - - Args: - tree ([]): the current RRT tree - sampled_point (tuple of (float, float)): point sampled in free space - Returns: - nearest_node (int): index of neareset node on the tree - """ - nearest_node = 0 - return nearest_node - - def steer(self, nearest_node, sampled_point): - """ - This method should return a point in the viable set such that it is closer - to the nearest_node than sampled_point is. - - Args: - nearest_node (Node): nearest node on the tree to the sampled point - sampled_point (tuple of (float, float)): sampled point - Returns: - new_node (Node): new node created from steering - """ - new_node = None - return new_node - - def check_collision(self, nearest_node, new_node): - """ - This method should return whether the path between nearest and new_node is - collision free. - - Args: - nearest (Node): nearest node on the tree - new_node (Node): new node from steering - Returns: - collision (bool): whether the path between the two nodes are in collision - with the occupancy grid - """ - return True - - def is_goal(self, latest_added_node, goal_x, goal_y): - """ - This method should return whether the latest added node is close enough - to the goal. - - Args: - latest_added_node (Node): latest added node on the tree - goal_x (double): x coordinate of the current goal - goal_y (double): y coordinate of the current goal - Returns: - close_enough (bool): true if node is close enoughg to the goal - """ - return False - - def find_path(self, tree, latest_added_node): - """ - This method returns a path as a list of Nodes connecting the starting point to - the goal once the latest added node is close enough to the goal - - Args: - tree ([]): current tree as a list of Nodes - latest_added_node (Node): latest added node in the tree - Returns: - path ([]): valid path as a list of Nodes - """ - path = [] - return path - - - - # The following methods are needed for RRT* and not RRT - def cost(self, tree, node): - """ - This method should return the cost of a node - - Args: - node (Node): the current node the cost is calculated for - Returns: - cost (float): the cost value of the node - """ - return 0 - - def line_cost(self, n1, n2): - """ - This method should return the cost of the straight line between n1 and n2 - - Args: - n1 (Node): node at one end of the straight line - n2 (Node): node at the other end of the straint line - Returns: - cost (float): the cost value of the line - """ - return 0 - - def near(self, tree, node): - """ - This method should return the neighborhood of nodes around the given node - - Args: - tree ([]): current tree as a list of Nodes - node (Node): current node we're finding neighbors for - Returns: - neighborhood ([]): neighborhood of nodes as a list of Nodes - """ - neighborhood = [] - return neighborhood - -def main(args=None): - rclpy.init(args=args) - print("RRT Initialized") - rrt_node = RRT() - rclpy.spin(rrt_node) - - rrt_node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/temporizador.py b/controllers/controllers/temporizador.py deleted file mode 100644 index e4afe42..0000000 --- a/controllers/controllers/temporizador.py +++ /dev/null @@ -1,52 +0,0 @@ -import rclpy -from rclpy.node import Node -from std_msgs.msg import String - - -class LapTimeLogger(Node): - def __init__(self): - super().__init__('timer_node') - - self.lap_count = 0 - self.best_lap_time_s = 9999.0 - self.last_trigger_time = None - self.clock = self.get_clock() - - self.subscription = self.create_subscription(String,'/lap_trigger',self.lap_callback,10) - - - def lap_callback(self, msg: String): - current_time = self.clock.now() - - if self.last_trigger_time is None: - self.last_trigger_time = current_time - self.get_logger().info("Carrera iniciada") - return - - lap_duration = current_time - self.last_trigger_time - lap_time_s = lap_duration.nanoseconds / 1e9 - - self.lap_count += 1 - - if lap_time_s < self.best_lap_time_s: - self.best_lap_time_s = lap_time_s - best_lap_str = f"Vuelta completada en menor tiempo" - else: - best_lap_str = "" - - self.get_logger().info(f"Vuelta {self.lap_count} completada en" f": {lap_time_s:.4f}s | {best_lap_str}") - - if self.lap_count ==10: - self.get_logger().info(f"5 vueltas completadas. Tiempo mejor vuelta:{self.best_lap_time_s:.2f}s") - - self.last_trigger_time = current_time - -def main(args=None): - rclpy.init(args=args) - lap_logger_node = LapTimeLogger() - rclpy.spin(lap_logger_node) - lap_logger_node.destroy_node() - rclpy.shutdown() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/controllers/ttc_node.py b/controllers/controllers/ttc_node.py deleted file mode 100644 index 0af5665..0000000 --- a/controllers/controllers/ttc_node.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 -import rclpy -from rclpy.node import Node - -import numpy as np -# TODO: include needed ROS msg type headers and libraries -from sensor_msgs.msg import LaserScan -from nav_msgs.msg import Odometry -from ackermann_msgs.msg import AckermannDriveStamped, AckermannDrive - - -class SafetyNode(Node): - """ - The class that handles emergency braking. - """ - def __init__(self): - super().__init__('safety_node') - """ - One publisher should publish to the /drive topic with a AckermannDriveStamped drive message. - - You should also subscribe to the /scan topic to get the LaserScan messages and - the /ego_racecar/odom topic to get the current speed of the vehicle. - - The subscribers should use the provided odom_callback and scan_callback as callback methods - - NOTE that the x component of the linear velocity in odom is the speed - """ - self.speed = 0. - # TODO: create ROS subscribers and publishers. - - def odom_callback(self, odom_msg): - # TODO: update current speed - self.speed = 0. - - def scan_callback(self, scan_msg): - # TODO: calculate TTC - - # TODO: publish command to brake - pass - -def main(args=None): - rclpy.init(args=args) - safety_node = SafetyNode() - rclpy.spin(safety_node) - - # Destroy the node explicitly - # (optional - otherwise it will be done automatically - # when the garbage collector destroys the node object) - safety_node.destroy_node() - rclpy.shutdown() - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/controllers/package.xml b/controllers/package.xml deleted file mode 100644 index 6c0c8fd..0000000 --- a/controllers/package.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - controllers - 0.0.0 - TODO: Package description - israel - TODO: License declaration - - rclpy - std_msgs - ackermann_msgs - std_srvs - sensor_msgs - nav_msgs - geometry_msgs - visualization_msgs - - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/controllers/resource/controllers b/controllers/resource/controllers deleted file mode 100644 index e69de29..0000000 diff --git a/controllers/setup.cfg b/controllers/setup.cfg deleted file mode 100644 index 83202a3..0000000 --- a/controllers/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script_dir=$base/lib/controllers -[install] -install_scripts=$base/lib/controllers diff --git a/controllers/setup.py b/controllers/setup.py deleted file mode 100644 index 9564a7b..0000000 --- a/controllers/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -from setuptools import find_packages, setup - -package_name = 'controllers' - -setup( - name=package_name, - version='0.0.0', - packages=find_packages(exclude=['test']), - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='israel', - maintainer_email='israel@todo.todo', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - 'ttc_node = controllers.ttc_node:main', - 'pid_node = controllers.pid_node:main', - 'gap_node = controllers.gap_node:main', - 'purepursuit_node = controllers.purepursuit_node:main', - 'rrt_node = controllers.rrt_node:main', - 'mpc_node = controllers.mpc_node:main', - 'proyectoFTG = controllers.proyectoFTG:main', - 'temporizador = controllers.temporizador:main', - 'proyectoRob = controllers.proyectoRob:main', - 'proyectoObstaculos = controllers.proyectoObstaculos:main', - 'proyectoWF = controllers.proyectoWF:main', - 'obstaculosWF=controllers.obstaculosWF:main', - 'obstaculosFTG=controllers.obstaculosFTG:main', - 'graficas=controllers.graficas:main', - ], - }, -) diff --git a/controllers/test/test_copyright.py b/controllers/test/test_copyright.py deleted file mode 100644 index 97a3919..0000000 --- a/controllers/test/test_copyright.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -# Remove the `skip` decorator once the source file(s) have a copyright header -@pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/controllers/test/test_flake8.py b/controllers/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/controllers/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/controllers/test/test_pep257.py b/controllers/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/controllers/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/f1tenth_gym_ros/LICENSE b/f1tenth_gym_ros/LICENSE deleted file mode 100644 index cd28e87..0000000 --- a/f1tenth_gym_ros/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Hongrui Zheng - -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. diff --git a/f1tenth_gym_ros/config/ackermann_controllers.yaml b/f1tenth_gym_ros/config/ackermann_controllers.yaml deleted file mode 100644 index 65f16b1..0000000 --- a/f1tenth_gym_ros/config/ackermann_controllers.yaml +++ /dev/null @@ -1,76 +0,0 @@ -controller_manager: - ros__parameters: - update_rate: 100 # Hz - - # Lista de controladores - ackermann_steering_controller: - type: ackermann_steering_controller/AckermannSteeringController - - joint_state_broadcaster: - type: joint_state_broadcaster/JointStateBroadcaster - -# Configuración del controlador de dirección Ackermann -ackermann_steering_controller: - ros__parameters: - # Ruedas de tracción (delanteras) - front_wheels_names: ["front_left_hinge_to_wheel", "front_right_hinge_to_wheel"] - - # Ruedas traseras (solo para odometría) - rear_wheels_names: ["base_to_back_left_wheel", "base_to_back_right_wheel"] - - # Juntas de dirección - front_steering_names: ["base_to_front_left_hinge", "base_to_front_right_hinge"] - - # Parámetros del vehículo (basados en tu XACRO) - wheelbase: 0.24 # Distancia entre ejes - front_wheel_track: 0.20 # Distancia entre ruedas delanteras (wheel_length + width = 0.04 + 0.16) - rear_wheel_track: 0.20 # Distancia entre ruedas traseras - wheel_radius: 0.04 # Radio de las ruedas - - # Configuración de tópicos - reference_timeout: 2.0 - front_steering: true - - # Publicar odometría - publish_rate: 50.0 - odom_frame_id: odom - base_frame_id: ego_racecar/base_link - pose_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.01] - twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.01] - - # Habilitar odometría - enable_odom_tf: true - - # Comandos de velocidad - linear: - x: - has_velocity_limits: true - has_acceleration_limits: true - max_velocity: 3.0 # m/s (reducido para F1Tenth) - min_velocity: -3.0 # m/s - max_acceleration: 1.5 # m/s^2 - min_acceleration: -1.5 # m/s^2 - - angular: - z: - has_velocity_limits: true - has_acceleration_limits: true - max_velocity: 2.0 # rad/s - min_velocity: -2.0 # rad/s - max_acceleration: 1.0 # rad/s^2 - min_acceleration: -1.0 # rad/s^2 - -# Configuración del publicador de estados de juntas -joint_state_broadcaster: - ros__parameters: - joints: - - front_left_hinge_to_wheel - - front_right_hinge_to_wheel - - base_to_back_left_wheel - - base_to_back_right_wheel - - base_to_front_left_hinge - - base_to_front_right_hinge - - interfaces: - - position - - velocity \ No newline at end of file diff --git a/f1tenth_gym_ros/config/gazebo_params.yaml b/f1tenth_gym_ros/config/gazebo_params.yaml deleted file mode 100644 index 5c61215..0000000 --- a/f1tenth_gym_ros/config/gazebo_params.yaml +++ /dev/null @@ -1,16 +0,0 @@ -gazebo: - ros__parameters: - publish_rate: 400.0 - -physics: - ros__parameters: - ode: - solver: - type: "quick" - iters: 50 - sor: 1.4 - constraints: - cfm: 0.0 - erp: 0.2 - contact_max_correcting_vel: 0.1 - contact_surface_layer: 0.0 \ No newline at end of file diff --git a/f1tenth_gym_ros/config/sim.yaml b/f1tenth_gym_ros/config/sim.yaml deleted file mode 100644 index 193a9ac..0000000 --- a/f1tenth_gym_ros/config/sim.yaml +++ /dev/null @@ -1,62 +0,0 @@ -# MIT License - -# Copyright (c) 2020 Hongrui Zheng - -# 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. - -bridge: - ros__parameters: - # topics and namespaces - ego_namespace: 'ego_racecar' - ego_scan_topic: 'scan' - ego_odom_topic: 'odom' - ego_opp_odom_topic: 'opp_odom' - ego_drive_topic: 'drive' - opp_namespace: 'opp_racecar' - opp_scan_topic: 'opp_scan' - opp_odom_topic: 'odom' - opp_ego_odom_topic: 'opp_odom' - opp_drive_topic: 'opp_drive' - - # transform related - scan_distance_to_base_link: 0.0 - - # laserscan parameters - scan_fov: 4.7 - scan_beams: 1080 - - # map parameters - map_path: '/home/ivan/F1Tenth-Repository/src/f1tenth_gym_ros/maps/levineB' - map_img_ext: '.png' - - # opponent parameters - num_agent: 1 - - # ego starting pose on map - sx: 0.0 - sy: 0.0 - stheta: 3.420 - - # opp starting pose on map - sx1: 9.5 - sy1: 8.5 - stheta1: 3.14 - - # teleop - kb_teleop: True diff --git a/f1tenth_gym_ros/f1tenth_gym_ros/__init__.py b/f1tenth_gym_ros/f1tenth_gym_ros/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/f1tenth_gym_ros/f1tenth_gym_ros/gym_bridge.py b/f1tenth_gym_ros/f1tenth_gym_ros/gym_bridge.py deleted file mode 100644 index 5869c50..0000000 --- a/f1tenth_gym_ros/f1tenth_gym_ros/gym_bridge.py +++ /dev/null @@ -1,420 +0,0 @@ -# MIT License - -# Copyright (c) 2020 Hongrui Zheng - -# 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. - -import rclpy -from rclpy.node import Node - -from sensor_msgs.msg import LaserScan -from nav_msgs.msg import Odometry -from geometry_msgs.msg import PoseStamped -from geometry_msgs.msg import PoseWithCovarianceStamped -from geometry_msgs.msg import Twist -from geometry_msgs.msg import TransformStamped -from geometry_msgs.msg import Transform -from geometry_msgs.msg import Quaternion -from ackermann_msgs.msg import AckermannDriveStamped -from tf2_ros import TransformBroadcaster - -import gym -import numpy as np -from transforms3d import euler - -class GymBridge(Node): - def __init__(self): - super().__init__('gym_bridge') - - self.declare_parameter('ego_namespace', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('ego_odom_topic', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('ego_opp_odom_topic', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('ego_scan_topic', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('ego_drive_topic', '') # Tipo 'str' con valor predeterminado vacío - - self.declare_parameter('opp_namespace', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('opp_odom_topic', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('opp_ego_odom_topic', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('opp_scan_topic', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('opp_drive_topic', '') # Tipo 'str' con valor predeterminado vacío - - self.declare_parameter('scan_distance_to_base_link', 0.0) # Tipo 'float' con valor predeterminado - self.declare_parameter('scan_fov', 0.0) # Tipo 'float' con valor predeterminado - self.declare_parameter('scan_beams', 0) # Tipo 'int' con valor predeterminado - - self.declare_parameter('map_path', '') # Tipo 'str' con valor predeterminado vacío - self.declare_parameter('map_img_ext', '') # Tipo 'str' con valor predeterminado vacío - - self.declare_parameter('num_agent', 0) # Tipo 'int' con valor predeterminado - - self.declare_parameter('sx', 0.0) # Tipo 'float' con valor predeterminado - self.declare_parameter('sy', 0.0) # Tipo 'float' con valor predeterminado - self.declare_parameter('stheta', 0.0) # Tipo 'float' con valor predeterminado - - self.declare_parameter('sx1', 0.0) # Tipo 'float' con valor predeterminado - self.declare_parameter('sy1', 0.0) # Tipo 'float' con valor predeterminado - self.declare_parameter('stheta1', 0.0) # Tipo 'float' con valor predeterminado - - self.declare_parameter('kb_teleop', False) # Tipo 'bool' con valor predeterminado - - - - # check num_agents - num_agents = self.get_parameter('num_agent').value - if num_agents < 1 or num_agents > 2: - raise ValueError('num_agents should be either 1 or 2.') - elif type(num_agents) != int: - raise ValueError('num_agents should be an int.') - - # env backend - self.env = gym.make('f110_gym:f110-v0', - map=self.get_parameter('map_path').value, - map_ext=self.get_parameter('map_img_ext').value, - num_agents=num_agents) - - sx = self.get_parameter('sx').value - sy = self.get_parameter('sy').value - stheta = self.get_parameter('stheta').value - self.ego_pose = [sx, sy, stheta] - self.ego_speed = [0.0, 0.0, 0.0] - self.ego_requested_speed = 0.0 - self.ego_steer = 0.0 - self.ego_collision = False - ego_scan_topic = self.get_parameter('ego_scan_topic').value - ego_drive_topic = self.get_parameter('ego_drive_topic').value - scan_fov = self.get_parameter('scan_fov').value - scan_beams = self.get_parameter('scan_beams').value - self.angle_min = -scan_fov / 2. - self.angle_max = scan_fov / 2. - self.angle_inc = scan_fov / scan_beams - self.ego_namespace = self.get_parameter('ego_namespace').value - ego_odom_topic = self.ego_namespace + '/' + self.get_parameter('ego_odom_topic').value - self.scan_distance_to_base_link = self.get_parameter('scan_distance_to_base_link').value - - if num_agents == 2: - self.has_opp = True - self.opp_namespace = self.get_parameter('opp_namespace').value - sx1 = self.get_parameter('sx1').value - sy1 = self.get_parameter('sy1').value - stheta1 = self.get_parameter('stheta1').value - self.opp_pose = [sx1, sy1, stheta1] - self.opp_speed = [0.0, 0.0, 0.0] - self.opp_requested_speed = 0.0 - self.opp_steer = 0.0 - self.opp_collision = False - self.obs, _ , self.done, _ = self.env.reset(np.array([[sx, sy, stheta], [sx1, sy1, stheta1]])) - self.ego_scan = list(self.obs['scans'][0]) - self.opp_scan = list(self.obs['scans'][1]) - - opp_scan_topic = self.get_parameter('opp_scan_topic').value - opp_odom_topic = self.opp_namespace + '/' + self.get_parameter('opp_odom_topic').value - opp_drive_topic = self.get_parameter('opp_drive_topic').value - - ego_opp_odom_topic = self.ego_namespace + '/' + self.get_parameter('ego_opp_odom_topic').value - opp_ego_odom_topic = self.opp_namespace + '/' + self.get_parameter('opp_ego_odom_topic').value - else: - self.has_opp = False - self.obs, _ , self.done, _ = self.env.reset(np.array([[sx, sy, stheta]])) - self.ego_scan = list(self.obs['scans'][0]) - - # sim physical step timer - self.drive_timer = self.create_timer(0.01, self.drive_timer_callback) - # topic publishing timer - self.timer = self.create_timer(0.004, self.timer_callback) - - # transform broadcaster - self.br = TransformBroadcaster(self) - - # publishers - self.ego_scan_pub = self.create_publisher(LaserScan, ego_scan_topic, 10) - self.ego_odom_pub = self.create_publisher(Odometry, ego_odom_topic, 10) - self.ego_drive_published = False - if num_agents == 2: - self.opp_scan_pub = self.create_publisher(LaserScan, opp_scan_topic, 10) - self.ego_opp_odom_pub = self.create_publisher(Odometry, ego_opp_odom_topic, 10) - self.opp_odom_pub = self.create_publisher(Odometry, opp_odom_topic, 10) - self.opp_ego_odom_pub = self.create_publisher(Odometry, opp_ego_odom_topic, 10) - self.opp_drive_published = False - - # subscribers - self.ego_drive_sub = self.create_subscription( - AckermannDriveStamped, - ego_drive_topic, - self.drive_callback, - 10) - self.ego_reset_sub = self.create_subscription( - PoseWithCovarianceStamped, - '/initialpose', - self.ego_reset_callback, - 10) - if num_agents == 2: - self.opp_drive_sub = self.create_subscription( - AckermannDriveStamped, - opp_drive_topic, - self.opp_drive_callback, - 10) - self.opp_reset_sub = self.create_subscription( - PoseStamped, - '/goal_pose', - self.opp_reset_callback, - 10) - - if self.get_parameter('kb_teleop').value: - self.teleop_sub = self.create_subscription( - Twist, - '/cmd_vel', - self.teleop_callback, - 10) - - - def drive_callback(self, drive_msg): - self.ego_requested_speed = drive_msg.drive.speed - self.ego_steer = drive_msg.drive.steering_angle - self.ego_drive_published = True - - def opp_drive_callback(self, drive_msg): - self.opp_requested_speed = drive_msg.drive.speed - self.opp_steer = drive_msg.drive.steering_angle - self.opp_drive_published = True - - def ego_reset_callback(self, pose_msg): - rx = pose_msg.pose.pose.position.x - ry = pose_msg.pose.pose.position.y - rqx = pose_msg.pose.pose.orientation.x - rqy = pose_msg.pose.pose.orientation.y - rqz = pose_msg.pose.pose.orientation.z - rqw = pose_msg.pose.pose.orientation.w - _, _, rtheta = euler.quat2euler([rqw, rqx, rqy, rqz], axes='sxyz') - if self.has_opp: - opp_pose = [self.obs['poses_x'][1], self.obs['poses_y'][1], self.obs['poses_theta'][1]] - self.obs, _ , self.done, _ = self.env.reset(np.array([[rx, ry, rtheta], opp_pose])) - else: - self.obs, _ , self.done, _ = self.env.reset(np.array([[rx, ry, rtheta]])) - - def opp_reset_callback(self, pose_msg): - if self.has_opp: - rx = pose_msg.pose.position.x - ry = pose_msg.pose.position.y - rqx = pose_msg.pose.orientation.x - rqy = pose_msg.pose.orientation.y - rqz = pose_msg.pose.orientation.z - rqw = pose_msg.pose.orientation.w - _, _, rtheta = euler.quat2euler([rqw, rqx, rqy, rqz], axes='sxyz') - self.obs, _ , self.done, _ = self.env.reset(np.array([list(self.ego_pose), [rx, ry, rtheta]])) - def teleop_callback(self, twist_msg): - if not self.ego_drive_published: - self.ego_drive_published = True - - self.ego_requested_speed = twist_msg.linear.x - - if twist_msg.angular.z > 0.0: - self.ego_steer = 0.3 - elif twist_msg.angular.z < 0.0: - self.ego_steer = -0.3 - else: - self.ego_steer = 0.0 - - def drive_timer_callback(self): - if self.ego_drive_published and not self.has_opp: - self.obs, _, self.done, _ = self.env.step(np.array([[self.ego_steer, self.ego_requested_speed]])) - elif self.ego_drive_published and self.has_opp and self.opp_drive_published: - self.obs, _, self.done, _ = self.env.step(np.array([[self.ego_steer, self.ego_requested_speed], [self.opp_steer, self.opp_requested_speed]])) - self._update_sim_state() - - def timer_callback(self): - ts = self.get_clock().now().to_msg() - - # pub scans - scan = LaserScan() - scan.header.stamp = ts - scan.header.frame_id = self.ego_namespace + '/laser' - scan.angle_min = self.angle_min - scan.angle_max = self.angle_max - scan.angle_increment = self.angle_inc - scan.range_min = 0. - scan.range_max = 30. - scan.ranges = self.ego_scan - self.ego_scan_pub.publish(scan) - - if self.has_opp: - opp_scan = LaserScan() - opp_scan.header.stamp = ts - opp_scan.header.frame_id = self.opp_namespace + '/laser' - opp_scan.angle_min = self.angle_min - opp_scan.angle_max = self.angle_max - opp_scan.angle_increment = self.angle_inc - opp_scan.range_min = 0. - opp_scan.range_max = 30. - opp_scan.ranges = self.opp_scan - self.opp_scan_pub.publish(opp_scan) - - # pub tf - self._publish_odom(ts) - self._publish_transforms(ts) - self._publish_laser_transforms(ts) - self._publish_wheel_transforms(ts) - - def _update_sim_state(self): - self.ego_scan = list(self.obs['scans'][0]) - if self.has_opp: - self.opp_scan = list(self.obs['scans'][1]) - self.opp_pose[0] = self.obs['poses_x'][1] - self.opp_pose[1] = self.obs['poses_y'][1] - self.opp_pose[2] = self.obs['poses_theta'][1] - self.opp_speed[0] = self.obs['linear_vels_x'][1] - self.opp_speed[1] = self.obs['linear_vels_y'][1] - self.opp_speed[2] = self.obs['ang_vels_z'][1] - - self.ego_pose[0] = self.obs['poses_x'][0] - self.ego_pose[1] = self.obs['poses_y'][0] - self.ego_pose[2] = self.obs['poses_theta'][0] - self.ego_speed[0] = self.obs['linear_vels_x'][0] - self.ego_speed[1] = self.obs['linear_vels_y'][0] - self.ego_speed[2] = self.obs['ang_vels_z'][0] - - - - def _publish_odom(self, ts): - ego_odom = Odometry() - ego_odom.header.stamp = ts - ego_odom.header.frame_id = 'map' - ego_odom.child_frame_id = self.ego_namespace + '/base_link' - ego_odom.pose.pose.position.x = self.ego_pose[0] - ego_odom.pose.pose.position.y = self.ego_pose[1] - ego_quat = euler.euler2quat(0., 0., self.ego_pose[2], axes='sxyz') - ego_odom.pose.pose.orientation.x = ego_quat[1] - ego_odom.pose.pose.orientation.y = ego_quat[2] - ego_odom.pose.pose.orientation.z = ego_quat[3] - ego_odom.pose.pose.orientation.w = ego_quat[0] - ego_odom.twist.twist.linear.x = self.ego_speed[0] - ego_odom.twist.twist.linear.y = self.ego_speed[1] - ego_odom.twist.twist.angular.z = self.ego_speed[2] - self.ego_odom_pub.publish(ego_odom) - - if self.has_opp: - opp_odom = Odometry() - opp_odom.header.stamp = ts - opp_odom.header.frame_id = 'map' - opp_odom.child_frame_id = self.opp_namespace + '/base_link' - opp_odom.pose.pose.position.x = self.opp_pose[0] - opp_odom.pose.pose.position.y = self.opp_pose[1] - opp_quat = euler.euler2quat(0., 0., self.opp_pose[2], axes='sxyz') - opp_odom.pose.pose.orientation.x = opp_quat[1] - opp_odom.pose.pose.orientation.y = opp_quat[2] - opp_odom.pose.pose.orientation.z = opp_quat[3] - opp_odom.pose.pose.orientation.w = opp_quat[0] - opp_odom.twist.twist.linear.x = self.opp_speed[0] - opp_odom.twist.twist.linear.y = self.opp_speed[1] - opp_odom.twist.twist.angular.z = self.opp_speed[2] - self.opp_odom_pub.publish(opp_odom) - self.opp_ego_odom_pub.publish(ego_odom) - self.ego_opp_odom_pub.publish(opp_odom) - - def _publish_transforms(self, ts): - ego_t = Transform() - ego_t.translation.x = self.ego_pose[0] - ego_t.translation.y = self.ego_pose[1] - ego_t.translation.z = 0.0 - ego_quat = euler.euler2quat(0.0, 0.0, self.ego_pose[2], axes='sxyz') - ego_t.rotation.x = ego_quat[1] - ego_t.rotation.y = ego_quat[2] - ego_t.rotation.z = ego_quat[3] - ego_t.rotation.w = ego_quat[0] - - ego_ts = TransformStamped() - ego_ts.transform = ego_t - ego_ts.header.stamp = ts - ego_ts.header.frame_id = 'map' - ego_ts.child_frame_id = self.ego_namespace + '/base_link' - self.br.sendTransform(ego_ts) - - if self.has_opp: - opp_t = Transform() - opp_t.translation.x = self.opp_pose[0] - opp_t.translation.y = self.opp_pose[1] - opp_t.translation.z = 0.0 - opp_quat = euler.euler2quat(0.0, 0.0, self.opp_pose[2], axes='sxyz') - opp_t.rotation.x = opp_quat[1] - opp_t.rotation.y = opp_quat[2] - opp_t.rotation.z = opp_quat[3] - opp_t.rotation.w = opp_quat[0] - - opp_ts = TransformStamped() - opp_ts.transform = opp_t - opp_ts.header.stamp = ts - opp_ts.header.frame_id = 'map' - opp_ts.child_frame_id = self.opp_namespace + '/base_link' - self.br.sendTransform(opp_ts) - - def _publish_wheel_transforms(self, ts): - ego_wheel_ts = TransformStamped() - ego_wheel_quat = euler.euler2quat(0., 0., self.ego_steer, axes='sxyz') - ego_wheel_ts.transform.rotation.x = ego_wheel_quat[1] - ego_wheel_ts.transform.rotation.y = ego_wheel_quat[2] - ego_wheel_ts.transform.rotation.z = ego_wheel_quat[3] - ego_wheel_ts.transform.rotation.w = ego_wheel_quat[0] - ego_wheel_ts.header.stamp = ts - ego_wheel_ts.header.frame_id = self.ego_namespace + '/front_left_hinge' - ego_wheel_ts.child_frame_id = self.ego_namespace + '/front_left_wheel' - self.br.sendTransform(ego_wheel_ts) - ego_wheel_ts.header.frame_id = self.ego_namespace + '/front_right_hinge' - ego_wheel_ts.child_frame_id = self.ego_namespace + '/front_right_wheel' - self.br.sendTransform(ego_wheel_ts) - - if self.has_opp: - opp_wheel_ts = TransformStamped() - opp_wheel_quat = euler.euler2quat(0., 0., self.opp_steer, axes='sxyz') - opp_wheel_ts.transform.rotation.x = opp_wheel_quat[1] - opp_wheel_ts.transform.rotation.y = opp_wheel_quat[2] - opp_wheel_ts.transform.rotation.z = opp_wheel_quat[3] - opp_wheel_ts.transform.rotation.w = opp_wheel_quat[0] - opp_wheel_ts.header.stamp = ts - opp_wheel_ts.header.frame_id = self.opp_namespace + '/front_left_hinge' - opp_wheel_ts.child_frame_id = self.opp_namespace + '/front_left_wheel' - self.br.sendTransform(opp_wheel_ts) - opp_wheel_ts.header.frame_id = self.opp_namespace + '/front_right_hinge' - opp_wheel_ts.child_frame_id = self.opp_namespace + '/front_right_wheel' - self.br.sendTransform(opp_wheel_ts) - - def _publish_laser_transforms(self, ts): - ego_scan_ts = TransformStamped() - ego_scan_ts.transform.translation.x = self.scan_distance_to_base_link - # ego_scan_ts.transform.translation.z = 0.04+0.1+0.025 - ego_scan_ts.transform.rotation.w = 1. - ego_scan_ts.header.stamp = ts - ego_scan_ts.header.frame_id = self.ego_namespace + '/base_link' - ego_scan_ts.child_frame_id = self.ego_namespace + '/laser' - self.br.sendTransform(ego_scan_ts) - - if self.has_opp: - opp_scan_ts = TransformStamped() - opp_scan_ts.transform.translation.x = self.scan_distance_to_base_link - opp_scan_ts.transform.rotation.w = 1. - opp_scan_ts.header.stamp = ts - opp_scan_ts.header.frame_id = self.opp_namespace + '/base_link' - opp_scan_ts.child_frame_id = self.opp_namespace + '/laser' - self.br.sendTransform(opp_scan_ts) - -def main(args=None): - rclpy.init(args=args) - gym_bridge = GymBridge() - rclpy.spin(gym_bridge) - -if __name__ == '__main__': - main() diff --git a/f1tenth_gym_ros/launch/camera.launch.py b/f1tenth_gym_ros/launch/camera.launch.py deleted file mode 100644 index 3691721..0000000 --- a/f1tenth_gym_ros/launch/camera.launch.py +++ /dev/null @@ -1,21 +0,0 @@ -import os - -from launch import LaunchDescription -from launch_ros.actions import Node - -def generate_launch_description(): - - - - return LaunchDescription([ - - Node( - package='v4l2_camera', - executable='v4l2_camera_node', - output='screen', - parameters=[{ - 'image_size': [640,480], - 'camera_frame_id': 'camera_link_optical' - }] - ) - ]) \ No newline at end of file diff --git a/f1tenth_gym_ros/launch/ego_racecar.xacro b/f1tenth_gym_ros/launch/ego_racecar.xacro deleted file mode 100644 index 0ca6741..0000000 --- a/f1tenth_gym_ros/launch/ego_racecar.xacro +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/f1tenth_gym_ros/launch/gazebo_racecar.xacro b/f1tenth_gym_ros/launch/gazebo_racecar.xacro deleted file mode 100644 index 27a8438..0000000 --- a/f1tenth_gym_ros/launch/gazebo_racecar.xacro +++ /dev/null @@ -1,382 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - joint_states:=joint_states - - 50 - base_to_back_left_wheel - base_to_back_right_wheel - front_left_hinge_to_wheel - front_right_hinge_to_wheel - base_to_front_left_hinge - base_to_front_right_hinge - - - - - - - Gazebo/Blue - 0.2 - 0.2 - - - - Gazebo/White - ${wheel_mu1} - ${wheel_mu2} - - - - Gazebo/White - ${wheel_mu1} - ${wheel_mu2} - - - - Gazebo/White - ${wheel_mu1} - ${wheel_mu2} - - - - Gazebo/White - ${wheel_mu1} - ${wheel_mu2} - - - - Gazebo/Black - - - - - Gazebo/Red - - 0 0 0 0 0 0 - true - 10 - - 1.089 - - R8G8B8 - 640 - 480 - - - 0.05 - 8.0 - - - - - - image_raw:=image_raw - image_depth:=depth/image_raw - camera_info:=camera_info - camera_info_depth:=depth/camera_info - points:=depth/points - - camera - ego_racecar/camera_optical_frame - 0.07 - 0.1 - 100.0 - - - - - \ No newline at end of file diff --git a/f1tenth_gym_ros/launch/gazebo_test.launch.py b/f1tenth_gym_ros/launch/gazebo_test.launch.py deleted file mode 100644 index e450688..0000000 --- a/f1tenth_gym_ros/launch/gazebo_test.launch.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env python3 -# MIT License - F1Tenth Gym ROS with Gazebo support -# Based on original F1Tenth launch but adding Gazebo simulation - -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.actions import IncludeLaunchDescription -from launch.launch_description_sources import PythonLaunchDescriptionSource -from launch.substitutions import Command -from launch.actions import TimerAction -from launch.actions import DeclareLaunchArgument -from launch.substitutions import LaunchConfiguration -from ament_index_python.packages import get_package_share_directory -import os -import yaml - -def generate_launch_description(): - ld = LaunchDescription() - - # Cargar configuración original de F1Tenth - config = os.path.join( - get_package_share_directory('f1tenth_gym_ros'), - 'config', - 'sim.yaml' - ) - config_dict = yaml.safe_load(open(config, 'r')) - has_opp = config_dict['bridge']['ros__parameters']['num_agent'] > 1 - - # === PARTE NUEVA: GAZEBO === - package_name = 'f1tenth_gym_ros' - - # Parámetros de Gazebo - gazebo_params_file = os.path.join(get_package_share_directory(package_name), 'config', 'gazebo_params.yaml') - - # Lanzar Gazebo Classic con mundo seleccionable - gazebo = IncludeLaunchDescription( - PythonLaunchDescriptionSource([os.path.join( - get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py')]), - launch_arguments={ - 'world': LaunchConfiguration('world'), # ESTA LÍNEA FALTA - 'extra_gazebo_args': '--ros-args --params-file ' + gazebo_params_file - }.items() - ) - - world_arg = DeclareLaunchArgument( - 'world', - default_value='', - description='Path to world file' - ) - - # === ROBOT STATE PUBLISHERS MODIFICADOS PARA GAZEBO === - - # Ego robot con soporte Gazebo (usando nuestro nuevo XACRO) - ego_robot_publisher = Node( - package='robot_state_publisher', - executable='robot_state_publisher', - name='ego_robot_state_publisher', - parameters=[{ - 'robot_description': Command(['xacro ', os.path.join(get_package_share_directory('f1tenth_gym_ros'), 'launch', 'gazebo_racecar.xacro'), ' use_ros2_control:=false']), - 'use_sim_time': True # Importante para Gazebo - }], - remappings=[('/robot_description', 'ego_robot_description')] - ) - - # Spawner del ego robot en Gazebo - spawn_ego_robot = Node( - package='gazebo_ros', - executable='spawn_entity.py', - arguments=[ - '-topic', 'ego_robot_description', - '-entity', 'ego_racecar', - '-x', '0', '-y', '0', '-z', '0.1' - ], - output='screen' - ) - - # Robot oponente (si existe) - if has_opp: - opp_robot_publisher = Node( - package='robot_state_publisher', - executable='robot_state_publisher', - name='opp_robot_state_publisher', - parameters=[{ - 'robot_description': Command(['xacro ', os.path.join(get_package_share_directory('f1tenth_gym_ros'), 'launch', 'opp_racecar.xacro')]), - 'use_sim_time': True - }], - remappings=[('/robot_description', 'opp_robot_description')] - ) - - # Spawner del robot oponente - spawn_opp_robot = Node( - package='gazebo_ros', - executable='spawn_entity.py', - arguments=[ - '-topic', 'opp_robot_description', - '-entity', 'opp_racecar', - '-x', '2', '-y', '0', '-z', '0.1' # Posición diferente - ], - output='screen' - ) - - # === PARTE ORIGINAL DE F1TENTH === - - # Bridge node (comunicación con el simulador F1Tenth) - bridge_node = Node( - package='f1tenth_gym_ros', - executable='gym_bridge', - name='bridge', - parameters=[config, {'use_sim_time': True}] # Añadido use_sim_time - ) - - # RViz - rviz_node = Node( - package='rviz2', - executable='rviz2', - name='rviz', - arguments=['-d', os.path.join(get_package_share_directory('f1tenth_gym_ros'), 'launch', 'gym_bridge.rviz')], - parameters=[{'use_sim_time': True}] - ) - - # Map server - map_server_node = Node( - package='nav2_map_server', - executable='map_server', - parameters=[ - {'yaml_filename': config_dict['bridge']['ros__parameters']['map_path'] + '.yaml'}, - {'topic': 'map'}, - {'frame_id': 'map'}, - {'output': 'screen'}, - {'use_sim_time': True} - ] - ) - - # Navigation lifecycle manager - nav_lifecycle_node = Node( - package='nav2_lifecycle_manager', - executable='lifecycle_manager', - name='lifecycle_manager_localization', - output='screen', - parameters=[ - {'use_sim_time': True}, - {'autostart': True}, - {'node_names': ['map_server']} - ] - ) - - # Spawners de controladores ros2_control - ackermann_controller_spawner = TimerAction( - period=5.0, # Esperar 5 segundos - actions=[ - Node( - package="controller_manager", - executable="spawner", - arguments=["ackermann_steering_controller"], - parameters=[{'use_sim_time': True}], - output='screen' - ) - ] - ) - - joint_broadcaster_spawner = TimerAction( - period=3.0, # Esperar 3 segundos - actions=[ - Node( - package="controller_manager", - executable="spawner", - arguments=["joint_state_broadcaster"], - parameters=[{'use_sim_time': True}], - output='screen' - ) - ] - ) - - # === CONSTRUIR LAUNCH DESCRIPTION === - - # Gazebo primero - ld.add_action(gazebo) - - # Robots - ld.add_action(ego_robot_publisher) - ld.add_action(spawn_ego_robot) - - if has_opp: - ld.add_action(opp_robot_publisher) - ld.add_action(spawn_opp_robot) - - # F1Tenth original - ld.add_action(bridge_node) - ld.add_action(rviz_node) - ld.add_action(nav_lifecycle_node) - ld.add_action(map_server_node) - ld.add_action(world_arg) - # ros2_control spawners - ld.add_action(ackermann_controller_spawner) - ld.add_action(joint_broadcaster_spawner) - - return ld \ No newline at end of file diff --git a/f1tenth_gym_ros/launch/gym_bridge.rviz b/f1tenth_gym_ros/launch/gym_bridge.rviz deleted file mode 100644 index bb54b01..0000000 --- a/f1tenth_gym_ros/launch/gym_bridge.rviz +++ /dev/null @@ -1,322 +0,0 @@ -Panels: - - Class: rviz_common/Displays - Help Height: 78 - Name: Displays - Property Tree Widget: - Expanded: - - /Global Options1 - - /Status1 - - /Map1/Topic1 - Splitter Ratio: 0.5 - Tree Height: 802 - - Class: rviz_common/Selection - Name: Selection - - Class: rviz_common/Tool Properties - Expanded: - - /2D Goal Pose1 - - /Publish Point1 - Name: Tool Properties - Splitter Ratio: 0.5886790156364441 - - Class: rviz_common/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.5 -Visualization Manager: - Class: "" - Displays: - - Alpha: 0.5 - Cell Size: 1 - Class: rviz_default_plugins/Grid - Color: 160; 160; 164 - Enabled: false - Line Style: - Line Width: 0.029999999329447746 - Value: Lines - Name: Grid - Normal Cell Count: 0 - Offset: - X: 0 - Y: 0 - Z: 0 - Plane: XY - Plane Cell Count: 10 - Reference Frame: - Value: true - - Alpha: 0.699999988079071 - Class: rviz_default_plugins/Map - Color Scheme: map - Draw Behind: false - Enabled: true - Name: Map - Topic: - Depth: 5 - Durability Policy: Transient Local - History Policy: Keep Last - Reliability Policy: Reliable - Value: /map - Update Topic: - Depth: 5 - Durability Policy: Volatile - History Policy: Keep Last - Reliability Policy: Reliable - Value: /map_updates - Use Timestamp: false - Value: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Autocompute Value Bounds: - Max Value: 30.2736759185791 - Min Value: -0.7132953405380249 - Value: true - Axis: X - Channel Name: intensity - Class: rviz_default_plugins/LaserScan - Color: 255; 255; 255 - Color Transformer: AxisColor - Decay Time: 0 - Enabled: true - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 4096 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: LaserScan - Position Transformer: XYZ - Selectable: true - Size (Pixels): 3 - Size (m): 0.10000000149011612 - Style: Flat Squares - Topic: - Depth: 5 - Durability Policy: Volatile - History Policy: Keep Last - Reliability Policy: Reliable - Value: /scan - Use Fixed Frame: true - Use rainbow: true - Value: true - - Alpha: 1 - Class: rviz_default_plugins/RobotModel - Collision Enabled: false - Description File: "" - Description Source: Topic - Description Topic: - Depth: 5 - Durability Policy: Volatile - History Policy: Keep Last - Reliability Policy: Reliable - Value: /opp_robot_description - Enabled: true - Links: - All Links Enabled: true - Expand Joint Details: false - Expand Link Details: false - Expand Tree: false - Link Tree Style: Links in Alphabetic Order - opp_racecar/back_left_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - opp_racecar/back_right_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - opp_racecar/base_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - opp_racecar/front_left_hinge: - Alpha: 1 - Show Axes: false - Show Trail: false - opp_racecar/front_left_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - opp_racecar/front_right_hinge: - Alpha: 1 - Show Axes: false - Show Trail: false - opp_racecar/front_right_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - opp_racecar/laser_model: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - Name: OPP-RobotModel - TF Prefix: "" - Update Interval: 0 - Value: true - Visual Enabled: true - - Alpha: 1 - Class: rviz_default_plugins/RobotModel - Collision Enabled: false - Description File: "" - Description Source: Topic - Description Topic: - Depth: 5 - Durability Policy: Volatile - History Policy: Keep Last - Reliability Policy: Reliable - Value: /ego_robot_description - Enabled: true - Links: - All Links Enabled: true - Expand Joint Details: false - Expand Link Details: false - Expand Tree: false - Link Tree Style: Links in Alphabetic Order - ego_racecar/back_left_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ego_racecar/back_right_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ego_racecar/base_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ego_racecar/front_left_hinge: - Alpha: 1 - Show Axes: false - Show Trail: false - ego_racecar/front_left_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ego_racecar/front_right_hinge: - Alpha: 1 - Show Axes: false - Show Trail: false - ego_racecar/front_right_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ego_racecar/laser_model: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - Name: RobotModel - TF Prefix: "" - Update Interval: 0 - Value: true - Visual Enabled: true - - Alpha: 1 - Buffer Length: 1 - Class: rviz_default_plugins/Path - Color: 25; 255; 0 - Enabled: false - Head Diameter: 0.30000001192092896 - Head Length: 0.20000000298023224 - Length: 0.30000001192092896 - Line Style: Billboards - Line Width: 0.1 - Name: Path - Offset: - X: 0 - Y: 0 - Z: 0 - Pose Color: 255; 85; 255 - Pose Style: None - Radius: 0.029999999329447746 - Shaft Diameter: 0.10000000149011612 - Shaft Length: 0.10000000149011612 - Topic: /planned_path - Unreliable: false - Value: true - Enabled: true - Global Options: - Background Color: 48; 48; 48 - Fixed Frame: map - Frame Rate: 30 - Name: root - Tools: - - Class: rviz_default_plugins/Interact - Hide Inactive Objects: true - - Class: rviz_default_plugins/MoveCamera - - Class: rviz_default_plugins/Select - - Class: rviz_default_plugins/FocusCamera - - Class: rviz_default_plugins/Measure - Line color: 128; 128; 0 - - Class: rviz_default_plugins/SetInitialPose - Topic: - Depth: 5 - Durability Policy: Volatile - History Policy: Keep Last - Reliability Policy: Reliable - Value: /initialpose - - Class: rviz_default_plugins/SetGoal - Topic: - Depth: 5 - Durability Policy: Volatile - History Policy: Keep Last - Reliability Policy: Reliable - Value: /goal_pose - - Class: rviz_default_plugins/PublishPoint - Single click: true - Topic: - Depth: 5 - Durability Policy: Volatile - History Policy: Keep Last - Reliability Policy: Reliable - Value: /clicked_point - Transformation: - Current: - Class: rviz_default_plugins/TF - Value: true - Views: - Current: - Class: rviz_default_plugins/Orbit - Distance: 10 - Enable Stereo Rendering: - Stereo Eye Separation: 0.05999999865889549 - Stereo Focal Distance: 1 - Swap Stereo Eyes: false - Value: false - Focal Point: - X: 0 - Y: 0 - Z: 0 - Focal Shape Fixed Size: true - Focal Shape Size: 0.05000000074505806 - Invert Z Axis: false - Name: Current View - Near Clip Distance: 0.009999999776482582 - Pitch: 0.5353981852531433 - Target Frame: - Value: Orbit (rviz) - Yaw: 3.1453983783721924 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 900 - Hide Left Dock: false - Hide Right Dock: false - QMainWindow State: 000000ff00000000fd000000040000000000000156000003abfc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b000003ab000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f000003abfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003b000003ab000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d006501000000000000045000000000000000000000075b000003ab00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: false - Width: 1600 - X: 52 - Y: 25 diff --git a/f1tenth_gym_ros/launch/gym_bridge_launch.py b/f1tenth_gym_ros/launch/gym_bridge_launch.py deleted file mode 100644 index 7bc6acc..0000000 --- a/f1tenth_gym_ros/launch/gym_bridge_launch.py +++ /dev/null @@ -1,95 +0,0 @@ -# MIT License - -# Copyright (c) 2020 Hongrui Zheng - -# 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. - -from launch import LaunchDescription -from launch_ros.actions import Node -from launch.substitutions import Command -from ament_index_python.packages import get_package_share_directory -import os -import yaml - -def generate_launch_description(): - ld = LaunchDescription() - config = os.path.join( - get_package_share_directory('f1tenth_gym_ros'), - 'config', - 'sim.yaml' - ) - config_dict = yaml.safe_load(open(config, 'r')) - has_opp = config_dict['bridge']['ros__parameters']['num_agent'] > 1 - teleop = config_dict['bridge']['ros__parameters']['kb_teleop'] - - bridge_node = Node( - package='f1tenth_gym_ros', - executable='gym_bridge', - name='bridge', - parameters=[config] - ) - rviz_node = Node( - package='rviz2', - executable='rviz2', - name='rviz', - arguments=['-d', os.path.join(get_package_share_directory('f1tenth_gym_ros'), 'launch', 'gym_bridge.rviz')] - ) - map_server_node = Node( - package='nav2_map_server', - executable='map_server', - parameters=[{'yaml_filename': config_dict['bridge']['ros__parameters']['map_path'] + '.yaml'}, - {'topic': 'map'}, - {'frame_id': 'map'}, - {'output': 'screen'}, - {'use_sim_time': True}] - ) - nav_lifecycle_node = Node( - package='nav2_lifecycle_manager', - executable='lifecycle_manager', - name='lifecycle_manager_localization', - output='screen', - parameters=[{'use_sim_time': True}, - {'autostart': True}, - {'node_names': ['map_server']}] - ) - ego_robot_publisher = Node( - package='robot_state_publisher', - executable='robot_state_publisher', - name='ego_robot_state_publisher', - parameters=[{'robot_description': Command(['xacro ', os.path.join(get_package_share_directory('f1tenth_gym_ros'), 'launch', 'ego_racecar.xacro')])}], - remappings=[('/robot_description', 'ego_robot_description')] - ) - opp_robot_publisher = Node( - package='robot_state_publisher', - executable='robot_state_publisher', - name='opp_robot_state_publisher', - parameters=[{'robot_description': Command(['xacro ', os.path.join(get_package_share_directory('f1tenth_gym_ros'), 'launch', 'opp_racecar.xacro')])}], - remappings=[('/robot_description', 'opp_robot_description')] - ) - - # finalize - ld.add_action(rviz_node) - ld.add_action(bridge_node) - ld.add_action(nav_lifecycle_node) - ld.add_action(map_server_node) - ld.add_action(ego_robot_publisher) - if has_opp: - ld.add_action(opp_robot_publisher) - - return ld \ No newline at end of file diff --git a/f1tenth_gym_ros/launch/opp_racecar.xacro b/f1tenth_gym_ros/launch/opp_racecar.xacro deleted file mode 100644 index bedec5a..0000000 --- a/f1tenth_gym_ros/launch/opp_racecar.xacro +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/f1tenth_gym_ros/launch/ros2_control_ackermann.xacro b/f1tenth_gym_ros/launch/ros2_control_ackermann.xacro deleted file mode 100644 index 2d053f4..0000000 --- a/f1tenth_gym_ros/launch/ros2_control_ackermann.xacro +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - gazebo_ros2_control/GazeboSystem - - - - - - - - - - - - - - - - - -10 - 10 - - - - - - - - -10 - 10 - - - - - - - - - -0.7854 - 0.7854 - - - - - - - - -0.7854 - 0.7854 - - - - - - - - - - $(find f1tenth_gym_ros)/config/ackermann_controllers.yaml - ego_robot_description - ego_robot_state_publisher - - - - \ No newline at end of file diff --git a/f1tenth_gym_ros/launch/rplidar.launch.py b/f1tenth_gym_ros/launch/rplidar.launch.py deleted file mode 100644 index 352594d..0000000 --- a/f1tenth_gym_ros/launch/rplidar.launch.py +++ /dev/null @@ -1,20 +0,0 @@ -import os -from launch import LaunchDescription -from launch_ros.actions import Node - -def generate_launch_description(): - - return LaunchDescription([ - - Node( - package='rplidar_ros', - executable='rplidar_composition', - output='screen', - parameters=[{ - 'serial_port': '/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0-port0', - 'frame_id': 'laser_frame', - 'angle_compensate': True, - 'scan_mode': 'Standard' - }] - ) - ]) \ No newline at end of file diff --git a/f1tenth_gym_ros/maps/SaoPaulo_map.png b/f1tenth_gym_ros/maps/SaoPaulo_map.png deleted file mode 100644 index 5b0876efc6b1a5de122af095e4e73a599861bf6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92014 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 DRNQd* diff --git a/f1tenth_gym_ros/maps/SaoPaulo_map.yaml b/f1tenth_gym_ros/maps/SaoPaulo_map.yaml deleted file mode 100644 index eb0fb79..0000000 --- a/f1tenth_gym_ros/maps/SaoPaulo_map.yaml +++ /dev/null @@ -1,6 +0,0 @@ -image: SaoPaulo_map.png -resolution: 0.04877 -origin: [-27.988851027944648,-33.41588383183014, 0.000000] -negate: 0 -occupied_thresh: 0.45 -free_thresh: 0.196 diff --git a/f1tenth_gym_ros/maps/Spielberg_map.png b/f1tenth_gym_ros/maps/Spielberg_map.png deleted file mode 100644 index e9ef68d14b471ae811438323162d4d825244a18c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62176 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

16EF5=)ovF|7 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 khUa$pe46`=0@p_$B)l(p@7Ndr0x94;>Hq)$ diff --git a/f1tenth_gym_ros/maps/Spielberg_map.yaml b/f1tenth_gym_ros/maps/Spielberg_map.yaml deleted file mode 100644 index 2397577..0000000 --- a/f1tenth_gym_ros/maps/Spielberg_map.yaml +++ /dev/null @@ -1,6 +0,0 @@ -image: Spielberg_map.png -resolution: 0.05796 -origin: [-84.85359914210505,-36.30299725862132, 0.000000] -negate: 0 -occupied_thresh: 0.45 -free_thresh: 0.196 diff --git a/f1tenth_gym_ros/maps/Spielberg_obs_map.png b/f1tenth_gym_ros/maps/Spielberg_obs_map.png deleted file mode 100644 index 56706fa4e56ab7dd1fb2d96f0684b74f4a68c778..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95482 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 E10*nJO#lD@ diff --git a/f1tenth_gym_ros/maps/Spielberg_obs_map.yaml b/f1tenth_gym_ros/maps/Spielberg_obs_map.yaml deleted file mode 100644 index 68dcb93..0000000 --- a/f1tenth_gym_ros/maps/Spielberg_obs_map.yaml +++ /dev/null @@ -1,6 +0,0 @@ -image: Spielberg_obs_map.png -resolution: 0.05796 -origin: [-84.85359914210505,-36.30299725862132, 0.000000] -negate: 0 -occupied_thresh: 0.45 -free_thresh: 0.196 diff --git a/f1tenth_gym_ros/maps/levine.png b/f1tenth_gym_ros/maps/levine.png deleted file mode 100644 index 2803b387d54d6aee2915a67b6d14b95f932c421c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13273 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 diff --git a/f1tenth_gym_ros/maps/levineB.yaml b/f1tenth_gym_ros/maps/levineB.yaml deleted file mode 100644 index 1ec9b18..0000000 --- a/f1tenth_gym_ros/maps/levineB.yaml +++ /dev/null @@ -1,6 +0,0 @@ -image: levineB.png -resolution: 0.050000 -origin: [-25.0, -12.75, 0.000000] -negate: 0 -occupied_thresh: 0.65 -free_thresh: 0.196 diff --git a/f1tenth_gym_ros/package.xml b/f1tenth_gym_ros/package.xml deleted file mode 100644 index f65fff2..0000000 --- a/f1tenth_gym_ros/package.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - f1tenth_gym_ros - 0.0.0 - Bridge for using f1tenth_gym in ROS2 - Billy Zheng - MIT - - geometry_msgs - nav_msgs - sensor_msgs - ackermann_msgs - launch - launch_ros - tf2_ros - rclpy - joint_state_publisher - xacro - nav2_map_server - nav2_lifecycle_manager - teleop_twist_keyboard - - python-transforms3d-pip - gazebo_ros - ros2_control - ros2_controllers - gazebo_ros2_control - ackermann_steering_controller - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/f1tenth_gym_ros/resource/f1tenth_gym_ros b/f1tenth_gym_ros/resource/f1tenth_gym_ros deleted file mode 100644 index e69de29..0000000 diff --git a/f1tenth_gym_ros/setup.cfg b/f1tenth_gym_ros/setup.cfg deleted file mode 100644 index 80194fa..0000000 --- a/f1tenth_gym_ros/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script_dir=$base/lib/f1tenth_gym_ros -[install] -install_scripts=$base/lib/f1tenth_gym_ros diff --git a/f1tenth_gym_ros/setup.py b/f1tenth_gym_ros/setup.py deleted file mode 100644 index f6dab7e..0000000 --- a/f1tenth_gym_ros/setup.py +++ /dev/null @@ -1,32 +0,0 @@ -from setuptools import setup -import os -from glob import glob - -package_name = 'f1tenth_gym_ros' - -setup( - name=package_name, - version='0.0.0', - 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, 'launch'), glob('launch/*.py')), - (os.path.join('share', package_name, 'launch'), glob('launch/*.xacro')), - (os.path.join('share', package_name, 'launch'), glob('launch/*.rviz')), - (os.path.join('share', package_name, 'config'), glob('config/*.yaml')), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='Billy Zheng', - maintainer_email='billyzheng.bz@gmail.com', - description='Bridge for using f1tenth_gym in ROS2', - license='MIT', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - 'gym_bridge = f1tenth_gym_ros.gym_bridge:main' - ], - }, -) diff --git a/f1tenth_gym_ros/test/test_copyright.py b/f1tenth_gym_ros/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/f1tenth_gym_ros/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/f1tenth_gym_ros/test/test_flake8.py b/f1tenth_gym_ros/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/f1tenth_gym_ros/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/f1tenth_gym_ros/test/test_pep257.py b/f1tenth_gym_ros/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/f1tenth_gym_ros/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/f1tenth_gym_ros/worlds/empty.world b/f1tenth_gym_ros/worlds/empty.world deleted file mode 100644 index 5321672..0000000 --- a/f1tenth_gym_ros/worlds/empty.world +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - model://sun - - - - model://ground_plane - - - diff --git a/f1tenth_gym_ros/worlds/levine.world b/f1tenth_gym_ros/worlds/levine.world deleted file mode 100644 index 8317c0a..0000000 --- a/f1tenth_gym_ros/worlds/levine.world +++ /dev/null @@ -1,9025 +0,0 @@ - - - - - 1 - 0 0 10 0 -0 0 - 0.8 0.8 0.8 1 - 0.2 0.2 0.2 1 - - 1000 - 0.9 - 0.01 - 0.001 - - -0.5 0.1 -0.9 - - 0 - 0 - 0 - - - - 1 - - - - - 0 0 1 - 100 100 - - - - - - 100 - 50 - - - - - - - - - - - 10 - - - 0 - - - 0 0 1 - 100 100 - - - - - - - 0 - 0 - 0 - - - 0 0 -9.8 - 6e-06 2.3e-05 -4.2e-05 - - - 0.001 - 1 - 1000 - - - 0.4 0.4 0.4 1 - 0.7 0.7 0.7 1 - 1 - - - - - EARTH_WGS84 - 0 - 0 - 0 - 0 - - - 0.555504 1.12858 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 1.7631 1.40061 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 2.63146 1.21638 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 3.67297 1.219 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 4.70994 1.20235 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 5.76654 1.19215 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 6.85552 1.16656 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 7.9487 1.15326 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 9.03135 1.11313 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 9.3925 -1.93079 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 7.71543 -1.67512 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 6.68845 -1.68928 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 5.63972 -1.68978 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 4.52806 -1.65041 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 3.41947 -1.62704 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 2.23436 -1.60062 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 1.19901 -1.60491 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 8.79403 -2.72073 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 8.89804 -3.86534 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 9.59968 -4.97218 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 10.916 -5.08427 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 11.9942 -5.11769 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.128 -4.61853 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.2109 -3.58645 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.3131 -2.54327 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.3431 -1.50287 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.4227 -0.430545 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 14.4911 -0.475827 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 15.5576 -0.450193 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 16.5913 -0.356369 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 17.6667 0.111068 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 17.7155 1.18357 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 15.533 2.5241 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 16.6003 2.46368 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 16.6668 0.917588 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.342 3.4316 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.3525 4.50859 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.3079 5.63666 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.346 6.71776 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 13.3236 7.76853 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 9.10292 2.14492 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 9.08102 3.26349 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 8.97202 4.41197 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 8.92411 5.50557 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 8.90039 6.60085 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 8.89491 7.65407 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 11.5614 7.28234 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 8.41954 10.443 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 9.37924 10.7607 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 10.4354 10.7533 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 11.4623 10.7523 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 11.5874 8.48628 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 11.5683 9.58154 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 7.26487 10.8009 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 6.17175 10.8343 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 5.04461 10.852 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 3.95809 10.893 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 7.8022 7.65591 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 6.69164 7.6545 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 5.60862 7.62727 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 4.46278 7.63473 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 2.84719 10.9112 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 1.73992 10.9582 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 0.66692 10.9659 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 3.38354 7.7267 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 2.13895 7.78205 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 1.03513 7.75902 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -0.495272 11.0462 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -0.104328 7.99805 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -1.60407 11.2656 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -1.07686 8.20701 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -2.77324 11.3221 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -2.09643 8.13987 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -3.9399 11.375 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -3.22691 8.14265 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -5.00002 11.3706 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -6.19269 11.4491 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -7.36966 11.5014 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -8.67595 11.6101 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -9.84164 11.5912 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -10.9208 11.5643 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -4.3458 8.14362 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -5.37999 8.10127 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -6.5467 8.08655 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -7.62958 8.05369 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -8.83422 8.13954 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -11.9972 11.6792 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.1299 11.7058 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -9.9062 8.11613 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -11.0062 8.11662 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -12.1401 8.13165 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.4024 8.25386 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.0801 12.7181 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.1566 13.8382 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -16.4113 12.0594 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -16.7208 9.01924 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.8541 10.0347 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.8622 12.115 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.839 13.1183 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.9405 7.97497 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.9352 6.93311 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.913 5.87885 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.9509 4.86819 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.3553 7.38097 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.3012 6.24082 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.2875 5.18055 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.1438 4.119 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.1862 3.07745 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.1906 2.0408 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.9896 3.83812 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -16.0044 2.81289 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -16.0156 1.78233 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -16.0063 0.710137 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -15.9928 -0.34604 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -14.877 -0.728863 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -13.6985 -0.736769 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -12.0773 2.0238 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -11.0152 2.00561 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -9.97692 2.00046 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -8.93478 1.99215 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -7.9059 1.97211 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -6.89613 1.97278 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -5.81978 1.93246 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -4.75596 1.92004 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -3.72552 1.91922 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -2.67393 1.86658 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -1.51822 1.78266 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -0.500902 1.27134 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 0.157735 -1.59175 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -0.912083 -1.58529 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -1.94608 -1.56292 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -3.00828 -1.53047 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -4.13807 -1.49451 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -5.19182 -1.44907 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -6.21451 -1.46484 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -7.2365 -1.44735 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -8.39557 -1.35085 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -9.62361 -1.19336 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -10.74 -1.15437 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -11.8546 -1.08265 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - -12.736 -0.970076 0.5 0 -0 0 - - - 1 - - 0.166667 - 0 - 0 - 0.166667 - 0 - 0.166667 - - 0 0 0 0 -0 0 - - - - - 1 1 1 - - - 10 - - - - - - - - - - - - - - - - - 1 1 1 - - - - - - - 0 - 0 - 0 - - - - 2262 535000000 - 2685 66394843 - 1756923285 779809602 - 2262535 - - 0 0 0 0 -0 0 - 1 1 1 - - 0 0 0 0 -0 0 - 0 0 0 0 -0 0 - 0 0 0 0 -0 0 - 0 0 0 0 -0 0 - - - - -2.37462 0.266413 0.039999 -1.4e-05 -6e-06 -0.175538 - 1 1 1 - - -2.37462 0.266413 0.039999 -1.4e-05 -6e-06 -0.175538 - 0.000502 0.00011 -3e-06 -0.026802 0.004741 -0.006431 - 0.269005 1.4998 -0.001562 -1.31475 -1.48477 0.950964 - 0.212514 1.18484 -0.001234 0 -0 0 - - - -2.35716 0.364876 0.039997 -1.5709 0.678421 -0.175605 - 0.001146 0.000224 -0.00275 -0.010621 0.001895 -0.006457 - 1.27597 0.388122 -5.47472 0.276903 0.352852 0.610546 - 0.127597 0.038812 -0.547472 0 -0 0 - - - -2.39209 0.167951 0.04 1.57093 -0.997251 -0.175652 - -8.4e-05 0.000427 0.002767 -0.011217 -0.002074 -0.006401 - -1.07652 0.790035 5.48577 3.05608 -0.842808 -2.44733 - -0.107652 0.079003 0.548577 0 -0 0 - - - - 0.555507 1.19168 0.499995 0 1e-05 0 - 1 1 1 - - 0.555507 1.19168 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 1.57825 1.23788 0.499995 0 -1e-05 0 - 1 1 1 - - 1.57825 1.23788 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 - -0.010615 -0.006191 -9.78231 0 -0 0 - - - - 2.63146 1.21638 0.499995 0 1e-05 0 - 1 1 1 - - 2.63146 1.21638 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 6.68845 -1.68927 0.499995 -1e-05 0 0 - 1 1 1 - - 6.68845 -1.68927 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -16.7856 5.87885 0.499995 1e-05 -0 0 - 1 1 1 - - -16.7856 5.87885 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 - -0.004709 -0.011055 -9.78158 0 -0 0 - - - - -15.9509 4.8761 0.499995 0 1e-05 0 - 1 1 1 - - -15.9509 4.8761 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -13.3553 7.38097 0.499995 0 1e-05 0 - 1 1 1 - - -13.3553 7.38097 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -12.4339 6.24083 0.499995 -1e-05 0 0 - 1 1 1 - - -12.4339 6.24083 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -13.1391 5.18055 0.499995 1e-05 -0 0 - 1 1 1 - - -13.1391 5.18055 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 - -0.004709 -0.011055 -9.78158 0 -0 0 - - - - -13.1438 4.119 0.499995 -1e-05 0 0 - 1 1 1 - - -13.1438 4.119 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -13.1862 3.07745 0.499995 0 1e-05 0 - 1 1 1 - - -13.1862 3.07745 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -13.1906 2.04081 0.499995 -1e-05 0 0 - 1 1 1 - - -13.1906 2.04081 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -15.9896 3.83812 0.499995 0 1e-05 0 - 1 1 1 - - -15.9896 3.83812 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -16.0044 2.81289 0.499995 1e-05 -0 0 - 1 1 1 - - -16.0044 2.81289 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 - -0.004709 -0.011055 -9.78158 0 -0 0 - - - - 5.63972 -1.68978 0.499995 0 1e-05 0 - 1 1 1 - - 5.63972 -1.68978 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -16.0156 1.78233 0.499995 0 1e-05 0 - 1 1 1 - - -16.0156 1.78233 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -16.0063 0.710142 0.499995 -1e-05 0 0 - 1 1 1 - - -16.0063 0.710142 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -15.9928 -0.34604 0.499995 0 1e-05 0 - 1 1 1 - - -15.9928 -0.34604 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -14.877 -0.728858 0.499995 -1e-05 0 0 - 1 1 1 - - -14.877 -0.728858 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -13.7609 -0.72631 0.499995 1e-05 0 -0.011216 - 1 1 1 - - -13.7609 -0.72631 0.499995 1e-05 0 -0.011216 - 0 0 0 0 -0 0 - -0.00469 -0.01099 -9.7816 0.021976 -0.009376 1e-06 - -0.00469 -0.01099 -9.7816 0 -0 0 - - - - -12.0773 1.87529 0.499995 -1e-05 0 0 - 1 1 1 - - -12.0773 1.87529 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -11.0152 1.88765 0.5 0 -0 0 - 1 1 1 - - -11.0152 1.88765 0.5 0 -0 0 - 0 0 0 0 -0 0 - 0 -0 0 1e-06 1e-06 0 - 0 -0 0 0 -0 0 - - - - -9.97691 1.86931 0.499995 0 1e-05 0 - 1 1 1 - - -9.97691 1.86931 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 - 0.010615 -0.006191 -9.78231 0 -0 0 - - - - -8.93478 1.86691 0.499995 1e-05 -0 0 - 1 1 1 - - -8.93478 1.86691 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 - 0.004709 -0.011055 -9.78158 0 -0 0 - - - - -7.84055 1.83815 0.499995 -0 -1e-05 0.002763 - 1 1 1 - - -7.84055 1.83815 0.499995 -0 -1e-05 0.002763 - 0 0 0 0 -0 0 - -0.013424 -0.009385 -9.7776 0.018974 -0.02681 -9.7e-05 - -0.013424 -0.009385 -9.7776 0 -0 0 - - - - 4.52806 -1.6504 0.499995 -1e-05 0 0 - 1 1 1 - - 4.52806 -1.6504 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -6.84061 1.87689 0.499995 -0 1e-05 0.002709 - 1 1 1 - - -6.84061 1.87689 0.499995 -0 1e-05 0.002709 - 0 0 0 0 -0 0 - 0.012918 -0.008766 -9.77852 0.017719 0.025804 8.9e-05 - 0.012918 -0.008766 -9.77852 0 -0 0 - - - - -5.81978 1.82803 0.499995 0 1e-05 0 - 1 1 1 - - -5.81978 1.82803 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -4.75596 1.7931 0.499995 0 1e-05 0 - 1 1 1 - - -4.75596 1.7931 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -3.72552 1.78985 0.499995 0 1e-05 0 - 1 1 1 - - -3.72552 1.78985 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 - 0.010615 -0.006191 -9.78231 0 -0 0 - - - - -2.66754 1.63848 0.499995 0 1e-05 0 - 1 1 1 - - -2.66754 1.63848 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -1.51822 1.42433 0.499995 -1e-05 -0 -0 - 1 1 1 - - -1.51822 1.42433 0.499995 -1e-05 -0 -0 - 0 0 0 0 -0 0 - 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 - 0.004709 0.011055 -9.78158 0 -0 0 - - - - -0.500907 1.27134 0.499995 0 -1e-05 0 - 1 1 1 - - -0.500907 1.27134 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 - -0.010615 -0.006191 -9.78231 0 -0 0 - - - - 0.15774 -1.36253 0.499995 0 1e-05 0 - 1 1 1 - - 0.15774 -1.36253 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 - 0.010615 -0.006191 -9.78231 0 -0 0 - - - - -0.90612 -1.30563 0.499995 0 -1e-05 0 - 1 1 1 - - -0.90612 -1.30563 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 - -0.010615 -0.006191 -9.78231 0 -0 0 - - - - -1.94608 -1.25155 0.499995 -1e-05 0 0 - 1 1 1 - - -1.94608 -1.25155 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 3.47624 -1.6198 0.499995 0 1e-05 0 - 1 1 1 - - 3.47624 -1.6198 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -3.00827 -1.23218 0.499995 0 1e-05 0 - 1 1 1 - - -3.00827 -1.23218 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 - 0.010615 -0.006191 -9.78231 0 -0 0 - - - - -4.13807 -1.16413 0.499995 0 1e-05 0 - 1 1 1 - - -4.13807 -1.16413 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -5.19182 -1.13485 0.499995 0 -1e-05 0 - 1 1 1 - - -5.19182 -1.13485 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 - -0.010615 -0.006191 -9.78231 0 -0 0 - - - - -6.21451 -1.11865 0.499995 0 -1e-05 0 - 1 1 1 - - -6.21451 -1.11865 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 - -0.010615 0.006191 -9.78231 0 -0 0 - - - - -7.23651 -1.11583 0.499995 0 -1e-05 0 - 1 1 1 - - -7.23651 -1.11583 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 - -0.010615 -0.006191 -9.78231 0 -0 0 - - - - -8.39557 -1.03793 0.499995 0 -1e-05 0 - 1 1 1 - - -8.39557 -1.03793 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 - -0.010615 0.006191 -9.78231 0 -0 0 - - - - -9.62361 -0.935877 0.499995 -1e-05 -0 -0 - 1 1 1 - - -9.62361 -0.935877 0.499995 -1e-05 -0 -0 - 0 0 0 0 -0 0 - 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 - 0.004709 0.011055 -9.78158 0 -0 0 - - - - -10.74 -0.869872 0.499995 1e-05 -0 0 - 1 1 1 - - -10.74 -0.869872 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 - 0.004709 -0.011055 -9.78158 0 -0 0 - - - - -11.7618 -0.833957 0.499995 0 1e-05 -0.011209 - 1 1 1 - - -11.7618 -0.833957 0.499995 0 1e-05 -0.011209 - 0 0 0 0 -0 0 - 0.010684 0.006193 -9.78231 -0.012449 0.021363 -2.9e-05 - 0.010684 0.006193 -9.78231 0 -0 0 - - - - -12.7618 -0.818376 0.499995 1e-05 -0 -0.011211 - 1 1 1 - - -12.7618 -0.818376 0.499995 1e-05 -0 -0.011211 - 0 0 0 0 -0 0 - 0.004721 -0.011108 -9.78158 0.022213 0.009438 -1e-06 - 0.004721 -0.011108 -9.78158 0 -0 0 - - - - 2.2423 -1.45852 0.499995 0 -1e-05 0 - 1 1 1 - - 2.2423 -1.45852 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 - -0.010615 -0.006191 -9.78231 0 -0 0 - - - - 1.19901 -1.44068 0.5 -0 -0 -0 - 1 1 1 - - 1.19901 -1.44068 0.5 -0 -0 -0 - 0 0 0 0 -0 0 - -0 0 0 -1e-06 -1e-06 0 - -0 0 0 0 -0 0 - - - - 8.79403 -2.72072 0.499995 -1e-05 0 0 - 1 1 1 - - 8.79403 -2.72072 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 8.89804 -3.86534 0.499995 0 1e-05 0 - 1 1 1 - - 8.89804 -3.86534 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 9.59968 -4.97217 0.499995 -1e-05 0 0 - 1 1 1 - - 9.59968 -4.97217 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 10.916 -5.08427 0.499995 0 1e-05 0 - 1 1 1 - - 10.916 -5.08427 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 3.74606 1.22705 0.499995 -1e-05 -0 -0.082022 - 1 1 1 - - 3.74606 1.22705 0.499995 -1e-05 -0 -0.082022 - 0 0 0 0 -0 0 - -0.004658 0.011102 -9.78219 -0.022206 -0.009308 0 - -0.004658 0.011102 -9.78219 0 -0 0 - - - - 11.9942 -5.11768 0.499995 -1e-05 0 0 - 1 1 1 - - 11.9942 -5.11768 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 13.128 -4.61853 0.499995 0 1e-05 0 - 1 1 1 - - 13.128 -4.61853 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 13.2109 -3.58644 0.499995 -1e-05 0 0 - 1 1 1 - - 13.2109 -3.58644 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 13.3131 -2.54327 0.499995 0 1e-05 0 - 1 1 1 - - 13.3131 -2.54327 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 13.3431 -1.50286 0.499995 -1e-05 0 0 - 1 1 1 - - 13.3431 -1.50286 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 13.4227 -0.430542 0.499995 0 1e-05 0 - 1 1 1 - - 13.4227 -0.430542 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 14.4911 -0.475819 0.499995 -1e-05 0 0 - 1 1 1 - - 14.4911 -0.475819 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 15.5576 -0.45019 0.499995 0 1e-05 0 - 1 1 1 - - 15.5576 -0.45019 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 16.5913 -0.356361 0.499995 -1e-05 0 0 - 1 1 1 - - 16.5913 -0.356361 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 14.5156 2.51049 0.499995 -0 -1e-05 0.030671 - 1 1 1 - - 14.5156 2.51049 0.499995 -0 -1e-05 0.030671 - 0 0 0 0 -0 0 - -0.010775 0.006144 -9.78237 -0.012379 -0.021543 4.2e-05 - -0.010775 0.006144 -9.78237 0 -0 0 - - - - 4.82643 1.14872 0.499995 -1e-05 0 -0.080673 - 1 1 1 - - 4.82643 1.14872 0.499995 -1e-05 0 -0.080673 - 0 0 0 0 -0 0 - -0.004661 0.011107 -9.78217 -0.022216 -0.009314 0 - -0.004661 0.011107 -9.78217 0 -0 0 - - - - 11.6391 3.0877 0.499995 1e-05 -0 0 - 1 1 1 - - 11.6391 3.0877 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 - -0.004709 -0.011055 -9.78158 0 -0 0 - - - - 15.533 2.52411 0.499995 -1e-05 0 0 - 1 1 1 - - 15.533 2.52411 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 16.6003 2.46368 0.499995 0 1e-05 0 - 1 1 1 - - 16.6003 2.46368 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 16.6668 0.917596 0.499995 -1e-05 0 0 - 1 1 1 - - 16.6668 0.917596 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 11.6314 4.22803 0.499995 1e-05 -0 0 - 1 1 1 - - 11.6314 4.22803 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 - 0.004709 -0.011055 -9.78158 0 -0 0 - - - - 11.654 5.25725 0.499995 1e-05 -0 0.004424 - 1 1 1 - - 11.654 5.25725 0.499995 1e-05 -0 0.004424 - 0 0 0 0 -0 0 - -0.004714 -0.011078 -9.78157 0.022152 -0.009425 1e-06 - -0.004714 -0.011078 -9.78157 0 -0 0 - - - - 13.5174 2.43423 0.499995 1e-05 0 0.030648 - 1 1 1 - - 13.5174 2.43423 0.499995 1e-05 0 0.030648 - 0 0 0 0 -0 0 - -0.004728 -0.011161 -9.78165 0.02232 -0.009451 1e-06 - -0.004728 -0.011161 -9.78165 0 -0 0 - - - - 11.6462 6.2886 0.5 0 -0 0.069266 - 1 1 1 - - 11.6462 6.2886 0.5 0 -0 0.069266 - 0 0 0 0 -0 0 - 1e-06 -0 -0 1e-06 1e-06 0 - 1e-06 -0 -0 0 -0 0 - - - - 12.4601 2.0331 0.499995 -1e-05 0 0 - 1 1 1 - - 12.4601 2.0331 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 9.10292 2.14493 0.499995 -1e-05 0 0 - 1 1 1 - - 9.10292 2.14493 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 5.83439 1.19515 0.499995 -1e-05 -0 -0.078203 - 1 1 1 - - 5.83439 1.19515 0.499995 -1e-05 -0 -0.078203 - 0 0 0 0 -0 0 - -0.004667 0.011116 -9.78214 -0.022234 -0.009327 0 - -0.004667 0.011116 -9.78214 0 -0 0 - - - - 9.08102 3.26349 0.499995 0 1e-05 0 - 1 1 1 - - 9.08102 3.26349 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 8.97202 4.41198 0.499995 -1e-05 0 0 - 1 1 1 - - 8.97202 4.41198 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 8.92411 5.50557 0.499995 0 1e-05 0 - 1 1 1 - - 8.92411 5.50557 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 8.90039 6.60086 0.499995 -1e-05 0 0 - 1 1 1 - - 8.90039 6.60086 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 8.89491 7.65407 0.499995 0 1e-05 0 - 1 1 1 - - 8.89491 7.65407 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 11.54 7.48372 0.499995 -1e-05 -0 0.048086 - 1 1 1 - - 11.54 7.48372 0.499995 -1e-05 -0 0.048086 - 0 0 0 0 -0 0 - -0.004571 0.010671 -9.78187 -0.02134 -0.009139 0 - -0.004571 0.010671 -9.78187 0 -0 0 - - - - 8.33103 10.7601 0.499995 -1e-05 0 0 - 1 1 1 - - 8.33103 10.7601 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 9.37924 10.7607 0.499995 -1e-05 0 0 - 1 1 1 - - 9.37924 10.7607 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 10.4354 10.7533 0.499995 0 1e-05 0 - 1 1 1 - - 10.4354 10.7533 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 11.4623 10.7523 0.499995 -1e-05 0 0 - 1 1 1 - - 11.4623 10.7523 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 6.86221 1.16701 0.499995 -1e-05 -0 -0.020162 - 1 1 1 - - 6.86221 1.16701 0.499995 -1e-05 -0 -0.020162 - 0 0 0 0 -0 0 - -0.004726 0.011139 -9.7816 -0.022275 -0.009449 -1e-06 - -0.004726 0.011139 -9.7816 0 -0 0 - - - - 11.5881 8.49628 0.499995 0 -1e-05 0.026715 - 1 1 1 - - 11.5881 8.49628 0.499995 0 -1e-05 0.026715 - 0 0 0 0 -0 0 - -0.01076 0.006156 -9.78235 -0.012396 -0.021513 3.9e-05 - -0.01076 0.006156 -9.78235 0 -0 0 - - - - 11.5683 9.58155 0.499995 -1e-05 0 0 - 1 1 1 - - 11.5683 9.58155 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 7.26487 10.8009 0.499995 0 1e-05 0 - 1 1 1 - - 7.26487 10.8009 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 6.17175 10.8343 0.499995 -1e-05 0 0 - 1 1 1 - - 6.17175 10.8343 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 5.04461 10.852 0.499995 0 1e-05 0 - 1 1 1 - - 5.04461 10.852 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 3.95809 10.893 0.499995 -1e-05 0 0 - 1 1 1 - - 3.95809 10.893 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 7.78281 7.61521 0.499995 1e-05 -0 0 - 1 1 1 - - 7.78281 7.61521 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 - -0.004709 -0.011055 -9.78158 0 -0 0 - - - - 6.69164 7.50635 0.499995 -1e-05 0 0 - 1 1 1 - - 6.69164 7.50635 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 5.60862 7.74772 0.499995 1e-05 -0 0 - 1 1 1 - - 5.60862 7.74772 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 - -0.004709 -0.011055 -9.78158 0 -0 0 - - - - 4.46278 7.82964 0.499995 0 1e-05 0 - 1 1 1 - - 4.46278 7.82964 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 7.9487 1.15327 0.499995 -1e-05 0 0 - 1 1 1 - - 7.9487 1.15327 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 2.84719 10.9112 0.499995 -1e-05 0 0 - 1 1 1 - - 2.84719 10.9112 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 1.73992 10.9582 0.499995 0 1e-05 0 - 1 1 1 - - 1.73992 10.9582 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 0.619512 11.197 0.499995 -1e-05 -0 0 - 1 1 1 - - 0.619512 11.197 0.499995 -1e-05 -0 0 - 0 0 0 0 -0 0 - 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 - 0.004709 0.011055 -9.78158 0 -0 0 - - - - 3.38354 8.04833 0.499995 0 1e-05 0 - 1 1 1 - - 3.38354 8.04833 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 - 0.010615 -0.006191 -9.78231 0 -0 0 - - - - 2.24413 8.11599 0.499995 -1e-05 0 0 - 1 1 1 - - 2.24413 8.11599 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 1.20797 8.19953 0.499995 0 1e-05 0 - 1 1 1 - - 1.20797 8.19953 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -0.495272 11.2728 0.499995 1e-05 -0 0 - 1 1 1 - - -0.495272 11.2728 0.499995 1e-05 -0 0 - 0 0 0 0 -0 0 - 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 - 0.004709 -0.011055 -9.78158 0 -0 0 - - - - 0.003792 8.23484 0.499995 -1e-05 0 0 - 1 1 1 - - 0.003792 8.23484 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -1.60407 11.2656 0.499995 -1e-05 0 0 - 1 1 1 - - -1.60407 11.2656 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -1.07686 8.20701 0.499995 0 1e-05 0 - 1 1 1 - - -1.07686 8.20701 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 9.03135 1.11313 0.499995 0 1e-05 0 - 1 1 1 - - 9.03135 1.11313 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -2.77324 11.3221 0.499995 -1e-05 0 0 - 1 1 1 - - -2.77324 11.3221 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -2.09643 8.13987 0.499995 0 1e-05 0 - 1 1 1 - - -2.09643 8.13987 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -3.9399 11.375 0.499995 -1e-05 0 0 - 1 1 1 - - -3.9399 11.375 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -3.22691 8.14265 0.499995 0 1e-05 0 - 1 1 1 - - -3.22691 8.14265 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -5.00002 11.3706 0.499995 -1e-05 0 0 - 1 1 1 - - -5.00002 11.3706 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -6.19269 11.4491 0.499995 0 1e-05 0 - 1 1 1 - - -6.19269 11.4491 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -7.36966 11.5014 0.499995 -1e-05 0 0 - 1 1 1 - - -7.36966 11.5014 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -8.67595 11.6101 0.499995 0 1e-05 0 - 1 1 1 - - -8.67595 11.6101 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -9.68226 11.5677 0.499995 0 -1e-05 0 - 1 1 1 - - -9.68226 11.5677 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 - -0.010615 0.006191 -9.78231 0 -0 0 - - - - -10.8496 11.6353 0.499995 0 1e-05 0 - 1 1 1 - - -10.8496 11.6353 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 8.76045 -1.66109 0.499995 0 -1e-05 0 - 1 1 1 - - 8.76045 -1.66109 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 - -0.010615 0.006191 -9.78231 0 -0 0 - - - - -4.3458 8.14363 0.499995 -1e-05 0 0 - 1 1 1 - - -4.3458 8.14363 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -5.37999 8.16639 0.499995 -1e-05 0 0 - 1 1 1 - - -5.37999 8.16639 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -6.5467 8.19298 0.499995 0 1e-05 0 - 1 1 1 - - -6.5467 8.19298 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -7.62958 8.22347 0.499995 0 -1e-05 0 - 1 1 1 - - -7.62958 8.22347 0.499995 0 -1e-05 0 - 0 0 0 0 -0 0 - -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 - -0.010615 0.006191 -9.78231 0 -0 0 - - - - -8.83422 8.36705 0.499995 0 1e-05 0 - 1 1 1 - - -8.83422 8.36705 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -11.9972 11.6792 0.499995 -1e-05 0 0 - 1 1 1 - - -11.9972 11.6792 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -13.1299 11.7058 0.499995 0 1e-05 0 - 1 1 1 - - -13.1299 11.7058 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -9.9062 8.41725 0.499995 0 1e-05 0 - 1 1 1 - - -9.9062 8.41725 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -11.0062 8.36397 0.499995 -1e-05 -0 0 - 1 1 1 - - -11.0062 8.36397 0.499995 -1e-05 -0 0 - 0 0 0 0 -0 0 - 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 - 0.004709 0.011055 -9.78158 0 -0 0 - - - - -12.1401 8.38199 0.499995 0 1e-05 0 - 1 1 1 - - -12.1401 8.38199 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - 7.71543 -1.67512 0.499995 0 1e-05 0 - 1 1 1 - - 7.71543 -1.67512 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -13.4024 8.4816 0.499995 0 1e-05 0 - 1 1 1 - - -13.4024 8.4816 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -13.0801 12.7181 0.499995 -1e-05 0 0 - 1 1 1 - - -13.0801 12.7181 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -13.1566 13.8382 0.499995 0 1e-05 0 - 1 1 1 - - -13.1566 13.8382 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -15.872 11.0985 0.5 -0 -0 -0 - 1 1 1 - - -15.872 11.0985 0.5 -0 -0 -0 - 0 0 0 0 -0 0 - -0 0 -0 -1e-06 -1e-06 0 - -0 0 -0 0 -0 0 - - - - -15.9201 9.01925 0.499995 -1e-05 -0 0 - 1 1 1 - - -15.9201 9.01925 0.499995 -1e-05 -0 0 - 0 0 0 0 -0 0 - 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 - 0.004709 0.011055 -9.78158 0 -0 0 - - - - -15.8541 10.0347 0.499995 0 1e-05 0 - 1 1 1 - - -15.8541 10.0347 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -15.8622 12.115 0.499995 0 1e-05 0 - 1 1 1 - - -15.8622 12.115 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -15.839 13.1183 0.499995 -1e-05 0 0 - 1 1 1 - - -15.839 13.1183 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - -15.9405 7.97497 0.499995 0 1e-05 0 - 1 1 1 - - -15.9405 7.97497 0.499995 0 1e-05 0 - 0 0 0 0 -0 0 - 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 - 0.010615 0.006191 -9.78231 0 -0 0 - - - - -15.9352 6.93311 0.499995 -1e-05 0 0 - 1 1 1 - - -15.9352 6.93311 0.499995 -1e-05 0 0 - 0 0 0 0 -0 0 - -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 - -0.004709 0.011055 -9.78158 0 -0 0 - - - - 0 0 10 0 -0 0 - - - - - 27.9092 -19.3342 10.071 0 0.275643 2.35619 - orbit - perspective - - - - diff --git a/f1tenth_gym_ros/worlds/obstacles.world b/f1tenth_gym_ros/worlds/obstacles.world deleted file mode 100644 index aa727e3..0000000 --- a/f1tenth_gym_ros/worlds/obstacles.world +++ /dev/null @@ -1,937 +0,0 @@ - - - - - 1 - 0 0 10 0 -0 0 - 0.8 0.8 0.8 1 - 0.2 0.2 0.2 1 - - 1000 - 0.9 - 0.01 - 0.001 - - -0.5 0.1 -0.9 - - 0 - 0 - 0 - - - - 1 - - - - - 0 0 1 - 100 100 - - - - - 65535 - - - - - 100 - 50 - - - - - - - - 10 - - - 0 - - - 0 0 1 - 100 100 - - - - - - - 0 - 0 - 0 - - - 0 0 -9.8 - 6e-06 2.3e-05 -4.2e-05 - - - 0.001 - 1 - 1000 - - - 0.4 0.4 0.4 1 - 0.7 0.7 0.7 1 - 1 - - - - EARTH_WGS84 - 0 - 0 - 0 - 0 - - - - - 0 0 0.4 0 -0 0 - 500 - - 51.2096 - 51.2096 - 25 - 0 - 0 - 0 - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - 10 - - - - - - - - - - - - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - - 0 - 0 - 0 - - -0.756237 1.39226 0 0 -0 0 - - - - - 0 0 0.4 0 -0 0 - 500 - - 51.2096 - 51.2096 - 25 - 0 - 0 - 0 - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - 10 - - - - - - - - - - - - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - - 0 - 0 - 0 - - 1.80022 0.377178 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - -2.19745 -2.25046 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - -1.40494 -2.55135 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - -0.501986 -2.9745 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - 2.09724 -2.18232 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - -3.69879 0.345038 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - -0.406438 -4.23374 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - 2.38815 -3.2576 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - 2.39316 -4.49605 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - -3.00495 -2.78053 0 0 -0 0 - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - 10 - - - - - - - - - - - - - - - - - 10 10 10 - model://construction_cone/meshes/construction_cone.dae - - - - 0 - - 0 0 0 0 -0 0 - - 1 - 0 - 0 - 1 - 0 - 1 - - 1 - - 0 - 0 - - -4.64786 -0.646522 0 0 -0 0 - - - - - 0 0 0.4 0 -0 0 - 500 - - 51.2096 - 51.2096 - 25 - 0 - 0 - 0 - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - 10 - - - - - - - - - - - - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - - 0 - 0 - 0 - - -5.3108 -2.23708 0 0 -0 0 - - - - - 0 0 0.4 0 -0 0 - 500 - - 51.2096 - 51.2096 - 25 - 0 - 0 - 0 - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - 10 - - - - - - - - - - - - - - - - - model://construction_barrel/meshes/construction_barrel.dae - - - - 0 - 0 - 0 - - -2.07692 -4.26198 0 0 -0 0 - - - 457 444000000 - 459 829915274 - 1646216792 728719362 - 457444 - - -0.756319 1.39223 0 0 0 -2.4e-05 - 1 1 1 - - -0.756319 1.39223 0 0 0 -2.4e-05 - 0 0 0 0 -0 0 - 3.45865 5.7443 4.40608 1.34644 0.778762 3.14097 - 1729.32 2872.15 2203.04 0 -0 0 - - - - 1.80014 0.377148 0 0 0 -2.2e-05 - 1 1 1 - - 1.80014 0.377148 0 0 0 -2.2e-05 - 0 0 0 0 -0 0 - 3.45864 5.7443 4.40608 1.34642 0.778778 3.14097 - 1729.32 2872.15 2203.04 0 -0 0 - - - - -5.31082 -2.23709 -0 0 -0 -7e-06 - 1 1 1 - - -5.31082 -2.23709 -0 0 -0 -7e-06 - 0 0 0 0 -0 0 - -3.87743 -2.8936 0.727843 -2.17783 0.268134 -3.13538 - -1938.71 -1446.8 363.922 0 -0 0 - - - - -2.07693 -4.26199 -0 0 0 -4e-06 - 1 1 1 - - -2.07693 -4.26199 -0 0 0 -4e-06 - 0 0 0 0 -0 0 - 7.60795 0.965639 1.20183 -2.41278 0.170207 0.001195 - 3803.98 482.819 600.916 0 -0 0 - - - - -2.19745 -2.25046 -0 0 -0 0 - 1 1 1 - - -2.19745 -2.25046 -0 0 -0 0 - 0 0 0 0 -0 0 - 0 -0 -0.008512 -2.58585 1.13682 3.14159 - 0 -0 -0.008512 0 -0 0 - - - - -1.40494 -2.55135 -0 0 -0 0 - 1 1 1 - - -1.40494 -2.55135 -0 0 -0 0 - 0 0 0 0 -0 0 - 0 -0 -0.008512 -2.58585 1.13682 3.14159 - 0 -0 -0.008512 0 -0 0 - - - - -0.501986 -2.9745 -0 0 -0 0 - 1 1 1 - - -0.501986 -2.9745 -0 0 -0 0 - 0 0 0 0 -0 0 - 0 -0 -0.008512 -2.58585 1.13682 3.14159 - 0 -0 -0.008512 0 -0 0 - - - - 2.09724 -2.18232 -0 1e-06 -0 0 - 1 1 1 - - 2.09724 -2.18232 -0 1e-06 -0 0 - 0 0 0 0 -0 0 - -0 -0 -9.79988 3e-05 2e-05 -0 - -0 -0 -9.79988 0 -0 0 - - - - -3.69879 0.345038 -1e-05 0 -0 0 - 1 1 1 - - -3.69879 0.345038 -1e-05 0 -0 0 - 0 0 0 0 -0 0 - 0 0 -9.8 0 -0 0 - 0 0 -9.8 0 -0 0 - - - - -0.406438 -4.23374 -0 0 -1e-06 0 - 1 1 1 - - -0.406438 -4.23374 -0 0 -1e-06 0 - 0 0 0 0 -0 0 - -0 0 0.008512 2.58585 -1.13682 -3.14159 - -0 0 0.008512 0 -0 0 - - - - 2.38815 -3.2576 -0 0 -0 0 - 1 1 1 - - 2.38815 -3.2576 -0 0 -0 0 - 0 0 0 0 -0 0 - 0 -0 -0.008512 -2.58585 1.13682 3.14159 - 0 -0 -0.008512 0 -0 0 - - - - 2.39316 -4.49605 -0 0 -1e-06 0 - 1 1 1 - - 2.39316 -4.49605 -0 0 -1e-06 0 - 0 0 0 0 -0 0 - -0 0 0.008512 2.58585 -1.13682 -3.14159 - -0 0 0.008512 0 -0 0 - - - - -3.00495 -2.78053 -0 0 -1e-06 0 - 1 1 1 - - -3.00495 -2.78053 -0 0 -1e-06 0 - 0 0 0 0 -0 0 - -0 0 0.008512 2.58585 -1.13682 -3.14159 - -0 0 0.008512 0 -0 0 - - - - -4.64786 -0.646522 -0 0 -1e-06 0 - 1 1 1 - - -4.64786 -0.646522 -0 0 -1e-06 0 - 0 0 0 0 -0 0 - -0 0 0.008512 2.58585 -1.13682 -3.14159 - -0 0 0.008512 0 -0 0 - - - - 0 0 0 0 -0 0 - 1 1 1 - - 0 0 0 0 -0 0 - 0 0 0 0 -0 0 - 0 0 0 0 -0 0 - 0 0 0 0 -0 0 - - - - 0 0 10 0 -0 0 - - - - - -15.5892 0.392985 21.6628 0 0.851642 0.028194 - orbit - perspective - - - - - diff --git a/path_planning/package.xml b/path_planning/package.xml deleted file mode 100644 index 95c31e6..0000000 --- a/path_planning/package.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - path_planning - 0.0.0 - TODO: Package description - israel - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - rclpy - tf2_ros - tf2_geometry_msgs - geometry_msgs - nav_msgs - - - ament_python - - diff --git a/path_planning/path_planning/__init__.py b/path_planning/path_planning/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/path_planning/path_planning/waypoint_recorder.py b/path_planning/path_planning/waypoint_recorder.py deleted file mode 100755 index 7f809db..0000000 --- a/path_planning/path_planning/waypoint_recorder.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import rclpy -from rclpy.node import Node -import os -import numpy as np -import pandas as pd -from nav_msgs.msg import Odometry -from tf_transformations import euler_from_quaternion - -class WaypointsLogger(Node): - def __init__(self): - # Initialize the node - super().__init__('waypoints_logger') - - # Configure the output file path - self.filename = "" # Define file path for saving waypoints - - # Initialize the DataFrame to store waypoints - self.waypoints_df = pd.DataFrame(columns=['x', 'y', 'w']) - - # Last recorded position (used to compare movements) - self.last_position = None - self.min_distance = 0.05 # Minimum distance to register a new waypoint (in meters) - - # Define the odometry topic to listen to - self.odom_topic = "" # Define the odometry topic here - self.create_subscription(Odometry, self.odom_topic, self.save_waypoint, 10) - - def save_waypoint(self, data): - """ - Callback function to save x, y, and w (orientation) from the robot. - You should implement logic to save the waypoint under certain conditions. - """ - pass # Implement saving the waypoint here - - def has_moved_significantly(self, x, y): - """ - Check if the robot has moved significantly (i.e., beyond the minimum distance). - Implement logic to calculate the distance between the current and last position. - """ - pass # Implement distance check here - - def save_to_file(self): - """ - Save the waypoints DataFrame to a CSV file. - Implement logic to save the waypoints to a file when the node shuts down. - """ - pass # Implement saving to CSV here - -def main(args=None): - rclpy.init(args=args) - node = WaypointsLogger() - - try: - # Run the main ROS loop to process callbacks - rclpy.spin(node) - except KeyboardInterrupt: - pass - finally: - # Ensure to save the waypoints when shutting down - node.save_to_file() - rclpy.shutdown() - -if __name__ == '__main__': - main() diff --git a/path_planning/resource/path_planning b/path_planning/resource/path_planning deleted file mode 100644 index e69de29..0000000 diff --git a/path_planning/setup.cfg b/path_planning/setup.cfg deleted file mode 100644 index 7411385..0000000 --- a/path_planning/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script_dir=$base/lib/path_planning -[install] -install_scripts=$base/lib/path_planning diff --git a/path_planning/setup.py b/path_planning/setup.py deleted file mode 100644 index 1e46e09..0000000 --- a/path_planning/setup.py +++ /dev/null @@ -1,26 +0,0 @@ -from setuptools import find_packages, setup - -package_name = 'path_planning' - -setup( - name=package_name, - version='0.0.0', - packages=find_packages(exclude=['test']), - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='israel', - maintainer_email='israel@todo.todo', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - 'waypoint_recorder = path_planning.waypoint_recorder:main', - ], - }, -) diff --git a/path_planning/test/test_copyright.py b/path_planning/test/test_copyright.py deleted file mode 100644 index 97a3919..0000000 --- a/path_planning/test/test_copyright.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -# Remove the `skip` decorator once the source file(s) have a copyright header -@pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/path_planning/test/test_flake8.py b/path_planning/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/path_planning/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/path_planning/test/test_pep257.py b/path_planning/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/path_planning/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/waypoints/levine_path.csv b/waypoints/levine_path.csv deleted file mode 100644 index 3f42452..0000000 --- a/waypoints/levine_path.csv +++ /dev/null @@ -1,1152 +0,0 @@ -x,y,w -0.0,0.0,0.0 -0.05,0.0,0.0 -0.1,0.0,0.0 -0.153,0.0,0.0 -0.204,0.0,0.0 -0.257,0.0,0.0 -0.31,0.0,0.0 -0.364,0.0,0.0 -0.419,0.0,0.0 -0.474,0.0,0.0 -0.524,0.0,0.0 -0.578,0.0,0.0 -0.628,0.0,0.0 -0.678,0.0,0.0 -0.733,0.0,0.0 -0.783,0.0,0.0 -0.838,0.0,0.0 -0.888,0.0,0.0 -0.943,0.0,0.0 -0.993,0.0,0.0 -1.048,0.0,0.0 -1.098,0.0,0.0 -1.153,0.0,0.0 -1.203,0.0,0.0 -1.258,0.0,0.0 -1.308,0.0,0.0 -1.358,0.0,0.0 -1.413,0.0,0.0 -1.463,0.0,0.0 -1.518,-0.0,-0.009 -1.568,-0.002,-0.053 -1.618,-0.005,-0.101 -1.668,-0.012,-0.148 -1.722,-0.021,-0.173 -1.776,-0.029,-0.139 -1.826,-0.035,-0.091 -1.876,-0.039,-0.044 -1.926,-0.04,-0.019 -1.976,-0.041,-0.044 -2.026,-0.045,-0.091 -2.08,-0.051,-0.143 -2.13,-0.059,-0.189 -2.179,-0.069,-0.199 -2.228,-0.079,-0.184 -2.282,-0.089,-0.184 -2.336,-0.099,-0.184 -2.39,-0.109,-0.184 -2.444,-0.119,-0.184 -2.498,-0.129,-0.184 -2.552,-0.139,-0.159 -2.602,-0.145,-0.126 -2.656,-0.152,-0.125 -2.706,-0.159,-0.125 -2.756,-0.165,-0.125 -2.81,-0.171,-0.109 -2.86,-0.176,-0.077 -2.91,-0.18,-0.076 -2.96,-0.183,-0.076 -3.01,-0.187,-0.076 -3.064,-0.191,-0.076 -3.114,-0.195,-0.076 -3.164,-0.199,-0.072 -3.214,-0.202,-0.033 -3.264,-0.203,-0.017 -3.314,-0.204,-0.017 -3.369,-0.204,-0.017 -3.419,-0.205,-0.017 -3.469,-0.206,-0.011 -3.519,-0.206,0.021 -3.569,-0.205,0.023 -3.619,-0.204,0.023 -3.669,-0.202,0.023 -3.719,-0.201,0.023 -3.769,-0.2,0.023 -3.819,-0.199,0.023 -3.869,-0.198,0.023 -3.919,-0.197,0.023 -3.969,-0.196,0.023 -4.019,-0.194,0.021 -4.074,-0.194,-0.02 -4.124,-0.196,-0.036 -4.174,-0.198,-0.036 -4.224,-0.199,-0.027 -4.274,-0.2,0.017 -4.324,-0.198,0.065 -4.378,-0.193,0.117 -4.428,-0.186,0.146 -4.482,-0.178,0.146 -4.532,-0.17,0.146 -4.586,-0.162,0.146 -4.636,-0.155,0.146 -4.69,-0.147,0.146 -4.74,-0.14,0.122 -4.794,-0.134,0.097 -4.844,-0.13,0.097 -4.894,-0.125,0.097 -4.944,-0.12,0.097 -4.998,-0.115,0.097 -5.048,-0.11,0.073 -5.098,-0.107,0.048 -5.148,-0.105,0.048 -5.198,-0.103,0.048 -5.248,-0.1,0.028 -5.303,-0.1,-0.001 -5.358,-0.1,-0.001 -5.408,-0.1,-0.001 -5.463,-0.1,-0.001 -5.518,-0.1,-0.001 -5.568,-0.101,-0.013 -5.618,-0.102,-0.049 -5.668,-0.105,-0.051 -5.718,-0.107,-0.051 -5.768,-0.11,-0.051 -5.818,-0.112,-0.051 -5.868,-0.115,-0.051 -5.918,-0.117,-0.051 -5.972,-0.12,-0.051 -6.022,-0.123,-0.051 -6.072,-0.125,-0.051 -6.122,-0.128,-0.051 -6.172,-0.13,-0.051 -6.222,-0.133,-0.051 -6.272,-0.135,-0.051 -6.322,-0.138,-0.051 -6.372,-0.141,-0.055 -6.422,-0.144,-0.091 -6.472,-0.149,-0.1 -6.526,-0.154,-0.1 -6.576,-0.159,-0.1 -6.626,-0.164,-0.1 -6.676,-0.169,-0.1 -6.73,-0.175,-0.1 -6.78,-0.18,-0.1 -6.83,-0.185,-0.1 -6.88,-0.19,-0.1 -6.934,-0.195,-0.1 -6.984,-0.2,-0.1 -7.034,-0.205,-0.1 -7.084,-0.21,-0.1 -7.138,-0.216,-0.1 -7.188,-0.221,-0.1 -7.238,-0.226,-0.1 -7.292,-0.231,-0.1 -7.342,-0.236,-0.1 -7.392,-0.241,-0.1 -7.442,-0.246,-0.1 -7.496,-0.252,-0.1 -7.546,-0.257,-0.1 -7.596,-0.262,-0.1 -7.646,-0.267,-0.1 -7.7,-0.272,-0.1 -7.75,-0.277,-0.076 -7.8,-0.28,-0.06 -7.85,-0.283,-0.06 -7.9,-0.286,-0.06 -7.95,-0.289,-0.059 -8.0,-0.292,-0.033 -8.05,-0.293,-0.029 -8.1,-0.294,-0.029 -8.15,-0.296,-0.028 -8.2,-0.297,0.005 -8.25,-0.295,0.052 -8.3,-0.292,0.068 -8.354,-0.288,0.068 -8.404,-0.285,0.068 -8.454,-0.282,0.069 -8.504,-0.277,0.102 -8.554,-0.271,0.146 -8.608,-0.263,0.155 -8.662,-0.254,0.155 -8.712,-0.246,0.164 -8.766,-0.236,0.213 -8.819,-0.223,0.265 -8.867,-0.209,0.313 -8.919,-0.191,0.365 -8.97,-0.17,0.417 -9.015,-0.148,0.465 -9.064,-0.122,0.517 -9.111,-0.094,0.569 -9.156,-0.063,0.622 -9.2,-0.03,0.671 -9.243,0.005,0.68 -9.286,0.039,0.68 -9.328,0.074,0.68 -9.371,0.109,0.7 -9.412,0.145,0.752 -9.448,0.18,0.799 -9.482,0.217,0.847 -9.517,0.259,0.899 -9.547,0.299,0.947 -9.576,0.34,0.994 -9.604,0.387,1.046 -9.628,0.431,1.094 -9.65,0.476,1.141 -9.67,0.522,1.189 -9.689,0.573,1.241 -9.704,0.621,1.289 -9.718,0.674,1.341 -9.728,0.723,1.388 -9.737,0.777,1.439 -9.743,0.827,1.451 -9.749,0.877,1.451 -9.756,0.931,1.451 -9.761,0.981,1.451 -9.768,1.035,1.451 -9.774,1.085,1.466 -9.779,1.135,1.475 -9.783,1.185,1.475 -9.789,1.239,1.475 -9.794,1.289,1.475 -9.798,1.339,1.475 -9.803,1.389,1.475 -9.808,1.443,1.475 -9.813,1.493,1.475 -9.818,1.543,1.491 -9.821,1.593,1.523 -9.823,1.643,1.524 -9.825,1.693,1.524 -9.828,1.743,1.524 -9.83,1.793,1.524 -9.832,1.843,1.524 -9.834,1.893,1.54 -9.835,1.943,1.579 -9.834,1.993,1.583 -9.834,2.043,1.583 -9.833,2.093,1.583 -9.832,2.147,1.583 -9.832,2.197,1.583 -9.831,2.247,1.583 -9.831,2.297,1.583 -9.83,2.347,1.583 -9.829,2.397,1.583 -9.829,2.447,1.583 -9.828,2.497,1.583 -9.827,2.547,1.583 -9.827,2.602,1.583 -9.826,2.652,1.583 -9.825,2.707,1.583 -9.825,2.757,1.583 -9.824,2.807,1.583 -9.824,2.857,1.583 -9.823,2.907,1.583 -9.822,2.957,1.583 -9.822,3.007,1.583 -9.821,3.057,1.583 -9.821,3.107,1.583 -9.82,3.157,1.583 -9.819,3.207,1.583 -9.819,3.257,1.583 -9.818,3.307,1.583 -9.817,3.357,1.583 -9.817,3.412,1.583 -9.816,3.462,1.583 -9.815,3.517,1.583 -9.815,3.567,1.583 -9.814,3.617,1.583 -9.814,3.672,1.583 -9.813,3.722,1.583 -9.812,3.772,1.583 -9.812,3.822,1.583 -9.811,3.872,1.583 -9.81,3.922,1.583 -9.81,3.977,1.583 -9.809,4.027,1.583 -9.809,4.082,1.583 -9.808,4.132,1.583 -9.807,4.182,1.583 -9.807,4.237,1.583 -9.806,4.287,1.583 -9.805,4.337,1.583 -9.805,4.392,1.583 -9.804,4.442,1.583 -9.803,4.492,1.583 -9.803,4.547,1.583 -9.802,4.597,1.583 -9.801,4.652,1.583 -9.801,4.707,1.583 -9.8,4.757,1.583 -9.8,4.807,1.583 -9.799,4.857,1.583 -9.798,4.907,1.583 -9.798,4.962,1.583 -9.797,5.012,1.583 -9.796,5.062,1.583 -9.796,5.117,1.583 -9.795,5.167,1.583 -9.794,5.217,1.583 -9.794,5.267,1.583 -9.793,5.317,1.583 -9.793,5.372,1.583 -9.792,5.422,1.583 -9.791,5.472,1.583 -9.791,5.527,1.583 -9.79,5.577,1.583 -9.789,5.627,1.583 -9.789,5.682,1.583 -9.788,5.732,1.583 -9.787,5.787,1.583 -9.787,5.842,1.583 -9.786,5.892,1.583 -9.785,5.947,1.583 -9.785,6.002,1.583 -9.784,6.052,1.583 -9.784,6.102,1.583 -9.783,6.152,1.583 -9.782,6.202,1.583 -9.782,6.257,1.583 -9.781,6.307,1.583 -9.781,6.362,1.55 -9.783,6.412,1.534 -9.785,6.462,1.534 -9.786,6.512,1.534 -9.788,6.562,1.534 -9.79,6.612,1.534 -9.792,6.662,1.534 -9.794,6.712,1.534 -9.796,6.762,1.534 -9.797,6.812,1.534 -9.799,6.862,1.538 -9.8,6.912,1.577 -9.799,6.962,1.625 -9.795,7.012,1.673 -9.788,7.066,1.714 -9.781,7.116,1.716 -9.773,7.17,1.716 -9.765,7.22,1.716 -9.757,7.274,1.716 -9.749,7.328,1.716 -9.742,7.378,1.716 -9.734,7.432,1.716 -9.727,7.482,1.716 -9.719,7.536,1.716 -9.712,7.586,1.716 -9.704,7.64,1.716 -9.696,7.69,1.728 -9.686,7.744,1.779 -9.674,7.797,1.831 -9.658,7.85,1.883 -9.64,7.902,1.936 -9.619,7.953,1.988 -9.595,8.002,2.04 -9.569,8.051,2.092 -9.541,8.098,2.145 -9.512,8.139,2.192 -9.482,8.179,2.24 -9.447,8.221,2.292 -9.413,8.258,2.339 -9.374,8.296,2.392 -9.337,8.33,2.421 -9.299,8.363,2.421 -9.258,8.399,2.421 -9.22,8.432,2.446 -9.177,8.466,2.496 -9.137,8.496,2.508 -9.096,8.525,2.508 -9.056,8.555,2.517 -9.011,8.586,2.566 -8.968,8.612,2.614 -8.924,8.636,2.661 -8.879,8.658,2.709 -8.829,8.68,2.761 -8.777,8.699,2.813 -8.725,8.715,2.866 -8.676,8.728,2.913 -8.627,8.738,2.961 -8.573,8.746,3.013 -8.523,8.752,3.05 -8.469,8.757,3.052 -8.419,8.761,3.052 -8.369,8.766,3.052 -8.319,8.77,3.068 -8.269,8.773,3.107 -8.219,8.774,3.111 -8.169,8.776,3.111 -8.119,8.777,3.111 -8.069,8.779,3.111 -8.019,8.78,3.111 -7.969,8.782,3.119 -7.919,8.782,-3.119 -7.865,8.78,-3.095 -7.815,8.777,-3.095 -7.765,8.775,-3.095 -7.715,8.773,-3.095 -7.665,8.77,-3.095 -7.615,8.768,-3.095 -7.565,8.766,-3.095 -7.515,8.763,-3.095 -7.465,8.761,-3.095 -7.415,8.759,-3.097 -7.365,8.757,-3.132 -7.31,8.757,3.139 -7.255,8.757,3.139 -7.2,8.757,3.139 -7.15,8.758,3.139 -7.1,8.758,3.139 -7.045,8.758,3.139 -6.99,8.758,3.139 -6.935,8.758,3.139 -6.88,8.758,3.139 -6.825,8.758,3.139 -6.77,8.759,3.139 -6.715,8.759,3.139 -6.66,8.759,3.139 -6.605,8.759,3.139 -6.555,8.759,3.139 -6.5,8.759,3.139 -6.445,8.759,3.139 -6.395,8.759,3.139 -6.345,8.76,3.139 -6.29,8.76,3.139 -6.235,8.76,3.139 -6.185,8.76,3.139 -6.13,8.76,3.139 -6.075,8.76,3.139 -6.02,8.76,3.139 -5.965,8.76,3.139 -5.915,8.761,3.139 -5.86,8.761,3.139 -5.81,8.761,3.139 -5.755,8.761,3.139 -5.7,8.761,3.139 -5.645,8.761,3.139 -5.59,8.761,3.139 -5.54,8.762,3.139 -5.485,8.762,3.139 -5.435,8.762,3.139 -5.38,8.762,3.139 -5.325,8.762,3.139 -5.27,8.762,3.139 -5.215,8.762,3.139 -5.16,8.762,3.139 -5.11,8.763,3.139 -5.06,8.763,3.139 -5.005,8.763,3.139 -4.95,8.763,3.139 -4.895,8.763,3.139 -4.84,8.763,3.139 -4.785,8.763,3.139 -4.735,8.764,3.139 -4.685,8.764,3.139 -4.63,8.764,3.139 -4.575,8.764,3.139 -4.52,8.764,3.139 -4.465,8.764,3.139 -4.41,8.764,3.139 -4.355,8.764,3.139 -4.305,8.765,3.139 -4.25,8.765,3.139 -4.195,8.765,3.139 -4.145,8.765,3.139 -4.09,8.765,3.139 -4.035,8.765,3.139 -3.985,8.765,3.139 -3.93,8.765,3.139 -3.88,8.766,3.139 -3.825,8.766,3.139 -3.775,8.766,3.139 -3.72,8.766,3.139 -3.67,8.766,3.139 -3.615,8.766,3.139 -3.565,8.766,3.139 -3.51,8.767,3.139 -3.455,8.767,3.139 -3.405,8.767,3.139 -3.35,8.767,3.139 -3.3,8.767,3.139 -3.245,8.767,3.139 -3.195,8.767,3.139 -3.14,8.767,3.139 -3.09,8.768,3.139 -3.035,8.768,3.139 -2.985,8.768,3.139 -2.93,8.768,3.139 -2.88,8.768,3.139 -2.825,8.768,3.139 -2.775,8.768,3.139 -2.72,8.768,3.139 -2.67,8.769,3.139 -2.615,8.769,3.139 -2.565,8.769,3.139 -2.51,8.769,3.139 -2.455,8.769,3.139 -2.405,8.769,3.139 -2.35,8.769,3.139 -2.3,8.769,3.139 -2.25,8.77,3.139 -2.195,8.77,3.139 -2.14,8.77,3.139 -2.09,8.77,3.139 -2.035,8.77,3.139 -1.985,8.77,3.139 -1.935,8.77,3.139 -1.885,8.77,3.139 -1.835,8.771,3.139 -1.785,8.771,3.139 -1.73,8.771,3.139 -1.68,8.771,3.139 -1.63,8.771,3.139 -1.578,8.771,3.139 -1.524,8.771,3.139 -1.471,8.772,3.139 -1.416,8.772,3.139 -1.362,8.772,3.139 -1.312,8.772,3.139 -1.258,8.772,3.139 -1.208,8.772,3.139 -1.153,8.772,3.139 -1.098,8.772,3.139 -1.043,8.773,3.139 -0.988,8.773,3.139 -0.933,8.773,3.139 -0.878,8.773,3.139 -0.827,8.773,3.139 -0.775,8.773,3.139 -0.722,8.773,3.139 -0.668,8.773,3.139 -0.615,8.774,3.139 -0.561,8.774,3.139 -0.506,8.774,3.139 -0.452,8.774,3.139 -0.398,8.774,3.139 -0.343,8.774,3.139 -0.289,8.774,3.139 -0.235,8.775,3.139 -0.18,8.775,3.139 -0.125,8.775,3.139 -0.075,8.775,3.139 -0.023,8.775,3.139 --0.031,8.775,3.139 --0.087,8.775,3.139 --0.138,8.775,3.139 --0.191,8.776,3.139 --0.245,8.776,3.139 --0.299,8.776,3.139 --0.355,8.776,3.139 --0.41,8.776,3.139 --0.466,8.776,3.139 --0.522,8.776,3.139 --0.578,8.777,3.139 --0.634,8.777,3.139 --0.69,8.777,3.139 --0.746,8.777,3.139 --0.803,8.777,3.139 --0.859,8.777,3.139 --0.915,8.777,3.139 --0.972,8.778,3.139 --1.028,8.778,3.139 --1.084,8.778,3.139 --1.141,8.778,3.139 --1.197,8.778,3.139 --1.253,8.778,3.139 --1.31,8.778,3.139 --1.366,8.778,3.139 --1.422,8.779,3.139 --1.479,8.779,3.139 --1.535,8.779,3.139 --1.592,8.779,3.139 --1.648,8.779,3.139 --1.704,8.779,3.139 --1.761,8.779,3.139 --1.817,8.78,3.139 --1.873,8.78,3.139 --1.93,8.78,3.139 --1.986,8.78,3.139 --2.042,8.78,3.139 --2.099,8.78,3.139 --2.155,8.78,3.139 --2.212,8.781,3.139 --2.268,8.781,3.139 --2.324,8.781,3.139 --2.381,8.781,3.139 --2.437,8.781,3.139 --2.493,8.781,3.139 --2.55,8.781,3.139 --2.606,8.782,3.139 --2.663,8.782,3.139 --2.719,8.782,3.139 --2.775,8.782,3.139 --2.832,8.782,3.139 --2.888,8.782,3.139 --2.944,8.782,3.139 --3.001,8.782,3.139 --3.057,8.783,3.139 --3.113,8.783,3.139 --3.17,8.783,3.139 --3.226,8.783,3.139 --3.283,8.783,3.139 --3.339,8.783,3.139 --3.395,8.783,3.139 --3.452,8.784,3.139 --3.508,8.784,3.139 --3.564,8.784,3.139 --3.621,8.784,3.139 --3.677,8.784,3.139 --3.733,8.784,3.139 --3.79,8.784,3.139 --3.846,8.785,3.139 --3.903,8.785,3.139 --3.959,8.785,3.139 --4.015,8.785,3.139 --4.072,8.785,3.139 --4.128,8.785,3.139 --4.184,8.785,3.139 --4.241,8.786,3.139 --4.297,8.786,3.139 --4.354,8.786,3.139 --4.41,8.786,3.139 --4.466,8.786,3.139 --4.523,8.786,3.139 --4.579,8.786,3.139 --4.635,8.786,3.139 --4.692,8.787,3.139 --4.748,8.787,3.139 --4.804,8.787,3.139 --4.861,8.787,3.139 --4.917,8.787,3.139 --4.974,8.787,3.139 --5.03,8.787,3.139 --5.086,8.788,3.139 --5.143,8.788,3.139 --5.199,8.788,3.139 --5.255,8.788,3.139 --5.312,8.788,3.139 --5.368,8.788,3.139 --5.425,8.788,3.139 --5.481,8.789,3.139 --5.537,8.789,3.139 --5.594,8.789,3.139 --5.65,8.789,3.139 --5.706,8.789,3.139 --5.763,8.789,3.139 --5.819,8.789,3.139 --5.875,8.79,3.139 --5.932,8.79,3.139 --5.988,8.79,3.139 --6.045,8.79,3.139 --6.101,8.79,3.139 --6.157,8.79,3.139 --6.214,8.79,3.139 --6.27,8.791,3.139 --6.326,8.791,3.139 --6.383,8.791,3.139 --6.439,8.791,3.139 --6.496,8.791,3.139 --6.552,8.791,3.139 --6.608,8.791,3.139 --6.665,8.791,3.139 --6.721,8.792,3.139 --6.777,8.792,3.139 --6.834,8.792,3.139 --6.89,8.792,3.139 --6.946,8.792,3.139 --7.003,8.792,3.139 --7.059,8.792,3.139 --7.116,8.793,3.139 --7.172,8.793,3.139 --7.228,8.793,3.139 --7.285,8.793,3.139 --7.341,8.793,3.139 --7.397,8.793,3.139 --7.454,8.793,3.139 --7.51,8.794,3.139 --7.566,8.794,3.139 --7.623,8.794,3.139 --7.679,8.794,3.139 --7.736,8.794,3.139 --7.792,8.794,3.139 --7.848,8.794,3.139 --7.905,8.795,3.139 --7.961,8.795,3.139 --8.017,8.795,3.139 --8.074,8.795,3.139 --8.13,8.795,3.139 --8.187,8.795,3.139 --8.243,8.795,3.139 --8.299,8.795,3.139 --8.356,8.796,3.139 --8.412,8.796,3.139 --8.468,8.796,3.139 --8.525,8.796,3.139 --8.581,8.796,3.139 --8.637,8.796,3.139 --8.694,8.796,3.139 --8.75,8.797,3.139 --8.807,8.797,3.139 --8.863,8.797,3.139 --8.919,8.797,3.139 --8.976,8.797,3.139 --9.032,8.797,3.139 --9.088,8.797,3.139 --9.145,8.798,3.139 --9.201,8.798,3.139 --9.258,8.798,3.139 --9.314,8.798,3.139 --9.37,8.798,3.139 --9.427,8.798,3.139 --9.483,8.798,3.139 --9.539,8.799,3.139 --9.596,8.799,3.139 --9.652,8.799,3.139 --9.708,8.799,3.139 --9.765,8.799,3.139 --9.821,8.799,3.139 --9.878,8.799,3.139 --9.934,8.799,3.139 --9.99,8.8,3.139 --10.047,8.8,3.139 --10.103,8.8,3.139 --10.159,8.8,3.139 --10.216,8.8,3.139 --10.272,8.797,-3.125 --10.328,8.794,-3.116 --10.385,8.793,-3.116 --10.441,8.791,-3.116 --10.497,8.79,-3.116 --10.554,8.788,-3.116 --10.61,8.787,-3.116 --10.666,8.786,-3.116 --10.723,8.784,-3.116 --10.779,8.782,-3.114 --10.835,8.776,-3.083 --10.89,8.763,-3.032 --10.945,8.75,-2.998 --11.0,8.741,-2.994 --11.056,8.733,-2.994 --11.112,8.724,-2.994 --11.168,8.716,-2.994 --11.223,8.708,-2.994 --11.279,8.7,-2.994 --11.335,8.694,-3.015 --11.392,8.695,-3.058 --11.448,8.694,-3.072 --11.504,8.69,-3.072 --11.56,8.686,-3.072 --11.617,8.682,-3.072 --11.673,8.679,-3.076 --11.729,8.681,-3.112 --11.785,8.688,3.128 --11.841,8.691,3.119 --11.898,8.692,3.119 --11.954,8.694,3.119 --12.01,8.695,3.119 --12.067,8.696,3.119 --12.123,8.697,3.119 --12.18,8.699,3.119 --12.236,8.7,3.119 --12.292,8.701,3.119 --12.349,8.703,3.119 --12.405,8.704,3.119 --12.461,8.704,3.13 --12.517,8.697,-3.109 --12.572,8.685,-3.058 --12.627,8.671,-3.006 --12.681,8.654,-2.955 --12.734,8.636,-2.916 --12.789,8.621,-2.91 --12.843,8.608,-2.91 --12.898,8.596,-2.91 --12.953,8.58,-2.895 --13.004,8.559,-2.847 --13.055,8.533,-2.796 --13.104,8.505,-2.744 --13.151,8.475,-2.692 --13.197,8.442,-2.641 --13.241,8.407,-2.589 --13.283,8.37,-2.538 --13.324,8.33,-2.486 --13.362,8.289,-2.435 --13.398,8.245,-2.383 --13.433,8.202,-2.349 --13.472,8.161,-2.345 --13.512,8.121,-2.345 --13.551,8.08,-2.341 --13.585,8.036,-2.305 --13.615,7.988,-2.254 --13.643,7.939,-2.202 --13.668,7.888,-2.15 --13.69,7.836,-2.099 --13.71,7.784,-2.047 --13.727,7.73,-1.996 --13.741,7.675,-1.944 --13.752,7.62,-1.892 --13.761,7.564,-1.841 --13.766,7.508,-1.789 --13.771,7.452,-1.755 --13.781,7.397,-1.752 --13.791,7.341,-1.752 --13.801,7.286,-1.752 --13.811,7.23,-1.752 --13.821,7.175,-1.752 --13.831,7.119,-1.752 --13.841,7.064,-1.752 --13.852,7.008,-1.752 --13.862,6.953,-1.752 --13.872,6.898,-1.752 --13.882,6.842,-1.752 --13.892,6.787,-1.752 --13.901,6.731,-1.745 --13.904,6.675,-1.704 --13.904,6.618,-1.665 --13.908,6.562,-1.659 --13.913,6.506,-1.659 --13.917,6.45,-1.659 --13.922,6.394,-1.659 --13.926,6.337,-1.652 --13.924,6.281,-1.612 --13.917,6.225,-1.561 --13.911,6.169,-1.538 --13.909,6.113,-1.537 --13.907,6.057,-1.537 --13.905,6.0,-1.537 --13.903,5.944,-1.537 --13.902,5.888,-1.537 --13.9,5.831,-1.538 --13.901,5.775,-1.558 --13.908,5.719,-1.602 --13.913,5.663,-1.615 --13.916,5.607,-1.615 --13.918,5.55,-1.615 --13.921,5.494,-1.615 --13.922,5.438,-1.604 --13.916,5.382,-1.56 --13.906,5.326,-1.509 --13.896,5.271,-1.48 --13.891,5.215,-1.478 --13.885,5.158,-1.478 --13.88,5.102,-1.478 --13.875,5.046,-1.478 --13.87,4.99,-1.478 --13.865,4.934,-1.478 --13.859,4.878,-1.478 --13.854,4.822,-1.478 --13.849,4.766,-1.478 --13.844,4.709,-1.478 --13.839,4.653,-1.478 --13.833,4.597,-1.478 --13.828,4.541,-1.478 --13.823,4.485,-1.478 --13.818,4.429,-1.478 --13.813,4.373,-1.478 --13.807,4.317,-1.478 --13.802,4.26,-1.478 --13.797,4.204,-1.478 --13.792,4.148,-1.478 --13.787,4.092,-1.478 --13.781,4.036,-1.478 --13.776,3.98,-1.479 --13.775,3.923,-1.505 --13.78,3.867,-1.552 --13.784,3.811,-1.571 --13.784,3.755,-1.571 --13.784,3.698,-1.571 --13.784,3.642,-1.571 --13.784,3.586,-1.571 --13.784,3.529,-1.571 --13.784,3.473,-1.571 --13.784,3.416,-1.571 --13.784,3.36,-1.571 --13.784,3.304,-1.571 --13.784,3.247,-1.571 --13.784,3.191,-1.571 --13.784,3.135,-1.571 --13.784,3.078,-1.571 --13.784,3.022,-1.571 --13.784,2.966,-1.571 --13.784,2.909,-1.571 --13.784,2.853,-1.571 --13.784,2.796,-1.571 --13.784,2.74,-1.571 --13.784,2.684,-1.571 --13.784,2.627,-1.571 --13.784,2.571,-1.571 --13.784,2.515,-1.571 --13.784,2.458,-1.571 --13.784,2.402,-1.571 --13.784,2.345,-1.571 --13.784,2.289,-1.571 --13.784,2.233,-1.571 --13.784,2.176,-1.571 --13.784,2.12,-1.571 --13.784,2.064,-1.571 --13.784,2.007,-1.571 --13.784,1.951,-1.571 --13.784,1.895,-1.571 --13.784,1.838,-1.571 --13.784,1.782,-1.571 --13.784,1.725,-1.571 --13.784,1.669,-1.571 --13.784,1.613,-1.571 --13.784,1.556,-1.571 --13.784,1.5,-1.571 --13.784,1.444,-1.571 --13.784,1.387,-1.571 --13.784,1.331,-1.571 --13.784,1.275,-1.571 --13.784,1.218,-1.571 --13.784,1.162,-1.571 --13.784,1.105,-1.569 --13.778,1.049,-1.538 --13.767,0.994,-1.486 --13.753,0.94,-1.435 --13.736,0.886,-1.383 --13.716,0.833,-1.332 --13.693,0.781,-1.28 --13.669,0.731,-1.237 --13.649,0.678,-1.228 --13.63,0.625,-1.228 --13.611,0.572,-1.228 --13.592,0.519,-1.228 --13.573,0.466,-1.228 --13.554,0.413,-1.228 --13.535,0.36,-1.228 --13.513,0.308,-1.207 --13.485,0.259,-1.158 --13.454,0.212,-1.107 --13.42,0.167,-1.055 --13.384,0.123,-1.003 --13.346,0.081,-0.952 --13.306,0.042,-0.9 --13.264,0.004,-0.848 --13.22,-0.031,-0.797 --13.175,-0.064,-0.745 --13.127,-0.095,-0.694 --13.078,-0.123,-0.642 --13.028,-0.148,-0.59 --12.977,-0.171,-0.539 --12.924,-0.191,-0.487 --12.87,-0.209,-0.436 --12.816,-0.223,-0.384 --12.761,-0.235,-0.332 --12.705,-0.244,-0.281 --12.649,-0.25,-0.229 --12.593,-0.254,-0.178 --12.537,-0.254,-0.126 --12.48,-0.251,-0.074 --12.424,-0.246,-0.023 --12.368,-0.237,0.029 --12.313,-0.23,0.057 --12.256,-0.226,0.059 --12.2,-0.222,0.059 --12.144,-0.219,0.059 --12.088,-0.216,0.059 --12.031,-0.212,0.059 --11.975,-0.209,0.059 --11.919,-0.206,0.059 --11.863,-0.202,0.059 --11.806,-0.199,0.059 --11.75,-0.196,0.059 --11.694,-0.192,0.059 --11.637,-0.189,0.059 --11.581,-0.186,0.059 --11.525,-0.182,0.059 --11.469,-0.179,0.059 --11.412,-0.176,0.055 --11.356,-0.179,0.019 --11.3,-0.185,-0.015 --11.244,-0.187,-0.019 --11.187,-0.188,-0.019 --11.131,-0.189,-0.014 --11.075,-0.183,0.022 --11.02,-0.173,0.073 --10.964,-0.161,0.112 --10.909,-0.153,0.118 --10.853,-0.146,0.118 --10.797,-0.14,0.118 --10.741,-0.134,0.107 --10.684,-0.136,0.063 --10.628,-0.141,0.02 --10.572,-0.142,0.011 --10.515,-0.142,0.011 --10.459,-0.141,0.011 --10.403,-0.14,0.011 --10.346,-0.14,0.011 --10.29,-0.139,0.011 --10.234,-0.139,0.011 --10.177,-0.138,0.011 --10.121,-0.137,0.011 --10.065,-0.137,0.011 --10.008,-0.136,0.011 --9.952,-0.136,0.011 --9.895,-0.135,0.011 --9.839,-0.134,0.015 --9.783,-0.127,0.051 --9.728,-0.115,0.1 --9.673,-0.105,0.118 --9.617,-0.098,0.118 --9.561,-0.092,0.118 --9.505,-0.085,0.118 --9.449,-0.078,0.118 --9.393,-0.072,0.116 --9.336,-0.071,0.085 --9.28,-0.075,0.035 --9.224,-0.078,0.012 --9.168,-0.078,0.011 --9.111,-0.077,0.011 --9.055,-0.077,0.011 --8.999,-0.076,0.011 --8.942,-0.076,0.011 --8.886,-0.073,0.022 --8.83,-0.069,0.039 --8.773,-0.066,0.039 --8.717,-0.064,0.039 --8.661,-0.062,0.039 --8.604,-0.06,0.039 --8.548,-0.057,0.039 --8.492,-0.055,0.039 --8.435,-0.053,0.039 --8.379,-0.051,0.039 --8.323,-0.049,0.039 --8.266,-0.047,0.039 --8.21,-0.044,0.039 --8.154,-0.042,0.039 --8.097,-0.04,0.039 --8.041,-0.038,0.039 --7.985,-0.036,0.039 --7.929,-0.033,0.039 --7.872,-0.031,0.039 --7.816,-0.029,0.039 --7.76,-0.027,0.039 --7.71,-0.025,0.039 --7.657,-0.023,0.039 --7.606,-0.022,0.031 --7.555,-0.028,-0.011 --7.5,-0.034,-0.036 --7.449,-0.036,-0.036 --7.397,-0.038,-0.036 --7.343,-0.04,-0.036 --7.288,-0.042,-0.036 --7.233,-0.044,-0.036 --7.178,-0.046,-0.036 --7.122,-0.048,-0.036 --7.067,-0.05,-0.036 --7.011,-0.052,-0.036 --6.955,-0.054,-0.036 --6.898,-0.056,-0.036 --6.842,-0.058,-0.036 --6.786,-0.06,-0.036 --6.73,-0.062,-0.036 --6.673,-0.064,-0.036 --6.617,-0.066,-0.036 --6.561,-0.068,-0.036 --6.505,-0.07,-0.036 --6.448,-0.072,-0.036 --6.392,-0.074,-0.036 --6.336,-0.076,-0.036 --6.279,-0.078,-0.036 --6.223,-0.08,-0.036 --6.167,-0.082,-0.036 --6.11,-0.084,-0.036 --6.054,-0.086,-0.036 --5.998,-0.088,-0.036 --5.941,-0.09,-0.036 --5.885,-0.092,-0.036 --5.829,-0.094,-0.036 --5.772,-0.094,-0.017 --5.716,-0.092,-0.008 --5.66,-0.093,-0.008 --5.603,-0.093,-0.008 --5.547,-0.094,-0.008 --5.49,-0.094,-0.008 --5.434,-0.095,-0.008 --5.378,-0.094,-0.004 --5.322,-0.089,0.031 --5.266,-0.082,0.054 --5.209,-0.079,0.055 --5.153,-0.076,0.055 --5.097,-0.072,0.055 --5.041,-0.069,0.055 --4.984,-0.066,0.055 --4.928,-0.063,0.055 --4.872,-0.06,0.055 --4.815,-0.057,0.055 --4.759,-0.054,0.055 --4.703,-0.051,0.055 --4.647,-0.048,0.055 --4.59,-0.045,0.055 --4.534,-0.042,0.055 --4.478,-0.038,0.055 --4.421,-0.035,0.055 --4.365,-0.032,0.055 --4.309,-0.029,0.055 --4.253,-0.026,0.055 --4.196,-0.023,0.055 --4.14,-0.02,0.055 --4.084,-0.017,0.055 --4.027,-0.014,0.055 --3.971,-0.011,0.055 --3.915,-0.008,0.055 --3.859,-0.005,0.055 --3.802,-0.001,0.055 --3.746,0.001,0.048 --3.69,-0.003,0.008 --3.634,-0.009,-0.021 --3.577,-0.011,-0.023 --3.521,-0.012,-0.023 --3.465,-0.014,-0.023 --3.408,-0.015,-0.023 --3.352,-0.016,-0.023 --3.296,-0.017,-0.023 --3.239,-0.019,-0.023 --3.183,-0.02,-0.023 --3.127,-0.021,-0.023 --3.07,-0.023,-0.023 --3.014,-0.024,-0.023 --2.958,-0.024,-0.016 --2.902,-0.018,0.025 --2.846,-0.011,0.053 --2.789,-0.007,0.055 --2.733,-0.004,0.055 --2.677,-0.001,0.055 --2.621,0.002,0.055 --2.564,0.005,0.055 --2.508,0.008,0.055 --2.452,0.011,0.055 --2.395,0.015,0.055 --2.339,0.014,0.034 --2.283,0.008,-0.009 --2.227,0.005,-0.023 --2.171,0.003,-0.023 --2.114,0.002,-0.023 --2.058,0.001,-0.023 --2.001,-0.001,-0.023 --1.945,-0.002,-0.023 --1.889,-0.003,-0.023 --1.832,-0.005,-0.023 --1.776,-0.006,-0.023 --1.72,-0.007,-0.023 --1.663,-0.008,-0.023 --1.607,-0.01,-0.023 --1.551,-0.011,-0.023 --1.494,-0.012,-0.023 --1.438,-0.014,-0.023 --1.382,-0.015,-0.023 --1.325,-0.016,-0.023 --1.269,-0.017,-0.023 --1.213,-0.019,-0.023 --1.156,-0.02,-0.023 --1.1,-0.021,-0.023 --1.043,-0.023,-0.023 --0.993,-0.024,-0.023 --0.943,-0.025,-0.023 --0.892,-0.026,-0.023 --0.84,-0.027,-0.023 --0.788,-0.028,-0.023 --0.736,-0.03,-0.023 --0.685,-0.031,-0.023 --0.635,-0.032,-0.023 --0.585,-0.033,-0.023 --0.534,-0.034,-0.023 --0.481,-0.035,-0.023 -0.0,0.0,0.0 \ No newline at end of file From 8508249fc9b0879efd49c73ad582dcf839277c0e Mon Sep 17 00:00:00 2001 From: IvanCG14 Date: Sat, 6 Sep 2025 18:14:40 -0500 Subject: [PATCH 2/7] proyecto con nav2 y slam --- my_bot | 1 + 1 file changed, 1 insertion(+) create mode 160000 my_bot diff --git a/my_bot b/my_bot new file mode 160000 index 0000000..d8f15c1 --- /dev/null +++ b/my_bot @@ -0,0 +1 @@ +Subproject commit d8f15c16f662b210375441a669d536328c82befd From e19a90dbe0728701aa6173e76fbb58203842fe00 Mon Sep 17 00:00:00 2001 From: IvanCG14 Date: Sat, 6 Sep 2025 18:24:11 -0500 Subject: [PATCH 3/7] borrar --- my_bot | 1 - 1 file changed, 1 deletion(-) delete mode 160000 my_bot diff --git a/my_bot b/my_bot deleted file mode 160000 index d8f15c1..0000000 --- a/my_bot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d8f15c16f662b210375441a669d536328c82befd From 01c91139a70c836a3b4127c3eda7ff6353893291 Mon Sep 17 00:00:00 2001 From: IvanCG14 Date: Sat, 6 Sep 2025 18:25:14 -0500 Subject: [PATCH 4/7] proyeto con nav2 y SLAM --- my_bot/CMakeLists.txt | 40 + my_bot/LICENSE.md | 201 + my_bot/config/empty.yaml | 1 + my_bot/config/gazebo_params.yaml | 3 + my_bot/config/mapper_params_online_async.yaml | 77 + my_bot/config/mapping.rviz | 361 + my_bot/config/my_controllers.yaml | 68 + my_bot/config/nav2_params.yaml | 350 + my_bot/config/twist_mux.yaml | 11 + my_bot/config/view_bot.rviz | 240 + my_bot/description/depth_camera.xacro | 55 + my_bot/description/gazebo_control.xacro | 30 + my_bot/description/inertial_macros.xacro | 40 + my_bot/description/robot.urdf.xacro | 17 + my_bot/description/robot_core.xacro | 308 + my_bot/description/ros2_control.xacro | 33 + my_bot/launch/camera.launch.py | 21 + my_bot/launch/launch_sim.launch.py | 82 + my_bot/launch/launch_sim.py | 47 + my_bot/launch/localization_launch.py | 192 + my_bot/launch/nav_launch.py | 83 + my_bot/launch/navigation_launch.py | 272 + my_bot/launch/online_async_launch.py | 59 + my_bot/launch/rplidar.launch.py | 20 + my_bot/launch/rsp.launch.py | 48 + my_bot/maps/Spielberg_map.png | Bin 0 -> 62176 bytes my_bot/maps/Spielberg_map.yaml | 6 + my_bot/maps/levine.png | Bin 0 -> 13273 bytes my_bot/maps/levine.yaml | 6 + my_bot/maps/levine2.pgm | Bin 0 -> 224591 bytes my_bot/maps/levine2.yaml | 7 + my_bot/maps/map1_save.pgm | Bin 0 -> 25920 bytes my_bot/maps/map1_save.yaml | 7 + my_bot/package.xml | 24 + my_bot/worlds/empty.world | 13 + my_bot/worlds/levine.world | 9365 +++++++++++++++++ my_bot/worlds/obstacles.world | 937 ++ 37 files changed, 13024 insertions(+) create mode 100644 my_bot/CMakeLists.txt create mode 100644 my_bot/LICENSE.md create mode 100644 my_bot/config/empty.yaml create mode 100644 my_bot/config/gazebo_params.yaml create mode 100644 my_bot/config/mapper_params_online_async.yaml create mode 100644 my_bot/config/mapping.rviz create mode 100644 my_bot/config/my_controllers.yaml create mode 100644 my_bot/config/nav2_params.yaml create mode 100644 my_bot/config/twist_mux.yaml create mode 100644 my_bot/config/view_bot.rviz create mode 100644 my_bot/description/depth_camera.xacro create mode 100644 my_bot/description/gazebo_control.xacro create mode 100644 my_bot/description/inertial_macros.xacro create mode 100644 my_bot/description/robot.urdf.xacro create mode 100644 my_bot/description/robot_core.xacro create mode 100644 my_bot/description/ros2_control.xacro create mode 100644 my_bot/launch/camera.launch.py create mode 100644 my_bot/launch/launch_sim.launch.py create mode 100644 my_bot/launch/launch_sim.py create mode 100644 my_bot/launch/localization_launch.py create mode 100644 my_bot/launch/nav_launch.py create mode 100644 my_bot/launch/navigation_launch.py create mode 100644 my_bot/launch/online_async_launch.py create mode 100644 my_bot/launch/rplidar.launch.py create mode 100644 my_bot/launch/rsp.launch.py create mode 100644 my_bot/maps/Spielberg_map.png create mode 100644 my_bot/maps/Spielberg_map.yaml create mode 100644 my_bot/maps/levine.png create mode 100644 my_bot/maps/levine.yaml create mode 100644 my_bot/maps/levine2.pgm create mode 100644 my_bot/maps/levine2.yaml create mode 100644 my_bot/maps/map1_save.pgm create mode 100644 my_bot/maps/map1_save.yaml create mode 100644 my_bot/package.xml create mode 100644 my_bot/worlds/empty.world create mode 100644 my_bot/worlds/levine.world create mode 100644 my_bot/worlds/obstacles.world diff --git a/my_bot/CMakeLists.txt b/my_bot/CMakeLists.txt new file mode 100644 index 0000000..dfa34c8 --- /dev/null +++ b/my_bot/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.5) +project(my_bot) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +install( + DIRECTORY config description launch worlds + DESTINATION share/${PROJECT_NAME} +) + +ament_package() diff --git a/my_bot/LICENSE.md b/my_bot/LICENSE.md new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/my_bot/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/my_bot/config/empty.yaml b/my_bot/config/empty.yaml new file mode 100644 index 0000000..04700ba --- /dev/null +++ b/my_bot/config/empty.yaml @@ -0,0 +1 @@ +# This is an empty file, so that git commits the folder correctly \ No newline at end of file diff --git a/my_bot/config/gazebo_params.yaml b/my_bot/config/gazebo_params.yaml new file mode 100644 index 0000000..d7caf6d --- /dev/null +++ b/my_bot/config/gazebo_params.yaml @@ -0,0 +1,3 @@ +gazebo: + ros__parameters: + publish_rate: 400.0 \ No newline at end of file diff --git a/my_bot/config/mapper_params_online_async.yaml b/my_bot/config/mapper_params_online_async.yaml new file mode 100644 index 0000000..2a0448f --- /dev/null +++ b/my_bot/config/mapper_params_online_async.yaml @@ -0,0 +1,77 @@ +slam_toolbox: + ros__parameters: + + # Plugin params + solver_plugin: solver_plugins::CeresSolver + ceres_linear_solver: SPARSE_NORMAL_CHOLESKY + ceres_preconditioner: SCHUR_JACOBI + ceres_trust_strategy: LEVENBERG_MARQUARDT + ceres_dogleg_type: TRADITIONAL_DOGLEG + ceres_loss_function: None + + # ROS Parameters + odom_frame: odom + map_frame: map + base_frame: base_footprint + scan_topic: /scan + use_map_saver: true + mode: localization + + # if you'd like to immediately start continuing a map at a given pose + # or at the dock, but they are mutually exclusive, if pose is given + # will use pose + map_file_name: /home/ivan/dev_ws/map1_serial + # map_start_pose: [0.0, 0.0, 0.0] + map_start_at_dock: true + + debug_logging: false + throttle_scans: 1 + transform_publish_period: 0.02 #if 0 never publishes odometry + map_update_interval: 5.0 + resolution: 0.05 + min_laser_range: 0.0 #for rastering images + max_laser_range: 20.0 #for rastering images + minimum_time_interval: 0.5 + transform_timeout: 0.2 + tf_buffer_duration: 30. + stack_size_to_use: 40000000 #// program needs a larger stack size to serialize large maps + enable_interactive_mode: true + + # General Parameters + use_scan_matching: true + use_scan_barycenter: true + minimum_travel_distance: 0.1 + minimum_travel_heading: 0.1 + scan_buffer_size: 10 + scan_buffer_maximum_scan_distance: 10.0 + link_match_minimum_response_fine: 0.1 + link_scan_maximum_distance: 1.5 + loop_search_maximum_distance: 3.0 + do_loop_closing: true + loop_match_minimum_chain_size: 10 + loop_match_maximum_variance_coarse: 3.0 + loop_match_minimum_response_coarse: 0.35 + loop_match_minimum_response_fine: 0.45 + + # Correlation Parameters - Correlation Parameters + correlation_search_space_dimension: 0.5 + correlation_search_space_resolution: 0.01 + correlation_search_space_smear_deviation: 0.1 + + # Correlation Parameters - Loop Closure Parameters + loop_search_space_dimension: 8.0 + loop_search_space_resolution: 0.05 + loop_search_space_smear_deviation: 0.03 + + # Scan Matcher Parameters + distance_variance_penalty: 0.5 + angle_variance_penalty: 1.0 + + fine_search_angle_offset: 0.00349 + coarse_search_angle_offset: 0.349 + coarse_angle_resolution: 0.0349 + minimum_angle_penalty: 0.9 + minimum_distance_penalty: 0.5 + use_response_expansion: true + min_pass_through: 2 + occupancy_threshold: 0.1 diff --git a/my_bot/config/mapping.rviz b/my_bot/config/mapping.rviz new file mode 100644 index 0000000..443c684 --- /dev/null +++ b/my_bot/config/mapping.rviz @@ -0,0 +1,361 @@ +Panels: + - Class: rviz_common/Displays + Help Height: 78 + Name: Displays + Property Tree Widget: + Expanded: ~ + Splitter Ratio: 0.5 + Tree Height: 178 + - Class: rviz_common/Selection + Name: Selection + - Class: rviz_common/Tool Properties + Expanded: + - /2D Goal Pose1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz_common/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz_common/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: PointCloud2 + - Class: slam_toolbox::SlamToolboxPlugin + Name: SlamToolboxPlugin +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz_default_plugins/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Class: rviz_default_plugins/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + base_footprint: + Value: true + base_link: + Value: true + camera_link: + Value: true + camera_link_optical: + Value: true + caster_wheel: + Value: true + chassis: + Value: true + laser_frame: + Value: true + left_wheel: + Value: true + map: + Value: true + odom: + Value: true + right_wheel: + Value: true + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: false + Show Names: false + Tree: + map: + {} + odom: + base_link: + base_footprint: + {} + chassis: + camera_link: + camera_link_optical: + {} + caster_wheel: + {} + laser_frame: + {} + left_wheel: + {} + right_wheel: + {} + Update Interval: 0 + Value: true + - Alpha: 1 + Class: rviz_default_plugins/RobotModel + Collision Enabled: false + Description File: "" + Description Source: Topic + Description Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /robot_description + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + Link Tree Style: Links in Alphabetic Order + base_footprint: + Alpha: 1 + Show Axes: false + Show Trail: false + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_link_optical: + Alpha: 1 + Show Axes: false + Show Trail: false + caster_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + chassis: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + laser_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + left_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + right_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Mass Properties: + Inertia: false + Mass: false + Name: RobotModel + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Class: rviz_default_plugins/Image + Enabled: true + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /camera/depth/image_raw + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz_default_plugins/LaserScan + Color: 255; 255; 255 + Color Transformer: Intensity + Decay Time: 0 + Enabled: true + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 0 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: LaserScan + Position Transformer: XYZ + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /scan + Use Fixed Frame: true + Use rainbow: true + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz_default_plugins/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: true + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 4096 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: PointCloud2 + Position Transformer: XYZ + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /camera/points + Use Fixed Frame: true + Use rainbow: true + Value: true + - Alpha: 0.699999988079071 + Class: rviz_default_plugins/Map + Color Scheme: map + Draw Behind: false + Enabled: true + Name: Map + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /map + Update Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /map_updates + Use Timestamp: false + Value: true + Enabled: true + Global Options: + Background Color: 48; 48; 48 + Fixed Frame: map + Frame Rate: 30 + Name: root + Tools: + - Class: rviz_default_plugins/Interact + Hide Inactive Objects: true + - Class: rviz_default_plugins/MoveCamera + - Class: rviz_default_plugins/Select + - Class: rviz_default_plugins/FocusCamera + - Class: rviz_default_plugins/Measure + Line color: 128; 128; 0 + - Class: rviz_default_plugins/SetInitialPose + Covariance x: 0.25 + Covariance y: 0.25 + Covariance yaw: 0.06853891909122467 + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /initialpose + - Class: rviz_default_plugins/SetGoal + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /goal_pose + - Class: rviz_default_plugins/PublishPoint + Single click: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /clicked_point + Transformation: + Current: + Class: rviz_default_plugins/TF + Value: true + Views: + Current: + Class: rviz_default_plugins/Orbit + Distance: 5.952032089233398 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Focal Point: + X: 0 + Y: 0 + Z: 0 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 1.1647965908050537 + Target Frame: + Value: Orbit (rviz) + Yaw: 3.5485846996307373 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1016 + Hide Left Dock: false + Hide Right Dock: false + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000002170000035afc020000000afb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000013d000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000001800000008c0000002800fffffffb000000220053006c0061006d0054006f006f006c0062006f00780050006c007500670069006e0100000212000001850000018500ffffff000000010000010f0000035afc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d0000035a000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073a0000003efc0100000002fb0000000800540069006d006501000000000000073a000002fb00fffffffb0000000800540069006d00650100000000000004500000000000000000000004080000035a00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + SlamToolboxPlugin: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: false + Width: 1850 + X: 70 + Y: 27 diff --git a/my_bot/config/my_controllers.yaml b/my_bot/config/my_controllers.yaml new file mode 100644 index 0000000..9e59717 --- /dev/null +++ b/my_bot/config/my_controllers.yaml @@ -0,0 +1,68 @@ +controller_manager: + ros__parameters: + update_rate: 30 + use_sim_time: true + + diff_cont: + type: diff_drive_controller/DiffDriveController + + joint_broad: + type: joint_state_broadcaster/JointStateBroadcaster + +diff_cont: + ros__parameters: + + publish_rate: 50.0 + + base_frame_id: base_link + + left_wheel_names: ['left_wheel_joint'] + right_wheel_names: ['right_wheel_joint'] + wheel_separation: 0.20 + wheel_radius: 0.04 + + use_stamped_vel: false + + # open_loop: false + + # wheels_per_side: x + wheel_separation_multiplier: 1.0 + left_wheel_radius_multiplier: 1.0 + right_wheel_radius_multiplier: 1.0 + + odom_frame_id: odom + # pose_covariance_diagonal: x + # twist_covariance_diagonal: x + # open_loop: x + enable_odom_tf: true + + # cmd_vel_timeout: x + # publish_limited_velocity: x + # velocity_rolling_window_size: x + + + # linear.x.has_velocity_limits: false + # linear.x.has_acceleration_limits: false + # linear.x.has_jerk_limits: false + # linear.x.max_velocity: NAN + # linear.x.min_velocity: NAN + # linear.x.max_acceleration: NAN + # linear.x.min_acceleration: NAN + # linear.x.max_jerk: NAN + # linear.x.min_jerk: NAN + + # angular.z.has_velocity_limits: false + # angular.z.has_acceleration_limits: false + # angular.z.has_jerk_limits: false + # angular.z.max_velocity: NAN + # angular.z.min_velocity: NAN + # angular.z.max_acceleration: NAN + # angular.z.min_acceleration: NAN + # angular.z.max_jerk: NAN + # angular.z.min_jerk: NAN + + + + +# joint_broad: +# ros__parameters: \ No newline at end of file diff --git a/my_bot/config/nav2_params.yaml b/my_bot/config/nav2_params.yaml new file mode 100644 index 0000000..954d1d8 --- /dev/null +++ b/my_bot/config/nav2_params.yaml @@ -0,0 +1,350 @@ +amcl: + ros__parameters: + use_sim_time: True + alpha1: 0.2 + alpha2: 0.2 + alpha3: 0.2 + alpha4: 0.2 + alpha5: 0.2 + base_frame_id: "base_footprint" + beam_skip_distance: 0.5 + beam_skip_error_threshold: 0.9 + beam_skip_threshold: 0.3 + do_beamskip: false + global_frame_id: "map" + lambda_short: 0.1 + laser_likelihood_max_dist: 2.0 + laser_max_range: 100.0 + laser_min_range: -1.0 + laser_model_type: "likelihood_field" + max_beams: 360 + max_particles: 2000 + min_particles: 500 + odom_frame_id: "odom" + pf_err: 0.05 + pf_z: 0.99 + recovery_alpha_fast: 0.0 + recovery_alpha_slow: 0.0 + resample_interval: 1 + robot_model_type: "nav2_amcl::DifferentialMotionModel" + save_pose_rate: 0.5 + sigma_hit: 0.2 + tf_broadcast: true + transform_tolerance: 1.0 + update_min_a: 0.2 + update_min_d: 0.25 + z_hit: 0.5 + z_max: 0.05 + z_rand: 0.5 + z_short: 0.05 + scan_topic: scan + +bt_navigator: + ros__parameters: + use_sim_time: True + global_frame: map + robot_base_frame: base_link + odom_topic: /odom + bt_loop_duration: 10 + default_server_timeout: 20 + wait_for_service_timeout: 1000 + # 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults: + # nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml + # nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml + # They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2. + plugin_lib_names: + - nav2_compute_path_to_pose_action_bt_node + - nav2_compute_path_through_poses_action_bt_node + - nav2_smooth_path_action_bt_node + - nav2_follow_path_action_bt_node + - nav2_spin_action_bt_node + - nav2_wait_action_bt_node + - nav2_assisted_teleop_action_bt_node + - nav2_back_up_action_bt_node + - nav2_drive_on_heading_bt_node + - nav2_clear_costmap_service_bt_node + - nav2_is_stuck_condition_bt_node + - nav2_goal_reached_condition_bt_node + - nav2_goal_updated_condition_bt_node + - nav2_globally_updated_goal_condition_bt_node + - nav2_is_path_valid_condition_bt_node + - nav2_initial_pose_received_condition_bt_node + - nav2_reinitialize_global_localization_service_bt_node + - nav2_rate_controller_bt_node + - nav2_distance_controller_bt_node + - nav2_speed_controller_bt_node + - nav2_truncate_path_action_bt_node + - nav2_truncate_path_local_action_bt_node + - nav2_goal_updater_node_bt_node + - nav2_recovery_node_bt_node + - nav2_pipeline_sequence_bt_node + - nav2_round_robin_node_bt_node + - nav2_transform_available_condition_bt_node + - nav2_time_expired_condition_bt_node + - nav2_path_expiring_timer_condition + - nav2_distance_traveled_condition_bt_node + - nav2_single_trigger_bt_node + - nav2_goal_updated_controller_bt_node + - nav2_is_battery_low_condition_bt_node + - nav2_navigate_through_poses_action_bt_node + - nav2_navigate_to_pose_action_bt_node + - nav2_remove_passed_goals_action_bt_node + - nav2_planner_selector_bt_node + - nav2_controller_selector_bt_node + - nav2_goal_checker_selector_bt_node + - nav2_controller_cancel_bt_node + - nav2_path_longer_on_approach_bt_node + - nav2_wait_cancel_bt_node + - nav2_spin_cancel_bt_node + - nav2_back_up_cancel_bt_node + - nav2_assisted_teleop_cancel_bt_node + - nav2_drive_on_heading_cancel_bt_node + - nav2_is_battery_charging_condition_bt_node + +bt_navigator_navigate_through_poses_rclcpp_node: + ros__parameters: + use_sim_time: True + +bt_navigator_navigate_to_pose_rclcpp_node: + ros__parameters: + use_sim_time: True + +controller_server: + ros__parameters: + use_sim_time: True + controller_frequency: 20.0 + min_x_velocity_threshold: 0.001 + min_y_velocity_threshold: 0.5 + min_theta_velocity_threshold: 0.001 + failure_tolerance: 0.3 + progress_checker_plugin: "progress_checker" + goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker" + controller_plugins: ["FollowPath"] + + # Progress checker parameters + progress_checker: + plugin: "nav2_controller::SimpleProgressChecker" + required_movement_radius: 0.5 + movement_time_allowance: 10.0 + # Goal checker parameters + #precise_goal_checker: + # plugin: "nav2_controller::SimpleGoalChecker" + # xy_goal_tolerance: 0.25 + # yaw_goal_tolerance: 0.25 + # stateful: True + general_goal_checker: + stateful: True + plugin: "nav2_controller::SimpleGoalChecker" + xy_goal_tolerance: 0.15 + yaw_goal_tolerance: 0.15 + # DWB parameters + FollowPath: + plugin: "dwb_core::DWBLocalPlanner" + debug_trajectory_details: True + min_vel_x: 0.0 + min_vel_y: 0.0 + max_vel_x: 1.04 + max_vel_y: 0.0 + max_vel_theta: 4.0 + min_speed_xy: 0.0 + max_speed_xy: 1.04 + min_speed_theta: 0.0 + # Add high threshold velocity for turtlebot 3 issue. + # https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75 + acc_lim_x: 10.0 + acc_lim_y: 0.0 + acc_lim_theta: 6.4 + decel_lim_x: -5.0 + decel_lim_y: 0.0 + decel_lim_theta: -6.4 + vx_samples: 20 + vy_samples: 0 + vtheta_samples: 20 + sim_time: 1.7 + linear_granularity: 0.05 + angular_granularity: 0.025 + transform_tolerance: 0.2 + xy_goal_tolerance: 0.25 + trans_stopped_velocity: 1.0 + short_circuit_trajectory_evaluation: True + stateful: True + critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"] + BaseObstacle.scale: 0.02 + PathAlign.scale: 32.0 + PathAlign.forward_point_distance: 0.1 + GoalAlign.scale: 24.0 + GoalAlign.forward_point_distance: 0.1 + PathDist.scale: 32.0 + GoalDist.scale: 24.0 + RotateToGoal.scale: 32.0 + RotateToGoal.slowing_factor: 5.0 + RotateToGoal.lookahead_time: -1.0 + +local_costmap: + local_costmap: + ros__parameters: + update_frequency: 5.0 + publish_frequency: 2.0 + global_frame: odom + robot_base_frame: base_link + use_sim_time: True + rolling_window: true + width: 3 + height: 3 + resolution: 0.05 + robot_radius: 0.15 + plugins: ["voxel_layer", "inflation_layer"] + inflation_layer: + plugin: "nav2_costmap_2d::InflationLayer" + cost_scaling_factor: 3.0 + inflation_radius: 0.55 + voxel_layer: + plugin: "nav2_costmap_2d::VoxelLayer" + enabled: True + publish_voxel_map: True + origin_z: 0.0 + z_resolution: 0.05 + z_voxels: 16 + max_obstacle_height: 2.0 + mark_threshold: 0 + observation_sources: scan + scan: + topic: /scan + max_obstacle_height: 2.0 + clearing: True + marking: True + data_type: "LaserScan" + raytrace_max_range: 3.0 + raytrace_min_range: 0.0 + obstacle_max_range: 2.5 + obstacle_min_range: 0.0 + static_layer: + plugin: "nav2_costmap_2d::StaticLayer" + map_subscribe_transient_local: True + always_send_full_costmap: True + +global_costmap: + global_costmap: + ros__parameters: + update_frequency: 1.0 + publish_frequency: 1.0 + global_frame: map + robot_base_frame: base_link + use_sim_time: True + robot_radius: 0.15 + resolution: 0.05 + track_unknown_space: true + plugins: ["static_layer", "obstacle_layer", "inflation_layer"] + obstacle_layer: + plugin: "nav2_costmap_2d::ObstacleLayer" + enabled: True + observation_sources: scan + scan: + topic: /scan + max_obstacle_height: 2.0 + clearing: True + marking: True + data_type: "LaserScan" + raytrace_max_range: 3.0 + raytrace_min_range: 0.0 + obstacle_max_range: 2.5 + obstacle_min_range: 0.0 + static_layer: + plugin: "nav2_costmap_2d::StaticLayer" + map_subscribe_transient_local: True + inflation_layer: + plugin: "nav2_costmap_2d::InflationLayer" + cost_scaling_factor: 3.0 + inflation_radius: 0.55 + always_send_full_costmap: True + +map_server: + ros__parameters: + use_sim_time: True + # Overridden in launch by the "map" launch configuration or provided default value. + # To use in yaml, remove the default "map" value in the tb3_simulation_launch.py file & provide full path to map below. + yaml_filename: "/src/my_bot/maps/levine2.yaml" + +map_saver: + ros__parameters: + use_sim_time: True + save_map_timeout: 5.0 + free_thresh_default: 0.25 + occupied_thresh_default: 0.65 + map_subscribe_transient_local: True + +planner_server: + ros__parameters: + expected_planner_frequency: 20.0 + use_sim_time: True + planner_plugins: ["GridBased"] + GridBased: + plugin: "nav2_navfn_planner/NavfnPlanner" + tolerance: 0.5 + use_astar: false + allow_unknown: true + +smoother_server: + ros__parameters: + use_sim_time: True + smoother_plugins: ["simple_smoother"] + simple_smoother: + plugin: "nav2_smoother::SimpleSmoother" + tolerance: 1.0e-10 + max_its: 1000 + do_refinement: True + +behavior_server: + ros__parameters: + costmap_topic: local_costmap/costmap_raw + footprint_topic: local_costmap/published_footprint + cycle_frequency: 10.0 + behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"] + spin: + plugin: "nav2_behaviors/Spin" + backup: + plugin: "nav2_behaviors/BackUp" + drive_on_heading: + plugin: "nav2_behaviors/DriveOnHeading" + wait: + plugin: "nav2_behaviors/Wait" + assisted_teleop: + plugin: "nav2_behaviors/AssistedTeleop" + global_frame: odom + robot_base_frame: base_link + transform_tolerance: 0.1 + use_sim_time: true + simulate_ahead_time: 2.0 + max_rotational_vel: 2.0 + min_rotational_vel: 1.0 + rotational_acc_lim: 8.4 + +robot_state_publisher: + ros__parameters: + use_sim_time: True + +waypoint_follower: + ros__parameters: + use_sim_time: True + loop_rate: 20 + stop_on_failure: false + waypoint_task_executor_plugin: "wait_at_waypoint" + wait_at_waypoint: + plugin: "nav2_waypoint_follower::WaitAtWaypoint" + enabled: True + waypoint_pause_duration: 200 + +velocity_smoother: + ros__parameters: + use_sim_time: True + smoothing_frequency: 20.0 + scale_velocities: False + feedback: "OPEN_LOOP" + max_velocity: [1.04, 0.0, 4.0] + min_velocity: [-1.04, 0.0, -4.0] + max_accel: [5.0, 0.0, 6.4] + max_decel: [-5.0, 0.0, -6.4] + odom_topic: "odom" + odom_duration: 0.1 + deadband_velocity: [0.0, 0.0, 0.0] + velocity_timeout: 1.0 diff --git a/my_bot/config/twist_mux.yaml b/my_bot/config/twist_mux.yaml new file mode 100644 index 0000000..7f10de0 --- /dev/null +++ b/my_bot/config/twist_mux.yaml @@ -0,0 +1,11 @@ +twist_mux: + ros__parameters: + topics: + navigation: + topic : cmd_vel + timeout : 0.5 + priority: 10 + teleop: + topic : cmd_vel_teleop + timeout : 0.5 + priority: 100 \ No newline at end of file diff --git a/my_bot/config/view_bot.rviz b/my_bot/config/view_bot.rviz new file mode 100644 index 0000000..7f6371d --- /dev/null +++ b/my_bot/config/view_bot.rviz @@ -0,0 +1,240 @@ +Panels: + - Class: rviz_common/Displays + Help Height: 78 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /Status1 + - /TF1 + - /RobotModel1 + Splitter Ratio: 0.5 + Tree Height: 455 + - Class: rviz_common/Selection + Name: Selection + - Class: rviz_common/Tool Properties + Expanded: + - /2D Goal Pose1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz_common/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz_common/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: "" +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz_default_plugins/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Class: rviz_default_plugins/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + base_link: + Value: true + chassis: + Value: true + front_left_steer_link: + Value: true + front_left_wheel: + Value: true + front_right_steer_link: + Value: true + front_right_wheel: + Value: true + left_wheel: + Value: true + right_wheel: + Value: true + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + base_link: + chassis: + {} + front_left_steer_link: + front_left_wheel: + {} + front_right_steer_link: + front_right_wheel: + {} + left_wheel: + {} + right_wheel: + {} + Update Interval: 0 + Value: true + - Alpha: 1 + Class: rviz_default_plugins/RobotModel + Collision Enabled: false + Description File: "" + Description Source: Topic + Description Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /robot_description + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + Link Tree Style: Links in Alphabetic Order + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + chassis: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + front_left_steer_link: + Alpha: 1 + Show Axes: false + Show Trail: false + front_left_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + front_right_steer_link: + Alpha: 1 + Show Axes: false + Show Trail: false + front_right_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + left_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + right_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Mass Properties: + Inertia: false + Mass: false + Name: RobotModel + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + Enabled: true + Global Options: + Background Color: 48; 48; 48 + Fixed Frame: base_link + Frame Rate: 30 + Name: root + Tools: + - Class: rviz_default_plugins/Interact + Hide Inactive Objects: true + - Class: rviz_default_plugins/MoveCamera + - Class: rviz_default_plugins/Select + - Class: rviz_default_plugins/FocusCamera + - Class: rviz_default_plugins/Measure + Line color: 128; 128; 0 + - Class: rviz_default_plugins/SetInitialPose + Covariance x: 0.25 + Covariance y: 0.25 + Covariance yaw: 0.06853891909122467 + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /initialpose + - Class: rviz_default_plugins/SetGoal + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /goal_pose + - Class: rviz_default_plugins/PublishPoint + Single click: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /clicked_point + Transformation: + Current: + Class: rviz_default_plugins/TF + Value: true + Views: + Current: + Class: rviz_default_plugins/Orbit + Distance: 0.7628582715988159 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Focal Point: + X: 0 + Y: 0 + Z: 0 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.6597976088523865 + Target Frame: + Value: Orbit (rviz) + Yaw: 0.818588137626648 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 752 + Hide Left Dock: false + Hide Right Dock: false + QMainWindow State: 000000ff00000000fd00000004000000000000015600000252fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000252000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000252fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d00000252000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000056b0000003efc0100000002fb0000000800540069006d006501000000000000056b000002fb00fffffffb0000000800540069006d00650100000000000004500000000000000000000002fa0000025200000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: false + Width: 1387 + X: 301 + Y: 114 diff --git a/my_bot/description/depth_camera.xacro b/my_bot/description/depth_camera.xacro new file mode 100644 index 0000000..1d4a57f --- /dev/null +++ b/my_bot/description/depth_camera.xacro @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gazebo/Blue + + + 0 0 0 0 0 0 + true + 10 + + 1.089 + + B8G8R8 + 640 + 480 + + + 0.05 + 8.0 + + + + camera_link_optical + 0.1 + 100.0 + + + + + \ No newline at end of file diff --git a/my_bot/description/gazebo_control.xacro b/my_bot/description/gazebo_control.xacro new file mode 100644 index 0000000..256d9ad --- /dev/null +++ b/my_bot/description/gazebo_control.xacro @@ -0,0 +1,30 @@ + + + + + + + + left_wheel_joint + right_wheel_joint + + + 0.2 + 0.08 + + + 200 + 10.0 + + + odom + base_link + + true + true + true + + + + + diff --git a/my_bot/description/inertial_macros.xacro b/my_bot/description/inertial_macros.xacro new file mode 100644 index 0000000..5cf1cac --- /dev/null +++ b/my_bot/description/inertial_macros.xacro @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/my_bot/description/robot.urdf.xacro b/my_bot/description/robot.urdf.xacro new file mode 100644 index 0000000..6be109d --- /dev/null +++ b/my_bot/description/robot.urdf.xacro @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/my_bot/description/robot_core.xacro b/my_bot/description/robot_core.xacro new file mode 100644 index 0000000..0cee42f --- /dev/null +++ b/my_bot/description/robot_core.xacro @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gazebo/White + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gazebo/Blue + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gazebo/Blue + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gazebo/Black + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gazebo/Red + + + 0 0 0 0 0 0 + true + 10 + + + + 360 + -3.14 + 3.14 + + + + 0.3 + 12 + + + + + ~/out:=scan + + sensor_msgs/LaserScan + laser_frame + + + + + diff --git a/my_bot/description/ros2_control.xacro b/my_bot/description/ros2_control.xacro new file mode 100644 index 0000000..f0e97e6 --- /dev/null +++ b/my_bot/description/ros2_control.xacro @@ -0,0 +1,33 @@ + + + + + + + gazebo_ros2_control/GazeboSystem + + + + -10 + 10 + + + + + + + -10 + 10 + + + + + + + + + $(find my_bot)/config/my_controllers.yaml + + + + \ No newline at end of file diff --git a/my_bot/launch/camera.launch.py b/my_bot/launch/camera.launch.py new file mode 100644 index 0000000..3691721 --- /dev/null +++ b/my_bot/launch/camera.launch.py @@ -0,0 +1,21 @@ +import os + +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + + + + return LaunchDescription([ + + Node( + package='v4l2_camera', + executable='v4l2_camera_node', + output='screen', + parameters=[{ + 'image_size': [640,480], + 'camera_frame_id': 'camera_link_optical' + }] + ) + ]) \ No newline at end of file diff --git a/my_bot/launch/launch_sim.launch.py b/my_bot/launch/launch_sim.launch.py new file mode 100644 index 0000000..4a3e430 --- /dev/null +++ b/my_bot/launch/launch_sim.launch.py @@ -0,0 +1,82 @@ +import os + +from ament_index_python.packages import get_package_share_directory + + +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource + +from launch_ros.actions import Node + + + +def generate_launch_description(): + + + # Include the robot_state_publisher launch file, provided by our own package. Force sim time to be enabled + # !!! MAKE SURE YOU SET THE PACKAGE NAME CORRECTLY !!! + + package_name='my_bot' #<--- CHANGE ME + + rsp = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory(package_name),'launch','rsp.launch.py' + )]), launch_arguments={'use_sim_time': 'true', 'use_ros2_control': 'true'}.items() + ) + + twist_mux_params = os.path.join(get_package_share_directory(package_name),'config','twist_mux.yaml') + twist_mux = Node( + package="twist_mux", + executable="twist_mux", + parameters=[twist_mux_params, {'use_sim_time': True}], + remappings=[('/cmd_vel_out','/diff_cont/cmd_vel_unstamped')] + ) + + gazebo_params_file = os.path.join(get_package_share_directory(package_name),'config','gazebo_params.yaml') + # Include the Gazebo launch file, provided by the gazebo_ros package + gazebo = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py')]), + launch_arguments={'extra_gazebo_args': '--ros-args --params-file ' + gazebo_params_file}.items() + ) + + # Run the spawner node from the gazebo_ros package. The entity name doesn't really matter if you only have a single robot. + spawn_entity = Node(package='gazebo_ros', executable='spawn_entity.py', + arguments=['-topic', 'robot_description', + '-entity', 'my_bot'], + output='screen') + + diff_drive_spawner = Node( + package="controller_manager", + executable="spawner", + arguments=["diff_cont"], + ) + + joint_broad_spawner = Node( + package="controller_manager", + executable="spawner", + arguments=["joint_broad"], + ) + + teleop = Node( + package='teleop_twist_keyboard', + executable='teleop_twist_keyboard', + name='teleop_keyboard', + output='screen', + prefix='xterm -e', + remappings=[ + ('/cmd_vel', '/cmd_vel_teleop') + ] + ) + + # Launch them all! + return LaunchDescription([ + rsp, + twist_mux, + gazebo, + spawn_entity, + diff_drive_spawner, + joint_broad_spawner, + teleop + ]) diff --git a/my_bot/launch/launch_sim.py b/my_bot/launch/launch_sim.py new file mode 100644 index 0000000..5b1ed07 --- /dev/null +++ b/my_bot/launch/launch_sim.py @@ -0,0 +1,47 @@ +import os + +from ament_index_python.packages import get_package_share_directory + + +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource + +from launch_ros.actions import Node + + + +def generate_launch_description(): + + + # Include the robot_state_publisher launch file, provided by our own package. Force sim time to be enabled + # !!! MAKE SURE YOU SET THE PACKAGE NAME CORRECTLY !!! + + package_name='my_bot' #<--- CHANGE ME + + rsp = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory(package_name),'launch','rsp.launch.py' + )]), launch_arguments={'use_sim_time': 'true'}.items() + ) + + # Include the Gazebo launch file, provided by the gazebo_ros package + gazebo = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py')]), + ) + + # Run the spawner node from the gazebo_ros package. The entity name doesn't really matter if you only have a single robot. + spawn_entity = Node(package='gazebo_ros', executable='spawn_entity.py', + arguments=['-topic', 'robot_description', + '-entity', 'my_bot'], + output='screen') + + + + # Launch them all! + return LaunchDescription([ + rsp, + gazebo, + spawn_entity, + ]) diff --git a/my_bot/launch/localization_launch.py b/my_bot/launch/localization_launch.py new file mode 100644 index 0000000..8a18781 --- /dev/null +++ b/my_bot/launch/localization_launch.py @@ -0,0 +1,192 @@ +# Copyright (c) 2018 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, GroupAction, SetEnvironmentVariable +from launch.conditions import IfCondition +from launch.substitutions import LaunchConfiguration, PythonExpression +from launch_ros.actions import LoadComposableNodes +from launch_ros.actions import Node +from launch_ros.descriptions import ComposableNode, ParameterFile +from nav2_common.launch import RewrittenYaml + + +def generate_launch_description(): + # Get the launch directory + bringup_dir = get_package_share_directory('my_bot') + + namespace = LaunchConfiguration('namespace') + map_yaml_file = LaunchConfiguration('map') + use_sim_time = LaunchConfiguration('use_sim_time') + autostart = LaunchConfiguration('autostart') + params_file = LaunchConfiguration('params_file') + use_composition = LaunchConfiguration('use_composition') + container_name = LaunchConfiguration('container_name') + container_name_full = (namespace, '/', container_name) + use_respawn = LaunchConfiguration('use_respawn') + log_level = LaunchConfiguration('log_level') + + lifecycle_nodes = ['map_server', 'amcl'] + + # Map fully qualified names to relative ones so the node's namespace can be prepended. + # In case of the transforms (tf), currently, there doesn't seem to be a better alternative + # https://github.com/ros/geometry2/issues/32 + # https://github.com/ros/robot_state_publisher/pull/30 + # TODO(orduno) Substitute with `PushNodeRemapping` + # https://github.com/ros2/launch_ros/issues/56 + remappings = [('/tf', 'tf'), + ('/tf_static', 'tf_static')] + + # Create our own temporary YAML files that include substitutions + param_substitutions = { + 'use_sim_time': use_sim_time, + 'yaml_filename': map_yaml_file} + + configured_params = ParameterFile( + RewrittenYaml( + source_file=params_file, + root_key=namespace, + param_rewrites=param_substitutions, + convert_types=True), + allow_substs=True) + + stdout_linebuf_envvar = SetEnvironmentVariable( + 'RCUTILS_LOGGING_BUFFERED_STREAM', '1') + + declare_namespace_cmd = DeclareLaunchArgument( + 'namespace', + default_value='', + description='Top-level namespace') + + declare_map_yaml_cmd = DeclareLaunchArgument( + 'map', + description='Full path to map yaml file to load') + + declare_use_sim_time_cmd = DeclareLaunchArgument( + 'use_sim_time', + default_value='false', + description='Use simulation (Gazebo) clock if true') + + declare_params_file_cmd = DeclareLaunchArgument( + 'params_file', + default_value=os.path.join(bringup_dir, 'config', 'nav2_params.yaml'), + description='Full path to the ROS2 parameters file to use for all launched nodes') + + declare_autostart_cmd = DeclareLaunchArgument( + 'autostart', default_value='true', + description='Automatically startup the nav2 stack') + + declare_use_composition_cmd = DeclareLaunchArgument( + 'use_composition', default_value='False', + description='Use composed bringup if True') + + declare_container_name_cmd = DeclareLaunchArgument( + 'container_name', default_value='nav2_container', + description='the name of conatiner that nodes will load in if use composition') + + declare_use_respawn_cmd = DeclareLaunchArgument( + 'use_respawn', default_value='False', + description='Whether to respawn if a node crashes. Applied when composition is disabled.') + + declare_log_level_cmd = DeclareLaunchArgument( + 'log_level', default_value='info', + description='log level') + + load_nodes = GroupAction( + condition=IfCondition(PythonExpression(['not ', use_composition])), + actions=[ + Node( + package='nav2_map_server', + executable='map_server', + name='map_server', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings), + Node( + package='nav2_amcl', + executable='amcl', + name='amcl', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings), + Node( + package='nav2_lifecycle_manager', + executable='lifecycle_manager', + name='lifecycle_manager_localization', + output='screen', + arguments=['--ros-args', '--log-level', log_level], + parameters=[{'use_sim_time': use_sim_time}, + {'autostart': autostart}, + {'node_names': lifecycle_nodes}]) + ] + ) + + load_composable_nodes = LoadComposableNodes( + condition=IfCondition(use_composition), + target_container=container_name_full, + composable_node_descriptions=[ + ComposableNode( + package='nav2_map_server', + plugin='nav2_map_server::MapServer', + name='map_server', + parameters=[configured_params], + remappings=remappings), + ComposableNode( + package='nav2_amcl', + plugin='nav2_amcl::AmclNode', + name='amcl', + parameters=[configured_params], + remappings=remappings), + ComposableNode( + package='nav2_lifecycle_manager', + plugin='nav2_lifecycle_manager::LifecycleManager', + name='lifecycle_manager_localization', + parameters=[{'use_sim_time': use_sim_time, + 'autostart': autostart, + 'node_names': lifecycle_nodes}]), + ], + ) + + # Create the launch description and populate + ld = LaunchDescription() + + # Set environment variables + ld.add_action(stdout_linebuf_envvar) + + # Declare the launch options + ld.add_action(declare_namespace_cmd) + ld.add_action(declare_map_yaml_cmd) + ld.add_action(declare_use_sim_time_cmd) + ld.add_action(declare_params_file_cmd) + ld.add_action(declare_autostart_cmd) + ld.add_action(declare_use_composition_cmd) + ld.add_action(declare_container_name_cmd) + ld.add_action(declare_use_respawn_cmd) + ld.add_action(declare_log_level_cmd) + + # Add the actions to launch all of the localiztion nodes + ld.add_action(load_nodes) + ld.add_action(load_composable_nodes) + + return ld diff --git a/my_bot/launch/nav_launch.py b/my_bot/launch/nav_launch.py new file mode 100644 index 0000000..275b167 --- /dev/null +++ b/my_bot/launch/nav_launch.py @@ -0,0 +1,83 @@ +import os +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + +def generate_launch_description(): + # Package name + package_name = 'my_bot' + + # Launch configuration variables + use_sim_time = LaunchConfiguration('use_sim_time') + map_file = LaunchConfiguration('map') + params_file = LaunchConfiguration('params_file') + + # Paths + nav2_launch_file_dir = os.path.join(get_package_share_directory('nav2_bringup'), 'launch') + default_params_file = os.path.join( + get_package_share_directory(package_name), + 'config', + 'nav2_params.yaml' # Tu archivo corregido + ) + rviz_config_file = os.path.join( + get_package_share_directory(package_name), + 'config', + 'view_bot.rviz' + ) + + # Declare launch arguments + declare_use_sim_time_cmd = DeclareLaunchArgument( + 'use_sim_time', + default_value='true', # True para simulación + description='Use simulation (Gazebo) clock if true' + ) + + declare_map_cmd = DeclareLaunchArgument( + 'map', + description='Full path to map file to load' + ) + + declare_params_file_cmd = DeclareLaunchArgument( + 'params_file', + default_value=default_params_file, + description='Full path to param file to load' + ) + + # Launch Nav2 + nav2_cmd = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + os.path.join(nav2_launch_file_dir, 'bringup_launch.py') + ), + launch_arguments={ + 'map': map_file, + 'use_sim_time': use_sim_time, + 'params_file': params_file + }.items(), + ) + + # Launch RViz (opcional) + rviz_cmd = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + arguments=['-d', rviz_config_file], + parameters=[{'use_sim_time': use_sim_time}], + output='screen' + ) + + # Create launch description + ld = LaunchDescription() + + # Add launch arguments + ld.add_action(declare_use_sim_time_cmd) + ld.add_action(declare_map_cmd) + ld.add_action(declare_params_file_cmd) + + # Add actions + ld.add_action(nav2_cmd) + ld.add_action(rviz_cmd) # Descomenta si quieres RViz automático + + return ld \ No newline at end of file diff --git a/my_bot/launch/navigation_launch.py b/my_bot/launch/navigation_launch.py new file mode 100644 index 0000000..26be797 --- /dev/null +++ b/my_bot/launch/navigation_launch.py @@ -0,0 +1,272 @@ +# Copyright (c) 2018 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, GroupAction, SetEnvironmentVariable +from launch.conditions import IfCondition +from launch.substitutions import LaunchConfiguration, PythonExpression +from launch_ros.actions import LoadComposableNodes +from launch_ros.actions import Node +from launch_ros.descriptions import ComposableNode, ParameterFile +from nav2_common.launch import RewrittenYaml + + +def generate_launch_description(): + # Get the launch directory + bringup_dir = get_package_share_directory('my_bot') + + namespace = LaunchConfiguration('namespace') + use_sim_time = LaunchConfiguration('use_sim_time') + autostart = LaunchConfiguration('autostart') + params_file = LaunchConfiguration('params_file') + use_composition = LaunchConfiguration('use_composition') + container_name = LaunchConfiguration('container_name') + container_name_full = (namespace, '/', container_name) + use_respawn = LaunchConfiguration('use_respawn') + log_level = LaunchConfiguration('log_level') + + lifecycle_nodes = ['controller_server', + 'smoother_server', + 'planner_server', + 'behavior_server', + 'bt_navigator', + 'waypoint_follower', + 'velocity_smoother'] + + # Map fully qualified names to relative ones so the node's namespace can be prepended. + # In case of the transforms (tf), currently, there doesn't seem to be a better alternative + # https://github.com/ros/geometry2/issues/32 + # https://github.com/ros/robot_state_publisher/pull/30 + # TODO(orduno) Substitute with `PushNodeRemapping` + # https://github.com/ros2/launch_ros/issues/56 + remappings = [('/tf', 'tf'), + ('/tf_static', 'tf_static')] + + # Create our own temporary YAML files that include substitutions + param_substitutions = { + 'use_sim_time': use_sim_time, + 'autostart': autostart} + + configured_params = ParameterFile( + RewrittenYaml( + source_file=params_file, + root_key=namespace, + param_rewrites=param_substitutions, + convert_types=True), + allow_substs=True) + + stdout_linebuf_envvar = SetEnvironmentVariable( + 'RCUTILS_LOGGING_BUFFERED_STREAM', '1') + + declare_namespace_cmd = DeclareLaunchArgument( + 'namespace', + default_value='', + description='Top-level namespace') + + declare_use_sim_time_cmd = DeclareLaunchArgument( + 'use_sim_time', + default_value='false', + description='Use simulation (Gazebo) clock if true') + + declare_params_file_cmd = DeclareLaunchArgument( + 'params_file', + default_value=os.path.join(bringup_dir, 'config', 'nav2_params.yaml'), + description='Full path to the ROS2 parameters file to use for all launched nodes') + + declare_autostart_cmd = DeclareLaunchArgument( + 'autostart', default_value='true', + description='Automatically startup the nav2 stack') + + declare_use_composition_cmd = DeclareLaunchArgument( + 'use_composition', default_value='False', + description='Use composed bringup if True') + + declare_container_name_cmd = DeclareLaunchArgument( + 'container_name', default_value='nav2_container', + description='the name of conatiner that nodes will load in if use composition') + + declare_use_respawn_cmd = DeclareLaunchArgument( + 'use_respawn', default_value='False', + description='Whether to respawn if a node crashes. Applied when composition is disabled.') + + declare_log_level_cmd = DeclareLaunchArgument( + 'log_level', default_value='info', + description='log level') + + load_nodes = GroupAction( + condition=IfCondition(PythonExpression(['not ', use_composition])), + actions=[ + Node( + package='nav2_controller', + executable='controller_server', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings + [('cmd_vel', 'cmd_vel_nav')]), + Node( + package='nav2_smoother', + executable='smoother_server', + name='smoother_server', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings), + Node( + package='nav2_planner', + executable='planner_server', + name='planner_server', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings), + Node( + package='nav2_behaviors', + executable='behavior_server', + name='behavior_server', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings), + Node( + package='nav2_bt_navigator', + executable='bt_navigator', + name='bt_navigator', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings), + Node( + package='nav2_waypoint_follower', + executable='waypoint_follower', + name='waypoint_follower', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings), + Node( + package='nav2_velocity_smoother', + executable='velocity_smoother', + name='velocity_smoother', + output='screen', + respawn=use_respawn, + respawn_delay=2.0, + parameters=[configured_params], + arguments=['--ros-args', '--log-level', log_level], + remappings=remappings + + [('cmd_vel', 'cmd_vel_nav'), ('cmd_vel_smoothed', 'cmd_vel')]), + Node( + package='nav2_lifecycle_manager', + executable='lifecycle_manager', + name='lifecycle_manager_navigation', + output='screen', + arguments=['--ros-args', '--log-level', log_level], + parameters=[{'use_sim_time': use_sim_time}, + {'autostart': autostart}, + {'node_names': lifecycle_nodes}]), + ] + ) + + load_composable_nodes = LoadComposableNodes( + condition=IfCondition(use_composition), + target_container=container_name_full, + composable_node_descriptions=[ + ComposableNode( + package='nav2_controller', + plugin='nav2_controller::ControllerServer', + name='controller_server', + parameters=[configured_params], + remappings=remappings + [('cmd_vel', 'cmd_vel_nav')]), + ComposableNode( + package='nav2_smoother', + plugin='nav2_smoother::SmootherServer', + name='smoother_server', + parameters=[configured_params], + remappings=remappings), + ComposableNode( + package='nav2_planner', + plugin='nav2_planner::PlannerServer', + name='planner_server', + parameters=[configured_params], + remappings=remappings), + ComposableNode( + package='nav2_behaviors', + plugin='behavior_server::BehaviorServer', + name='behavior_server', + parameters=[configured_params], + remappings=remappings), + ComposableNode( + package='nav2_bt_navigator', + plugin='nav2_bt_navigator::BtNavigator', + name='bt_navigator', + parameters=[configured_params], + remappings=remappings), + ComposableNode( + package='nav2_waypoint_follower', + plugin='nav2_waypoint_follower::WaypointFollower', + name='waypoint_follower', + parameters=[configured_params], + remappings=remappings), + ComposableNode( + package='nav2_velocity_smoother', + plugin='nav2_velocity_smoother::VelocitySmoother', + name='velocity_smoother', + parameters=[configured_params], + remappings=remappings + + [('cmd_vel', 'cmd_vel_nav'), ('cmd_vel_smoothed', 'cmd_vel')]), + ComposableNode( + package='nav2_lifecycle_manager', + plugin='nav2_lifecycle_manager::LifecycleManager', + name='lifecycle_manager_navigation', + parameters=[{'use_sim_time': use_sim_time, + 'autostart': autostart, + 'node_names': lifecycle_nodes}]), + ], + ) + + # Create the launch description and populate + ld = LaunchDescription() + + # Set environment variables + ld.add_action(stdout_linebuf_envvar) + + # Declare the launch options + ld.add_action(declare_namespace_cmd) + ld.add_action(declare_use_sim_time_cmd) + ld.add_action(declare_params_file_cmd) + ld.add_action(declare_autostart_cmd) + ld.add_action(declare_use_composition_cmd) + ld.add_action(declare_container_name_cmd) + ld.add_action(declare_use_respawn_cmd) + ld.add_action(declare_log_level_cmd) + # Add the actions to launch all of the navigation nodes + ld.add_action(load_nodes) + ld.add_action(load_composable_nodes) + + return ld diff --git a/my_bot/launch/online_async_launch.py b/my_bot/launch/online_async_launch.py new file mode 100644 index 0000000..833d694 --- /dev/null +++ b/my_bot/launch/online_async_launch.py @@ -0,0 +1,59 @@ +import os + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, LogInfo +from launch.conditions import UnlessCondition +from launch.substitutions import LaunchConfiguration, PythonExpression +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory +from nav2_common.launch import HasNodeParams + + +def generate_launch_description(): + use_sim_time = LaunchConfiguration('use_sim_time') + params_file = LaunchConfiguration('params_file') + default_params_file = os.path.join(get_package_share_directory("my_bot"), + 'config', 'mapper_params_online_async.yaml') + + declare_use_sim_time_argument = DeclareLaunchArgument( + 'use_sim_time', + default_value='true', + description='Use simulation/Gazebo clock') + declare_params_file_cmd = DeclareLaunchArgument( + 'params_file', + default_value=default_params_file, + description='Full path to the ROS2 parameters file to use for the slam_toolbox node') + + # If the provided param file doesn't have slam_toolbox params, we must pass the + # default_params_file instead. This could happen due to automatic propagation of + # LaunchArguments. See: + # https://github.com/ros-planning/navigation2/pull/2243#issuecomment-800479866 + has_node_params = HasNodeParams(source_file=params_file, + node_name='slam_toolbox') + + actual_params_file = PythonExpression(['"', params_file, '" if ', has_node_params, + ' else "', default_params_file, '"']) + + log_param_change = LogInfo(msg=['provided params_file ', params_file, + ' does not contain slam_toolbox parameters. Using default: ', + default_params_file], + condition=UnlessCondition(has_node_params)) + + start_async_slam_toolbox_node = Node( + parameters=[ + actual_params_file, + {'use_sim_time': use_sim_time} + ], + package='slam_toolbox', + executable='async_slam_toolbox_node', + name='slam_toolbox', + output='screen') + + ld = LaunchDescription() + + ld.add_action(declare_use_sim_time_argument) + ld.add_action(declare_params_file_cmd) + ld.add_action(log_param_change) + ld.add_action(start_async_slam_toolbox_node) + + return ld \ No newline at end of file diff --git a/my_bot/launch/rplidar.launch.py b/my_bot/launch/rplidar.launch.py new file mode 100644 index 0000000..352594d --- /dev/null +++ b/my_bot/launch/rplidar.launch.py @@ -0,0 +1,20 @@ +import os +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + + return LaunchDescription([ + + Node( + package='rplidar_ros', + executable='rplidar_composition', + output='screen', + parameters=[{ + 'serial_port': '/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0-port0', + 'frame_id': 'laser_frame', + 'angle_compensate': True, + 'scan_mode': 'Standard' + }] + ) + ]) \ No newline at end of file diff --git a/my_bot/launch/rsp.launch.py b/my_bot/launch/rsp.launch.py new file mode 100644 index 0000000..b6713c6 --- /dev/null +++ b/my_bot/launch/rsp.launch.py @@ -0,0 +1,48 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.substitutions import LaunchConfiguration, Command +from launch.actions import DeclareLaunchArgument +from launch_ros.actions import Node + +import xacro + + +def generate_launch_description(): + + # Check if we're told to use sim time + use_sim_time = LaunchConfiguration('use_sim_time') + use_ros2_control = LaunchConfiguration('use_ros2_control') + + # Process the URDF file + pkg_path = os.path.join(get_package_share_directory('my_bot')) + xacro_file = os.path.join(pkg_path,'description','robot.urdf.xacro') + #robot_description_config = xacro.process_file(xacro_file).toxml() + robot_description_config = Command(['xacro ', xacro_file, ' use_ros2_control:=', use_ros2_control]) + + # Create a robot_state_publisher node + params = {'robot_description': robot_description_config, 'use_sim_time': use_sim_time} + node_robot_state_publisher = Node( + package='robot_state_publisher', + executable='robot_state_publisher', + name='robot_state_publisher', + output='screen', + parameters=[params] + ) + + + # Launch! + return LaunchDescription([ + DeclareLaunchArgument( + 'use_sim_time', + default_value='false', + description='Use sim time if true'), + DeclareLaunchArgument( + 'use_ros2_control', + default_value='true', + description='Use ros2_control if true'), + + node_robot_state_publisher + ]) diff --git a/my_bot/maps/Spielberg_map.png b/my_bot/maps/Spielberg_map.png new file mode 100644 index 0000000000000000000000000000000000000000..e9ef68d14b471ae811438323162d4d825244a18c GIT binary patch literal 62176 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

16EF5=)ovF|7 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 khUa$pe46`=0@p_$B)l(p@7Ndr0x94;>Hq)$ literal 0 HcmV?d00001 diff --git a/my_bot/maps/Spielberg_map.yaml b/my_bot/maps/Spielberg_map.yaml new file mode 100644 index 0000000..2397577 --- /dev/null +++ b/my_bot/maps/Spielberg_map.yaml @@ -0,0 +1,6 @@ +image: Spielberg_map.png +resolution: 0.05796 +origin: [-84.85359914210505,-36.30299725862132, 0.000000] +negate: 0 +occupied_thresh: 0.45 +free_thresh: 0.196 diff --git a/my_bot/maps/levine.png b/my_bot/maps/levine.png new file mode 100644 index 0000000000000000000000000000000000000000..2803b387d54d6aee2915a67b6d14b95f932c421c GIT binary patch literal 13273 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 + + + my_bot + 0.0.0 + TODO: Package description + MY NAME + TODO: License declaration + + ament_cmake + + xacro + robot_state_publisher + gazebo_ros + rclpy + teleop_twist_keyboard + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/my_bot/worlds/empty.world b/my_bot/worlds/empty.world new file mode 100644 index 0000000..5321672 --- /dev/null +++ b/my_bot/worlds/empty.world @@ -0,0 +1,13 @@ + + + + + + model://sun + + + + model://ground_plane + + + diff --git a/my_bot/worlds/levine.world b/my_bot/worlds/levine.world new file mode 100644 index 0000000..e3cfe8a --- /dev/null +++ b/my_bot/worlds/levine.world @@ -0,0 +1,9365 @@ + + + + 1 + 0 0 10 0 -0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + 0 + 0 + 0 + + + + 1 + + + + + 0 0 1 + 100 100 + + + + + + 100 + 50 + + + + + + + + + + + 10 + + + 0 + + + 0 0 1 + 100 100 + + + + + + + 0 + 0 + 0 + + + 0 0 -9.8 + 6e-06 2.3e-05 -4.2e-05 + + + 0.001 + 1 + 1000 + + + 0.4 0.4 0.4 1 + 0.7 0.7 0.7 1 + 1 + + + + + EARTH_WGS84 + 0 + 0 + 0 + 0 + + + + + 0.177215 0 0.060506 0 -0 0 + 0.79 + + 0.00271819 + 0 + 0.000910886 + 0.0116814 + 0 + 0.011264 + + + + 0.12 0 0.05 0 -0 0 + + + 0.24 0.16 0.1 + + + + + + + + + + + + + + + 10 + + + 0.24 0 0 0 -0 0 + + + 0.04 + + + + + + + + + 0.001 + 0.001 + + + + + + + + 10 + + + 0.2 0 0.12 0 -0 0 + + + 0.04 + 0.033 + + + + + + + + + + + + + + + 10 + + + 0.12 0 0.05 0 -0 0 + + + 0.24 0.2 0.1 + + + + + + + + 0.2 0 0.16 0 -0 0 + + + 0.025 0.09 0.02 + + + + + + + + 0.24 0 0 0 -0 0 + + + 0.04 + + + + + + + + 0.2 0 0.12 0 -0 0 + + + 0.04 + 0.033 + + + + + + + + 1 + 10 + + 1.089 + + B8G8R8 + 640 + 480 + + + 0.05 + 8 + + + + camera_link_optical + 0.1 + 100.0 + + 0.2 0 0.16 0 -0 0 + + + 1 + 10 + + + + 360 + -3.14 + 3.14 + 1 + + + 1 + 0 + 0 + + + + 0.3 + 12 + + + + + ~/out:=scan + + sensor_msgs/LaserScan + laser_frame + + 0.2 0 0.12 0 -0 0 + + 0 + 0 + 0 + + + 0 0.1 0 -1.5708 0 0 + base_link + left_wheel + + 0 0 1 + + -1e+16 + 1e+16 + + + 0 + 0 + + + + + 0 0 0 0 -0 0 + + 0 0 0 0 -0 0 + 0.1 + + 5.33333e-05 + 0 + 0 + 5.33333e-05 + 0 + 8e-05 + + + + 0 0 0 0 -0 0 + + + 0.04 + + + + + + + + + + + + + + + 10 + + + 0 0 0 0 -0 0 + + + 0.04 + 0.04 + + + + + + + 0 + 0 + 0 + + + 0 -0.1 0 1.5708 -0 0 + base_link + right_wheel + + 0 0 -1 + + -1e+16 + 1e+16 + + + 0 + 0 + + + + + 0 0 0 0 -0 0 + + 0 0 0 0 -0 0 + 0.1 + + 5.33333e-05 + 0 + 0 + 5.33333e-05 + 0 + 8e-05 + + + + 0 0 0 0 -0 0 + + + 0.04 + + + + + + + + + + + + + + + 10 + + + 0 0 0 0 -0 0 + + + 0.04 + 0.04 + + + + + + + 0 + 0 + 0 + + 0 + + /home/ivan/dev_ws/install/my_bot/share/my_bot/config/my_controllers.yaml + + 0 0 0 0 -0 0 + + + 0.555504 1.12858 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 1.7631 1.40061 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 2.63146 1.21638 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 3.67297 1.219 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 4.70994 1.20235 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 5.76654 1.19215 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 6.85552 1.16656 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 7.9487 1.15326 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 9.03135 1.11313 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 9.3925 -1.93079 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 7.71543 -1.67512 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 6.68845 -1.68928 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 5.63972 -1.68978 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 4.52806 -1.65041 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 3.41947 -1.62704 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 2.23436 -1.60062 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 1.19901 -1.60491 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 8.79403 -2.72073 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 8.89804 -3.86534 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 9.59968 -4.97218 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 10.916 -5.08427 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 11.9942 -5.11769 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.128 -4.61853 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.2109 -3.58645 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.3131 -2.54327 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.3431 -1.50287 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.4227 -0.430545 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 14.4911 -0.475827 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 15.5576 -0.450193 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 16.5913 -0.356369 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 17.6667 0.111068 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 17.7155 1.18357 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 15.533 2.5241 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 16.6003 2.46368 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 16.6668 0.917588 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.342 3.4316 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.3525 4.50859 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.3079 5.63666 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.346 6.71776 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 13.3236 7.76853 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 9.10292 2.14492 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 9.08102 3.26349 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 8.97202 4.41197 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 8.92411 5.50557 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 8.90039 6.60085 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 8.89491 7.65407 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 11.5614 7.28234 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 8.41954 10.443 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 9.37924 10.7607 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 10.4354 10.7533 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 11.4623 10.7523 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 11.5874 8.48628 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 11.5683 9.58154 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 7.26487 10.8009 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 6.17175 10.8343 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 5.04461 10.852 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 3.95809 10.893 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 7.8022 7.65591 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 6.69164 7.6545 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 5.60862 7.62727 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 4.46278 7.63473 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 2.84719 10.9112 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 1.73992 10.9582 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 0.66692 10.9659 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 3.38354 7.7267 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 2.13895 7.78205 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 1.03513 7.75902 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -0.495272 11.0462 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -0.104328 7.99805 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -1.60407 11.2656 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -1.07686 8.20701 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -2.77324 11.3221 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -2.09643 8.13987 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -3.9399 11.375 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -3.22691 8.14265 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -5.00002 11.3706 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -6.19269 11.4491 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -7.36966 11.5014 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -8.67595 11.6101 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -9.84164 11.5912 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -10.9208 11.5643 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -4.3458 8.14362 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -5.37999 8.10127 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -6.5467 8.08655 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -7.62958 8.05369 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -8.83422 8.13954 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -11.9972 11.6792 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.1299 11.7058 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -9.9062 8.11613 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -11.0062 8.11662 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -12.1401 8.13165 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.4024 8.25386 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.0801 12.7181 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.1566 13.8382 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -16.4113 12.0594 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -16.7208 9.01924 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.8541 10.0347 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.8622 12.115 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.839 13.1183 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.9405 7.97497 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.9352 6.93311 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.913 5.87885 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.9509 4.86819 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.3553 7.38097 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.3012 6.24082 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.2875 5.18055 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.1438 4.119 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.1862 3.07745 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.1906 2.0408 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.9896 3.83812 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -16.0044 2.81289 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -16.0156 1.78233 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -16.0063 0.710137 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -15.9928 -0.34604 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -14.877 -0.728863 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -13.6985 -0.736769 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -12.0773 2.0238 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -11.0152 2.00561 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -9.97692 2.00046 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -8.93478 1.99215 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -7.9059 1.97211 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -6.89613 1.97278 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -5.81978 1.93246 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -4.75596 1.92004 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -3.72552 1.91922 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -2.67393 1.86658 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -1.51822 1.78266 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -0.500902 1.27134 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 0.157735 -1.59175 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -0.912083 -1.58529 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -1.94608 -1.56292 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -3.00828 -1.53047 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -4.13807 -1.49451 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -5.19182 -1.44907 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -6.21451 -1.46484 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -7.2365 -1.44735 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -8.39557 -1.35085 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -9.62361 -1.19336 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -10.74 -1.15437 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -11.8546 -1.08265 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + -12.736 -0.970076 0.5 0 -0 0 + + + 1 + + 0.166667 + 0 + 0 + 0.166667 + 0 + 0.166667 + + 0 0 0 0 -0 0 + + + + + 1 1 1 + + + 10 + + + + + + + + + + + + + + + + + 1 1 1 + + + + + + + 0 + 0 + 0 + + + + 2262 535000000 + 2685 66394843 + 1756923285 779809602 + 2262535 + + 0 0 0 0 -0 0 + 1 1 1 + + 0 0 0 0 -0 0 + 0 0 0 0 -0 0 + 0 0 0 0 -0 0 + 0 0 0 0 -0 0 + + + + -2.37462 0.266413 0.039999 -1.4e-05 -6e-06 -0.175538 + 1 1 1 + + -2.37462 0.266413 0.039999 -1.4e-05 -6e-06 -0.175538 + 0.000502 0.00011 -3e-06 -0.026802 0.004741 -0.006431 + 0.269005 1.4998 -0.001562 -1.31475 -1.48477 0.950964 + 0.212514 1.18484 -0.001234 0 -0 0 + + + -2.35716 0.364876 0.039997 -1.5709 0.678421 -0.175605 + 0.001146 0.000224 -0.00275 -0.010621 0.001895 -0.006457 + 1.27597 0.388122 -5.47472 0.276903 0.352852 0.610546 + 0.127597 0.038812 -0.547472 0 -0 0 + + + -2.39209 0.167951 0.04 1.57093 -0.997251 -0.175652 + -8.4e-05 0.000427 0.002767 -0.011217 -0.002074 -0.006401 + -1.07652 0.790035 5.48577 3.05608 -0.842808 -2.44733 + -0.107652 0.079003 0.548577 0 -0 0 + + + + 0.555507 1.19168 0.499995 0 1e-05 0 + 1 1 1 + + 0.555507 1.19168 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 1.57825 1.23788 0.499995 0 -1e-05 0 + 1 1 1 + + 1.57825 1.23788 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 + -0.010615 -0.006191 -9.78231 0 -0 0 + + + + 2.63146 1.21638 0.499995 0 1e-05 0 + 1 1 1 + + 2.63146 1.21638 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 6.68845 -1.68927 0.499995 -1e-05 0 0 + 1 1 1 + + 6.68845 -1.68927 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -16.7856 5.87885 0.499995 1e-05 -0 0 + 1 1 1 + + -16.7856 5.87885 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 + -0.004709 -0.011055 -9.78158 0 -0 0 + + + + -15.9509 4.8761 0.499995 0 1e-05 0 + 1 1 1 + + -15.9509 4.8761 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -13.3553 7.38097 0.499995 0 1e-05 0 + 1 1 1 + + -13.3553 7.38097 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -12.4339 6.24083 0.499995 -1e-05 0 0 + 1 1 1 + + -12.4339 6.24083 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -13.1391 5.18055 0.499995 1e-05 -0 0 + 1 1 1 + + -13.1391 5.18055 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 + -0.004709 -0.011055 -9.78158 0 -0 0 + + + + -13.1438 4.119 0.499995 -1e-05 0 0 + 1 1 1 + + -13.1438 4.119 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -13.1862 3.07745 0.499995 0 1e-05 0 + 1 1 1 + + -13.1862 3.07745 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -13.1906 2.04081 0.499995 -1e-05 0 0 + 1 1 1 + + -13.1906 2.04081 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -15.9896 3.83812 0.499995 0 1e-05 0 + 1 1 1 + + -15.9896 3.83812 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -16.0044 2.81289 0.499995 1e-05 -0 0 + 1 1 1 + + -16.0044 2.81289 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 + -0.004709 -0.011055 -9.78158 0 -0 0 + + + + 5.63972 -1.68978 0.499995 0 1e-05 0 + 1 1 1 + + 5.63972 -1.68978 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -16.0156 1.78233 0.499995 0 1e-05 0 + 1 1 1 + + -16.0156 1.78233 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -16.0063 0.710142 0.499995 -1e-05 0 0 + 1 1 1 + + -16.0063 0.710142 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -15.9928 -0.34604 0.499995 0 1e-05 0 + 1 1 1 + + -15.9928 -0.34604 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -14.877 -0.728858 0.499995 -1e-05 0 0 + 1 1 1 + + -14.877 -0.728858 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -13.7609 -0.72631 0.499995 1e-05 0 -0.011216 + 1 1 1 + + -13.7609 -0.72631 0.499995 1e-05 0 -0.011216 + 0 0 0 0 -0 0 + -0.00469 -0.01099 -9.7816 0.021976 -0.009376 1e-06 + -0.00469 -0.01099 -9.7816 0 -0 0 + + + + -12.0773 1.87529 0.499995 -1e-05 0 0 + 1 1 1 + + -12.0773 1.87529 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -11.0152 1.88765 0.5 0 -0 0 + 1 1 1 + + -11.0152 1.88765 0.5 0 -0 0 + 0 0 0 0 -0 0 + 0 -0 0 1e-06 1e-06 0 + 0 -0 0 0 -0 0 + + + + -9.97691 1.86931 0.499995 0 1e-05 0 + 1 1 1 + + -9.97691 1.86931 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 + 0.010615 -0.006191 -9.78231 0 -0 0 + + + + -8.93478 1.86691 0.499995 1e-05 -0 0 + 1 1 1 + + -8.93478 1.86691 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 + 0.004709 -0.011055 -9.78158 0 -0 0 + + + + -7.84055 1.83815 0.499995 -0 -1e-05 0.002763 + 1 1 1 + + -7.84055 1.83815 0.499995 -0 -1e-05 0.002763 + 0 0 0 0 -0 0 + -0.013424 -0.009385 -9.7776 0.018974 -0.02681 -9.7e-05 + -0.013424 -0.009385 -9.7776 0 -0 0 + + + + 4.52806 -1.6504 0.499995 -1e-05 0 0 + 1 1 1 + + 4.52806 -1.6504 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -6.84061 1.87689 0.499995 -0 1e-05 0.002709 + 1 1 1 + + -6.84061 1.87689 0.499995 -0 1e-05 0.002709 + 0 0 0 0 -0 0 + 0.012918 -0.008766 -9.77852 0.017719 0.025804 8.9e-05 + 0.012918 -0.008766 -9.77852 0 -0 0 + + + + -5.81978 1.82803 0.499995 0 1e-05 0 + 1 1 1 + + -5.81978 1.82803 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -4.75596 1.7931 0.499995 0 1e-05 0 + 1 1 1 + + -4.75596 1.7931 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -3.72552 1.78985 0.499995 0 1e-05 0 + 1 1 1 + + -3.72552 1.78985 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 + 0.010615 -0.006191 -9.78231 0 -0 0 + + + + -2.66754 1.63848 0.499995 0 1e-05 0 + 1 1 1 + + -2.66754 1.63848 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -1.51822 1.42433 0.499995 -1e-05 -0 -0 + 1 1 1 + + -1.51822 1.42433 0.499995 -1e-05 -0 -0 + 0 0 0 0 -0 0 + 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 + 0.004709 0.011055 -9.78158 0 -0 0 + + + + -0.500907 1.27134 0.499995 0 -1e-05 0 + 1 1 1 + + -0.500907 1.27134 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 + -0.010615 -0.006191 -9.78231 0 -0 0 + + + + 0.15774 -1.36253 0.499995 0 1e-05 0 + 1 1 1 + + 0.15774 -1.36253 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 + 0.010615 -0.006191 -9.78231 0 -0 0 + + + + -0.90612 -1.30563 0.499995 0 -1e-05 0 + 1 1 1 + + -0.90612 -1.30563 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 + -0.010615 -0.006191 -9.78231 0 -0 0 + + + + -1.94608 -1.25155 0.499995 -1e-05 0 0 + 1 1 1 + + -1.94608 -1.25155 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 3.47624 -1.6198 0.499995 0 1e-05 0 + 1 1 1 + + 3.47624 -1.6198 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -3.00827 -1.23218 0.499995 0 1e-05 0 + 1 1 1 + + -3.00827 -1.23218 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 + 0.010615 -0.006191 -9.78231 0 -0 0 + + + + -4.13807 -1.16413 0.499995 0 1e-05 0 + 1 1 1 + + -4.13807 -1.16413 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -5.19182 -1.13485 0.499995 0 -1e-05 0 + 1 1 1 + + -5.19182 -1.13485 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 + -0.010615 -0.006191 -9.78231 0 -0 0 + + + + -6.21451 -1.11865 0.499995 0 -1e-05 0 + 1 1 1 + + -6.21451 -1.11865 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 + -0.010615 0.006191 -9.78231 0 -0 0 + + + + -7.23651 -1.11583 0.499995 0 -1e-05 0 + 1 1 1 + + -7.23651 -1.11583 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 + -0.010615 -0.006191 -9.78231 0 -0 0 + + + + -8.39557 -1.03793 0.499995 0 -1e-05 0 + 1 1 1 + + -8.39557 -1.03793 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 + -0.010615 0.006191 -9.78231 0 -0 0 + + + + -9.62361 -0.935877 0.499995 -1e-05 -0 -0 + 1 1 1 + + -9.62361 -0.935877 0.499995 -1e-05 -0 -0 + 0 0 0 0 -0 0 + 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 + 0.004709 0.011055 -9.78158 0 -0 0 + + + + -10.74 -0.869872 0.499995 1e-05 -0 0 + 1 1 1 + + -10.74 -0.869872 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 + 0.004709 -0.011055 -9.78158 0 -0 0 + + + + -11.7618 -0.833957 0.499995 0 1e-05 -0.011209 + 1 1 1 + + -11.7618 -0.833957 0.499995 0 1e-05 -0.011209 + 0 0 0 0 -0 0 + 0.010684 0.006193 -9.78231 -0.012449 0.021363 -2.9e-05 + 0.010684 0.006193 -9.78231 0 -0 0 + + + + -12.7618 -0.818376 0.499995 1e-05 -0 -0.011211 + 1 1 1 + + -12.7618 -0.818376 0.499995 1e-05 -0 -0.011211 + 0 0 0 0 -0 0 + 0.004721 -0.011108 -9.78158 0.022213 0.009438 -1e-06 + 0.004721 -0.011108 -9.78158 0 -0 0 + + + + 2.2423 -1.45852 0.499995 0 -1e-05 0 + 1 1 1 + + 2.2423 -1.45852 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 -0.006191 -9.78231 0.012424 -0.021225 -1.8e-05 + -0.010615 -0.006191 -9.78231 0 -0 0 + + + + 1.19901 -1.44068 0.5 -0 -0 -0 + 1 1 1 + + 1.19901 -1.44068 0.5 -0 -0 -0 + 0 0 0 0 -0 0 + -0 0 0 -1e-06 -1e-06 0 + -0 0 0 0 -0 0 + + + + 8.79403 -2.72072 0.499995 -1e-05 0 0 + 1 1 1 + + 8.79403 -2.72072 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 8.89804 -3.86534 0.499995 0 1e-05 0 + 1 1 1 + + 8.89804 -3.86534 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 9.59968 -4.97217 0.499995 -1e-05 0 0 + 1 1 1 + + 9.59968 -4.97217 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 10.916 -5.08427 0.499995 0 1e-05 0 + 1 1 1 + + 10.916 -5.08427 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 3.74606 1.22705 0.499995 -1e-05 -0 -0.082022 + 1 1 1 + + 3.74606 1.22705 0.499995 -1e-05 -0 -0.082022 + 0 0 0 0 -0 0 + -0.004658 0.011102 -9.78219 -0.022206 -0.009308 0 + -0.004658 0.011102 -9.78219 0 -0 0 + + + + 11.9942 -5.11768 0.499995 -1e-05 0 0 + 1 1 1 + + 11.9942 -5.11768 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 13.128 -4.61853 0.499995 0 1e-05 0 + 1 1 1 + + 13.128 -4.61853 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 13.2109 -3.58644 0.499995 -1e-05 0 0 + 1 1 1 + + 13.2109 -3.58644 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 13.3131 -2.54327 0.499995 0 1e-05 0 + 1 1 1 + + 13.3131 -2.54327 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 13.3431 -1.50286 0.499995 -1e-05 0 0 + 1 1 1 + + 13.3431 -1.50286 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 13.4227 -0.430542 0.499995 0 1e-05 0 + 1 1 1 + + 13.4227 -0.430542 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 14.4911 -0.475819 0.499995 -1e-05 0 0 + 1 1 1 + + 14.4911 -0.475819 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 15.5576 -0.45019 0.499995 0 1e-05 0 + 1 1 1 + + 15.5576 -0.45019 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 16.5913 -0.356361 0.499995 -1e-05 0 0 + 1 1 1 + + 16.5913 -0.356361 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 14.5156 2.51049 0.499995 -0 -1e-05 0.030671 + 1 1 1 + + 14.5156 2.51049 0.499995 -0 -1e-05 0.030671 + 0 0 0 0 -0 0 + -0.010775 0.006144 -9.78237 -0.012379 -0.021543 4.2e-05 + -0.010775 0.006144 -9.78237 0 -0 0 + + + + 4.82643 1.14872 0.499995 -1e-05 0 -0.080673 + 1 1 1 + + 4.82643 1.14872 0.499995 -1e-05 0 -0.080673 + 0 0 0 0 -0 0 + -0.004661 0.011107 -9.78217 -0.022216 -0.009314 0 + -0.004661 0.011107 -9.78217 0 -0 0 + + + + 11.6391 3.0877 0.499995 1e-05 -0 0 + 1 1 1 + + 11.6391 3.0877 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 + -0.004709 -0.011055 -9.78158 0 -0 0 + + + + 15.533 2.52411 0.499995 -1e-05 0 0 + 1 1 1 + + 15.533 2.52411 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 16.6003 2.46368 0.499995 0 1e-05 0 + 1 1 1 + + 16.6003 2.46368 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 16.6668 0.917596 0.499995 -1e-05 0 0 + 1 1 1 + + 16.6668 0.917596 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 11.6314 4.22803 0.499995 1e-05 -0 0 + 1 1 1 + + 11.6314 4.22803 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 + 0.004709 -0.011055 -9.78158 0 -0 0 + + + + 11.654 5.25725 0.499995 1e-05 -0 0.004424 + 1 1 1 + + 11.654 5.25725 0.499995 1e-05 -0 0.004424 + 0 0 0 0 -0 0 + -0.004714 -0.011078 -9.78157 0.022152 -0.009425 1e-06 + -0.004714 -0.011078 -9.78157 0 -0 0 + + + + 13.5174 2.43423 0.499995 1e-05 0 0.030648 + 1 1 1 + + 13.5174 2.43423 0.499995 1e-05 0 0.030648 + 0 0 0 0 -0 0 + -0.004728 -0.011161 -9.78165 0.02232 -0.009451 1e-06 + -0.004728 -0.011161 -9.78165 0 -0 0 + + + + 11.6462 6.2886 0.5 0 -0 0.069266 + 1 1 1 + + 11.6462 6.2886 0.5 0 -0 0.069266 + 0 0 0 0 -0 0 + 1e-06 -0 -0 1e-06 1e-06 0 + 1e-06 -0 -0 0 -0 0 + + + + 12.4601 2.0331 0.499995 -1e-05 0 0 + 1 1 1 + + 12.4601 2.0331 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 9.10292 2.14493 0.499995 -1e-05 0 0 + 1 1 1 + + 9.10292 2.14493 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 5.83439 1.19515 0.499995 -1e-05 -0 -0.078203 + 1 1 1 + + 5.83439 1.19515 0.499995 -1e-05 -0 -0.078203 + 0 0 0 0 -0 0 + -0.004667 0.011116 -9.78214 -0.022234 -0.009327 0 + -0.004667 0.011116 -9.78214 0 -0 0 + + + + 9.08102 3.26349 0.499995 0 1e-05 0 + 1 1 1 + + 9.08102 3.26349 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 8.97202 4.41198 0.499995 -1e-05 0 0 + 1 1 1 + + 8.97202 4.41198 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 8.92411 5.50557 0.499995 0 1e-05 0 + 1 1 1 + + 8.92411 5.50557 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 8.90039 6.60086 0.499995 -1e-05 0 0 + 1 1 1 + + 8.90039 6.60086 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 8.89491 7.65407 0.499995 0 1e-05 0 + 1 1 1 + + 8.89491 7.65407 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 11.54 7.48372 0.499995 -1e-05 -0 0.048086 + 1 1 1 + + 11.54 7.48372 0.499995 -1e-05 -0 0.048086 + 0 0 0 0 -0 0 + -0.004571 0.010671 -9.78187 -0.02134 -0.009139 0 + -0.004571 0.010671 -9.78187 0 -0 0 + + + + 8.33103 10.7601 0.499995 -1e-05 0 0 + 1 1 1 + + 8.33103 10.7601 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 9.37924 10.7607 0.499995 -1e-05 0 0 + 1 1 1 + + 9.37924 10.7607 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 10.4354 10.7533 0.499995 0 1e-05 0 + 1 1 1 + + 10.4354 10.7533 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 11.4623 10.7523 0.499995 -1e-05 0 0 + 1 1 1 + + 11.4623 10.7523 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 6.86221 1.16701 0.499995 -1e-05 -0 -0.020162 + 1 1 1 + + 6.86221 1.16701 0.499995 -1e-05 -0 -0.020162 + 0 0 0 0 -0 0 + -0.004726 0.011139 -9.7816 -0.022275 -0.009449 -1e-06 + -0.004726 0.011139 -9.7816 0 -0 0 + + + + 11.5881 8.49628 0.499995 0 -1e-05 0.026715 + 1 1 1 + + 11.5881 8.49628 0.499995 0 -1e-05 0.026715 + 0 0 0 0 -0 0 + -0.01076 0.006156 -9.78235 -0.012396 -0.021513 3.9e-05 + -0.01076 0.006156 -9.78235 0 -0 0 + + + + 11.5683 9.58155 0.499995 -1e-05 0 0 + 1 1 1 + + 11.5683 9.58155 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 7.26487 10.8009 0.499995 0 1e-05 0 + 1 1 1 + + 7.26487 10.8009 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 6.17175 10.8343 0.499995 -1e-05 0 0 + 1 1 1 + + 6.17175 10.8343 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 5.04461 10.852 0.499995 0 1e-05 0 + 1 1 1 + + 5.04461 10.852 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 3.95809 10.893 0.499995 -1e-05 0 0 + 1 1 1 + + 3.95809 10.893 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 7.78281 7.61521 0.499995 1e-05 -0 0 + 1 1 1 + + 7.78281 7.61521 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 + -0.004709 -0.011055 -9.78158 0 -0 0 + + + + 6.69164 7.50635 0.499995 -1e-05 0 0 + 1 1 1 + + 6.69164 7.50635 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 5.60862 7.74772 0.499995 1e-05 -0 0 + 1 1 1 + + 5.60862 7.74772 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + -0.004709 -0.011055 -9.78158 0.022108 -0.009414 1e-06 + -0.004709 -0.011055 -9.78158 0 -0 0 + + + + 4.46278 7.82964 0.499995 0 1e-05 0 + 1 1 1 + + 4.46278 7.82964 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 7.9487 1.15327 0.499995 -1e-05 0 0 + 1 1 1 + + 7.9487 1.15327 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 2.84719 10.9112 0.499995 -1e-05 0 0 + 1 1 1 + + 2.84719 10.9112 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 1.73992 10.9582 0.499995 0 1e-05 0 + 1 1 1 + + 1.73992 10.9582 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 0.619512 11.197 0.499995 -1e-05 -0 0 + 1 1 1 + + 0.619512 11.197 0.499995 -1e-05 -0 0 + 0 0 0 0 -0 0 + 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 + 0.004709 0.011055 -9.78158 0 -0 0 + + + + 3.38354 8.04833 0.499995 0 1e-05 0 + 1 1 1 + + 3.38354 8.04833 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 -0.006191 -9.78231 0.012424 0.021225 1.8e-05 + 0.010615 -0.006191 -9.78231 0 -0 0 + + + + 2.24413 8.11599 0.499995 -1e-05 0 0 + 1 1 1 + + 2.24413 8.11599 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 1.20797 8.19953 0.499995 0 1e-05 0 + 1 1 1 + + 1.20797 8.19953 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -0.495272 11.2728 0.499995 1e-05 -0 0 + 1 1 1 + + -0.495272 11.2728 0.499995 1e-05 -0 0 + 0 0 0 0 -0 0 + 0.004709 -0.011055 -9.78158 0.022108 0.009414 -1e-06 + 0.004709 -0.011055 -9.78158 0 -0 0 + + + + 0.003792 8.23484 0.499995 -1e-05 0 0 + 1 1 1 + + 0.003792 8.23484 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -1.60407 11.2656 0.499995 -1e-05 0 0 + 1 1 1 + + -1.60407 11.2656 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -1.07686 8.20701 0.499995 0 1e-05 0 + 1 1 1 + + -1.07686 8.20701 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 9.03135 1.11313 0.499995 0 1e-05 0 + 1 1 1 + + 9.03135 1.11313 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -2.77324 11.3221 0.499995 -1e-05 0 0 + 1 1 1 + + -2.77324 11.3221 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -2.09643 8.13987 0.499995 0 1e-05 0 + 1 1 1 + + -2.09643 8.13987 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -3.9399 11.375 0.499995 -1e-05 0 0 + 1 1 1 + + -3.9399 11.375 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -3.22691 8.14265 0.499995 0 1e-05 0 + 1 1 1 + + -3.22691 8.14265 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -5.00002 11.3706 0.499995 -1e-05 0 0 + 1 1 1 + + -5.00002 11.3706 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -6.19269 11.4491 0.499995 0 1e-05 0 + 1 1 1 + + -6.19269 11.4491 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -7.36966 11.5014 0.499995 -1e-05 0 0 + 1 1 1 + + -7.36966 11.5014 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -8.67595 11.6101 0.499995 0 1e-05 0 + 1 1 1 + + -8.67595 11.6101 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -9.68226 11.5677 0.499995 0 -1e-05 0 + 1 1 1 + + -9.68226 11.5677 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 + -0.010615 0.006191 -9.78231 0 -0 0 + + + + -10.8496 11.6353 0.499995 0 1e-05 0 + 1 1 1 + + -10.8496 11.6353 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 8.76045 -1.66109 0.499995 0 -1e-05 0 + 1 1 1 + + 8.76045 -1.66109 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 + -0.010615 0.006191 -9.78231 0 -0 0 + + + + -4.3458 8.14363 0.499995 -1e-05 0 0 + 1 1 1 + + -4.3458 8.14363 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -5.37999 8.16639 0.499995 -1e-05 0 0 + 1 1 1 + + -5.37999 8.16639 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -6.5467 8.19298 0.499995 0 1e-05 0 + 1 1 1 + + -6.5467 8.19298 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -7.62958 8.22347 0.499995 0 -1e-05 0 + 1 1 1 + + -7.62958 8.22347 0.499995 0 -1e-05 0 + 0 0 0 0 -0 0 + -0.010615 0.006191 -9.78231 -0.012424 -0.021225 1.8e-05 + -0.010615 0.006191 -9.78231 0 -0 0 + + + + -8.83422 8.36705 0.499995 0 1e-05 0 + 1 1 1 + + -8.83422 8.36705 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -11.9972 11.6792 0.499995 -1e-05 0 0 + 1 1 1 + + -11.9972 11.6792 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -13.1299 11.7058 0.499995 0 1e-05 0 + 1 1 1 + + -13.1299 11.7058 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -9.9062 8.41725 0.499995 0 1e-05 0 + 1 1 1 + + -9.9062 8.41725 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -11.0062 8.36397 0.499995 -1e-05 -0 0 + 1 1 1 + + -11.0062 8.36397 0.499995 -1e-05 -0 0 + 0 0 0 0 -0 0 + 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 + 0.004709 0.011055 -9.78158 0 -0 0 + + + + -12.1401 8.38199 0.499995 0 1e-05 0 + 1 1 1 + + -12.1401 8.38199 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + 7.71543 -1.67512 0.499995 0 1e-05 0 + 1 1 1 + + 7.71543 -1.67512 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -13.4024 8.4816 0.499995 0 1e-05 0 + 1 1 1 + + -13.4024 8.4816 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -13.0801 12.7181 0.499995 -1e-05 0 0 + 1 1 1 + + -13.0801 12.7181 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -13.1566 13.8382 0.499995 0 1e-05 0 + 1 1 1 + + -13.1566 13.8382 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -15.872 11.0985 0.5 -0 -0 -0 + 1 1 1 + + -15.872 11.0985 0.5 -0 -0 -0 + 0 0 0 0 -0 0 + -0 0 -0 -1e-06 -1e-06 0 + -0 0 -0 0 -0 0 + + + + -15.9201 9.01925 0.499995 -1e-05 -0 0 + 1 1 1 + + -15.9201 9.01925 0.499995 -1e-05 -0 0 + 0 0 0 0 -0 0 + 0.004709 0.011055 -9.78158 -0.022108 0.009414 1e-06 + 0.004709 0.011055 -9.78158 0 -0 0 + + + + -15.8541 10.0347 0.499995 0 1e-05 0 + 1 1 1 + + -15.8541 10.0347 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -15.8622 12.115 0.499995 0 1e-05 0 + 1 1 1 + + -15.8622 12.115 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -15.839 13.1183 0.499995 -1e-05 0 0 + 1 1 1 + + -15.839 13.1183 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + -15.9405 7.97497 0.499995 0 1e-05 0 + 1 1 1 + + -15.9405 7.97497 0.499995 0 1e-05 0 + 0 0 0 0 -0 0 + 0.010615 0.006191 -9.78231 -0.012424 0.021225 -1.8e-05 + 0.010615 0.006191 -9.78231 0 -0 0 + + + + -15.9352 6.93311 0.499995 -1e-05 0 0 + 1 1 1 + + -15.9352 6.93311 0.499995 -1e-05 0 0 + 0 0 0 0 -0 0 + -0.004709 0.011055 -9.78158 -0.022108 -0.009414 -1e-06 + -0.004709 0.011055 -9.78158 0 -0 0 + + + + 0 0 10 0 -0 0 + + + + + 27.9092 -19.3342 10.071 0 0.275643 2.35619 + orbit + perspective + + + + diff --git a/my_bot/worlds/obstacles.world b/my_bot/worlds/obstacles.world new file mode 100644 index 0000000..aa727e3 --- /dev/null +++ b/my_bot/worlds/obstacles.world @@ -0,0 +1,937 @@ + + + + + 1 + 0 0 10 0 -0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + 0 + 0 + 0 + + + + 1 + + + + + 0 0 1 + 100 100 + + + + + 65535 + + + + + 100 + 50 + + + + + + + + 10 + + + 0 + + + 0 0 1 + 100 100 + + + + + + + 0 + 0 + 0 + + + 0 0 -9.8 + 6e-06 2.3e-05 -4.2e-05 + + + 0.001 + 1 + 1000 + + + 0.4 0.4 0.4 1 + 0.7 0.7 0.7 1 + 1 + + + + EARTH_WGS84 + 0 + 0 + 0 + 0 + + + + + 0 0 0.4 0 -0 0 + 500 + + 51.2096 + 51.2096 + 25 + 0 + 0 + 0 + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + 10 + + + + + + + + + + + + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + + 0 + 0 + 0 + + -0.756237 1.39226 0 0 -0 0 + + + + + 0 0 0.4 0 -0 0 + 500 + + 51.2096 + 51.2096 + 25 + 0 + 0 + 0 + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + 10 + + + + + + + + + + + + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + + 0 + 0 + 0 + + 1.80022 0.377178 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + -2.19745 -2.25046 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + -1.40494 -2.55135 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + -0.501986 -2.9745 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + 2.09724 -2.18232 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + -3.69879 0.345038 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + -0.406438 -4.23374 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + 2.38815 -3.2576 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + 2.39316 -4.49605 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + -3.00495 -2.78053 0 0 -0 0 + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + + + + + + + + + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + 0 + + 0 0 0 0 -0 0 + + 1 + 0 + 0 + 1 + 0 + 1 + + 1 + + 0 + 0 + + -4.64786 -0.646522 0 0 -0 0 + + + + + 0 0 0.4 0 -0 0 + 500 + + 51.2096 + 51.2096 + 25 + 0 + 0 + 0 + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + 10 + + + + + + + + + + + + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + + 0 + 0 + 0 + + -5.3108 -2.23708 0 0 -0 0 + + + + + 0 0 0.4 0 -0 0 + 500 + + 51.2096 + 51.2096 + 25 + 0 + 0 + 0 + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + 10 + + + + + + + + + + + + + + + + + model://construction_barrel/meshes/construction_barrel.dae + + + + 0 + 0 + 0 + + -2.07692 -4.26198 0 0 -0 0 + + + 457 444000000 + 459 829915274 + 1646216792 728719362 + 457444 + + -0.756319 1.39223 0 0 0 -2.4e-05 + 1 1 1 + + -0.756319 1.39223 0 0 0 -2.4e-05 + 0 0 0 0 -0 0 + 3.45865 5.7443 4.40608 1.34644 0.778762 3.14097 + 1729.32 2872.15 2203.04 0 -0 0 + + + + 1.80014 0.377148 0 0 0 -2.2e-05 + 1 1 1 + + 1.80014 0.377148 0 0 0 -2.2e-05 + 0 0 0 0 -0 0 + 3.45864 5.7443 4.40608 1.34642 0.778778 3.14097 + 1729.32 2872.15 2203.04 0 -0 0 + + + + -5.31082 -2.23709 -0 0 -0 -7e-06 + 1 1 1 + + -5.31082 -2.23709 -0 0 -0 -7e-06 + 0 0 0 0 -0 0 + -3.87743 -2.8936 0.727843 -2.17783 0.268134 -3.13538 + -1938.71 -1446.8 363.922 0 -0 0 + + + + -2.07693 -4.26199 -0 0 0 -4e-06 + 1 1 1 + + -2.07693 -4.26199 -0 0 0 -4e-06 + 0 0 0 0 -0 0 + 7.60795 0.965639 1.20183 -2.41278 0.170207 0.001195 + 3803.98 482.819 600.916 0 -0 0 + + + + -2.19745 -2.25046 -0 0 -0 0 + 1 1 1 + + -2.19745 -2.25046 -0 0 -0 0 + 0 0 0 0 -0 0 + 0 -0 -0.008512 -2.58585 1.13682 3.14159 + 0 -0 -0.008512 0 -0 0 + + + + -1.40494 -2.55135 -0 0 -0 0 + 1 1 1 + + -1.40494 -2.55135 -0 0 -0 0 + 0 0 0 0 -0 0 + 0 -0 -0.008512 -2.58585 1.13682 3.14159 + 0 -0 -0.008512 0 -0 0 + + + + -0.501986 -2.9745 -0 0 -0 0 + 1 1 1 + + -0.501986 -2.9745 -0 0 -0 0 + 0 0 0 0 -0 0 + 0 -0 -0.008512 -2.58585 1.13682 3.14159 + 0 -0 -0.008512 0 -0 0 + + + + 2.09724 -2.18232 -0 1e-06 -0 0 + 1 1 1 + + 2.09724 -2.18232 -0 1e-06 -0 0 + 0 0 0 0 -0 0 + -0 -0 -9.79988 3e-05 2e-05 -0 + -0 -0 -9.79988 0 -0 0 + + + + -3.69879 0.345038 -1e-05 0 -0 0 + 1 1 1 + + -3.69879 0.345038 -1e-05 0 -0 0 + 0 0 0 0 -0 0 + 0 0 -9.8 0 -0 0 + 0 0 -9.8 0 -0 0 + + + + -0.406438 -4.23374 -0 0 -1e-06 0 + 1 1 1 + + -0.406438 -4.23374 -0 0 -1e-06 0 + 0 0 0 0 -0 0 + -0 0 0.008512 2.58585 -1.13682 -3.14159 + -0 0 0.008512 0 -0 0 + + + + 2.38815 -3.2576 -0 0 -0 0 + 1 1 1 + + 2.38815 -3.2576 -0 0 -0 0 + 0 0 0 0 -0 0 + 0 -0 -0.008512 -2.58585 1.13682 3.14159 + 0 -0 -0.008512 0 -0 0 + + + + 2.39316 -4.49605 -0 0 -1e-06 0 + 1 1 1 + + 2.39316 -4.49605 -0 0 -1e-06 0 + 0 0 0 0 -0 0 + -0 0 0.008512 2.58585 -1.13682 -3.14159 + -0 0 0.008512 0 -0 0 + + + + -3.00495 -2.78053 -0 0 -1e-06 0 + 1 1 1 + + -3.00495 -2.78053 -0 0 -1e-06 0 + 0 0 0 0 -0 0 + -0 0 0.008512 2.58585 -1.13682 -3.14159 + -0 0 0.008512 0 -0 0 + + + + -4.64786 -0.646522 -0 0 -1e-06 0 + 1 1 1 + + -4.64786 -0.646522 -0 0 -1e-06 0 + 0 0 0 0 -0 0 + -0 0 0.008512 2.58585 -1.13682 -3.14159 + -0 0 0.008512 0 -0 0 + + + + 0 0 0 0 -0 0 + 1 1 1 + + 0 0 0 0 -0 0 + 0 0 0 0 -0 0 + 0 0 0 0 -0 0 + 0 0 0 0 -0 0 + + + + 0 0 10 0 -0 0 + + + + + -15.5892 0.392985 21.6628 0 0.851642 0.028194 + orbit + perspective + + + + + From c92f3fcb6173d808c47f7b4b1af34917852a92b9 Mon Sep 17 00:00:00 2001 From: IvanCG14 <87621910+IvanCG14@users.noreply.github.com> Date: Thu, 11 Sep 2025 18:12:02 -0500 Subject: [PATCH 5/7] Create README.md --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..db8974f --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Proyecto Roboracer con Librerìa F1Tenth + +## Recorrido de circuito con Algoritmo de F1Tenth +El coche puede ser visualizado en rviz y al ejecutar el archivo obstaculosFTG, iniciarà el recorrido del circuito segùn el mapa designado en el archivo sim.yaml. +```bash +#F1tenth +ros2 launch f1tenth_gym_ros gym_bridge_launch.py +ros2 run controllers obstaculosFTG +``` +## Gazebo con F1Tenth +Se implementò tambièn la simulaciòn en Gazebo donde se cuenta con el vehìculo con su lidar y càmara de profundidad, por el momento no se puede trasladar el movimiento del robot hacia Gazebo porque hay problemas con los topicos al usar ros2_control. + +Los siguientes comandos son para ejecutar la simulaciòn en Gazebo y trabajan con el xacro gazebo_racecar.xacro. +```bash +# F1tenth con gazebo +# Mundo vacío (default) +ros2 launch f1tenth_gym_ros gazebo_test.launch.py + +# Con mundo personalizado +ros2 launch f1tenth_gym_ros gazebo_test.launch.py world:=./src/f1tenth_gym_ros/worlds/levine.world +``` + +Para instalar dependencias necesarias, seguir los primeros pasos de este repositorio de git: + +https://github.com/widegonz/F1Tenth-Repository From 514f0c8b0a487fbe2e8472611c8bf20c41b27998 Mon Sep 17 00:00:00 2001 From: IvanCG14 <87621910+IvanCG14@users.noreply.github.com> Date: Thu, 11 Sep 2025 18:20:38 -0500 Subject: [PATCH 6/7] Update README.md --- README.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index db8974f..81c31fb 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# Proyecto Roboracer con Librerìa F1Tenth +# Proyecto Roboracer con Librería Nav2 -## Recorrido de circuito con Algoritmo de F1Tenth -El coche puede ser visualizado en rviz y al ejecutar el archivo obstaculosFTG, iniciarà el recorrido del circuito segùn el mapa designado en el archivo sim.yaml. +## Recorrido de circuito con Nav2 +El coche puede ser visualizado en rviz y al ejecutar el archivo obstaculosFTG, iniciarà el recorrido del circuito según el mapa designado en el archivo sim.yaml. ```bash #F1tenth ros2 launch f1tenth_gym_ros gym_bridge_launch.py ros2 run controllers obstaculosFTG ``` -## Gazebo con F1Tenth -Se implementò tambièn la simulaciòn en Gazebo donde se cuenta con el vehìculo con su lidar y càmara de profundidad, por el momento no se puede trasladar el movimiento del robot hacia Gazebo porque hay problemas con los topicos al usar ros2_control. +## Mapeo usando SLAM +Se implementó también la simulación en Gazebo donde se cuenta con el vehìculo con su lidar y cámara de profundidad, por el momento no se puede trasladar el movimiento del robot hacia Gazebo porque hay problemas con los topicos al usar ros2_control. -Los siguientes comandos son para ejecutar la simulaciòn en Gazebo y trabajan con el xacro gazebo_racecar.xacro. +Los siguientes comandos son para ejecutar la simulación en Gazebo y trabajan con el xacro gazebo_racecar.xacro. ```bash # F1tenth con gazebo # Mundo vacío (default) @@ -19,7 +19,3 @@ ros2 launch f1tenth_gym_ros gazebo_test.launch.py # Con mundo personalizado ros2 launch f1tenth_gym_ros gazebo_test.launch.py world:=./src/f1tenth_gym_ros/worlds/levine.world ``` - -Para instalar dependencias necesarias, seguir los primeros pasos de este repositorio de git: - -https://github.com/widegonz/F1Tenth-Repository From 447605c6578391ba522d0cf3d40384274a74cf1e Mon Sep 17 00:00:00 2001 From: IvanCG14 <87621910+IvanCG14@users.noreply.github.com> Date: Fri, 12 Sep 2025 10:00:33 -0500 Subject: [PATCH 7/7] Update README.md --- README.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 81c31fb..bb49b83 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,26 @@ # Proyecto Roboracer con Librería Nav2 ## Recorrido de circuito con Nav2 -El coche puede ser visualizado en rviz y al ejecutar el archivo obstaculosFTG, iniciarà el recorrido del circuito según el mapa designado en el archivo sim.yaml. +El coche puede ser visualizado en rviz y al ejecutar el archivo se definen puntos para que siga una trayectoria. ```bash -#F1tenth -ros2 launch f1tenth_gym_ros gym_bridge_launch.py -ros2 run controllers obstaculosFTG +#definir ruta del world a utilizar +ros2 launch my_bot launch_sim.launch.py world:=./src/my_bot/worlds/obstacles.world +rviz2 + +#definir la ruta del mapa que se prefiera usar +ros2 launch my_bot localization_launch.py map:=./src/my_bot/maps/levine.yaml use_sim_time:=true +ros2 launch my_bot navigation_launch.py use_sim_time:=true map_subscribe_transient_local:=true ``` ## Mapeo usando SLAM -Se implementó también la simulación en Gazebo donde se cuenta con el vehìculo con su lidar y cámara de profundidad, por el momento no se puede trasladar el movimiento del robot hacia Gazebo porque hay problemas con los topicos al usar ros2_control. -Los siguientes comandos son para ejecutar la simulación en Gazebo y trabajan con el xacro gazebo_racecar.xacro. ```bash -# F1tenth con gazebo -# Mundo vacío (default) -ros2 launch f1tenth_gym_ros gazebo_test.launch.py +# ejecutar simulacion, definir mundo a usar +ros2 launch my_bot launch_sim.launch.py world:=./src/my_bot/worlds/obstacles.world +rviz2 + +# ejecutar SLAM +ros2 launch slam_toolbox online_async_launch.py params_file:=./src/my_bot/config/mapper_params_online_async.yaml use_sim_time:=true -# Con mundo personalizado -ros2 launch f1tenth_gym_ros gazebo_test.launch.py world:=./src/f1tenth_gym_ros/worlds/levine.world +# mapear con teleop (eliminar lo que esta despues del 2do keyboard si hay problemas) +ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -r /cmd_vel:=/diff_cont/cmd_vel_unstamped ```